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

#pragma once

#include "CPL_GUC_TextBox.h"


namespace CPL {
namespace GUC {

// _____________________________________________________________________________
/// @brief 値設定コンポーネント
///
// *****************************************************************************
class InputBox
  : public Container
{
  using td_base = Container;
  using td_self = InputBox;
  friend Factory<td_self>;
  friend CallPrivateConstructor<td_self>;
public:
  //CPL_GUC_DECL_BASIC_SMARTPOINTER( InputBox );

  struct CreateInfo
  {
    sdptr<Component>      sp_component_for_parent; ///< 親コンポーネントのスマートポインタを指定します。
    float2                position_for_component;  ///< コンポーネントの座標を指定します。
    td_DefString          string_for_label;        ///< ラベルの文字列を指定します。
    float                 width_for_label ;        ///< ラベルの幅を指定します。
    float                 width_for_numbox;        ///< 数値ボックスの幅を指定します。
    float                 value_of_minimum;        ///< 最小値を指定します。
    float                 value_of_maximum;        ///< 最大値を指定します。
    float                 value_of_initial;        ///< 初期値を指定します。
    WIN::NumBox::eNumMode mode;                    ///< 

    CreateInfo
    ( _in<sdptr<Component>     > in_sp_component_for_parent
    , _in<float2               > in_position_for_component
    , pin<td_DefChar           > in_string_for_label
    , _in<float                > in_width_for_label
    , _in<float                > in_width_for_numbox
    , _in<float                > in_value_of_minimum
    , _in<float                > in_value_of_maximum
    , _in<float                > in_value_of_initial
    , _in<WIN::NumBox::eNumMode> in_mode
    ) : sp_component_for_parent( in_sp_component_for_parent )
      , position_for_component ( in_position_for_component  )
      , string_for_label       ( in_string_for_label )
      , width_for_label        ( in_width_for_label  )
      , width_for_numbox       ( in_width_for_numbox )
      , value_of_minimum       ( in_value_of_minimum )
      , value_of_maximum       ( in_value_of_maximum )
      , value_of_initial       ( in_value_of_initial )
      , mode                   ( in_mode )
    {}
  };
protected:
  static int zzf_GetClassLevel(){
    return td_base::zzf_GetClassLevel() + 1; }

  sdptr<Label > m_sp_label;
  sdptr<NumBox> m_sp_num_box;

  //eEventReturnID
  //  On_Char
  //    ( _in<sdptr<Component>> in_sp_component
  //    , _in<TCHAR           > in_char_code
  //    , _in<int             > in_key_data
  //    ) override;

  GUC::eEventReturnID
    On_UserProc
      ( _in<sdptr<Component>> in_sp_component
      , _in<long            > in_message
      , _in<WPARAM          > in_wparam
      , _in<LPARAM          > in_lparam
      ) override;

  eEventReturnID
    On_KeyDown
      ( _in<sdptr<Component>> in_sp_component
      , _in<int             > in_virtual_key_code
      ) override;
  eEventReturnID
    On_Size( _in<sdptr<Component>> in_sp_component ) override;

protected:
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  InputBox( _in<CreateInfo> in_create_info );
  // _____________________________________________________________________________
  /// @brief コンストラクタ
  /// 
  /// @copydoc doxycomment::arg_in_sp_component_for_parent
  /// @copydoc doxycomment::arg_in_position_for_component
  /// @copydoc doxycomment::arg_in_string_for_label
  /// @param[in] in_width_for_label   : ラベルの幅を指定します。
  /// @param[in] in_width_for_numbox  : 数値ボックスの幅します。
  /// @param[in] in_value_of_minimum        : 最小値を指定します。
  /// @param[in] in_value_of_maximum        : 最大値を指定します。
  /// @param[in] in_value_of_initial : 初期値を指定します。
  /// @param[in] in_mode : 扱うデータの種類を設定。WIN::NumBox::MODEを参照。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  InputBox
  ( _in<sdptr<Component>     > in_sp_component_for_parent
  , _in<float2               > in_position_for_component
  , pin<td_DefChar           > in_string_for_label
  , _in<float                > in_width_for_label
  , _in<float                > in_width_for_numbox
  , _in<float                > in_value_of_minimum
  , _in<float                > in_value_of_maximum
  , _in<float                > in_value_of_initial
  , _in<WIN::NumBox::eNumMode> in_mode = WIN::NumBox::eNumMode::Float
  ) : InputBox
      { CreateInfo
        { in_sp_component_for_parent
        , in_position_for_component
        , in_string_for_label
        , in_width_for_label
        , in_width_for_numbox
        , in_value_of_minimum
        , in_value_of_maximum
        , in_value_of_initial
        , in_mode
        }
      }
  {}
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  InputBox( cref<InputBox> in_input_box );
public:
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ~InputBox(){}

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  sdptr<Component>
    CreateClone
      ( _in<sdptr<Component>> in_sp_component_for_parent       = nullptr
      , _in<float2          > in_offset_position_from_original = float2{0,0}
      ) const override;

  // _____________________________________________________________________________
  /// @brief ラベルコンポーネントの取得
  /// 
  /// @return ラベルコンポーネントオブジェクトを指すスマートポインタを返します。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  virtual sdptr<Label> GetComponent_Label()  const noexcept { return m_sp_label; }

  // _____________________________________________________________________________
  /// @brief 数値ボックスコンポーネントの取得
  /// 
  /// @return 数値ボックスコンポーネントオブジェクトを指すスマートポインタを返します。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  virtual sdptr<NumBox> GetComponent_NumBox() const noexcept { return m_sp_num_box; }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void   SetValue( _in<float> in_value );

  // _____________________________________________________________________________
  /// @brief 現在値の取得
  /// 
  /// @return 現在値を返します。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual double GetValue() const { return GetComponent_NumBox()->GetValue(); }

  // _____________________________________________________________________________
  /// @brief 最小値の設定
  /// 
  /// @copydoc CPL::GUC::doxycomment::arg_in_value_of_minimum
  /// 
  /// @return なし。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void SetMin( _in<float> in_value_of_minimum )
  {
    GetComponent_NumBox()->SetMin( in_value_of_minimum );
  }

  // _____________________________________________________________________________
  /// @brief 最大値の設定
  /// 
  /// @copydoc CPL::GUC::doxycomment::arg_in_value_of_maximum
  /// 
  /// @return なし。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void SetMax( _in<float> in_value_of_maximum )
  {
    GetComponent_NumBox()->SetMax( in_value_of_maximum );
  }
};

//CPL_GUC_DECL_BASIC_SMARTPOINTER( InputBox );



} // namespace GUC
} // namespace CPL
