// all packages need to dojo.provide() _something_, and only one thing
dojo.provide("com.ba.gui.SimpleStep");

dojo.require("dojo.fx");
dojo.require("com.ba.gui");
dojo.require("com.ba.Util");
dojo.require("com.ba.gui.ConnectionTrackingWidget");
dojo.require("com.ba.gui.SimpleStepManager");

dojo.declare(
    "com.ba.gui._SimpleStepOption",
    com.ba.gui.ConnectionTrackingWidget,
    {
        _simpleStepOptionId: "",
        _selectOptionId: "",
        _hoverClass: "hover",
        
        constructor: function(stepOptionId, selectOptionId)
        {
            this._simpleStepOptionId = stepOptionId;
            this._selectOptionId = selectOptionId;
            var stepOption = dojo.byId(this._simpleStepOptionId);

            this.CreateConnect(stepOption, "onmouseenter", this, "OnMouseEnter");
            this.CreateConnect(stepOption, "onmouseleave", this, "OnMouseLeave");
            this.CreateConnect(stepOption, "onclick", this, "OnClick");
            
        },
        
        GetOptionText: function()
        {
            return(dojo.byId(this._simpleStepOptionId).innerHTML);
        },
        
        OnDeselect: function()
        {
            if(dojo.hasClass(this._simpleStepOptionId, this._hoverClass) === true)
            {
                dojo.removeClass(this._simpleStepOptionId, this._hoverClass);
            }
        }, 
        
        OnMouseEnter: function(domEvent)
        {
            //var stepOption = dojo.byId(this._simpleStepOptionId);
            dojo.addClass(this._simpleStepOptionId, this._hoverClass);
        },
        
        OnMouseLeave: function(domEvent)
        {
            dojo.removeClass(this._simpleStepOptionId, this._hoverClass);
        },
        
        OnClick: function(domEvent)
        {
            this.OnSelect(this);
			dojo.stopEvent(domEvent);
        },
        
        OnSelect: function(eventSource)
        {
            dojo.byId(this._selectOptionId).selected = true;
            //~ dojo.removeClass(this._simpleStepOptionId, this._hoverClass);
        }
    }
);



