/******************************************************************************
FILE:  WB_RGBCtl.h

SERVICES:  AEE RGB Custom Control

GENERAL DESCRIPTION:
  This is a custom control which is used to select a numeric value between 0 
  and 255.  It is used by the WhiteBoard application to allow users to 
  specify Red, Green and Blue color values for drawing shapes.

  The control behaves just like an IListCtl, Showing a single selected
  entry at a time.  Pressing the Up and Down keys increases or decreases
  the numeric value.  Pressing the Left or Right keys causes an EVT_CTL_TAB
  event to be posted.  The primary difference between this control and 
  a IMenuCtl is that a seperate menu item does not need to be created
  for each of the 256 possible color values.  This provides a significant
  memory savings.

  The CRGBCtl allows the user to enter two different color values, one 
  for the fill color and the other the border color.  Which value the
  control displays depends on the value passed to the CRGBCtl_SetMode
  function.

  This is NOT a true BREW control.  It simply uses an interface that makes 
  it behave like one.  The primary difference between this control 
  and true BREW controls is that this control is not derived from IControl.
  Therefore, special handling is occasionally required when using this control.

PUBLIC CLASSES AND STATIC FUNCTIONS:
	Classes:
    IDisplay

INITIALIZATION & SEQUENCING REQUIREMENTS:

	See Exported Routines

       Copyright © 2002 QUALCOMM Incorporated.
               All Rights Reserved.
            QUALCOMM Proprietary/GTDR
******************************************************************************/

//*****************************************************************************
// INCLUDE FILES
//*****************************************************************************

#include "WB_RGBCtl.h"
#include "AEEStdLib.h"
#include "AEEAppGen.h"
#include "nmdef.h"


/*===========================================================================

FUNCTION: CRGBCtl_CreateInstance

DESCRIPTION:
  This function creates a single instance of an CRGBCtl control.

PARAMETERS:
  None

DEPENDENCIES:
  None

RETURN VALUE:
  Returns a pointer to the CRGBCtl or returns NULL if an error occurred.

SIDE EFFECTS:
  None
===========================================================================*/

CRGBCtl* CRGBCtl_CreateInstance( void )
{
  CRGBCtl* pCtl = (CRGBCtl*) MALLOC( sizeof( CRGBCtl ) );
  
  if( pCtl )
  {
    pCtl->m_bIsActive = FALSE;
    pCtl->m_nBorderValue = 0;
    pCtl->m_nFillValue = 0;
    pCtl->m_bIsBorderMode = TRUE;
    SETAEERECT( &pCtl->m_rRect, 0, 0, 10, 10 );
  }
  return pCtl;
}

/*===========================================================================

FUNCTION: CRGBCtl_SetRect

DESCRIPTION:
  Sets the rectangle coordinates of an CRGBCtl control.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

  pRect [in] - Pointer to an AEERect structure containing the rectangle 
    coordinates.

DEPENDENCIES:
  None

RETURN VALUE:
  None

SIDE EFFECTS:
  If pCtl is NULL, noe rectangle is set.
===========================================================================*/

void CRGBCtl_SetRect( CRGBCtl* pCtl, AEERect* pRect )
{
  if( pCtl )
    SETAEERECT( &pCtl->m_rRect, pRect->x, pRect->y, pRect->dx, pRect->dy );
}

/*===========================================================================

FUNCTION: CRGBCtl_GetRect

DESCRIPTION:
  Retrieves the current rectangle coordinates of an CRGBCtl control.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

  pRect [out] - Pointer to an AEERect structure which is set to the current
    rectangle coordinates of the control.

DEPENDENCIES:
  None

RETURN VALUE:
  None

SIDE EFFECTS:
  If pCtl is NULL, the rectangle coordinates in pRect are not changed.
===========================================================================*/

void CRGBCtl_GetRect( CRGBCtl* pCtl, AEERect* pRect )
{
  if( pCtl )
    SETAEERECT( pRect, pCtl->m_rRect.x, pCtl->m_rRect.y, pCtl->m_rRect.dx, pCtl->m_rRect.dy );
}

/*===========================================================================

FUNCTION: CRGBCtl_SetMode

DESCRIPTION:
  Indicates if the control allows entry of Border or Fill values.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

  bIsBorderMode [in] - A boolean flag indicating the mode of the control.
    A value of TRUE places the control in Border mode.  A value of FALSE 
    places the control in Fill mode.

DEPENDENCIES:
  None

RETURN VALUE:
  None

SIDE EFFECTS:
  If pCtl is NULL, the mode is not set.
  Causes the control to redraw itself.
===========================================================================*/

