/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2014/05/17 - 2016/12/16
/// 
/// @brief  ダイアログ関連。
/// 
/// ****************************************************************************

#pragma once

#include "CPL_GUC_Window.h"

namespace CPL {
namespace GUC {


// _____________________________________________________________________________
/// @brief ダイアログクラス
///
// *****************************************************************************
class DialogWindow
  : public Window
{
  using td_base = Window;
  using td_self = DialogWindow;
  friend Factory<td_self>;
  friend CallPrivateConstructor<td_self>;
private:
  struct baseCreateInfo
  {
    sdptr<Component> in_sp_component_for_parent;
    wchar_t_cptr     in_title;

    baseCreateInfo()
      : in_title( nullptr )
    {}
    baseCreateInfo
    ( _in<sdptr<Component>> in_sp_component_for_parent_
    , pin<wchar_t         > in_title_
    ) : in_sp_component_for_parent( in_sp_component_for_parent_ )
      , in_title( in_title_ )
    {}
  };
public:
  CPL_SCOPED_ENUM
    ( eButtonType, int
    , Ok     = BIT0 // [OK]ボタンを表示。
    , Yes    = BIT2 // [YES]ボタンを表示。
    , No     = BIT3 // [NO]ボタンを表示。
    , Add    = BIT5 // [ADD]ボタンを表示。
    , Delete = BIT6 // [DELETE]ボタンを表示。
    , Retry  = BIT4 // [RETRY]ボタンを表示。
    , Cancel = BIT1 // [CANCEL]ボタンを表示。
    , OkCancel  = Ok | Cancel
    , YesNo     = Yes | No
    , AddDelete = Add | Delete

    , JpnOk     = Ok     | BIT15 // [ＯＫ]ボタンを表示。
    , JpnCancel = Cancel | BIT15 // [キャンセル]ボタンを表示。
    , JpnYes    = Yes    | BIT15 // [はい]ボタンを表示。
    , JpnNo     = No     | BIT15 // [いいえ]ボタンを表示。
    , JpnRetry  = Retry  | BIT15 // [再試行]ボタンを表示。
    , JpnAdd    = Add    | BIT15 // [追加]ボタンを表示。
    , JpnDelete = Delete | BIT15 // [削除]ボタンを表示。
    );

  struct Param {
    struct Pos     : public float2 { using float2::float2; };
    struct Size    : public float2 { using float2::float2; };
    struct Title   : public td_DefString { using td_DefString::td_DefString; };
    struct Message : public td_DefString { using td_DefString::td_DefString; };
    struct Button  : public td_DefString { using td_DefString::td_DefString; };
    struct Label   : public td_DefString { using td_DefString::td_DefString; };
  };

  //struct CreateInfo
  //{
  //  sdptr<Component> in_sp_component_for_parent;
  //  short2_cptr      in_ptr_pos  = nullptr;
  //  short2_cptr      in_ptr_size = nullptr;
  //  str_cptr         in_title    = nullptr; // タイトルを表示する場合設定する。
  //  str_cptr         in_message  = nullptr;
  //  int              in_type_num = 0;
  //  Type const*      in_type_table = nullptr;
  //};

  void AutoRepositionItems( _in<int> in_type_adjust, _in<float> in_btn_space = 5.0f );
  void AutoCenterPosition( _in<sdptr<Component>> in_sp_component_for_parent );
  void SetComponent_ItemsForm( _in<sdptr<Component>> in_sp_comp_items )
  {
    m_sp_comp_items = in_sp_comp_items;
    m_sp_comp_items->SetBelongComponent( GetComponent_RenderClient(), eParentType::All );
    m_sp_comp_items->SetPosition( float2(m_space_frame) );
  }

  auto const& GetButton_OK    ()  const { return m_sp_btn_OK    ; } // [OK]ボタンを表示。
  auto const& GetButton_CANCEL()  const { return m_sp_btn_CANCEL; } // [CANCEL]ボタンを表示。
  auto const& GetButton_YES   ()  const { return m_sp_btn_YES   ; } // [YES]ボタンを表示。
  auto const& GetButton_NO    ()  const { return m_sp_btn_NO    ; } // [NO]ボタンを表示。
  auto const& GetButton_RETRY ()  const { return m_sp_btn_RETRY ; } // [RETRY]ボタンを表示。
  auto const& GetButton_ADD   ()  const { return m_sp_btn_ADD   ; } // [ADD]ボタンを表示。
  auto const& GetButton_DELETE()  const { return m_sp_btn_DELETE; } // [DELETE]ボタンを表示。
  auto const& GetComponent_ItemsForm() const { return m_sp_comp_items; }
protected:
private:
  // ダイアログ配置用のレイヤー。
  // 他のコンポーネントを無効にするために用意。
  sdptr<Component> m_sp_backlayer;
  // 保持するアイテム
  sdptr<Component> m_sp_comp_items;
  // ボタン配置用
  sdptr<Component> m_sp_btn_form;
  // 各ボタン
  sdptr<Button> m_sp_btn_OK    ; // [OK]ボタンを表示。
  sdptr<Button> m_sp_btn_CANCEL; // [CANCEL]ボタンを表示。
  sdptr<Button> m_sp_btn_YES   ; // [YES]ボタンを表示。
  sdptr<Button> m_sp_btn_NO    ; // [NO]ボタンを表示。
  sdptr<Button> m_sp_btn_RETRY ; // [RETRY]ボタンを表示。
  sdptr<Button> m_sp_btn_ADD   ; // [ADD]ボタンを表示。
  sdptr<Button> m_sp_btn_DELETE; // [DELETE]ボタンを表示。
  // スペース
  float m_space_btn   = 3.0f;
  float m_space_frame = 3.0f;

  //
  template<class T>
  void zzz_work_( _in<T> in_paramX ){}
  // 座標
  void zzz_work_( _in<Param::Pos> in_pos )
  {
    this->SetPosition( in_pos );
  }
  // サイズ
  void zzz_work_( _in<Param::Size> in_size )
  {
    this->SetSize( in_size );
  }
  // タイトル
  void zzz_work_( _in<Param::Title> in_title )
  {
    this->SetTitle( in_title );
  }

protected:
  // 
  template<class... T_Params>
  void zzz_create_( _in<T_Params>... in_args ){}

  template<class X, class... T_Params>
  void zzz_create_( _in<X> in_param0, _in<T_Params>... in_args )
  {
    zzz_work_( in_param0 );
    zzz_create_( in_args... );
  }

  template<class X>
  void zzz_create_( _in<X> in_param0 )
  {
    zzz_work_( in_param0 );
  }

protected:
  //eEventReturnID
  //  On_Close( _in<sdptr<Component>> in_sp_component ) override;

  eEventReturnID
    On_Show
      ( _in<sdptr<Component>> in_sp_component
      , _in<BOOL            > in_show_flag
      ) override;

  GUC::eEventReturnID
    On_Size
      ( _in<sdptr<Component>> in_sp_component
      ) override;

  DialogWindow
  ( _in<sdptr<Component>> in_sp_component_for_parent
  , _in<td_DefString    > in_title
  , _in<sdptr<Component>> in_sp_comp_items
  , _in<eButtonType     > in_type_button
  );
  DialogWindow( cref<td_self> in_dialog_window );
public:
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  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 メッセージボックスダイアログ
///
// *****************************************************************************
class MessageDialog
  : public DialogWindow
{
  using td_base = DialogWindow;
  using td_self = MessageDialog;
  friend Factory<td_self>;
  friend CallPrivateConstructor<td_self>;
public:
  MessageDialog
  ( _in<sdptr<Component>> in_sp_component_for_parent
  , pin<td_DefChar      > in_title
  , pin<td_DefChar      > in_message
  , _in<eButtonType     > in_type_buttons
  );
protected:
  MessageDialog( cref<MessageDialog> in_message_dialog );
public:
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  sdptr<Component>
    CreateClone
      ( _in<sdptr<Component>> in_sp_component_for_parent       = nullptr
      , _in<float2          > in_offset_position_from_original = float2{0,0}
      ) const override
  {
    return
      zzz_CreateClone_Basic<td_self>
        ( in_sp_component_for_parent
        , in_offset_position_from_original
        );
  }
};


//// _____________________________________________________________________________
///// @brief ファイルダイアログ
/////
//// *****************************************************************************
//class FileDialog
//  : public DialogWindow
//{
//public:
//  FileDialog
//  ( _in<sdptr<Component>> in_sp_component_for_parent
//  , _in<int             > in_type
//  , pin<td_DefChar      > in_default_path = nullptr
//  );
//};


} // namespace GUC
} // namespace CPL
