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


#include "CPL_WIN_GroupBox.h"


namespace CPL {
namespace WIN {




// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// サブクラス化用プロシージャ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LRESULT CALLBACK GroupBox::zzf_StaticProcGroup(
    HWND   in_hdl_window,
    UINT   in_message,
    WPARAM in_wparam,
    LPARAM in_lparam )
{
  LRESULT ret =
    ::CallWindowProc(
        zzf_GROUP_PROC(),
        in_hdl_window, in_message, in_wparam, in_lparam );
  GroupBox*
    ptr_group_box =
      dynamic_cast<GroupBox*>(GetHandleToPointer(in_hdl_window));

  if( ptr_group_box  &&  ptr_group_box->GetEventMode() != eEventMode::AllCut )  // ここのm_fEventMode判定はこれでよい
  {
    if( ptr_group_box->m_exp_vilid ) // 展開表示ならば
    {
      if( in_message == WM_PAINT )
      {
        HDC hdc = ::GetDC(in_hdl_window); // BeginPaint()は禁止
        HFONT hfont = GetWindowFont( in_hdl_window );
        LOGFONT lfont;
        ::GetObject( hfont, sizeof(LOGFONT), &lfont );
        int y = (lfont.lfHeight - 9) / 2;
        if( ptr_group_box->m_expand )
        {
          sm_bmp().Draw
            ( hdc
            , sem::t_Position<td_Coord2>( {-2, y} )
            , sem::t_Rect<Rect>( {10,0,19,10} )
            );
        }
        else
        {
          sm_bmp().Draw
            ( hdc
            , sem::t_X<int>(-2)
            , sem::t_Y<int>(y)
            , sem::t_Rect<Rect>( {0,1,9,10} )
            );
        }
        ::ReleaseDC( in_hdl_window, hdc );
      }
      else
      if( in_message == WM_NCHITTEST )
      {
        Rect rt(0,0,9,9);
        ::MapWindowPoints( in_hdl_window, ::GetDesktopWindow(), (POINT*)&rt, 2 );
        if( rt.Hit( (short)LOWORD(in_lparam), (short)HIWORD(in_lparam) ) )
        {
          return ::DefWindowProc( in_hdl_window, in_message, in_wparam, in_lparam );
        }
      }
      else
      if( in_message == WM_LBUTTONDOWN )
      {
        ptr_group_box->SetExpand( !ptr_group_box->GetExpand() );
        ::PostMessage( ptr_group_box->zzf_GetParent_of_NotGroupBox(),
                       kWM_CPL_GROUPBOX_EXPAND,
                       0,
                       reinterpret_cast<LPARAM>(ptr_group_box) );
      }
    }
/*    if( ptr_group_box->zzf_GetMessageThrow() ){
      if( in_message == WM_COMMAND  ||
        in_message == WM_NOTIFY   ||
        in_message == WM_HSCROLL  ||
        in_message == WM_VSCROLL  || 
        in_message >= kWM_CPL )
      {
        ::SendMessage( ptr_group_box->zzf_GetParent_of_NotGroupBox(), in_message, in_wparam, in_lparam );
      }
    }else{*/
      ret = ptr_group_box->DefaultProc_( in_message, in_wparam, in_lparam );
      if( ret )
      {
        return ret;
      }
//    }
  }
  return ret;
}

  
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// グループボックスでない親ウィンドウハンドルを検索する
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HWND GroupBox::zzf_GetParent_of_NotGroupBox()
{
  HWND     in_hdl_win_parent = GetParentWindowHandle();
  LONG_PTR win_parent_style = GetWindowStyle( in_hdl_win_parent );
  while( (win_parent_style & 0xf) == BS_GROUPBOX )
  {
    in_hdl_win_parent = GetParent( in_hdl_win_parent );
    win_parent_style = GetWindowStyle( in_hdl_win_parent );
  }
  return in_hdl_win_parent;
}


// _____________________________________________________________________________
/// @brief 展開設定
/// 
/// @param[in] in_flag_open
///   : 開閉状態を指定します。展開モードがOFFの場合は無視されます。\n
///   : true  - グループエリアを開きます（通常状態）。\n
///   : fales - グループエリアを閉じます。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void GroupBox::SetExpand( _in<bool> in_flag_open )
{
  m_expand = in_flag_open;
  auto win_size = GetWindowSize();
  HWND hdl_win_parent = zzf_GetParent_of_NotGroupBox();

  if( m_expand )
  {
    // リサイズ
    SetWindowSize( {win_size.x, m_save_height} );
    // 親更新
    Rect rt;
    GetWindowRect( rt, false );
    ::MapWindowPoints( ::GetDesktopWindow(), hdl_win_parent, (POINT*)&rt, 2 );
    ::InvalidateRect( hdl_win_parent, &rt, true );
  }
  else
  {
    // 親更新
    Rect rt;
    GetWindowRect( rt, false );
    ::MapWindowPoints( ::GetDesktopWindow(), hdl_win_parent, (POINT*)&rt, 2 );
    ::InvalidateRect( hdl_win_parent, &rt, true );
    // リサイズ
    HFONT hfont = GetWindowFont( m_hdl_window );
    LOGFONT lfont;
    ::GetObject( hfont, sizeof(LOGFONT), &lfont );
    SetWindowSize( {win_size.x, short(lfont.lfHeight) + 4} );
    m_save_height = win_size.y;
  }
}



} // namespace WIN
} // namespace CPL
