// jquery.formcontrol.js
// autor: Rafał Pietrzak
// wersja: 1.0

//.fcForm(options)
// Ostylowuje wszystkie kontrolki zgodnie z podanymi klasami.
// Opcje:
//  selectOptions - opcje do ostylowania Selectów (domyślnie takie jak w $.fcSelect)
//  checkboxOptions - opcje do ostylowania Checkboxów (domyślnie takie jak w $.fcCheckbox)
//  radioOptions - opcje do ostylowania Radio (domyślnie takie jak w $.fcRadio)
//  fileOptions - opcje do ostylowania Input files (domyślnie takie jak w $.fcFile)
(function($){
    $.fn.fcForm = function(options) {
        var selectOpt = {
            className: "formcontrols_select",
            maxHeight: 100,
            showSpeed: "slow",
            hideSpeed: "fast"
        };
        var checkboxOpt = {
            className: "formcontrols_checkbox"
        };
        var radioOpt = {
            className: "formcontrols_radio"
        };
        var fileOpt = {
            className: "formcontrols_file",
            selectFileText: "wybierz plik"
        };
        var defaults = {
            selectOptions: selectOpt,
            checkboxOptions: checkboxOpt,
            radioOptions: radioOpt,
            fileOptions: fileOpt
        };
        options = $.extend(defaults, options);
        return this.each(function() {
            if($(this).is("select")) {
                $.fcSelect(options.selectOptions);
            }
            else if($(this).is(":checkbox")) {
                $.fcCheckbox(options.checkboxOptions);
            }
            else if($(this).is(":radio")) {
                $.fcRadio(options.radioOptions);
            }
            else if($(this).is("file")) {
                $.fcFile(options.fileOptions);
            }
        });
    };
})(jQuery);


// $.fcSelect(options)
// Ostylowuje select zgodnie z podaną klasą.
// Opcje:
//  className - nazwa klasy jaka ma zostać wykorzystana (domyślnie: "formcontrols_select")
//  maxHeight - maksymalna wysokość rozwijanej listy z opcjami (domyślnie: 100)
//  showSpeed - szybkość rozwijania się listy z opcjami (domyślnie "slow")
//  hideSpeed - szybkość zwijania się listy z opcjami (domyślnie: "fast")
//
// Struktura nowego selecta:
//  <label for="[ID]">[TEKST]</label> (opcjonalne)
//  <div class="[KLASA:className]">
//   <a class="fc_input">[WYBRANA WARTOŚĆ]</a>
//   <a class="fc_btn"></a>
//   <div class="clear"></div>
//   <div class="fc_options"> (ukryty, pojawia się przy wybieraniu)
//    <a>[OPCJA]</a>
//    ...
//   </div>
//   <select id="[ID]"> (ukryte na stałe)
//    <option>[OPCJA]</option>
//    ...
//   </select>
//  </div>
(function($){
    $.fn.fcSelect = function(options) {
        var defaults = {
            className: "formcontrols_select",
            maxHeight: 100,
            showSpeed: "slow",
            hideSpeed: "fast"
        };
        options = $.extend(defaults, options);
        $("*").click(function() {
            $("."+options.className+" .fc_options").hide(options.hideSpeed);
        });
        var showFunc = function(event) {
            event.preventDefault();
            event.stopPropagation();
            var optionsList = $(this).parent().find('.fc_options');
            
            if($(optionsList).height() > options.maxHeight) {
                $(optionsList).height(options.maxHeight);
                $(optionsList).find("a").width($(optionsList).width() - 30);
            }
            $('.fc_options').hide(options.hideSpeed);
            $(optionsList).show(options.showSpeed);
            return false;
        }
        var selectFunc = function() {
            $(this).parent().parent().find('.fc_input').text($(this).text());
            $(this).parent().parent().find('select').val($(this).data("value"));
            $(this).parent().hide(options.hideSpeed);
            $(this).parent().parent().find('select').change();
            return false;
        }
        return this.each(function() {
            if($(this).is("select")) {
                $(this).wrap('<div class="'+options.className+'"></div>');
                var inputTag = $('<a class="fc_input" href="#">'+$(this).find(":selected").text()+'</a>').click(showFunc);
                $(this).before(inputTag);
                var btnTag = $('<a class="fc_btn" href="#">&#160;</a>').click(showFunc);
                $(this).before(btnTag);
                $(this).before('<div class="clear"></div>');
                $(this).before('<div class="fc_options"></div>');
                $(this).find('option').each(function() {
                    var aTag = $('<a href="#">'+$(this).text()+'</a>').click(selectFunc);
                    $(aTag).data("value", $(this).val());
                    $(this).parent().parent().find('.fc_options').append(aTag);
                });
                $("label[for='"+$(this).attr("id")+"']").click(function(event){
                    event.preventDefault();
                    event.stopPropagation();
                    $("#"+$(this).attr("for")).parent().find(".fc_btn").click();
                })
                $(this).hide();
            }
        });
    };
})(jQuery);

