//**************************************************************************************************
//                                          PnlValue.cpp                                           *
//                                         --------------                                          *
// Started     : 2004-09-14                                                                        *
// Last Update : 2018-11-04                                                                        *
// Copyright   : (C) 2004-2018 MSWaters                                                            *
//**************************************************************************************************

//**************************************************************************************************
//                                                                                                 *
//      This program is free software; you can redistribute it and/or modify it under the          *
//      terms of the GNU General Public License as published by the Free Software Foundation;      *
//      either version 3 of the License, or (at your option) any later version.                    *
//                                                                                                 *
//**************************************************************************************************

#include "PnlValue.hpp"

//**************************************************************************************************
// Implement an event table.

wxBEGIN_EVENT_TABLE( PnlValue, wxPanel )

  EVT_SPIN_UP  ( PnlTxtSpn::ID_SPINBTN  , PnlValue::OnSpnScroll )
  EVT_SPIN_DOWN( PnlTxtSpn::ID_SPINBTN  , PnlValue::OnSpnScroll )

  EVT_CHOICE   ( PnlValue ::ID_CHO_UNITS, PnlValue::OnChoUnits  )

wxEND_EVENT_TABLE( )

//**************************************************************************************************
// Constructor.

PnlValue::PnlValue( void ) : wxPanel( )
{
  bClear( );
}

//**************************************************************************************************
// Destructor.

PnlValue::~PnlValue( )
{
}

//**************************************************************************************************
// Layout the display objects.

void  PnlValue::DoLayout( void )
{
  wxBoxSizer  * poSzr;
  wxSizerFlags  oFlags;

  // Create and set the sizer for the panel
  poSzr = new wxBoxSizer( wxHORIZONTAL );
  SetSizer( poSzr );

  // Add the value label
  oFlags.Proportion( 1 );
  // The next 3 lines vertically center the wxLabel
  oFlags.Border( wxTOP, 6 );
  poSzr->Add( &m_oLblName, oFlags );

  // Add the value itself
  oFlags.Proportion( 0 );
  oFlags.Border( wxTOP, 0 );
  poSzr->Add( &m_oSpnValue, oFlags );

  // Add units for the value
  poSzr->AddSpacer( 4 );
  poSzr->Add( &m_oChoUnits, oFlags );
  poSzr->AddSpacer( 3 );
  oFlags.Border( wxTOP, 6 );
  poSzr->Add( &m_oLblUnits, oFlags );

  // Set the panel sizer and the min. & init. sizes as calculated by the sizer
  poSzr->SetSizeHints( this );
}

//**************************************************************************************************
// Create an instance of this object.
//
// Argument List :
//   poWin      - The parent window
//   oWinID     - The window identifier
//   iNameWd    - The width of the name label in pixels
//   iValueWd   - The width of the value control
//   iUnitsWd   - The width of the units control
//   roPosn     - The position
//   eShowUnits - Flag indicating if units should be accommodated
//
// Return Values :
//   true  - Success
//   false - Failure

bool  PnlValue::bCreate( wxWindow * poWin, wxWindowID oWinID, int iNameWd, int iValueWd,
                         int iUnitsWd, const wxPoint & roPosn, eTypeShow eShowUnits )
{
  bool  bRtn=true;

  if( bIsCreated( ) )                                                         return( true );

  // Create the base class (wxPanel)
  if( ! wxPanel::Create( poWin, oWinID, roPosn ) )                            return( false );

  // Create the variable name label
  if( ! m_oLblName.Create( this, ID_UNUSED, wxT(""), wxDefaultPosition,
                           wxSize( iNameWd, GUI_CTRL_HT-2 ), wxALIGN_LEFT ) ) bRtn = false;

  // Create the value spin control
  if( ! m_oSpnValue.bCreate( this, ID_SPN_VALUE, iValueWd ) )                 bRtn = false;

  // Create the units choice box
  if( ! m_oChoUnits.bCreate( this, ID_CHO_UNITS, iUnitsWd ) )                 bRtn = false;

  // Create the units static label
  if( ! m_oLblUnits.bCreate( this, ID_LBL_UNITS, iUnitsWd ) )                 bRtn = false;

  // Specify how units should be displayed
  bShowUnits( eShowUnits );

  // Layout the display objects
  DoLayout( );

  return( bRtn );
}

