/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2016/11/16
/// 
/// @brief  Win32 ダイアログウィンドウ管理。
/// 
/// ****************************************************************************


#include "CPL_WIN_Dialog.h"


namespace CPL {
namespace WIN {


// _____________________________________________________________________________
/// @brief DialogWindow デフォルトコンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DialogWindow::DialogWindow()
  : m_hdl_win_top( nullptr ),
    m_ret_value( 0 )
{
  CPL_BLOCK_ONCE
  {
    // ウィンドウクラス登録
    WNDCLASSEX wcex;
    memset( &wcex, 0, sizeof(wcex) );
    wcex.cbSize        = sizeof(WNDCLASSEX);
    wcex.hInstance     = GetInstance_();
    wcex.style         = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc   = (WNDPROC)DefaultProcDialog;
    wcex.lpszClassName = zzf_GetClassName();
    wcex.hCursor       = nullptr;
    wcex.hbrBackground = nullptr;
    wcex.hIcon         = nullptr;

    ::RegisterClassEx( &wcex );

    // コモンコントロール用に初期化
    ::InitCommonControls();
  }
}


// _____________________________________________________________________________
/// @copydoc CPL::WIN::Window::Create
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool
  DialogWindow::Create
    ( _in<HWND     > in_hdl_win_parent
    , _in<td_Coord2> in_pos
    , _in<td_Coord2> in_size
    , _in<bool     > in_flag_client_size
    , _in<STYLE    > in_win_style
    )
{
  m_hdl_win_top = in_hdl_win_parent;

  WIN::Window::Create( nullptr, in_pos, in_size, in_flag_client_size, in_win_style );

  return m_ret_value != 0;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// プロシージャ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LRESULT
  CALLBACK DialogWindow::DefaultProcDialog
    ( HWND   in_hdl_window
    , UINT   in_message
    , WPARAM in_wparam
    , LPARAM in_lparam
    )
{
  LRESULT flag = 0;
  Component* ptr_comp = nullptr;

  if( in_message == WM_CREATE )
  {
    CREATESTRUCT* cs = (CREATESTRUCT*)in_lparam;
    ptr_comp = static_cast<Component*>(cs->lpCreateParams);
    DialogWindow* ptr_dialog_window = dynamic_cast<DialogWindow*>(ptr_comp);
    if( ptr_dialog_window )
    {
      CallStackMsg csm( ptr_dialog_window, in_message, in_wparam, in_lparam );
      ptr_dialog_window->zzf_SetHandle( in_hdl_window );
      flag = ptr_dialog_window->On_Create();

      // メッセージループ
      /* メインウインドウを無効化してモーダルに */
      EnableWindow( ptr_dialog_window->m_hdl_win_top, FALSE );
      ptr_dialog_window->SetModalWindow( true );

      // メッセージループ
      MSG message;
      while( ptr_dialog_window->m_hdl_window  &&  GetMessage( &message, nullptr, 0, 0 ) )
      {
        TranslateMessage( &message );
        DispatchMessage( &message );
      }
      /* メインウインドウを有効にしてモーダル解除 */
      EnableWindow( ptr_dialog_window->m_hdl_win_top, TRUE );
      BringWindowToTop( ptr_dialog_window->m_hdl_win_top );
      ptr_dialog_window->SetModalWindow( false );

      return ptr_dialog_window->GetReturnValue();
    }
  }
  else
  {
    ptr_comp = GetHandleToPointer( in_hdl_window );
    if( ptr_comp )
    {
      if( ptr_comp->GetEventMode() != eEventMode::AllCut )
      {
        flag = ptr_comp->DefaultProc_( in_message, in_wparam, in_lparam );
      }
      else
      {
        return 0;
      }
    }
  }

  if( !flag )
  {
    return ::DefWindowProc( in_hdl_window, in_message, in_wparam, in_lparam );
  }
  return flag;
}


} // namespace CPL
} // namespace WIN
