function CSSSelect(ID)
{
    this.ID             = ID;
    this.Options        = new Array();
    this.SelectedIndex  = 0;
    this.LastSelectedID = null;    
    this.Length         = 0;
    this.Visible        = false;            
    this.DisableHoverSelect=false;
    this.KeyStartTime   = null;
    this.SearchString   = '';
    this.MouseX         = 0;
    this.MouseY         = 0;
    this.Disabled       = false;
    this.DisabledClass  = "";
    this.EnableClassName= "";
    
    this.OnChangeEventHandler   = function(obj){};
    this.OnKeyDownEventHandler  = function(e){}
    this.OnMouseMoveEventHandler= function(e){}
    
    this.Reset = function()
    {
        this.SelectedIndex=0;
        //this.Length=1;
        for(var c=1;c<this.Length;c++)
        {
            this.Options.pop();
        }
        this.Length=1;
        this.Visible=false;
        this.DisableHoverSelect=false;
        this.KeyStartTime=null;
        this.SearchString='';
        this.MouseX=0;
        this.MouseY=0;
        this.OnChangeEventHandler   = function(obj){};
        this.OnKeyDownEventHandler  = function(e){};
        this.OnMouseMoveEventHandler= function(e){};
        
        if (this.Options.length>0)
            this.Select(this.Options[0].ID);
        
        //if (document.getElementById(this.ID+"_dropdown"))    
        //    document.getElementById(this.ID+"_dropdown").className = 'css_select_disabled';
    }
    
    this.SetDisabledClassName=function(ClassName)
    {
        this.DisabledClass=ClassName;
    }
    this.SetEnableClassName=function(ClassName)
    {
        this.EnableClassName=ClassName;
    }
    
    this.Disable=function()
    {
        this.Reset();
        this.Disabled=true;
        if(this.DisabledClass != '')
        {
            var obj=document.getElementById(this.ID+'_dropdown');
            if(obj != null)
                obj.className=this.DisabledClass;
        }
    }
    
    this.Enable=function()
    {
        this.Disabled=false;
        if(this.EnableClassName != '')
        {
            var obj=document.getElementById(this.ID+'_dropdown');
            if(obj != null)
                obj.className=this.EnableClassName;
        }
    }
    
    this.AddOption = function(ID,Value,ExtraData)
    {
        this.Options.push(new CSSSelectOption(ID,Value,ExtraData));
        this.Length=this.Options.length;
    }
    
    this.CreateUrlOptionByJSON = function(JSONData,OtherAttributes)
    {        
        var html='';        
        for(index in JSONData)
        {
            data = JSONData[index];            
            html+="<li id='"+data.ID+"'><a href='"+data.ExtraData+"'"+OtherAttributes+">"+data.Value+"</a></li>";            
        }
        document.getElementById(this.ID+'_ul').innerHTML=html;
        //do after li creation
        this.AddOptionsByJSON(JSONData);
        
    }
    this.CreateSimpleListByJSON = function(JSONData)
    {
        var html='';        
        for(index in JSONData)
        {
            data = JSONData[index];            
            html+="<li id='"+data.ID+"'>"+data.Value+"</li>";            
        }
        document.getElementById(this.ID+'_ul').innerHTML=html;
        //do after li creation
        this.AddOptionsByJSON(JSONData);
    }
    this.AddOptionsByJSON=function(JSONData)
    {
        for(index in JSONData)
        {            
            data = JSONData[index];
            this.AddOption(data.ID,data.Value,data.ExtraData);
        }
    }
    
    this.AddOnChangeEventHandler=function(handler)
    {
        this.OnChangeEventHandler=handler;
    }
    
    this.Select=function(ID)
    {
        //loop through our options and find by id and push to url of child a
        this.HideDropDown();
        
        for(var c=0;c<this.Options.length;c++)
        {
            if(this.Options[c].ID==ID)
            {
                this.SelectedIndex=c;
            }
        }
        document.getElementById(this.ID+'_dropdown').innerHTML=this.Options[this.SelectedIndex].Value;
        this.OnChangeEventHandler(this.Options[this.SelectedIndex]);
    }
    
    this.SelectByValue=function(Value)
    {
        for(var c=0;c<this.Options.length;c++)
        {
            if(this.Options[c].Value==Value)
            {
                this.Select(this.Options[c].ID);
                break;
            }
        }
    }
    this.HoverSelect=function(ID)
    {
        if(this.DisableHoverSelect || ID==this.LastSelectedID)             
            return;
        
        for(var c=0;c<this.Options.length;c++)
        {
            if(this.Options[c].ID==ID)
            {
                if(this.SelectedIndex != c)
                    this.UnSelectByIndex(this.SelectedIndex);                
                    
                this.SelectedIndex=c;                        
                this.SelectByIndex(this.SelectedIndex);
            }
        }
    }
    
    this.KeyCheck=function(e)
    {
        var LocalDate=new Date();
        var TempTime=LocalDate.getTime();
        if(this.KeyStartTime == null || TempTime-this.KeyStartTime > 1000)
        {            
            this.SearchString='';
        }
        this.KeyStartTime=TempTime;
        
        var HandledKeyStroke=false;                    
        var KeyID = (window.event) ? event.keyCode : e.keyCode;
        
        //if we're doing key input, disable hovers
        this.DisableHoverSelect=true;
        
        //esc = close
        if(KeyID==27)
        {
            this.HideDropDown();
            HandledKeyStroke=true;
        }
        if(KeyID==13)
        {
            //return is a click
            this.Select(this.Options[this.SelectedIndex].ID);
            HandledKeyStroke=true;
        }
        if(KeyID==38)
        {
            //UP
            if(this.SelectedIndex > 0)
            {
                this.UnSelectByIndex(this.SelectedIndex);
                this.SelectedIndex--;
                this.SelectByIndex(this.SelectedIndex);
                this.ScrollSelectedIntoView();
            }
            HandledKeyStroke=true;
        }
        if(KeyID==40)
        {
            //Down
            if(this.SelectedIndex+1 < this.Options.length)
            {
                this.UnSelectByIndex(this.SelectedIndex);
                this.SelectedIndex++;
                this.SelectByIndex(this.SelectedIndex);
                this.ScrollSelectedIntoView();
            }
            HandledKeyStroke=true;
        }           
        
        if(KeyID==32 || (KeyID >= 48 && KeyID <= 57) || (KeyID >= 65 && KeyID <= 90) || (KeyID >=97 && KeyID <= 122))
        {
            HandledKeyStroke=true;
            
            this.SearchString+=String.fromCharCode(KeyID).toLowerCase();
            //loop through our options and find the value next in line with the characer                    
            for(var c=0;c<this.Options.length;c++)
            {            
                var letters=this.Options[c].Value.substr(0,this.SearchString.length);
                letters=letters.toLowerCase();
                            
                if(this.SearchString==letters)
                {
                    //did they press a different key?
                    //if(this.LastKeyPressed != KeyID)
                    //{
                        if(this.SelectedIndex >=0)                        
                            this.UnSelectByIndex(this.SelectedIndex);
                            
                        //select new
                        this.SelectedIndex=c;
                        this.SelectByIndex(this.SelectedIndex);
                        this.ScrollSelectedIntoView();                                
                        break;
                   // }
                    /******else
                    {
                        //does our NEXT option have the same letter?
                        //select new
                        if(c > this.SelectedIndex)
                        {
                            letter=this.Options[c].Value.substr(0,1);
                            letter=letter.toLowerCase();
                            code=letter.charCodeAt(0);
                            if(code==KeyID)
                            {                                
                                this.UnSelectByIndex(this.SelectedIndex);                                
                                this.SelectedIndex=c;
                                this.SelectByIndex(this.SelectedIndex);
                                break;
                            }
                        }
                    }********/
                }
            }                    
        }
                
        if(HandledKeyStroke == true)
        {
            if (!e)
                var e = window.event;
            e.cancelBubble = true;
            if (e.stopPropagation)
                e.stopPropagation();
            
            if(e.preventDefault)
                e.preventDefault(); //FF
            return false; //stop propagation.
        }
        return true;                
    }
    
    this.ScrollSelectedIntoView=function()
    {            
        var top=document.getElementById(this.Options[this.SelectedIndex].ID).offsetTop;
        //make our option the middle of the list
        var height=document.getElementById(this.ID+'_ul').clientHeight;
        document.getElementById(this.ID+'_ul').scrollTop=top-(height/2); //give some room             
    }
    this.UnSelectByIndex=function(Index)
    {
        //get the li id and turn off the class
        var id=this.Options[Index].ID;
        var obj=document.getElementById(id);
        if(obj != null)
            obj.className='';
        this.LastSelectedID=null;
    }
    this.SelectByIndex=function(Index)
    {
        //get the li id and turn on the class        
        document.getElementById(this.Options[Index].ID).className='alpha_select';
        this.LastSelectedID=this.Options[Index].ID;
    }
    
    this.AddKeyListener=function(Context)
    {   
        this.OnKeyDownEventHandler=function(e){return Context.KeyCheck.call(Context,e);}
        this.OnMouseMoveEventHandler=function(e){return Context.OnMouseMove.call(Context,e);}
        
        if(window.addEventListener)
        {
            document.addEventListener('keydown',this.OnKeyDownEventHandler,true);                    
            document.addEventListener('mousemove',this.OnMouseMoveEventHandler,false);
        }
        else
        {
            //ie                    
            document.attachEvent('onkeydown',this.OnKeyDownEventHandler,true);
            document.attachEvent('onmousemove',this.OnMouseMoveEventHandler,true);
        }
    }            

    this.RemoveKeyListener=function()
    {     
        if(window.addEventListener)
        {
            document.removeEventListener('keydown',this.OnKeyDownEventHandler,true);
            document.removeEventListener('mousemove',this.OnMouseMoveEventHandler,false);
        }
        else
        {
            //ie
            document.detachEvent('onkeydown',this.OnKeyDownEventHandler);
            document.detachEvent('onmousemove',this.OnMouseMoveEventHandler,true);
        }           
    }
    
    this.OnMouseMove=function(e)
    {
        if(e.clientX != this.MouseX || e.clientY != this.MouseY)
        {
            this.MouseX=e.clientX;
            this.MouseY=e.clientY;
            this.DisableHoverSelect=false;
        }
        return false;
    }
               
    this.ToggleDropDown=function()
    {       
        if(this.Visible==0)            
            this.ShowDropDown();
        else            
            this.HideDropDown();                    
    }
    
    this.OnClickDropDown=function(e)
    {
        if(this.Disabled==true)
            return false;
        
        this.ToggleDropDown();
        
        if (!e)
            var e = window.event;
        e.cancelBubble = true;
        if (e.stopPropagation)
            e.stopPropagation();
        
        if(e.preventDefault)
            e.preventDefault(); //FF
            
        return false; //no hubba bubba
    }
    
    this.HideDropDown=function()
    {
        var obj=document.getElementById(this.ID+"_container");
        obj.style.visibility='hidden';
        this.Visible=0;
        this.RemoveKeyListener(this);
    }
    this.ShowDropDown=function()
    {
        var obj=document.getElementById(this.ID+"_container");
        obj.style.visibility='visible';
        this.Visible=1;
        this.AddKeyListener(this);
    }

    
    this.AttachEventHandlers=function(Context)
    {
        if(window.addEventListener)
        {                     
            document.addEventListener('click',function(e){Context.HideDropDown.call(Context);},true);
            document.getElementById(this.ID+'_dropdown').addEventListener('click',function(e){Context.OnClickDropDown.call(Context,e);},true);
                        
            var obj  = document.getElementById(this.ID+'_container');
            var list = obj.getElementsByTagName('LI');
            var li;
            for(var c=0;c<list.length;c++)
            {
                li = list[c];                
                if(li.addEventListener)
                {              
                    li.addEventListener('click',function(e){Context.Select(this.id);},true);
                    li.addEventListener('mouseover',function(e){Context.HoverSelect(this.id);},true);                    
                }                
            }            
        }
        else
        {                 
            document.attachEvent('onclick',function(e){Context.HideDropDown.call(Context);},true);                    
            //must do this method to prevent onclick document bubble up auto closing the menu
            document.getElementById(this.ID+'_dropdown').attachEvent('onclick',function(e){Context.OnClickDropDown.call(Context,e);},true);
            
            var obj  = document.getElementById(this.ID+'_container');
            var list = obj.getElementsByTagName('LI');
            var li;            
            for(var c=0;c<list.length;c++)
            {
                li = list[c];
                li.onclick=function(e){Context.Select(this.id);};
                li.onmouseover=function(e){Context.HoverSelect.call(Context,this.id);};                                
            }
        }
    }
}

function CSSSelectOption(ID,Value,ExtraData)
{
    this.ID   = ID;
    this.Value = Value;
    this.ExtraData=ExtraData;
}
