/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2010/X/X - 2017/02/03
/// 
/// @brief  ラベル付き値設定コンポーネント。
/// 
/// ****************************************************************************

#include "CPL_GUC_InputBox.h"


namespace CPL {
namespace GUC {

// _____________________________________________________________________________
/// @brief コンストラクタ
/// 
/// @param[in] in_create_info
///   : 作成情報 CreateInfo構造体を指定します。
///   : 詳しくはInputBox::CreateInfo構造体を参照してください。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InputBox::InputBox
( _in<CreateInfo> in_create_info
) : td_base
    ( in_create_info.sp_component_for_parent
    , in_create_info.position_for_component
    , float2(-1,-1)
    )
{
//  StackEventMode sem( this, EVMODE_CHILD_CUT ); // 子供からのイベントを無効化
  float2 nb_pos(in_create_info.width_for_label, 0);
  auto const LH = GetLineHeight();

  // アイテム配置
  m_sp_label =
    Factory<Label>::Create
      ( GetLinkMyself()
      , kPOS_DEFAULT
      , float2(in_create_info.width_for_label, LH)
      , in_create_info.string_for_label
      );
  if( in_create_info.width_for_label < 0 )
  {
    GetComponent_Label()->AdjustSize();
    nb_pos.x = 0;
    nb_pos.y = GetComponent_Label()->GetSize().y;
  }

  m_sp_num_box =
    Factory<NumBox>::Create
      ( this->GetLinkMyself()
      , nb_pos
      , float2( in_create_info.width_for_numbox, LH )
      );
  m_sp_num_box->SetIntegerMode( in_create_info.mode );
  m_sp_num_box->SetMin( in_create_info.value_of_minimum );
  m_sp_num_box->SetMax( in_create_info.value_of_maximum );
  m_sp_num_box->SetValue( in_create_info.value_of_initial );
  
  SetStateVisible( true );

  zzf_setupDrawState( false, false, false ); // 描画ステートのデフォルト設定。
  zzf_SetInitializedLevel( zzf_GetClassLevel() );

  AdjustSize();
}


// _____________________________________________________________________________
/// @brief コピーコンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InputBox::InputBox( cref<InputBox> in_input_box )
  : td_base( in_input_box )
  , m_sp_label
    { FindComponentT_by_UserID<Label>( in_input_box.m_sp_label )
    }
  , m_sp_num_box
    { FindComponentT_by_UserID<NumBox>( in_input_box.m_sp_num_box )
    }
{
  m_sp_label  ->SetAutoUserID();
  m_sp_num_box->SetAutoUserID();
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::On_UserProc 
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  InputBox::On_UserProc
    ( _in<sdptr<Component>> in_sp_component
    , _in<long            > in_message
    , _in<WPARAM          > in_wparam
    , _in<LPARAM          > in_lparam
    )
{
  if( in_sp_component == GetComponent_NumBox() )
  {
    this->SendParentMessage
      ( GetLinkMyself()
      , in_message
      , in_wparam
      , (LPARAM)this
      , eParentType::Position
      );
  }

  return eEventReturnID::LastCall;
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::KeyEventInterface::On_KeyDown
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  InputBox::On_KeyDown
    ( _in<sdptr<Component>> in_sp_component
    , _in<int             > in_virtual_key_code
    )
{
  if( in_sp_component == GetComponent_NumBox() )
  {
    double value = GetComponent_NumBox()->GetValue();//static_cast<float>(NumBox::sm_num_box().GetValue());
    this->SendParentMessage
      ( GetLinkMyself()
      , eID::ValueChanged
      , (WPARAM)&value
      , (LPARAM)this
      , eParentType::Position
      );
  }

  return eEventReturnID::LastCall;
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::On_Size
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  InputBox::On_Size( _in<sdptr<Component>> in_sp_component )
{
  if( in_sp_component == this->GetLinkMyself()  &&
      GetInitialized() >= zzf_GetClassLevel() )
  {
    float4 rect_client;
    this->GetRectCoord( rect_client );
    rect_client -=
      float4( rect_client.x
            , rect_client.y
            , rect_client.x
            , rect_client.y
            );

    this->GetComponent_NumBox()->SetRectCoord
      ( rect_client
      , WIN::Component::eRectFlag::Right
      );
  }

  return eEventReturnID::SendParent_Position;
}


// _____________________________________________________________________________
/// @brief 値の設定
/// 
/// @param[in] in_value : 設定する値を指定します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void InputBox::SetValue( _in<float> in_value )
{
  GetComponent_NumBox()->SetValue( in_value );
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::CreateClone
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<Component>
  InputBox::CreateClone
    ( _in<sdptr<Component>> in_sp_component_for_parent
    , _in<float2          > in_offset_position_from_original
    ) const
{
  return
    zzz_CreateClone_Basic<td_self>
      ( in_sp_component_for_parent
      , in_offset_position_from_original
      );
}


} // namespace GUC
} // namespace CPL
