function CSSSelect(ID)
{
    this.ID             = ID;
    this.Options        = new Array();
    this.SelectedIndex  = 0;    
    this.Length         = 0;
    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){}
        
    
    this.AddOption = function(ID,Value,ExtraData)
    {
        this.Options.push(new CSSSelectOption(ID,Value,ExtraData));
        this.Length=this.Options.length;
    }
    
    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.HoverSelect=function(ID)
    {
        if(this.DisableHoverSelect)
            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);
        obj.className='';                
    }
    this.SelectByIndex=function(Index)
    {
        //get the li id and turn on the class
        var id=this.Options[Index].ID;
        var obj=document.getElementById(id);
        obj.className='alpha_select';               
    }
    
    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)
    {
        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);
        }
        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);
        }
    }
}
function CSSSelectOption(ID,Value,ExtraData)
{
    this.ID   = ID;
    this.Value = Value;
    this.ExtraData=ExtraData;
}        