/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2016/11/12
/// 
/// @brief  Win32 ウィンドウ管理。
/// 
/// ****************************************************************************

#pragma once

#include "../Container/CPL_WIN_Container.h"
#include "../../Base/CPL_WIN_Mouse.h"
#include "../../Base/CPL_WIN_Keyboard.h"


namespace CPL {
namespace WIN {


// _____________________________________________________________________________
/// @brief ウィンドウクラス
///
// *****************************************************************************
class Window
  : public Container
{
public:
  friend class Window;
  friend class DialogWindow;

protected:
  static LRESULT CALLBACK
    zzf_StaticProcMdiChild
      ( HWND   in_hdl_window
      , UINT   in_message
      , WPARAM in_wparam
      , LPARAM in_lparam
      );

  virtual SDEF
    DefaultProc_
      ( _in<UINT  > in_message
      , _in<WPARAM> in_wparam
      , _in<LPARAM> in_lparam
      ) override;

  virtual SDEF  On_Close      ()              { return false; }
  virtual SDEF  On_NcMouseDown( eMouseButton ){ return false; }
  virtual SDEF  On_NcMouseUp  ( eMouseButton ){ return false; }
  virtual SDEF  On_NcMouseMove()              { return false; }
  virtual SDEF  On_NcDblClick ( eMouseButton ){ return false; }
  virtual SDEF  On_NcPaint    ()              { return false; }
  virtual SDEF  On_NcActive   ( _in<int> in_flag_active ){ return false; }
  virtual SDEF  On_Active( _in<int > in_flag_active
                         , _in<int > in_flag_min
                         , _in<HWND> in_hdl_win_prev
                         ) override;

public:
  virtual void  ChangeResizeStyle  ( _in<bool > in_flag_resize );
  virtual void  ChangeSysMenuStyle ( _in<bool > in_flag_sysmenu );
  virtual void  ChangeMinBoxStyle  ( _in<bool > in_flag_minbox );
  virtual void  ChangeMaxBoxStyle  ( _in<bool > in_flag_maxbox );
  virtual void  ChangeCloseBoxStyle( _in<bool > in_flag_close );
  virtual void  ChangeIcon         ( _in<HICON> in_hdl_icon );
  virtual void  SetModalWindow     ( _in<bool > in_flag_modal );


  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  bool
    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 = WS_OVERLAPPEDWINDOW
      );

  // _____________________________________________________________________________
  /// @brief ウィンドウ作成
  /// 
  /// @copydoc CPL::WIN::doxycomment::arg_in_hdl_win_parent
  /// @copydoc CPL::WIN::doxycomment::arg_in_pos
  /// @copydoc CPL::WIN::doxycomment::arg_in_size
  /// 
  /// @retval true  : 作成成功。
  /// @retval false : 作成失敗。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  bool
    Create
      ( _in<HWND     > in_hdl_win_parent
      , _in<td_Coord2> in_pos  = kPOS_DEFAULT
      , _in<td_Coord2> in_size = kSIZE_DEFAULT
      ) override
  {
    return Create( in_hdl_win_parent, in_pos, in_size, false, WS_OVERLAPPEDWINDOW );
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  bool
    CreateMdiChild
      ( _in<HWND     > in_hdl_win_parent
      , _in<td_Coord2> in_pos              = kPOS_DEFAULT
      , _in<td_Coord2> in_size             = kSIZE_DEFAULT
      , _in<bool     > in_flag_client_size = false
      , _in<STYLE    > in_win_style        = WS_OVERLAPPED
      );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Window( _in<bool> in_msg_throw = false );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual ~Window(){}

    
  // _____________________________________________________________________________
  /// @brief ウィンドウクラス　Pimpl実装用
  ///
  // *****************************************************************************
  class Binder
    : public Container::Binder
  {
    Window*       getEntity()       { return dynamic_cast<Window*      >(&*impl); }
    Window const* getEntity() const { return dynamic_cast<Window const*>(&*impl); }

  public:
    void  ChangeResizeStyle  ( bool  in_resize     ){ getEntity()->ChangeResizeStyle  ( in_resize     ); }
    void  ChangeSysMenuStyle ( bool  in_sysmenu    ){ getEntity()->ChangeSysMenuStyle ( in_sysmenu    ); }
    void  ChangeMinBoxStyle  ( bool  in_minbox     ){ getEntity()->ChangeMinBoxStyle  ( in_minbox     ); }
    void  ChangeMaxBoxStyle  ( bool  in_maxbox     ){ getEntity()->ChangeMaxBoxStyle  ( in_maxbox     ); }
    void  ChangeCloseBoxStyle( bool  in_close      ){ getEntity()->ChangeCloseBoxStyle( in_close      ); }
    void  ChangeIcon         ( HICON in_hdl_icon   ){ getEntity()->ChangeIcon         ( in_hdl_icon   ); }
    void  SetModalWindow     ( bool  in_flag_modal ){ getEntity()->SetModalWindow     ( in_flag_modal ); }

    bool
      Create
        ( _in<HWND     > in_hdl_win_parent
        , _in<td_Coord2> in_pos              = kPOS_DEFAULT
        , _in<td_Coord2> in_size             = kSIZE_DEFAULT
        , _in<bool     > in_flag_client_size = false
        , _in<STYLE    > in_win_style        = WS_OVERLAPPEDWINDOW
        )
    {
      return
        getEntity()->Create
          ( in_hdl_win_parent
          , in_pos
          , in_size
          , in_flag_client_size
          , in_win_style
          );
    }
    bool  CreateMdiChild
      ( _in<HWND     > in_hdl_win_parent
      , _in<td_Coord2> in_pos              = kPOS_DEFAULT
      , _in<td_Coord2> in_size             = kSIZE_DEFAULT
      , _in<bool     > in_flag_client_size = false
      , _in<STYLE    > in_win_style        = WS_OVERLAPPED
      )
    {
      return
        getEntity()->CreateMdiChild
          ( in_hdl_win_parent
          , in_pos
          , in_size
          , in_flag_client_size
          , in_win_style
          );
    }

    Binder( bool in_msg_throw = false )
      : Container::Binder( CPL_NEW(Window)( in_msg_throw ) ){}
  protected:
    //
    Binder( pio<Window> in_ptr_win )
      : Container::Binder( in_ptr_win )
    {}
    Binder( _in<sdptr<Window>> in_sp_win )
      : Container::Binder( in_sp_win )
    {}
  };

};



} // namespace WIN
} // namespace CPL