// $.fcSelectRefresh(options)
// Odświeża zawartość wirtualnego selecta z prawdziwego.
// Opcje:
//  className - nazwa klasy jaka ma zostać wykorzystana (domyślnie: "formcontrols_select")
//  showSpeed - szybkość rozwijania się listy z opcjami (domyślnie "slow")
//  hideSpeed - szybkość zwijania się listy z opcjami (domyślnie: "fast")
(function($){
    $.fn.fcSelectRefresh = function(options) {
        var defaults = {
            className: "formcontrols_select",
            showSpeed: "slow",
            hideSpeed: "fast"
        };
        options = $.extend(defaults, options);
        var selectFunc = function() {
            $(this).parent().parent().find('.fc_input').text($(this).text());
            $(this).parent().parent().find('select').val($(this).data("value"));
            $(this).parent().hide(options.hideSpeed);
            $(this).parent().parent().find('select').change();
            return false;
        }
        return this.each(function() {
            if($(this).is("."+options.className+" select")) {
                $(this).parent().find('.fc_options').remove();
                $(this).before('<div class="fc_options"></div>');
                $(this).find('option').each(function() {
                    var aTag = $('<a href="#">'+$(this).text()+'</a>').click(selectFunc);
                    $(aTag).data("value", $(this).val());
                    $(this).parent().parent().find('.fc_options').append(aTag);
                });
                $(this).parent().find('.fc_input').html($(this).find(":selected").text());
            }
        });
    };
})(jQuery);

// $.fcCheckbox()
// Ostylowuje checkboxy zgodnie z podaną klasą. Można podczepiać pod labele checkboxów lub pod same checkboxy.
// Opcje:
//  className - nazwa klasy jaka ma zostać wykorzystana (domyślnie: "formcontrols_checkbox")
//
// Struktura nowego checkboxa:
//  <label for="[ID]">[TEKST]</label> (opcjonalne)
//  <div class="[KLASA:className]">
//   <a class="fc_box (fc_checked)"></a>
//   <input type="checkbox" id="[ID]" name="[NAZWA]" value="[WARTOŚĆ]" /> (ukryte na stałe)
//  </div>
(function($){
    $.fn.fcCheckbox = function(options) {
        var defaults = {
            className: "formcontrols_checkbox"
        };
        options = $.extend(defaults, options);
        var checkFunc = function(event) {
            var fake, real;
            if($(this).is("a")) {
                fake = $(this);
                real = $(this).parent().find(":checkbox");
            }
            else if($(this).is("label")) {
                fake = $("#"+$(this).attr("for")).parent().find("a.fc_box");
                real = $("#"+$(this).attr("for"));
            }
            if($(real).is(":checked")) {
                $(real).removeAttr("checked");
            }
            else {
                $(real).attr("checked", "checked");
            }
            $(fake).toggleClass("fc_checked");
            $(real).change();
            return false;
        }
        return this.each(function() {
            if($(this).is("label")) {
                var forId = $(this).attr("for");
                if(forId != '') {
                    var input = $("#"+forId);
                    if($(input).is(":checkbox")) {
                        $(input).wrap('<div class="'+options.className+'"></div>');
                        var checked = '';
                        if($(input).is(":checked")) {
                            checked = " fc_checked";
                        }
                        var box = $('<a class="fc_box'+checked+'" href="#">&nbsp;</a>').click(checkFunc);
                        $(input).before(box);
                        $(this).click(checkFunc);
                        $(input).hide();
                    }
                }
            }
            else if($(this).is(":checkbox")) {
                var input = $(this);
                $(input).wrap('<div class="'+options.className+'"></div>');
                var checked = '';
                if($(input).is(":checked")) {
                    checked = " fc_checked";
                }
                var box = $('<a class="fc_box'+checked+'" href="#">&nbsp;</a>').click(checkFunc);
                $(input).before(box);
                $("label[for='"+$(this).attr("id")+"']").click(function(event){
                    event.preventDefault();
                    event.stopPropagation();
                    $("#"+$(this).attr("for")).parent().find(".fc_box").click();
                });
                $(input).hide();
            }
        });
    };
})(jQuery);