void CRGBCtl_SetMode( CRGBCtl* pCtl, boolean bIsBorderMode )
{
  if( pCtl )
  {
    pCtl->m_bIsBorderMode = bIsBorderMode;
    CRGBCtl_Redraw( pCtl );
  }
}

/*===========================================================================

FUNCTION: CRGBCtl_GetMode

DESCRIPTION:
  Returns the current mode of an CRGBCtl control.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

DEPENDENCIES:
  None

RETURN VALUE:
  Returns TRUE is the control is in Border mode.  Returns FALSE if the
  control is in Fill mode or if pCtl is NULL.

SIDE EFFECTS:
  None
===========================================================================*/

boolean CRGBCtl_GetMode( CRGBCtl* pCtl )
{
  if( pCtl )
    return pCtl->m_bIsBorderMode;
  else
    return FALSE;
}

/*===========================================================================

FUNCTION: CRGBCtl_GetBorderValue

DESCRIPTION:
  Returns the current Border value of an CRGBCtl control.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

DEPENDENCIES:
  None

RETURN VALUE:
  Returns the Border value of the control.  If pCtl is NULL, this function
  returns zero.

SIDE EFFECTS:
  None
===========================================================================*/

uint8 CRGBCtl_GetBorderValue( CRGBCtl* pCtl )
{
  if( pCtl )
    return pCtl->m_nBorderValue;
  else
    return 0;
}

/*===========================================================================

FUNCTION: CRGBCtl_GetFillValue

DESCRIPTION:
  Returns the current Fill value of an CRGBCtl control.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

DEPENDENCIES:
  None

RETURN VALUE:
  Returns the Fill value of the control.  If pCtl is NULL, this function
  returns zero.

SIDE EFFECTS:
  None
===========================================================================*/

uint8 CRGBCtl_GetFillValue( CRGBCtl* pCtl )
{
  if( pCtl )
    return pCtl->m_nFillValue;
  else
    return 0;
}

/*===========================================================================

FUNCTION: CRGBCtl_Redraw

DESCRIPTION:
  This function redraws an CRGBCtl control on the device screen.  The 
  control's value depends on the control's current mode setting.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

DEPENDENCIES:
  None

RETURN VALUE:
  None

SIDE EFFECTS:
  If pCtl is NULL, no action is taken.
  Redraws the control on the device screen.
===========================================================================*/

void CRGBCtl_Redraw( CRGBCtl* pCtl )
{
  AECHAR psTextBuf[ 5 ];
  AECHAR psFormat[] = { '%','i','\0' };
  AECHAR psSpace[] = { ' ', '\0' };

  if( pCtl )
  {
    if( pCtl->m_bIsBorderMode )
      WSPRINTF( psTextBuf, 5 * sizeof( AECHAR ), psFormat, pCtl->m_nBorderValue );
    else
      WSPRINTF( psTextBuf, 5 * sizeof( AECHAR ), psFormat, pCtl->m_nFillValue );

    WSTRCAT( psTextBuf, psSpace );
    IDISPLAY_EraseRect( ( (AEEApplet*) GETAPPINSTANCE() )->m_pIDisplay, &pCtl->m_rRect );
    IDISPLAY_DrawText( ( (AEEApplet*) GETAPPINSTANCE() )->m_pIDisplay, AEE_FONT_NORMAL, psTextBuf, -1, pCtl->m_rRect.x, pCtl->m_rRect.y, &pCtl->m_rRect, IDF_ALIGN_RIGHT | IDF_ALIGN_BOTTOM );
    if( pCtl->m_bIsActive )
      IDISPLAY_InvertRect( ( (AEEApplet*) GETAPPINSTANCE() )->m_pIDisplay, &pCtl->m_rRect );
    IDISPLAY_Update( ( (AEEApplet*) GETAPPINSTANCE() )->m_pIDisplay );
  }
}

/*===========================================================================

FUNCTION: CRGBCtl_SetActive

DESCRIPTION:
  Sets the active state of an CRGBCtl control.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

  bIsActive [in] - If TRUE, the control is set to the active state.  If 
    FALSE, the control is set to the inactive state.

DEPENDENCIES:
  None

RETURN VALUE:
  None

SIDE EFFECTS:
  An inactive CRGBCtl does not handle any events.
===========================================================================*/

