/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2016/11/26
/// 
/// @brief  Win32　グループボックス周り。
/// 
/// ****************************************************************************

#pragma once

#include "CPL_WIN_Container.h"
#include "../../GObj/CPL_WIN_DIBitmap.h"


namespace CPL {
namespace WIN {

// _____________________________________________________________________________
/// @brief グループボックスコントロール
///
// *****************************************************************************
class GroupBox
  : public Container
{
protected:
  CPL_SINGLETON_INIT( DIBitmap, sm_bmp, expandImage )
  static LRESULT CALLBACK
    zzf_StaticProcGroup
      ( HWND   in_hdl_window
      , UINT   in_message
      , WPARAM in_wparam
      , LPARAM in_lparam
      );
  CPL_SINGLETON_INIT( WNDPROC, zzf_GROUP_PROC, nullptr )

  U16 m_expand;
  U16 m_exp_vilid; // 展開有効
  int m_save_height;

  CPL_WIN_COMPONENT_GET_CLASS_NAME( "BUTTON" );
  HWND zzf_GetParent_of_NotGroupBox();
public:
  // _____________________________________________________________________________
  /// @brief 展開モード設定
  /// 
  /// @param[in] in_flag_mode
  ///   : true  - 開閉を可能にします。\n
  ///   : false - 開閉を不可能にします。
  /// 
  /// @return なし。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void SetExpandMode( _in<bool> in_flag_mode )
  {
    m_exp_vilid = in_flag_mode;
    Update(false);
  }
  virtual void SetExpand    ( _in<bool> in_flag_open );
  virtual BOOL GetExpandMode() const { return m_exp_vilid; }
  virtual BOOL GetExpand    () const { return m_expand; }

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T>
  GroupBox
  ( _in<HWND     > in_hdl_win_parent
  , T const&       in_title
  , _in<td_Coord2> in_pos
  , _in<td_Coord2> in_size      = kSIZE_DEFAULT
  , _in<bool     > in_msg_throw = true
  ) : Container( in_msg_throw )
    , m_expand( true )
    , m_exp_vilid( false )
  {
    bool flag_create =
      zzf_Create
        ( in_hdl_win_parent, &in_title[0]
        , in_pos, in_size, GetComponentID()
        , WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 0, this
        );
    if( !flag_create )
    {
      return;
    }

    m_save_height = GetWindowSize().y;

    // サブクラス化
    if( !zzf_GROUP_PROC() )
    {
      zzf_GROUP_PROC() = zzf_GetProc( m_hdl_window );
    }
    zzf_SetProc( zzf_StaticProcGroup );
  }
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual ~GroupBox(){}
  

  // _____________________________________________________________________________
  /// @brief グループボックスコントロール　Pimpl実装用
  ///
  // *****************************************************************************
  class Binder
    : public Container::Binder
  {
  private:
    GroupBox*       getEntity()       { return dynamic_cast<GroupBox*      >(&*impl); }
    GroupBox const* getEntity() const { return dynamic_cast<GroupBox const*>(&*impl); }

  public:
    void SetExpandMode( bool sw ){ return getEntity()->SetExpandMode( sw ); }
    void SetExpand    ( bool sw ){ return getEntity()->SetExpand    ( sw ); }
    BOOL GetExpandMode() const   { return getEntity()->GetExpandMode();     }
    BOOL GetExpand    () const   { return getEntity()->GetExpand    ();     }

    Binder
    ( _in<HWND     > in_hdl_win_parent
    , _in<str_cptr > in_title
    , _in<td_Coord2> in_pos
    , _in<td_Coord2> in_size      = kSIZE_DEFAULT
    , _in<bool     > in_msg_throw = true
    ) : Container::Binder
        ( CPL_NEW(GroupBox)
            ( in_hdl_win_parent
            , in_title
            , in_pos
            , in_size
            , in_msg_throw
            )
        )
    {}
  protected:
    // 継承用
    Binder( GroupBox* in_ptr_group_box )
      : Container::Binder( in_ptr_group_box )
    {}
  };
};


} // namespace WIN
} // namespace CPL