// our declared class
dojo.declare(
    "com.ba.gui.SimpleStep", 
    com.ba.gui.ConnectionTrackingWidget,
    {
        // Private properties
        _stepHolderId : "",
        _currentStepTextId: "",
        _selectId: "",
        _dropDownId: "",
        _dropDownOverflowerId: "",
        _olAnimation :"",
        _animating: "simplestep_animating",
        _animationDuration: 300,
        _optionList: "",
        _currentOption: undefined,
        _firstShow: true,
        _firstHide: true,
		_selectionChangeId: true,
    
        /**
        * Constructor....
        * Note this simpleStep class will notify the simpleStepManager of its pressence
        * Except when: the build function fails. (i.e. when it's already run, on script errors or when missing elements)
        **/
        constructor: function(simpleStepHolder){

            if(!simpleStepHolder.id.length)
            {
                simpleStepHolder.id = com.ba.Util.GenerateId();
            }
            
            this._optionList = [];
            
            this._stepHolderId = simpleStepHolder.id;

            if(this._BuildSimpleStepBody())
            {
                var managerInstance = com.ba.gui.SimpleStepManager.GetInstance();
                
                managerInstance.AddSimpleStep(this);
            
            }
            
        },
        
        GetSimpleStepName: function()
        {
            return(this._stepHolderId);
        },
        
        /***
        * Doing the real work: creating the html elements
         *
         * adds the right html for each select item in the <element class="simpleStep..."> 
         *   You end up with the followingStructure
         *    * parentElement class="stepX simpleStep"
         *       |- label
         *       |   |- span 
         *       |
         *       |- select
         *       |   |- option (optional)
         *       |
         *       |- div class = "simpleStepBody"
         *       |   |- div class = "simpleStepContent"
         *       |       |- div class="selectionHolder"
         *       |
         *       |- div class = "dropDown"
         *           |- ol
         *               |- li  (optional)
         *               
        **/
        _BuildSimpleStepBody: function(){

        
            var simpleStepHolder = dojo.byId(this._stepHolderId);
            
            var selectElement;
            
            var selectElements = dojo.query("select", simpleStepHolder);
            
            // Find the current selectElement
            selectElements.forEach(function(currentSelect){
                selectElement = currentSelect;
            });
            
            if(selectElement.id === undefined)
            {
                selectElement.id = com.ba.Util.GenerateId();
            }
            
            this._selectId = selectElement.id;
            
            if(!selectElement)
            {
                console.debug("Warning: no select element found for SimpleStep widget (Source com.ba.gui.SimpleStep)");
                return false;
            }
            
            var simpleStepBody;
            var simpleStepContent;
            var selectionHolder;
            var dropDown;
            var dropDownOverflower;
            var orderedList;
            
            // Existing DOMelements
            var optionList;
            var optionElement;
            
            
            // Mootools Fx.Slide instances
            var dropdownSlideFx;
            var olSlideFx;
            
            // Is it disabled?
            if(selectElement.disabled)
            {
                //~ console.debug("To do: set Opacity. Source: CBSCreateSimpleStepReplacement(selectElement)");
                dojo.style(simpleStepHolder,"opacity","0.5");
                //~ simpleStepHolder.setOpacity(0.5);
            } else {
                //~ console.debug("To do: set Opacity. Source: CBSCreateSimpleStepReplacement(selectElement)");
                dojo.style(simpleStepHolder,"opacity","1.0");
                //~ simpleStepHolder.setOpacity(1.0);
            }
            
            if(dojo.hasClass(simpleStepHolder, "simpleStepReplaced"))
            {
                return false;
            }
            
            // Create the 'input element'
            selectionHolder = document.createElement("div");
            
            // See if we can get the current value...
            if(selectElement.selectedIndex != -1)
            {
                // Create a textnode to fill and put it in the selectionHolder
                selectionHolder.appendChild(document.createTextNode(selectElement.options[selectElement.selectedIndex].innerHTML));
                if(selectElement.options[selectElement.selectedIndex].value!=-1)
                {
                    dojo.addClass(selectionHolder, "selectionHolder_active");
                }
                
            } else {
            
                // selection is empty/undefined
                selectionHolder.appendChild(document.createTextNode(" "));
            }
            
            // Set the class
            dojo.addClass(selectionHolder, "selectionHolder");
            
            simpleStepBody = document.createElement("div");
            dojo.addClass(simpleStepBody, "simpleStepBody");
            
            dojo.connect(simpleStepBody, "onmouseenter", function(domEvent){
                dojo.addClass(simpleStepBody, "simpleStepBodyHover");
            });
            dojo.connect(simpleStepBody, "onmouseleave", function(domEvent){
                dojo.removeClass(simpleStepBody, "simpleStepBodyHover");
            });
            simpleStepContent = document.createElement("div");
            simpleStepContent.id = com.ba.Util.GenerateId();
            dojo.addClass(simpleStepContent, "simpleStepContent");
            
            dojo.connect(simpleStepContent, "onmouseenter", function(domEvent){
                dojo.removeClass(simpleStepBody, "simpleStepBodyHover");
            });
            
            selectionHolder.id = com.ba.Util.GenerateId();
            this._currentStepTextId = selectionHolder.id;
            
            // Add it to the documentstructure
            simpleStepContent.appendChild(selectionHolder);
            simpleStepBody.appendChild(simpleStepContent);
            selectElement.parentNode.appendChild(simpleStepBody);
            
            // Create the holder for the dropDown itself. Needed because the css style overflow: auto ruins the slide behaviour...
            dropDown = document.createElement('div');
            dojo.addClass(dropDown, 'dropDown');
            dropDown.id = this._dropDownId = com.ba.Util.GenerateId();
            
            dropDownOverflower = document.createElement('div');
            dojo.addClass(dropDownOverflower, 'dropDownOverflower');
            dropDownOverflower.id = this._dropDownOverflowerId = com.ba.Util.GenerateId();
            
            // And create the ol itself
            orderedList = document.createElement("ol");
            
            // Attach those to the documentstructure
            selectElement.parentNode.appendChild(dropDown);
            dropDownOverflower.appendChild(orderedList);
            dropDown.appendChild(dropDownOverflower);

            //olSlideFx = dojo.fx(dropDown); 
            optionList = dojo.query('option', selectElement);
            
            if(optionList)
            {
                optionList.forEach(function(currentOption){
                
                    if(currentOption.value != -1)
                    {
                        optionElement = document.createElement("li");
                        optionElement.appendChild(document.createTextNode(currentOption.innerHTML));
                        
                        optionElement.id = com.ba.Util.GenerateId();
                        
                        if(currentOption.id.length === 0)
                        {
                            currentOption.id = com.ba.Util.GenerateId();
                        }
                        
                        orderedList.appendChild(optionElement);
                        
                        var simpleOption = new com.ba.gui._SimpleStepOption(optionElement.id, currentOption.id);
                        
                        this._optionList.push(simpleOption);
                        
                        this.CreateConnect(simpleOption, "OnSelect", this, "OnOptionSelected");
                        
                        if(currentOption.selected === true)
                        {
                            this._currentOption = simpleOption;
                        }
                    
                    }

                }, this);
            
            }
            
            this._ToggleSimpleExtendedClass(simpleStepHolder);
            
            var scrollBar = false;
            
            var olContentBox = dojo.contentBox(orderedList);
            
			var overflowerHeight = dojo.contentBox(dropDownOverflower).h
            //orderedList.style.overflow = "auto";
            if(overflowerHeight > 130)
            {
				overflowerHeight = 130;
                dropDownOverflower.style.height = overflowerHeight+"px";
                scrollBar = true;
            }
            
            // Create dropDown thingy
            olSlideFx = new dojo.fx.Toggler({
                node: dropDown,
                hideDuration: 3*overflowerHeight,
                showDuration: 3*overflowerHeight,
                hideFunc: dojo.fx.wipeOut,
                showFunc: dojo.fx.wipeIn 
                //~ hideFunc: com.ba.gui.fx.wipeOut,
                //~ showFunc: com.ba.gui.fx.wipeIn 
            });
            
            this._olAnimation = olSlideFx;
			
			var aniResult = this._olAnimation.hide();
			//~ this.CreateConnect(aniResult, "onEnd", this, "_OnAnimationEnd");

            //~ if( (dropDownOverflower.scrollWidth > dojo.coords(dropDown).w) || ( (scrollBar === true) && (dropDownOverflower.scrollWidth > dojo.coords(dropDown).w - 20 ) ) )
            //~ {
                //~ dropDown.style.width = (dropDownOverflower.scrollWidth + 20)+"px";
            //~ }

            this._ToggleSimpleExtendedClass(simpleStepHolder);
          
            dropDown.style.height = "1px";
            dropDown.style.visibility = "hidden";
            
            this.CreateConnect(simpleStepBody, 'onclick', this, "_OnClickContent");
            
            // The dropdown should NOT move any other content like the default slide FX would do...
            // So position is set to absolute
            dropDown.style.position = 'absolute';
            dojo.addClass(simpleStepHolder, "simpleStepReplaced");
            
            return true;
         
        },
        
        _OnClickContent: function(domEvent){
		
			
            var selectElement;
            var simpleStepHolder = dojo.byId(this._stepHolderId);
            var selectElements = dojo.query("select", simpleStepHolder);
            
            selectElements.forEach(function(currentSelect){
                selectElement = currentSelect;
            });
            
            if(selectElement)
            {
                if(!selectElement.disabled)
                {
					dojo.stopEvent(domEvent);
                    if(!dojo.hasClass(simpleStepHolder, this._animating))
                    {
                        dojo.addClass(simpleStepHolder, this._animating);
                        
                        var aniResult;
                        if(dojo.hasClass(simpleStepHolder, 'simpleExtended'))
                        {
                            aniResult = this._olAnimation.hide();
                            if(this._firstHide === true)
                            {
                                this._firstHide = false;
                                this.CreateConnect(aniResult, "onEnd", this, "_OnAnimationEnd");
                            }
                            
                            if(this._currentOption === undefined)
                                dojo.removeClass(this._stepHolderId, "selectionHolder_active");
                            
                            
                        } else {
                            com.ba.gui.SimpleStepManager.GetInstance().SetCurrentExpandedStep(this);
                            aniResult = this._olAnimation.show();
                            if(this._firstShow === true)
                            {
                                this._firstShow = false;
                                this.CreateConnect(aniResult, "onEnd", this, "_OnAnimationEnd");
                            }
                        }
                        
                        
                        
                    }
                }
            }
        },
        
        _OnAnimationEnd: function(domEvent)
        {
            dojo.toggleClass(this._stepHolderId, 'simpleExtended');
            if(dojo.hasClass(this._stepHolderId, this._animating) === true)
            {
                dojo.removeClass(this._stepHolderId, this._animating);
            }
        
        },
        
        OnOptionSelected: function(optionElement)
        {
            if(this._currentOption !== undefined)
            {
                this._currentOption.OnDeselect();
                this._currentOption = undefined;
            }
            
            dojo.addClass(this._stepHolderId, "selected");
            
            this._currentOption = optionElement;
            
            var selectionHolder = dojo.byId(this._currentStepTextId);
            
            while(selectionHolder.childNodes.length)
            {
                selectionHolder.removeChild(selectionHolder.childNodes[0]);
            }
                    
            selectionHolder.appendChild(document.createTextNode(optionElement.GetOptionText()));            
            dojo.addClass(selectionHolder, "selectionHolder_active");
            
            var aniResult = this._olAnimation.hide();
            
            this._selectionChangeId = this.CreateConnect(aniResult, "onEnd", this, "_ToggleChangeEvent");
            
            
            var nextSteps = dojo.query(".step" + (parseInt(dojo.byId(this._stepHolderId).className.match(/\d{1}/g),10)+1));
            
            nextSteps.forEach(function(nextStep){
                dojo.style(nextStep, "opacity", 1.0);
                var nextBodies = dojo.query(".simpleStepBody", nextStep);
                //var nextStep = undefined;
                nextBodies.forEach(function(nextBody){
                    dojo.addClass(nextBody, "loading");
                });
            });
            
        },
        
        _ToggleChangeEvent: function()
        {
		
			var elmnt = dojo.byId(this._selectId);
			
            if(elmnt.onchange){
            	elmnt.onchange();
    	    }
			
			dojo.disconnect(this._selectionChangeId);
			this._selectionChangeId = null;
		
            dojo.removeClass(this._stepHolderId, 'simpleExtended');
			
        },
        

        _ToggleSimpleExtendedClass: function(element)
        {
            dojo.toggleClass(element, 'simpleExtended');
        },
        
        DestroyConnections: function()
        {
            //~ console.debug("Destroying connections of : " + this._stepHolderId);
            while(this._optionList.length)
            {
                this._optionList[this._optionList.length-1].DestroyConnections();
                this._optionList.pop();
            }
            this.constructor.superclass.DestroyConnections.apply(this, arguments);
        },
        
        CollapseNow: function()
        {
            if(document.getElementById(this._dropDownId)){
                //(/*DomNode|String*/ node, /*String*/style, /*String?*/value)
                dojo.style(this._dropDownId, "display", "none");
                dojo.style(this._dropDownId, "height", "0px");
                if(dojo.hasClass(this._stepHolderId, 'simpleExtended'))
                {
                    dojo.removeClass(this._stepHolderId, 'simpleExtended');
                }
            }
        }
    }
);


