﻿Type.registerNamespace('DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown');

/// <summary>
/// Metro DropDown Extender Control
///     this extender loads the Metro dropdown based on the country or state ddl.
/// </summary>
/// <remarks>
///    properties: 
///      {name: 'PrimaryParentControlId', type: String} : id of primary parent (state DDL) control
///      {name: 'SecondaryParentControlId', type: String} : id of secondary parent (country DDL) control
///      {name: 'SelectedMetroValueId', type: string} : id of element that holds the metro area
///              value selected. element must have value property (eg. input type=hidden)
/// </remarks>
/// <history>
///     <change date="02/27/2007 12:18:00" ticket="">
///         <author>Steven Berenbrock</author>
///         <description>Initial version.</description>
///     </change>
///     <change date="04/24/2008 12:18:00" ticket="">
///         <author>Raja Kanapala</author>
///         <description>Selected Location Text</description>
///     </change>
/// </history>



DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior = function(element) {
    DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior.initializeBase(this, [element]);
    ///<summary>MetroDropDownBehavior Extender</summary>
    ///<param name="element">Associated element</param>

    //Properties
    this._primaryParentControlId = null;
    this._secondaryParentControlId = null;
    this._selectedMetroValueId = null;
    this._selectedLocation = null;
     
    // Member variables
    this._primaryParentElement = null;
    this._secondaryParentElement = null;
    this._selectedValue = null; 
    this._selectedText = null;
    this._separator = ':::';
    this._parentLoaded = true;

    // Event delegates
    this._changeEventHandler = null;
    this._primaryParentChangeHandler = null;
    this._secondaryParentChangeHandler = null;
}

DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior.prototype = {
    //*****************************************************************
    //Override methods
    //
    initialize : function() {
        DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior.callBaseMethod(this, 'initialize');

        var targetElement = this.get_element();

        // Clear any items that may have been put there for server side convenience
        this._clearItems();
        
        this._changeEventHandler = Function.createDelegate(this, this._onControlEvent);
        $addHandler(targetElement, "change", this._changeEventHandler);
        Sys.Debug.assert(this._changeEventHandler != null, "Couldn't create event ( change event handler for '" + targetElement.id + "'");
        
        if (this._primaryParentControlId) {
            this._primaryParentElement = $get(this._primaryParentControlId);
            Sys.Debug.assert(this._primaryParentElement != null, "Couldn't find element '" + this._primaryParentControlId + "'");
            
            if (this._primaryParentElement) {
                //setup change event hander to parent ddl
                this._primaryParentChangeHandler = Function.createDelegate(this, this._onParentControlEvent);
                $addHandler(this._primaryParentElement, "change", this._primaryParentChangeHandler);
                //set up array on parent element to track children dependents
                if (!this._primaryParentElement.childDropDown) {
                    this._primaryParentElement.childDropDown = new Array();
                }
                this._primaryParentElement.childDropDown.push(this);
            }
        }        
        
        if (this._secondaryParentControlId) {
            this._secondaryParentElement = $get(this._secondaryParentControlId);
            Sys.Debug.assert(this._secondaryParentElement != null, "Couldn't find element '" + this._secondaryParentControlId + "'");
            
            if (this._secondaryParentElement) {
                //setup change event hander to grand parent ddl
                //this._secondaryParentChangeHandler = Function.createDelegate(this, this._onGrandparentControlEvent);
                this._secondaryParentChangeHandler = Function.createDelegate(this, this._onParentControlEvent);
                $addHandler(this._secondaryParentElement, "change", this._secondaryParentChangeHandler);
                 //set up array on parent element to track children dependents
                if (!this._secondaryParentElement.childDropDown) {
                    this._secondaryParentElement.childDropDown = new Array();
                }
                this._secondaryParentElement.childDropDown.push(this);
            }
        }        
        
        //check for client state on postback...
        this._retrieveState();
        // load from primary parent to populate self
        this._loadFromPrimaryParent();
        if (!this._isPopulated()) {
            //primary failed to load metros...try secondary
            this._loadFromSecondaryParent();
        }
                
    },

    dispose : function() {
        var targetElement = this.get_element();

        if (this._changeEventHandler) {
            $removeHandler(targetElement, "change", this._changeEventHandler);
            this._changeEventHandler = null;
        }

        if (this._primaryParentElement) {
            if (this._primaryParentChangeHandler) {
                $removeHandler(this._primaryParentElement, "change", this._primaryParentChangeHandler);
                this._primaryParentChangeHandler = null;
            }        
        }

        if (this._secondaryParentElement) {
            if (this._secondaryParentChangeHandler) {
                $removeHandler(this._secondaryParentElement, "change", this._secondaryParentChangeHandler);
                this._secondaryParentChangeHandler = null;
            }        
        }
        
        
        DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior.callBaseMethod(this, 'dispose');
    },

    //*****************************************************************
    // Property get/set methods
    //
    get_PrimaryParentControlId : function() {
        return this._primaryParentControlId;
    },

    set_PrimaryParentControlId : function(value) {
        this._primaryParentControlId = value;
    },

    get_SecondaryParentControlId : function() {
        return this._secondaryParentControlId;
    },

    set_SecondaryParentControlId : function(value) {
        this._secondaryParentControlId = value;
    },
    
    get_SelectedMetroValueId : function() {
        return this._selectedMetroValueId;
    },

    set_SelectedMetroValueId : function(value) {
        this._selectedMetroValueId = value;
    },
    
    get_SelectedLocation : function() {
        return this._selectedLocation;
    },

    set_SelectedLocation : function(value) {
        this._selectedLocation = value;
    },
        
    //*****************************************************************
    // Custom methods
    //
    _storeState : function(selectedValue, selectedText) {
        ///<summary>Private method _storeState - set the client view state with 
        ///         selected value, and selected text.  separator must match extender class</summary>
        ///<param name="selectedValue" type="string">selected value in ddl</param>
        ///<param name="selectedText" type="string">selected text in ddl</param>                
        DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior.callBaseMethod(this, 'set_ClientState', [ selectedValue + this._separator + selectedText ]);
    },
    
    _retrieveState : function() {
        ///<summary>Private method _retrieveState - retrieve the client view metro for 
        ///         selected value, and selected text.  separator must match set client state</summary>
        // Check client state.  If it's present,
        // that means this is a postback, so we restore the state.
        var lastState = DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior.callBaseMethod(this, 'get_ClientState');                
        if (lastState && (-1 != lastState.indexOf(this._separator))) {        
            // Parse the value:::text out of ClientState and set them
            var result = lastState.split(this._separator);
            this._selectedValue = result[0];
            //this._selectedText = result[1];
        }        
    },    
    
    _clearItems : function() {
        /// <summary>Clear the items from the drop down</summary>
        var e = this.get_element();
        while (0 < e.options.length) {
            e.remove(0);
        }
    },

    _isPopulated : function() {
        /// <summary>Determine whether the drop down has any items</summary>
        /// <returns type="Boolean">Whether the drop down has any items</returns>
        var items = this.get_element().options.length;
        return items > 0;
    },

    _setOptions : function(list) {
        /// <summary>Set the contents of the DropDownList to the specified list</summary>
        /// <param name="list" mayBeNull="true" elementType="Object">Array of options</param>
        if (!this.get_isInitialized()) {
            return;
        }

        var targetElement = this.get_element();
        // Remove existing contents
        this._clearItems();

        var matchedSelectedValue = false;
        var defaultIndex = 0;

        // Add each item to the DropDownList
        if (list) {
            for (i = 0 ; i < list.length ; i++) {
                var listItemName = list[i].Name;
                var listItemValue = list[i].Id;

                var isSelectedValue = (listItemValue == this._selectedValue);
                var optionElement = new Option(listItemName, listItemValue, false, isSelectedValue);
                matchedSelectedValue |= isSelectedValue;
                targetElement.options[targetElement.options.length] = optionElement;
            }
        }

        if (this._isPopulated()) {
            // if we didn't match the selected value, select default
            if (matchedSelectedValue) {
                this._storeState(targetElement.options[targetElement.selectedIndex].value, targetElement.options[targetElement.selectedIndex].text);
                this._selectedValue = targetElement.options[targetElement.selectedIndex].value;
                this._selectedText = targetElement.options[targetElement.selectedIndex].text;
                this._setSelectedMetroValue(this._selectedValue);
                this._setSelectedLocation(this._selectedText);
            } else if (!matchedSelectedValue && defaultIndex != -1) {
                targetElement.options[defaultIndex].selected = true;
                this._selectedValue = targetElement.options[defaultIndex].value;
                this._selectedText = targetElement.options[targetElement.selectedIndex].text;
                this._storeState(targetElement.options[defaultIndex].value, targetElement.options[defaultIndex].text);
                this._setSelectedMetroValue(this._selectedValue);
                this._setSelectedLocation(this._selectedText);
            } else if (!matchedSelectedValue) {
                this._selectedValue = '';
                this._storeState('', '');
                this._setSelectedMetroValue(this._selectedValue);
                this._selectedText = '';
                this._setSelectedLocation(this._selectedText);
                
            }
        }
        
        //check for any child dependents that need to be notified of change
        if (targetElement.childDropDown) {
            for(i = 0; i < targetElement.childDropDown.length; i++) {
                targetElement.childDropDown[i]._onParentControlEvent();
            }
        }
        else {
            if (list && (Sys.Browser.agent !== Sys.Browser.Safari) && (Sys.Browser.agent !== Sys.Browser.Opera)) {
                // Fire the onchange event for the control to notify any listeners of the change
                if (document.createEvent) {
                    var onchangeEvent = document.createEvent('HTMLEvents');
                    onchangeEvent.initEvent('change', true, false);
                    targetElement.dispatchEvent(onchangeEvent);
                }
                else if (document.createEventObject) {
                    targetElement.fireEvent('onchange');
                }
            }
        }
    },

    _setSelectedMetroValue : function(metroAreaId) {
        ///<summary>Private method _setSelectedMetroValue</summary>
        ///<param name="metroAreaId">metro area id string</param>
        ///<remarks>Sets the value attribute of element identified by the selectedMetroValueId</remarks>
        if (this._selectedMetroValueId) {
            var selectedMetroValueElement = $get(this._selectedMetroValueId);
            if (selectedMetroValueElement) {
                selectedMetroValueElement.value = metroAreaId;
                     
            }
        }    
    },
    
    _setSelectedLocation : function(locationName) {
        ///<summary>Private method _setSelectedMetroValue</summary>
        ///<param name="locationName">locationName string</param>
        ///<remarks>Sets the value attribute of element identified by the SelectedLocation</remarks>
        if (this._selectedLocation) {
            var selectedLocationValueElement = $get(this._selectedLocation);
            if (selectedLocationValueElement) {
                selectedLocationValueElement.value = locationName;               
           }
        }    
    },
    
    
    _loadFromSecondaryParent : function() {
        ///<summary>private method _loadFromSecondaryParent</summary>
        ///<remarks>get selected value from secondary parent and call webservice</remarks>
        if (this._secondaryParentElement) {
            var index = this._secondaryParentElement.selectedIndex;
            if (index != -1) {
                var value = this._secondaryParentElement.options[index].value;
                switch (value) {
                    case "US":
                    case "CA":
                        //do not load metros for US and CA....being loaded by primary state ddl change event
                        break;
                    default:
                        //proxy for CustomerWebService.asmx GetMetroAreas(state, country, complete handler, error handler, user context);
                        DTG.Dollar.Web.Consumer.Services.CustomerWebService.GetMetroAreas(
                            "",
                            value,
                            this._onMethodComplete, 
                            this._onMethodError, 
                            [this, value]);                    
                }
            }
        }                
    },
    
    _loadFromPrimaryParent : function() {
        ///<summary>private method _loadFromPrimaryParent</summary>
        ///<remarks>get selected value from primary parent and call webservice</remarks>
        if (this._primaryParentElement) {
            var index = this._primaryParentElement.selectedIndex;
            if (index != -1) {
                var value = this._primaryParentElement.options[index].value;
                if (value) {
                    //proxy for CustomerWebService.asmx GetMetroAreas(state, country, complete handler, error handler, user context);
                    DTG.Dollar.Web.Consumer.Services.CustomerWebService.GetMetroAreas(
                        value,
                        "",
                        this._onMethodComplete, 
                        this._onMethodError, 
                        [this, value]);
                }
            }
        }
    },
    
    //*****************************************************************
    // Event handler methods
    //
    _onMethodComplete : function(result, userContext, methodName) {
        // Success, update the DropDownList
        var acBehavior = userContext[0];
        //var code = userContext[1];
        acBehavior._setOptions(result);
    },

    _onMethodError : function(error, userContext, methodName) {
        ///<summary>Private event method _onMethodError</summary>
        ///<param name="error">error object from web service call</param>
        ///<param name="userContext">value passed to web service call for user context</param>
        ///<param name="methodName">name of method that called the web service</param>
        ///<remarks>this method is called when an error has been received from the 
        /// web service call</remarks>
        Sys.Debug.trace(error.get_message());
    },
    
    _onParentControlEvent : function(envt) {
        ///<summary>Event handler for onchange of parent ddl event</summary>
        ///<remarks>determine which parent tirggered event...default to primary if no
        ///     target can be determined</remarks>
        //if this control has not been initialized....do not process
        if (!this.get_isInitialized()) {
            return;
        }

        if ((envt) && (envt.target.id == this._secondaryParentControlId)) {
            //redirect event to secondary load method
            this._loadFromSecondaryParent();
        }
        else {
            this._loadFromPrimaryParent();
        }        
    },        
    
    _onControlEvent : function(evnt) {
        ///<summary>Event handler for onchange ddl event</summary>
        //get selected value from target ddl
        if (!this._isPopulated()) {
            return;
        }
        var targetElement = this.get_element();
        if (-1 != targetElement.selectedIndex) {
            this._storeState(targetElement.options[targetElement.selectedIndex].value, targetElement.options[targetElement.selectedIndex].text);
            this._selectedValue = targetElement.options[targetElement.selectedIndex].value;
            this._setSelectedMetroValue(this._selectedValue);
            this._selectedText = targetElement.options[targetElement.selectedIndex].text;
            this._setSelectedLocation(this._selectedText);
            
        }
         else {
            this._storeState('', '');
            this._selectedValue = '';
            this._setSelectedMetroValue(this._selectedValue);
            this._selectedLocation = '';
            this._setSelectedLocation(this._selectedText);
        }
    }    
}

DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior.registerClass('DTG.Dollar.Web.Consumer.Common.Ajax.MetroDropDown.MetroDropDownBehavior', AjaxControlToolkit.BehaviorBase);

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();