Type.registerNamespace('Zextenders')

Zextenders.SelectList = function(element)
{

    this._template = null;
    this._nameValues = null; // [{"name":"xxx","value":"xxx","selected":false}]
    this._selectList = null;
    this._exclusive = false;
    this._addButton = null;
    this._state = null;
    this._exclusive = false;
    this._removeImage = false;
    this._cssClass = null;
    this._max = null;
    //event handlers
    this._addHandler = null;
    this._selectHandler = null;
    Zextenders.SelectList.initializeBase(this, [element]);
}

Zextenders.SelectList.prototype = 
{
    initialize : function()
    {
        Zextenders.SelectList.callBaseMethod(this, 'initialize');
        this._addHandler = Function.createDelegate(this, this.append);
        
        this._selectList = new Array();
        
        this.createTemplate();
        this._state.value = '';
        var added = false;
        for(var al=0;al<this._nameValues.length;al++)
        {
            if (this._nameValues[al].Selected == true)
            {
                this.appendSelect(this._nameValues[al].Value);
                added = true;
            }
        }
        if (!added)
            this.append();
        this.updateState();
        
        if (this._addButton)
            $addHandler(this._addButton, "click", this._addHandler);
    },
    
    dispose : function()
    {
        try{
        if ((this._addButton) && (this._addHandler))
            $removeHandler(this._addButton, "click", this._addHandler);
        }catch(e){}
        Zextenders.SelectList.callBaseMethod(this, 'dispose');
    },
    
    createTemplate : function()
    {
        var container = document.createElement("div");
        container.className = this._cssClass;
        //don't display the template.
        container.style.display="none";
        
        //add the <select> itme
        var tsel = document.createElement("select");
        tsel.id = "ss";
        
        //fill out the select list from the nameValues
        if (this._nameValues)
        {
          for(i=0;i<this._nameValues.length;i++)
          {
            var op = document.createElement("option");
            op.text = this._nameValues[i].Text;
            op.value = this._nameValues[i].Value;
            op.selected = this._nameValues[i].Selected;
            try 
            {
	            tsel.add(op,null);
	        } catch(ex) {
	            tsel.add(op); // IE only
	        }
          }
          this.sortSelect(tsel);
        }
        
        container.appendChild(tsel);
        
        //add the remove link
        var span = document.createElement("span");
        if (this._removeImage)
        {
            var rlink = document.createElement("input");
            rlink.setAttribute("type","image");
            rlink.setAttribute("src",this._removeImage);
            rlink.style.borderWidth="0px";
        }
        else
        {
            var rlink = document.createElement("a");
            rlink.innerHTML = "[Remove]";
            span.appendChild(rlink);
        }
        span.appendChild(rlink);
        rlink.id = "rlink";
        container.appendChild(span);
        this._template = container;
    },
    
    append : function()
    {
        if (this._selectList.length < this._nameValues.length)
            this.appendSelect(null);
    },
    
    appendSelect : function(value)
    {
        if (this._selectList.length >= this._nameValues.length) return;
        if (this._max && this._selectList.length >= this._max) return;
        
        var elem = this._template.cloneNode(true);
        
        //find the remove link and add the handler
        var rlink = $get("rlink", elem);
        if (rlink)
        {
            rlink.container = elem;
            rlink.control = this;
            var remHandler = Function.createDelegate(rlink, this.remove);
            $addHandler(rlink,"click",remHandler);
        }
        
        //find the select and add the handler
        var sel = $get("ss", elem)
        if (sel)
        {
            sel.container = elem;
            sel.control = this;
            var selHandler = Function.createDelegate(sel, this.selectChanged);
            $addHandler(sel,"change", selHandler);
            this._selectList.push(sel);
            
            //remove all the options that are already selected.
            if (this._exclusive)
            {
                var s = this._state.value.split(',');
                for(var t = 0;t<s.length;t++)
                    for(var c = 0;c<sel.options.length;c++)
                    {
                        if (sel.options[c].value == s[t])
                        {
                            sel.options[c] = null; break;
                        }
                    }
            }
            
            if (value)
            {
                for(i=0;i<sel.options.length;i++)
                    if (sel.options[i].value == value)
                    {
                        sel.options[i].selected = true;
                        break;
                    }
            }
            
            sel.oldText = sel.options[sel.selectedIndex].text;
            sel.oldVal = sel.options[sel.selectedIndex].value;
            
            if (this._exclusive)
                this.removeOption(sel, sel.value);
            
            this.updateState();
        }
        
        elem.style.display = "block";
        this.get_element().appendChild(elem);
        Zextenders.DynamicEvents.get_instance().fireAddedEvents(this, elem);
    },
    
    remove : function()
    {
        var control = this.control;
        //find the select in the container
        var ss = $get("ss", this.container);
        if (ss)
        {
            var text = ss.options[ss.selectedIndex].text;
            var val = ss.options[ss.selectedIndex].value;
            for(i = 0;i<this.control._selectList.length;i++)
                if (this.control._selectList[i] == ss) break;
        
            control._selectList.splice(i,1);
            
            if (control._exclusive)
                control.addOption(text,val);
        }
        $clearHandlers(this);
        control.get_element().removeChild(this.container);
        control.updateState();
        Zextenders.DynamicEvents.get_instance().fireRemovedEvents(control, this.container);
        return false;
    },
    
    removeOption : function(sel, val)
    {
        //removes the val option from all selects except sel
        for(var sels = 0;sels < this._selectList.length;sels++)
        {
            if (this._selectList[sels] == sel) continue;
            
            //find the option in the options array
            options = this._selectList[sels].options;
            for(var kk = 0;kk<options.length;kk++)
            {
                var o = options[kk];
                if (o.value == val)
                {
                    options[kk] = null;
                    break;
                }
            }
        }
    },
    
    addOption : function(text, val, sel)
    {
        //add a new option to all the selects except sel (cuz it should already be in there)
        for(var sels = 0;sels<this._selectList.length;sels++)
        {
            if (this._selectList[sels] == sel) continue;
            var o = document.createElement("option");
            o.text = text;
            o.value = val;
            try {
                this._selectList[sels].options.add(o,null);
            } catch (ex) {
                this._selectList[sels].options.add(o);
            }
            
            //prolly wanna sort them again.
            this.sortSelect(this._selectList[sels]);
        }
    },
    
    selectChanged : function()
    {
        //this == select
        var control = this.control;
        
        //get the old values
        var oldText = this.oldText;
        var oldVal = this.oldVal;
        if (!oldText) oldText = "";
        if (!oldVal) oldVal = "";
        
        //add the value
        if (control._exclusive)
            control.addOption(oldText, oldVal, this);
        
        this.oldText = this.options[this.selectedIndex].text;
        this.oldVal = this.options[this.selectedIndex].value;
        
        //remove the newly selected option
        if (control._exclusive)
            control.removeOption(this, this.value);
        
        control.updateState();
    },
    
    updateState : function()
    {
        //update the client state.
        var s = "";
        for(var i=0;i<this._selectList.length;i++)
        {
            
            indx = this._selectList[i].selectedIndex;
            t = this._selectList[i].options[indx].value;
            if (t != "")
            {
                if (s != "") s = s + ",";
                s = s + t;
            }
        }
        this._state.value = s;
        Zextenders.DynamicEvents.get_instance().fireItemUpdatedEvents(this, this.container);
    },
    
    sortSelect : function (targetSelect)
    {
      var val = targetSelect.value;
      var A = new Array();
      for(var i=0;i<targetSelect.options.length;i++)
      {
        var o = document.createElement("option");
        o.text = targetSelect.options[i].text;
        o.value = targetSelect.options[i].value;
        A.push(o);
      }
      A.sort(this.optionCompare);
      for(i=0;i<targetSelect.length;i++)
      {
        targetSelect.options[i] = A[i];
        if (targetSelect.options[i].value == val)
        {
            targetSelect.options[i].selected = true;
            targetSelect.oldText = targetSelect.options[i].text;
            targetSelect.oldVal = targetSelect.options[i].value;
        }
      }
    },

    optionCompare : function(o,i)
    {
      return (o.text.toLowerCase() < i.text.toLowerCase())? -1:1;
    },
    
    beginUpdate : function()
    {
    },
    
    get_addButton : function()
    {
        return this._addButton;
    },
    
    set_addButton : function(value)
    {
        this._addButton = $get(value);
    },
    
    get_nameValues : function()
    {
       return this._nameValues;
    },
    
    set_nameValues : function(value)
    {
        this._nameValues = eval( "(" + value + ")" );
    },
    
    get_state : function()
    {
        return this._state;
    },
    
    set_state : function(value)
    {
        this._state = $get(value);  
    },
    
    get_exclusive : function()
    {
        return this._exclusive;
    },
    
    set_exclusive : function(value)
    {
        this._exclusive = value;
    },
    
    get_removeImage : function()
    {
        return this._removeImage;
    },
    
    set_removeImage : function(value)
    {
        this._removeImage = value;
    },
    
    get_cssClass : function()
    {
        return this._cssClass;
    },
    
    set_cssClass : function(value)
    {
        this._cssClass = value;
    },
    
    get_max : function()
    {
        return this._max;
    },
    
    set_max : function(value)
    {
        this._max = value;
    }
}

Zextenders.SelectList.registerClass('Zextenders.SelectList', Sys.UI.Control);

if (typeof (Sys) !== "undefined") Sys.Application.notifyScriptLoaded();