//**************************************************************************************************
// Clear the spin and choice values.
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bClear( void )
{
  bool  bRtn=true;

  m_eShowUnits = eSHOW_CHO;

  if( ! m_oSpnValue.bClear( ) ) bRtn = false;
  if( ! m_oChoUnits.bClear( ) ) bRtn = false;
  if( ! m_oLblUnits.bClear( ) ) bRtn = false;

  return( bRtn );
}

//**************************************************************************************************
// Set the name label.
//
// Argument List :
//   rosName - The name of the variable
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bSetName( const wxString & rosName )
{
  if( ! bIsCreated( ) )    return( false );
  if( rosName.IsEmpty( ) ) return( false );

  m_oLblName.SetLabel( rosName );

  return( true );
}

//**************************************************************************************************
// Set the variable type for the spin control to display.
//
// Argument List :
//   eVType - The variable type
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bSetValueType( eTypeValue eVType )
{
  if( ! bIsCreated( ) ) return( false );

  return( m_oSpnValue.bSetValType( eVType ) );
}

//**************************************************************************************************
// Set the type of units to be displayed in the choice control.
//
// Argument List :
//   eUType  - The units specifier
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bSetUnitsType( eTypeUnits eUType )
{
  bool  bRtn=true;

  // Check that the display object has bee created
  if( ! bIsCreated( ) ) return( false );

  // Set the choice box units type
  if( m_oChoUnits.eGetUnitsType( ) != eUType )
  {
    if( m_oChoUnits.bSetUnitsType( eUType ) )
    {
      // Automatically set the spin control parameters
      switch( eUType )
      {
        case eUNITS_CAP  :  // Capacitance
          bSetDefValue( 100.0 ); bSetSpnRange(     0.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        case eUNITS_IND  :  // Inductance
          bSetDefValue( 100.0 ); bSetSpnRange(     0.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        case eUNITS_RES  :  // Resistance
          bSetDefValue( 100.0 ); bSetSpnRange(     0.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        case eUNITS_COND :  // Conductance
          bSetDefValue( 100.0 ); bSetSpnRange(     0.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        case eUNITS_VOLT :  // Voltage
          bSetDefValue(   1.0 ); bSetSpnRange( -10000.0,10000.0 ); bSetSpnIncSz( 1.0,1000.0 );
          break;
        case eUNITS_CURR :  // Current
          bSetDefValue(   1.0 ); bSetSpnRange( -1001.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        case eUNITS_TIME :  // Time
          bSetDefValue(   1.0 ); bSetSpnRange(     0.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        case eUNITS_FREQ :  // Frequency
          bSetDefValue( 100.0 ); bSetSpnRange(     0.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        case eUNITS_CHRG :  // Charge
          bSetDefValue( 100.0 ); bSetSpnRange(     0.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        case eUNITS_PHAD :  // Phase / angle in Degree
          bSetDefValue(   0.0 ); bSetSpnRange(  -200.0 ,  200.0 ); bSetSpnIncSz( 1.0,  10.0 );
          break;
        case eUNITS_PHAR :  // Phase / angle in Radian
          bSetDefValue(   0.0 ); bSetSpnRange(    -3.2 ,    3.2 ); bSetSpnIncSz( 0.1,   0.5 );
          break;
        case eUNITS_TMPC :  // Temperature in Celcius
          bSetDefValue(  27.0 ); bSetSpnRange(  -273.15,  300.0 ); bSetSpnIncSz( 1.0,  10.0 );
          break;
        case eUNITS_TMPF :  // Temperature in Fahrenheit
          bSetDefValue(  80.0 ); bSetSpnRange(  -459.7 ,  500.0 ); bSetSpnIncSz( 1.0,  10.0 );
          break;
        case eUNITS_EXP  :  // Exponent (dimensionless)
          bSetDefValue(   1.0 ); bSetSpnRange( -1001.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
        default :
          bSetDefValue( 100.0 ); bSetSpnRange( -1001.0 , 1001.0 ); bSetSpnIncSz( 1.0, 100.0 );
          break;
      }
    }
    else bRtn = false;
  }

  // Set the static label units type
  if( m_oLblUnits.eGetUnitsType( ) != eUType )
    if( ! m_oLblUnits.bSetUnitsType( eUType ) )
      bRtn = false;

  return( bRtn );
}

//**************************************************************************************************
// Set the spin control range.
//
// Argument List :
//   dfMinValue - The spin control minimum value
//   dfMaxValue - The spin control maximum value
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bSetSpnRange( double dfMinValue, double dfMaxValue )
{
  if( ! bIsCreated( ) ) return( false );

  return( m_oSpnValue.bSetRange( dfMinValue, dfMaxValue ) );
}

//**************************************************************************************************
// Set the increment sizes of the spin control.
//
// This spin control can be incremented using two different approaches, constant or variable step
// sizes. A constant step size means that the spin control is incremented by the same amount
// throughout it's range. A variable step size means that the spin control is incremented by an
// amount dependent on it's current value.
//
// Argument List :
//   dfMinIncSz - The minimum spin control increment size
//   dfMaxIncSz - The maximum spin control increment size
//
// Return Values :
//   true  - Success
//   false - Failure

bool  PnlValue::bSetSpnIncSz( double dfMinIncSz, double dfMaxIncSz )
{
  if( ! bIsCreated( ) ) return( false );

  return( m_oSpnValue.bSetIncSz( dfMinIncSz, dfMaxIncSz ) );
}

//**************************************************************************************************
// Set the value from a long integer.
//
// Argument List :
//   liValue - The long integer value
//   uiExp   - An optional exponent, specifies the units if it is a multiple of 3
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bSetValue( long liValue, uint uiExp )
{
  long  liMan;
  uint  ui1;
  int   i1;

  if( ! bIsCreated( ) )                          return( false );

  // Combine the value with the exponent function argument if specified
  liMan = liValue;
  if( uiExp != NOVAL_UINT ) for( ui1=uiExp; ui1>0; ui1-- ) liMan *= 10;

  // Set the value. Do different things depending on the units control on display
  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      // Parse the value passed to the function
      for( ui1=0; liMan>1000; ui1++ )
        { liMan += 5; liMan /= 10; } // Note : rounding could occur here

      // Restore values if the exponent is a multiple of 3
      if( uiExp != NOVAL_UINT )
      {
        if( uiExp % 3 == 0 )
        {
          liMan = liValue;
          ui1   = uiExp;
        }
      }

      // Set the units choice control values
      if( ! m_oChoUnits.bSetUnits( (int) ui1 ) ) return( false );
      break;

    case eSHOW_LBL  :
      // Combine the value with it's units
      i1 = m_oLblUnits.iGetUnits( );
      for( ; i1>0; i1-- ) { liMan += 5; liMan /= 10; } // Note : rounding could occur here
      for( ; i1<0; i1++ ) {             liMan *= 10; }
      break;

    case eSHOW_NONE :
      break;
  }

  // Set the spin control value
  if( ! m_oSpnValue.bSetValue( liMan ) )         return( false );

  return( true );
}

//**************************************************************************************************
// Set the value from a double float.
//
// Argument List :
//   dfValue - The double float value
//   iExp    - An optional exponent, specifies the units if it is a multiple of 3
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bSetValue( double dfValue, int iExp )
{
  double  dfMan;
  int     i1;

  if( ! bIsCreated( ) )                                     return( false );

  // Combine the value with the exponent function argument if specified
  if( iExp != NOVAL_INT ) dfMan = dfValue * EXP10( (double) iExp );
  else                    dfMan = dfValue;

  // Set the value. Do different things depending on the units control on display
  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      // Restore mantissa and exponent if the exponent is a multiple of 3
      if( iExp!=NOVAL_INT && iExp%3==0 )
      {
        dfMan = dfValue;
        i1    = iExp;
      }
      else
      {
        // Parse the value passed to the function
        if( ! CnvtType::bParseDbl( dfValue, &dfMan, &i1 ) ) return( false );

        // Determine the spin control value and the units choice selection
        if( dfMan != 0.0 )
          for( ; i1%3!=0; i1-- )
            dfMan *= 10.0;
      }

      // Set the units choice control values
      if( ! m_oChoUnits.bSetUnits( i1 ) )                   return( false );
      break;

    case eSHOW_LBL  :
      // Determine the spin control value combined with it's units
      i1 = m_oLblUnits.iGetUnits( );
      if( i1 != 0 ) dfMan /= EXP10( (double) i1 );
      break;

    case eSHOW_NONE :
      dfMan = dfValue;
      break;
  }

  // Set the spin control value
  if( ! m_oSpnValue.bSetValue( dfMan ) )                    return( false );

  return( true );
}

//**************************************************************************************************
// Set the value from a string.
//
// Notes : 1. If the arguments numeric component is zero but units have been specified the units
//            will still be set, eg. "0.00mVolt".
//         2. If the units type specified differ from the currently set units type then the
//            operation fails.
//         3. This function will cope with arguments which contain both an exponent and a units
//            specifier, eg. 12.3E-7mF will be set as 1.23nF.
//
// Argument List :
//   rosValue - The string value
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bSetValue( const wxString & rosValue )
{
  eTypeUnits  eUType=eUNITS_NONE;
  double      dfValue;
  int         iPfx;
  size_t      sz1;

  // Don't continue unless the panel has been created
  if( ! bIsCreated( ) )                                   return( false );

  // Check that the string represents a numeric value
  if( ! CnvtType::bStrToFlt( rosValue, &dfValue ) )       return( false );

  // If there is a units specifier check that it matches the object's units type
  if( UnitsBase::bGetUnitsType( rosValue, &eUType ) )
    if( eUType!=eGetUnitsType( ) && eUType!=eUNITS_NONE ) return( false );

  // Set the value. Do different things depending on the units control on display
  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      // Look for a units prefix and attempt to set the units accordingly
      sz1 = rosValue.find_first_not_of( wxT(" .-+0123456789Ee") );
      if( sz1 != std::string::npos )
        if( CnvtType::bUnitPfxToExp( rosValue[ sz1 ], &iPfx ) )
          if( bSetValue( dfValue / EXP10( (double) iPfx ), iPfx ) )
            break;

      // See if the value can be set without units
      if( bSetValue( dfValue, 0 ) )
        if( dfValue == dfGetValue( ) )
          break;

      // Set the value and allow the choice control to select an appropriate units prefix
      if( ! bSetValue( dfValue ) ) return( false );
      break;

    case eSHOW_LBL  :
      if( ! bSetValue( dfValue ) )                        return( false );
      break;

    case eSHOW_NONE :
      if( ! m_oSpnValue.bSetValue( rosValue ) )           return( false );
      break;
  }

  return( true );
}

//**************************************************************************************************
// Set the units to be displayed in the choice control or static label.
//
// Argument List :
//   rosUnits - The units to be displayed
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bSetUnits( const wxString & rosUnits )
{
  if( ! bIsCreated( ) )                         return( false );

  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      if( ! m_oChoUnits.bSetUnits( rosUnits ) ) return( false );
      break;

    case eSHOW_LBL  :
      if( ! m_oLblUnits.bSetUnits( rosUnits ) ) return( false );
      break;

    case eSHOW_NONE :                           return( false );
}

  return( true );
}

//**************************************************************************************************
// Specify if and how units should be displayed.
//
// The units can be hidden or displayed in either a choice control or a static label. A choice
// control allowes the user to specify the units. A label simply displays the units.
//
// Argument List :
//   eShowUnits - Enumerated show (units) specifier
//
// Return Values :
//   Success - true
//   Failure - false

bool  PnlValue::bShowUnits( eTypeShow eShowUnits )
{
  if( ! bIsCreated( ) ) return( false );

  switch( eShowUnits )
  {
    case eSHOW_CHO  :
      m_oChoUnits.Show( true );
      m_oLblUnits.Show( false );
      break;

    case eSHOW_LBL  :
      m_oChoUnits.Show( false );
      m_oLblUnits.Show( true );
      break;

    case eSHOW_NONE :
      m_oChoUnits.Show( false );
      m_oLblUnits.Show( false );
      break;
  }

  m_eShowUnits = eShowUnits;

  return( true );
}

//**************************************************************************************************
// Get the variable name.
//
// Return Values :
//   Success - The variable name as a string
//   Failure - An empty string

const wxString & PnlValue::rosGetName( void )
{
  static  wxString  osName;

  osName.Empty( );

  if( ! bIsCreated( ) ) return( osName );

  osName = m_oLblName.GetLabel( );

  return( osName );
}

//**************************************************************************************************
// Get the spin control value including units as an integer.
//
// Return Values :
//   Success - The value as a long integer
//   Failure - NOVAL_LNG

long  PnlValue::liGetValue( void )
{
  double  df1;
  long    li1=0;

  // Has the control been created?
  if( ! bIsCreated( ) )              return( NOVAL_LNG );

  // Get the spin control as a float and check it can be converted to a long
  df1 = m_oSpnValue.dfGetValue( );
  if( df1<LONG_MIN || df1>LONG_MAX ) return( NOVAL_LNG );

  // Get the value combining it with any units
  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      li1 = m_oChoUnits.liGetValue( df1 );
      break;

    case eSHOW_LBL  :
      li1 = m_oLblUnits.liGetValue( df1 );
      break;

    case eSHOW_NONE :
      li1 = m_oSpnValue.liGetValue( );
      break;
  }

  return( li1 );
}

//**************************************************************************************************
// Get the spin control value including units as a float.
//
// Return Values :
//   Success - The value as a double precision float
//   Failure - NOVAL_DBL

double  PnlValue::dfGetValue( void )
{
  double  df1;

  // Has the control been created?
  if( ! bIsCreated( ) )  return( NOVAL_DBL );

  // Get the spin control value
  df1 = m_oSpnValue.dfGetValue( );
  if( df1 == NOVAL_DBL ) return( NOVAL_DBL );

  // Combine the spin control value with any units
  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      df1 = m_oChoUnits.dfGetValue( df1 );
      break;

    case eSHOW_LBL  :
      df1 = m_oLblUnits.dfGetValue( df1 );
      break;

    case eSHOW_NONE :
      break;
  }

  return( df1 );
}

//**************************************************************************************************
// Get the spin control value including units as a string.
//
// Return Values :
//   Success - The value as a string
//   Failure - An empty string

const wxString & PnlValue::rosGetValue( void )
{
  static  wxString  osValue;
          double    df1;

  osValue.Empty( );

  // Has the control been created?
  if( ! bIsCreated( ) )  return( osValue );

  // Test the spin control value
  df1 = m_oSpnValue.dfGetValue( );
  if( df1 == NOVAL_DBL ) return( osValue );

  // Combine the spin control value with any units
  osValue = m_oSpnValue.rosGetValue( );
  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      if( m_oChoUnits.iGetUnits( ) != 0 ) osValue = m_oChoUnits.rosGetValue( df1 );
      break;

    case eSHOW_LBL  :
      if( m_oLblUnits.iGetUnits( ) != 0 ) osValue = m_oLblUnits.rosGetValue( df1 );
      break;

    case eSHOW_NONE :
      break;
  }

  return( osValue );
}

//**************************************************************************************************
// Get the units type.
//
// Return Values :
//   Enumerated units type specifier

eTypeUnits  PnlValue::eGetUnitsType( void )
{
  eTypeUnits  eUType=eUNITS_NONE;

  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      eUType = m_oChoUnits.eGetUnitsType( );
      break;

    case eSHOW_LBL  :
      eUType = m_oLblUnits.eGetUnitsType( );
      break;

    case eSHOW_NONE :
      eUType = eUNITS_NONE;
      break;
  }

  return( eUType );
}

//**************************************************************************************************
// Get the units.
//
// Return Values :
//   Success - The currently selected units
//   Failure - An empty string

const wxString & PnlValue::rosGetUnits( void )
{
  static  wxString  osUnits;

  osUnits.Empty( );

  if( ! bIsCreated( ) ) return( osUnits );

  switch( m_eShowUnits )
  {
    case eSHOW_CHO  :
      osUnits = m_oChoUnits.rosGetUnits( );
      break;

    case eSHOW_LBL  :
      osUnits = m_oLblUnits.rosGetUnits( );
      break;

    case eSHOW_NONE :
      break;
  }

  return( osUnits );
}

//**************************************************************************************************
// Print the object attributes.
//
// Argument List :
//   rosPrefix - A prefix to every line displayed (usually just spaces)

void  PnlValue::Print( const wxString & rosPrefix )
{
  m_oSpnValue.Print( rosPrefix + wxT("m_oSpnValue.") );
  m_oChoUnits.Print( rosPrefix + wxT("m_oChoUnits.") );
  m_oLblUnits.Print( rosPrefix + wxT("m_oLblUnits.") );
}

//**************************************************************************************************
//                                         Event Handlers                                          *
//**************************************************************************************************
// Spin button scroll event handler.
//
// Combine the spin control value and the choice control units
//
// Argument List :
//   roEvtSpn - An object holding information about the event

void  PnlValue::OnSpnScroll( wxSpinEvent & roEvtSpn )
{
  double  dfMan, df1;
  int     iExp;

  // If there's no units or the units are fixed then skip this event handler
  if( m_eShowUnits != eSHOW_CHO ) return;
  switch( m_oChoUnits.eGetUnitsType( ) )
  {
    case eUNITS_TMPC :
    case eUNITS_TMPF :
    case eUNITS_PHAD :
    case eUNITS_PHAR :            return;
    default          : break;
  }

  // Get the current values for the value and it's units
  dfMan = m_oSpnValue.dfGetValue( );
  iExp  = m_oChoUnits.iGetUnits( );
  df1 = dfMan;

  // Determine the event type and act accordingly
  if(      roEvtSpn.GetEventType( ) == wxEVT_SCROLL_LINEUP )
  { // Increment the value
    if( dfMan > 0.0 )
    { // Positive numbers
      if( dfMan <= 1000.0 )       return;
      df1 = 1.0;
      iExp += 3;
    }
    else
    { // Negative numbers
      if( dfMan <= -1.0 )         return;
      df1 = -1000.0;
      iExp -= 3;
    }
  }
  else if( roEvtSpn.GetEventType( ) == wxEVT_SCROLL_LINEDOWN )
  { // Decrement the value
    if( dfMan < 0.0 )
    { // Negative numbers
      if( dfMan >= -1000.0 )      return;
      df1 = -1.0;
      iExp += 3;
    }
    else
    { // Positive numbers
      if( dfMan >= 1.0 )          return;
      df1 = 1000.0;
      iExp -= 3;
    }
  }
  else                            return;

  // Set the new spin control and choice control values
  if( m_oChoUnits.bSetUnits( iExp ) ) dfMan = df1;
  m_oSpnValue.bSetValue( dfMan );
}

//**************************************************************************************************
// Units choice box event handler.
//
// Argument List :
//   roEvtCmd - An object holding information about the event

void  PnlValue::OnChoUnits( wxCommandEvent & roEvtCmd )
{
  eTypeUnits  eUType;

  eUType = m_oChoUnits.eGetUnitsType( );

  if(      eUType==eUNITS_TMPC || eUType==eUNITS_TMPF )
  {
    if(      m_oChoUnits.rosGetUnits( ).IsSameAs( wxT("Deg.C") )  ) bSetUnitsType( eUNITS_TMPC );
    else if( m_oChoUnits.rosGetUnits( ).IsSameAs( wxT("Deg.F") )  ) bSetUnitsType( eUNITS_TMPF );
  }
  else if( eUType==eUNITS_PHAD || eUType==eUNITS_PHAR )
  {
    if(      m_oChoUnits.rosGetUnits( ).IsSameAs( wxT("Degree") ) ) bSetUnitsType( eUNITS_PHAD );
    else if( m_oChoUnits.rosGetUnits( ).IsSameAs( wxT("Radian") ) ) bSetUnitsType( eUNITS_PHAR );
  }
}

//**************************************************************************************************
