/**
 * formConflictManager
 *
 * Im Objekt <code>OptionConflicts</code> wird für jede Option eines
 * Formulars festgelegt, mit welchen anderen Optionen ein
 * Konflikt besteht. Diese Konflikt-Optionen werden
 * inaktiv geschaltet. Beim Klick auf deren Label erscheint
 * eine Hilfsblase, die erklärt, warum die Option deaktiviert wurde
 *
 * @version      0.3
 * @author       Dragan Espenschied
 * @requires     jQuery 1.2.6, 1.3.1
 * @requires     help
 * @requires     utils
 * @requires     OptionConflicts
 * @todo         Muss internationalisiert werden über JS-Lexicon
 * @todo         Definieren, woraus die Hilfblasen ihre Info beziehen
 *               (DOM-Struktur)
 */

var formConflictManager = {

    /**
      * Bereitet anhand des Objektes <code>OptionConflicts</code>
      * Konflikt-Buttons vor.
      * Dazu müssen alle Buttons mit Konflikt-Fällen auf ihr
      * "name"-Attribut untersucht werden. Alle Buttons, die
      * den gleichen "name" tragen, werden mit dem Handler belegt.
      *
      * @todo: Auch für select/option ausprogrammieren
      * @todo: help als callback
      */


    controlClass: 'preSelect',

    init: function() {

        if(typeof(OptionConflicts) == "undefined") return false;

        for (var option in OptionConflicts) {
            element = Util.idDom(option);                       // DOM-Element mit der ID
            if ( !element) {
              element =  Util.idDom('e' + option);            // DOM-Element mit der ID im Umschlag
		          if ( !element ) continue;
              // ??
	            // cover element gefunden
              // cover attribut, -> neues Elemet anlehen und ueberall ein 'e' voranstellen
              OptionConflicts['e' + option]=new Array( OptionConflicts[option].length );
              jQuery.each( OptionConflicts[option], function(n) {
                  OptionConflicts['e' + option][n]= 'e'+this;
              });
            }
            formConflictManager.buttonList.push(element);       // Dieses Element in Liste
                                                                // speichern.

            // Verwandte Buttons suchen, gleiche Namen können bei
            // Radiobuttons oder Listboxen (<select>) vorkommen.
            // Alle diese müssen den Konflikt eventuell wieder
            // auflösen können!
            // Radio-Buttons haben den gleichen Namen,
            // <options> haben entsprechende Siblings.

            if (element.tagName == "INPUT" && element.type == "radio") {
            
              $("[name=" + element.name + "]").each(function(){
                formConflictManager.buttonList.push(this);
              });
              
              //als ausgewahlt merken fuer abwahl
              if (element.checked) {
               $(element).data('checked', true);
              }

            } else if(element.tagName == "OPTION") {

                $(element).siblings("option").each(function() {
                    formConflictManager.buttonList.push(this);
                });
            }

        };
        
        

        // gefundene Buttons konsolidieren (ein button kann von mehreren
        // anderen als Konflikt angegeben werden und daher mehrmals in der
        // liste erscheinen
        formConflictManager.buttonList = $.unique(formConflictManager.buttonList);

        // allen Buttons das Konflikt-Verhalten zuweisen
        $.each(formConflictManager.buttonList, function() {

            // den labels einen "überdecker" für die Radiobuttons mitgeben,
            // damit die im disabled-zustand geklickt werden können
            $('label[for='+this.id+']').append('<div class="cover"></div>');

            $(this).bind("click", function(event) {
                $(this).parents('form').find('.helpBubble-attached').removeBubble();
                //window,setTimeout(function(){
                //wenn radio schon ausgewahlt ist, abwaehlen
                if (this.tagName == "INPUT" && this.type == "radio") {
                  if ($(this).data('checked')) {
                    this.checked = false;
                    $(this).data('checked', false);
                    //preisberechung unterdruecken
                    PriceCalc.missingRadio = true;
                  }
                  else {
                    PriceCalc.missingRadio = false;
                    $(this).data('checked', true);
                  }
                }
                formConflictManager.handler();
                //},1000); //etwas warten wegen subForms
            });


            /**
             * @todo: help-funktion als callback!
             */
            $(this).parent("li").bind("click", function() {
                formConflictManager.help(this);
            });


        });

        // IE checkt click auf options nicht, daher
        // umgehung über select. Außerdem muss die disabled-funktionalität
        // für options nachgebaut werden, siehe auch ie-fix.js!
        if($.browser.msie) {
            $("select").bind("change", function(){formConflictManager.handler()});
        }

        // einmal alles laufen lassen, um den korrekten
        // Anfangszustand herzustellen.
        formConflictManager.handler();

    },

    /*
     * buttonList: Cache der Buttons-Nodes, die eventuell einen
     * Options-Konflikt auslösen oder auflösen können.
     * Wird von init gefüllt;
     */

    buttonList: [],

    /*
     * disabledButtons: Cache der aktuell inaktiven Button-Nodes
     */

    disabledButtons: [],

    /*
     * invisibleButtons: Cache der aktuell ausgeblendeten Button-Nodes
     */

    invisibleButtons: [],

    handler: function() {

        // zuerst alle inaktiven Buttons wieder aktivieren
        jQuery.each(formConflictManager.disabledButtons, function() {
            if ( this ) {
                this.disabled=false;
                $("label[for="+this.id+"]").removeClass("disabled");
                $(this).removeClass("disabled");
            }
        });

        formConflictManager.disabledButtons = [];

        // alle unsichtbaren Buttons wieder einblenden
        jQuery.each(formConflictManager.invisibleButtons, function() {
            if ( this ) {
                $([this.parentNode, this]).show();
            }
        });

        formConflictManager.invisibleButtons = [];

        for (var option in OptionConflicts) {

            element=Util.idDom(option);
            if (!element) continue;

            // Es werden Checkboxen, Radiobuttons und Option-Menüs unterstützt
            if(element.tagName == "INPUT" || element.tagName == "OPTION") {
                if(element.checked || element.selected) {


                    jQuery.each(OptionConflicts[option], function() {
                        var victim = Util.idDom(this);

                        //format cover extra testen, da cover kein eigenes format hat
                        if ( option.match(/^attr_format/) && Util.idDom('e'+this)) {
                               formConflictManager.disabledButtons.push(Util.idDom('e'+this));
                        }

                        if ( victim ) {

                            // Das Opfer wird in die Liste mit inaktiven Buttons
                            // geschoben
                            formConflictManager.disabledButtons.push(victim);

                            // ????
                            // abhängig von einer Klasse werden die betroffenen Elemente
                            // zusätzlich zum Inaktiv-Schalten auch noch ausgeblendet
                            if  (
                                    // der button oder dessen parent haben die Kontoll-Klasse
                                    // gesetzt ...
                                    (
                                    $(element).hasClass(formConflictManager.controlClass)
                                        ||
                                    $(element).parent().hasClass(formConflictManager.controlClass)
                                    )
                                    // ... und das Opfer hat sie NICHT gesetzt.
                                    // Denn zwei Kontrollen können sich gegenseitig nicht
                                    // ausblenden, sondern nur inaktiv schalten (Konfigurations-
                                    // Hierarchie)
                                    && !$(victim).hasClass(formConflictManager.controlClass)

                                    // Außerdem werden Elemente in <select>-Listen verschont!
                                    // zu viele Komplikationen mit dem IE
                                    && (victim.tagName!='OPTION')
                                ) {
                                    // Wenn das alles zutrifft, wird das Opfer ausgeblendet
                                    formConflictManager.invisibleButtons.push(victim);
                                }
                        }
                    });


                }
            }
        }


        // Die disabled- und invisible-Listen durchgehen und
        // die Elemente entsprechend vernichten
        $.each(formConflictManager.disabledButtons, function() {
            this.disabled = true;
            $("label[for="+this.id+"]").addClass("disabled");


            // Wenn ein <option>-Element, das bereits ausgewählt wurde, deaktiviert wird,
            // muss ein anderes gefunden werden, das noch auswählbar ist.
            if(this.tagName=="OPTION" && this.selected) {
                this.selected = false; // beim FF reicht das schon ... nett!

                var found = false;      // wurde eine ersatz-<option> gefunden?
                $("#" + this.id + " ~ option").each(function() {

                    // nach einer verwandten <option> suchen, die nicht
                    // in der ausblende-liste steht
                    if (!found) for(var i=0; i<formConflictManager.disabledButtons.length; i++) {
                        if(formConflictManager.disabledButtons[i] != this)
                            this.selected = true;
                            found = true;
                            break;
                    }
                });
            }
            // Wenn ein <radio>-Element, das bereits ausgewählt wurde, deaktiviert wird,
            // muss ein anderes gefunden werden, das noch auswählbar ist.
            if(this.tagName=="INPUT" && this.type=='radio' && this.checked) {
                this.checked = false; // beim FF reicht das schon ... nett!

                var found = false;
                $("input:radio[name=" + this.name+']').each(function() {
                     
                     if (found) return;
                     if(!$(this).is(':disabled')) {
 
                        this.checked = true;
                        found =true;
                        return;
                     }

                });
            }
        });

        // Wenn Elemente ausgeblendet werden, muss noch allerhand
        // anderes getan werden.
        $.each(formConflictManager.invisibleButtons, function() {
            // bei <select>-menüs sollte der parent nicht versteckt werden!
            if(this.tagName=="OPTION")
                $(this).hide()
            else
                $([this.parentNode, this]).hide();
            // ist der auszublendende knopf ausgewählt?
            // dann wird er deselektiert und der nächste passende Knopf
            // als Ersatz ausgesucht.

            if(this.tagName=="INPUT") {
                if(this.type=="radio" && this.checked) {
                    this.checked = false;
                    $("input[name="+ this.name +"]:visible:first")[0].checked = true;
                }

                // im Falle einer Checkbox wird diese beim Ausblenden gleich noch
                // de-selektiert.
                else if(this.type=="checkbox" && this.checked) {
                    this.checked = false;
                }
            }
        });



    },

    help: function(element) {

        var myLabel;
        var myButtonId;
        var helpMarker = [];

        if(element.tagName=="LABEL") {
            myLabel = element;
            buttonId = myLabel.attributes["for"].value;

        } else if(element.tagName=="INPUT") {
            myLabel = $("label[for="+element.id+"]")[0];
            buttonId = element.id;
        } else {
            myLabel = $(element).children("label")[0];
            buttonId = myLabel.attributes["for"].value;
        }

        var myLabelText = $(myLabel).text();

        var myCategory =
            $("#"+buttonId).parent().parent().parent().children("h3").text();


        // ist der button disabled?
        if(document.getElementById(buttonId).disabled) {
            // Liste der Elemente, die eventuell dafür gesorgt haben,
            // dass diese Option inaktiv ist, und in helpMarker speichern.
            $.each(OptionConflicts[buttonId], function() {
                if(
                    document.getElementById(this)
                    &&
                    document.getElementById(this).checked
                ) {
                    helpMarker.push( document.getElementById(this) );
                };
            });
            $.each(helpMarker, function() {

                var conflictLabelText = $("label[for="+this.id+"]").text();

                // Hier ist fest verdrahtet, woher die Hilfs-Informationen
                // geholt werden!
                var conflictCategory = $(this).parent().parent().parent().children("h3").text();

                var conflictext = $('#OptionConflict').html();
                if (conflictext) {
                  conflictext = conflictext.replace('%myLabelText%', myLabelText);
                  conflictext = conflictext.replace(/%conflictCategory%/g, conflictCategory);
                  conflictext = conflictext.replace('%conflictLabelText%', conflictLabelText);
                  $(this).createBubble(myCategory + " " + conflictext);
                }
            });
            $(myLabel).addClass("blink").animate({a:9}, 200, function(){$(this).removeClass("blink")});

        }
    }




};
