// $Revision: 4$
// $Date: 7/24/2007 7:03:11 PM$
// $Author: Donnie Tognazzini$
// $NoKeywords$

/******************************************************************************
  Classes defined in this file:

    CB_ComboBox         - Combo box.
    CB_ComboBoxMenuItem - Combo box menu item.

******************************************************************************/

/******************************************************************************
  CB_ComboBoxMenuItem

    Parameters:
        [in] name
        [in] value

******************************************************************************/
function CB_ComboBoxMenuItem( name, value )
{
    this.m_option = new Option( name, value );

    this.SetEnabled = function( value )
    {
        // no-op
    };
}

/******************************************************************************
  CB_ComboBox

    Parameters:
        [in/out] popupDOMElementId

******************************************************************************/
function CB_ComboBox( popupDOMElementId )
{
    try
    {
        this.m_popup = document.getElementById( popupDOMElementId );

        this.m_menuItems = new Array( );

        var self = this;

        this.m_onGainFocusSignal = new SIGSLOT_Signal( );
        this.m_popup.onfocus = function( )
        {
            try
            {
                self.m_onGainFocusSignal.Emit( );
            }
            catch ( e )
            {
                EX_Log( "CB_ComboBox::m_popup.onfocus( )\n" + e.message );
            }
        };

        this.m_onLoseFocusSignal = new SIGSLOT_Signal( );
        this.m_popup.onblur = function( )
        {
            try
            {
                self.m_onLoseFocusSignal.Emit( );
            }
            catch ( e )
            {
                EX_Log( "CB_ComboBox::m_popup.onblur( )\n" + e.message );
            }
        };

        this.m_onChangeSignal = new SIGSLOT_Signal( );
        this.m_popup.onchange = function( )
        {
            try
            {
                self.m_onChangeSignal.Emit( );
            }
            catch ( e )
            {
                EX_Log( "CB_ComboBox::m_popup.onchange( )\n" + e.message );
            }
        };
    }
    catch ( e )
    {
        EX_ASSERT_NO_EXCEPTIONS( e, "CB_ComboBox::CB_ComboBox( )" );
    }
}

CB_ComboBox.prototype =
{
    GetOnGainFocusSignal : function( )
    {
        return this.m_onGainFocusSignal;
    },

    GetOnLoseFocusSignal : function( )
    {
        return this.m_onLoseFocusSignal;
    },

    GetOnChangeSignal : function( )
    {
        return this.m_onChangeSignal;
    },

    OnSelectionChange : function( index )
    {
        try
        {
            this.SelectIndex( index );

            this.m_onChangeSignal.Emit( this );
        }
        catch ( e )
        {
            EX_ASSERT_NO_EXCEPTIONS( e, "CB_ComboBox::OnSelectionChange( )" );
        }
    },

    AddMenuItem : function( menuItem )
    {
        try
        {
            try
            {
                this.m_popup.add( menuItem.m_option, null );
            }
            catch ( e )
            {
                this.m_popup.add( menuItem.m_option );
            }

            this.m_menuItems[ this.m_menuItems.length ] = menuItem;
        }
        catch ( e )
        {
            EX_ASSERT_NO_EXCEPTIONS( e, "CB_ComboBox::AddMenuItem( )" );
        }
    },

    GetLength : function( )
    {
        return this.m_menuItems.length;
    },

    GetMenuItem : function( i )
    {
        try
        {
            if ( i < 0 || i >= this.m_menuItems.length )
            {
                throw new EX_ProgrammingError( "Invalid index: " + i + "; length: " + this.m_menuItems.length );
            }

            return this.m_menuItems[ i ];
        }
        catch ( e )
        {
            EX_ASSERT_NO_EXCEPTIONS( e, 'CB_ComboBox::GetMenuItem( )' );
        }
    },

    GetSelectedIndex : function( )
    {
        try
        {
            return this.m_popup.selectedIndex;
        }
        catch ( e )
        {
            EX_ASSERT_NO_EXCEPTIONS( e, 'CB_ComboBox::GetSelectedIndex( )' );
        }
    },

    GetSelectedMenuItem : function( )
    {
        try
        {
            return this.GetMenuItem( this.m_popup.selectedIndex );
        }
        catch ( e )
        {
            EX_ASSERT_NO_EXCEPTIONS( e, 'CB_ComboBox::GetSelectedMenuItem( )' );
        }
    },

    Select : function( functor )
    {
        try
        {
            var index = 0;

            for ( ; index < this.m_menuItems.length; ++index )
            {
                if ( functor( this.m_menuItems[ index ] ) )
                {
                    this.SelectIndex( index );
                    break;
                }
            }
        }
        catch ( e )
        {
            EX_ASSERT_NO_EXCEPTIONS( e, 'CB_ComboBox::Select( )' );
        }
    },

    SelectIndex : function( menuItemIndex )
    {
        try
        {
            if ( menuItemIndex < 0 || menuItemIndex >= this.m_menuItems.length )
            {
                throw new EX_ProgrammingError( "Invalid index: " + menuItemIndex + "; length: " + this.m_menuItems.length );
            }

            this.m_popup.selectedIndex = menuItemIndex;
        }
        catch ( e )
        {
            EX_ASSERT_NO_EXCEPTIONS( e, 'CB_ComboBox::SelectIndex( )' );
        }
    }
};