// $.fcRadio()
// Ostylowuje radio zgodnie z podaną klasą. Można podczepiać pod labele radio lub pod same radio.
// Opcje:
//  className - nazwa klasy jaka ma zostać wykorzystana (domyślnie: "formcontrols_radio")
//
// Struktura nowego checkboxa:
//  <label for="[ID]">[TEKST]</label> (opcjonalne)
//  <div class="[KLASA:className]">
//   <a class="fc_box (fc_checked)"></a>
//   <input type="checkbox" id="[ID]" name="[NAZWA]" value="[WARTOŚĆ]" /> (ukryte na stałe)
//  </div>
//  ... (inne radio o tej samej nazwie)
(function($){
    $.fn.fcRadio = function(options) {
        var defaults = {
            className: "formcontrols_radio"
        };
        options = $.extend(defaults, options);
        var checkFunc = function(event) {
            var fake, real;
            if($(this).is("a")) {
                fake = $(this);
                real = $(this).parent().find(":radio");
            }
            else if($(this).is("label")) {
                fake = $("#"+$(this).attr("for")).parent().find("a.fc_box");
                real = $("#"+$(this).attr("for"));
            }
            $(":radio[name='"+$(real).attr("name")+"']").parent().find("a.fc_box").removeClass("fc_checked");
            $(real).attr("checked", "checked");
            $(fake).addClass("fc_checked");
            $(real).change();
            return false;
        }
        return this.each(function() {
            if($(this).is("label")) {
                var forId = $(this).attr("for");
                if(forId != '') {
                    var input = $("#"+forId);
                    if($(input).is(":radio")) {
                        $(input).wrap('<div class="'+options.className+'"></div>');
                        var checked = '';
                        if($(input).is(":checked")) {
                            checked = " fc_checked";
                        }
                        var box = $('<a class="fc_box'+checked+'" href="#">&nbsp;</a>').click(checkFunc);
                        $(input).before(box);
                        $(this).click(checkFunc);
                        $(input).hide();
                    }
                }
            }
            else if($(this).is(":radio")) {
                var input = $(this);
                $(input).wrap('<div class="'+options.className+'"></div>');
                var checked = '';
                if($(input).is(":checked")) {
                    checked = " fc_checked";
                }
                var box = $('<a class="fc_box'+checked+'" href="#">&nbsp;</a>').click(checkFunc);
                $(input).before(box);
                $("label[for='"+$(this).attr("id")+"']").click(function(event){
                    event.preventDefault();
                    event.stopPropagation();
                    $("#"+$(this).attr("for")).parent().find(".fc_box").click();
                });
                $(input).hide();
            }
        });
    };
})(jQuery);

// $.fcFile()
// Ostylowuje input file zgodnie z podaną klasą.
// Opcje:
//  className - nazwa klasy jaka ma zostać wykorzystana (domyślnie: "formcontrols_file")
//
// Struktura nowego input file:
//  <label for="[ID]">[TEKST]</label> (opcjonalne)
//  <div class="[KLASA:className]">
//   <div class="fc_container">
//     <div class="fc_input"><input type="text" /></div>
//     <a class="fc_btn"></a>
//     <div class="clear"></div>
//   </div>
//   <input type="file" id="[ID]" name="[NAZWA]" /> (ukryte na stałe)
//  </div>
(function($){
    $.fn.fcFile = function(options) {
        var defaults = {
            className: "formcontrols_file",
            selectFileText: ""
        };
        options = $.extend(defaults, options);
        return this.each(function() {
            if($(this).is(":file")) {
                var replacer = $('<div class="'+options.className+'"></div>');
                $(this).wrap(replacer);
                var container = $('<div class="fc_container"></div>');
                var inputTag = $('<div class="fc_input"><input type="text" readonly="readonly" value="'+options.selectFileText+'" /></div>').click(function(){
                    $(this).parent().parent().parent().find(":file").click();
                });
                container.append(inputTag);
                var btnTag = $('<a class="fc_btn" href="#">&#160;</a>').click(function(event){
                    event.preventDefault();
                });
                container.append(btnTag);
                container.append('<div class="clear"></div>');
                container.css({'position': 'absolute', 'top': 0, 'left': 0});
                $(this).before(container);
                $(this).css({'width': btnTag.width()+'px', 'cursor': 'pointer', 'opacity': 0, 'height': '100%', 'position': 'absolute', 'top': 0, 'left': (container.width() - btnTag.width())+'px'});
                $(this).change(function() {
                    $(this).parent().find(".fc_input input").val($(this).val());
                });
                $("label[for='"+$(this).attr("id")+"']").click(function(event){
                    event.preventDefault();
                    event.stopPropagation();
                    $("#"+$(this).attr("for")).click();
                });
            }           
        });
    };
})(jQuery);