void CRGBCtl_SetActive( CRGBCtl* pCtl, boolean bIsActive )
{
  if( pCtl )
  {
    pCtl->m_bIsActive = bIsActive;
    CRGBCtl_Redraw( pCtl );
  }
}

/*===========================================================================

FUNCTION: CRGBCtl_IsActive

DESCRIPTION:
  This function returns the current active state of an CRGBCtl control.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

DEPENDENCIES:
  None

RETURN VALUE:
  Returns TRUE is the control is active.  Returns FALSE if the control is
  inactive or if pCtl is NULL.

SIDE EFFECTS:
  None
===========================================================================*/

boolean CRGBCtl_IsActive( CRGBCtl* pCtl )
{
  if( pCtl )
    return pCtl->m_bIsActive;
  else
    return FALSE;
}

/*===========================================================================

FUNCTION: CRGBCtl_HandleEvent

DESCRIPTION:
  The CRGBCtl control uses this function to handle any evets it receives.
  An active CRGBCtl control handles key press events.  These events include
  AVK_LEFT, AVK_RIGHT, AVK_UP and AVK_DOWN key events.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

  eCode [in] - Event code.

  wParam [in] - 16-bit event data.

  dwParam [in] - 32-bit event data.

DEPENDENCIES:
  None

RETURN VALUE:
  Returns TRUE if the event is handled by the control.  Otherwise, the 
  function returns false.

SIDE EFFECTS:
  AVK_UP & AVK_DOWN key events cause the control to increase or decrease
  its value depending on the current mode of the control.  The control
  redraws itself for these events.

  AVK_LEFT & AVK_RIGHT key events cause the control to post an EVT_CTL_TAB
  event to BREW's event list.
===========================================================================*/

boolean CRGBCtl_HandleEvent( CRGBCtl* pCtl, AEEEvent eCode, uint16 wParam, uint32 dwParam )
{
  if( pCtl && pCtl->m_bIsActive )
  {
    switch( eCode )
    {
    case EVT_KEY_PRESS:
      switch( wParam )
      {
      case AVK_DOWN:
        if( pCtl->m_bIsBorderMode )
          pCtl->m_nBorderValue--;
        else
          pCtl->m_nFillValue--;
        CRGBCtl_Redraw( pCtl );
        ISHELL_PostEvent( ( (AEEApplet*) GETAPPINSTANCE() )->m_pIShell, ( (AEEApplet*) GETAPPINSTANCE() )->clsID, EVT_CTL_SEL_CHANGED, 0, (uint32) pCtl );
        return TRUE;

      case AVK_UP:
        if( pCtl->m_bIsBorderMode )
          pCtl->m_nBorderValue++;
        else
          pCtl->m_nFillValue++;
        CRGBCtl_Redraw( pCtl );
        ISHELL_PostEvent( ( (AEEApplet*) GETAPPINSTANCE() )->m_pIShell, ( (AEEApplet*) GETAPPINSTANCE() )->clsID, EVT_CTL_SEL_CHANGED, 0, (uint32) pCtl );
        return TRUE;

      case AVK_LEFT:
        ISHELL_PostEvent( ( (AEEApplet*) GETAPPINSTANCE() )->m_pIShell, ( (AEEApplet*) GETAPPINSTANCE() )->clsID, EVT_CTL_TAB, 0, (uint32) pCtl );
        return TRUE;
  
      case AVK_RIGHT:
        ISHELL_PostEvent( ( (AEEApplet*) GETAPPINSTANCE() )->m_pIShell, ( (AEEApplet*) GETAPPINSTANCE() )->clsID, EVT_CTL_TAB, 1, (uint32) pCtl );
        return TRUE;
      }
      break;
    } 
  }
  return FALSE;
}

/*===========================================================================

FUNCTION: CRGBCtl_Release

DESCRIPTION:
  Releases all memory and resources used by the control.

PARAMETERS:
  pCtl [in] - Pointer to a valid CRGBCtl.

DEPENDENCIES:
  None

RETURN VALUE:
  None

SIDE EFFECTS:
  Releases all control allocated memeory.
===========================================================================*/

void CRGBCtl_Release( CRGBCtl* pCtl )
{
  FREEIF( pCtl );
}

