/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2010/X/X - 2015/11/19
/// 
/// @brief  タブウィンドウコンポーネント。
/// 
/// ****************************************************************************


#include "CPL_GUC_TabWindow.h"
#include "CPL_GUC_Button.h"
#include "CPL_GUC_Window.h"


namespace CPL {
namespace GUC {

static DX::RectColor4P
  cpl_guc_tab_gradient(
    kCOLOR_WHITE, kCOLOR_WHITE,
    kCOLOR_GRAY,  kCOLOR_GRAY );

// _____________________________________________________________________________
/// @brief タブウィンドウのデフォルト背景カラー
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<DrawColorSet> TabWindow::GetDefaultColor_TabBG()
{
  static auto
    sp_color =
      CPL_MAKE_SHARED
        ( DrawColorSet
        , DX::RectColor4P(kCOLOR_LIGHTGRAY) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_LIGHTBLUE) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_ORANGE   ) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_GRAY     ) * cpl_guc_tab_gradient
        );
  return sp_color;
}

// _____________________________________________________________________________
/// @brief タブウィンドウのデフォルトフレームカラー
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<DrawColorSet> TabWindow::GetDefaultColor_TabFrame()
{
  static auto
    sp_color =
      CPL_MAKE_SHARED
        ( DrawColorSet
        , DX::RectColor4P(CDI::ColorType( kCOLOR_GRAY.rgb,      0.8f  )) * cpl_guc_tab_gradient
        , DX::RectColor4P(CDI::ColorType( kCOLOR_LIGHTBLUE.rgb, 0.75f )) * cpl_guc_tab_gradient
        , DX::RectColor4P(CDI::ColorType( kCOLOR_GRAY.rgb,      0.6f  )) * cpl_guc_tab_gradient
        , DX::RectColor4P(CDI::ColorType( kCOLOR_LIGHTGRAY.rgb, 0.75f )) * cpl_guc_tab_gradient
        );
  return sp_color;
}

// _____________________________________________________________________________
/// @brief タブウィンドウの選択フォーム用フレームカラー
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<DrawColorSet> TabWindow::GetDefaultColor_TabText()
{
  static auto
    sp_color =
      CPL_MAKE_SHARED
        ( DrawColorSet
        , DX::RectColor4P(kCOLOR_BLACK) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_BLACK) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_BLACK) * cpl_guc_tab_gradient
        , DX::RectColor4P(CDI::ColorType( kCOLOR_LIGHTGRAY.rgb, 0.75f )) * cpl_guc_tab_gradient
        );
  return sp_color;
}

// _____________________________________________________________________________
/// @brief タブウィンドウの選択フォーム用背景カラー
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<DrawColorSet> TabWindow::GetDefaultColor_TabSelectBG()
{
  static auto
    sp_color =
      CPL_MAKE_SHARED
        ( DrawColorSet
        , DX::RectColor4P(kCOLOR_DARKBLUE) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_BLUE    ) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_ORANGE  ) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_GRAY    ) * cpl_guc_tab_gradient
        );
  return sp_color;
}

// _____________________________________________________________________________
/// @brief タブウィンドウのデフォルトテキストカラー
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<DrawColorSet> TabWindow::GetDefaultColor_TabSelectFrame()
{
  static auto
    sp_color =
      CPL_MAKE_SHARED
        ( DrawColorSet
        , DX::RectColor4P(kCOLOR_BLACK) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_BLACK) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_BLACK) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_GRAY ) * cpl_guc_tab_gradient
        );
  return sp_color;
}

// _____________________________________________________________________________
/// @brief タブウィンドウの選択フォーム用テキストカラー
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<DrawColorSet> TabWindow::GetDefaultColor_TabSelectText()
{
  static auto
    sp_color =
      CPL_MAKE_SHARED
        ( DrawColorSet
        , DX::RectColor4P(kCOLOR_WHITE    ) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_WHITE    ) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_WHITE    ) * cpl_guc_tab_gradient
        , DX::RectColor4P(kCOLOR_LIGHTGRAY) * cpl_guc_tab_gradient
        );
  return sp_color;
}




// _____________________________________________________________________________
/// @brief コンストラクタ
/// 
/// @copydoc doxycomment::arg_in_sp_component_for_parent
/// @copydoc doxycomment::arg_in_position_for_component
/// @copydoc doxycomment::arg_in_size_for_component
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TabWindow::TabWindow
( _in<sdptr<Component>> in_sp_component_for_parent
, _in<float2          > in_position_for_component
, _in<float2          > in_size_for_component
) : Owner
    ( in_sp_component_for_parent
    , in_position_for_component
    , in_size_for_component
    )
  , m_active_index( 0 )
{

  //SetColorParameterBG( sp_color_bg_default );
  //SetColorParameterFrame( sp_color_frame_default );

  zzf_setupDrawState( false, true, true ); // 描画ステートのデフォルト設定。
  zzf_SetInitializedLevel( zzf_GetClassLevel() );
}


// _____________________________________________________________________________
/// @brief コピーコンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TabWindow::TabWindow( cref<TabWindow> in_tab_window )
  : td_base( in_tab_window )
{
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::CreateClone
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<Component>
  TabWindow::CreateClone
    ( _in<sdptr<Component>> in_sp_component_for_parent
    , _in<float2          > in_offset_position_from_original
    ) const
{
  return
    zzz_CreateClone_Basic<td_self>
      ( in_sp_component_for_parent
      , in_offset_position_from_original
      );
}


// _____________________________________________________________________________
/// @brief タブの追加
/// 
/// 文字列タブと空のフォームが追加されます。
/// 
/// @param[in] in_form_title : タブの名前を指定します。
/// @param[in] in_sp_item    : 追加するフォームがあれば１つだけ指定できます。
/// 
/// @return 追加されたタブフォームのレイヤーコンポーネントを返します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<Layer>
  TabWindow::AddTab
    ( pin<td_DefChar      > in_form_title
    , _in<sdptr<Component>> in_sp_item
    )
{
  // タイトル設定
  td_DefString title( CPL_GUC_DEF_STR("  ") );
  if( in_form_title  &&  *in_form_title )
  {
    title = in_form_title;
  }

  // タブ用ボタン作成
  auto sp_btn =
    Factory<GUC::Button>::Create
      ( GetLinkMyself()
      , kPOS_DEFAULT // 座標はあとで補正される。
      , kSIZE_DEFAULT
      , title
      , nullptr
      );

  return AddTab( sp_btn, in_sp_item );
}


// _____________________________________________________________________________
/// @brief タブの追加
/// 
/// 文字列タブと空のフォームを追加する。
/// 
/// @param[in] in_sp_button_for_tab
///   : タブ用のボタンコンポーネントのスマートポインタを指定します。
/// @param[in] in_sp_item
///   : 追加するフォームがあれば１つ指定できます。
/// 
/// @return 追加されたタブフォームのレイヤーコンポーネントを返します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<Layer>
  TabWindow::AddTab
    ( _in<sdptr<Button>   > in_sp_button_for_tab
    , _in<sdptr<Component>> in_sp_item
    )
{
  //
  float offs_x = 0;
  // ｘ位置設定
  if( !m_btn_list.empty() )
  {
    sdptr<Component> sp_comp = m_btn_list.back();
    offs_x = sp_comp->GetRectCoord().right;
  }

  // フォームとなるレイヤーを作成
  auto sp_layer = Factory<Layer>::Create( GetLinkMyself() );
  // 配置するアイテムコンポーネントが指定されていたら追加。
  if( in_sp_item )
  {
    in_sp_item->SetBelongComponent( sp_layer, eParentType::All );
  }
  // フォーム登録
  m_comp_tbl.push_back( sp_layer );

  // ボタン調整
  in_sp_button_for_tab->SetBelongComponent( GetLinkMyself(), eParentType::All );
  in_sp_button_for_tab->SetPosition( float2{offs_x,0} );
  in_sp_button_for_tab->SetStateDrawFrame( false );
  m_btn_list.push_back( in_sp_button_for_tab );
  m_is_changed_tab = true;

  // フォーム位置補正
  auto height_btn_area = GetAllTabHeight();
  for( auto sp_form : m_comp_tbl )
  {
    sp_form->SetPosition( float2{ 0, height_btn_area } );
  }

  // 
  TabChange( static_cast<int>(m_comp_tbl.size()) - 1 );

  return sp_layer;
}


// _____________________________________________________________________________
/// @brief タブチェンジ
/// 
/// @param[in] in_tab_index : 選択するタブのインデックスを指定します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void TabWindow::TabChange( _in<int> in_tab_index )
{
  if( in_tab_index == m_active_index )
  {
    return;
  }

  CPL_LOOP2( m_comp_tbl.size(), idx )
  {
    auto sp_btn = m_btn_list[ idx ];

    if( idx == in_tab_index )
    {
      m_comp_tbl[ idx ]->SetStateVisible( true );
      m_active_index = in_tab_index;

      sp_btn->SetColorParameterBG   ( GetDefaultColor_TabSelectBG()    );
      sp_btn->SetColorParameterFrame( GetDefaultColor_TabSelectFrame() );
      sp_btn->SetColorParameterText ( GetDefaultColor_TabSelectText()  );
      sp_btn->SetBtnStateView( GUC::Button::eBtnViewState::HighLight );
    }
    else
    {
      m_comp_tbl[ idx ]->SetStateVisible( false );
      sp_btn->SetColorParameterBG   ( GetDefaultColor_TabBG()    );
      sp_btn->SetColorParameterFrame( GetDefaultColor_TabFrame() );
      sp_btn->SetColorParameterText ( GetDefaultColor_TabText()  );
      sp_btn->SetBtnStateView( GUC::Button::eBtnViewState::Auto );
    }
  }
}


// _____________________________________________________________________________
/// @brief タブボタンの必要サイズを取得
/// 
/// @return タブボタンのサイズを返します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
float2 TabWindow::GetAllTabSize() const
{
  if( m_is_changed_tab )
  {
    for( auto& sp_comp : m_btn_list )
    {
      auto rt = sp_comp->GetRectCoord();
      m_size_tab.x = Max( m_size_tab.x, rt.right );
      m_size_tab.y = Max( m_size_tab.y, rt.bottom );
    }
    m_is_changed_tab = false;
  }
  return m_size_tab;
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::On_DrawFrame
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void TabWindow::On_DrawFrame( _in<float4> in_rect )
{
  //int offs_h = in_str_size.y / 2;
  //short4 rt( in_rect.x+1, in_rect.y+offs_h, in_rect.z-1, in_rect.w-1 );
  //
  //// 頂点準備
  //DrawVtxInfo vtx_table[] = {
  //  DrawVtxInfo( rt.x + in_str_size.x + 10.0f, float(rt.y)+0.5f, 0.0f, in_color ),
  //  DrawVtxInfo( rt.z + 0.5f, rt.y + 0.5f, 0.0f, in_color ),
  //  DrawVtxInfo( rt.z + 0.5f, rt.w + 0.5f, 0.0f, in_color ),
  //  DrawVtxInfo( rt.x + 0.5f, rt.w + 0.5f, 0.0f, in_color ),
  //  DrawVtxInfo( rt.x + 0.5f, rt.y + 0.5f, 0.0f, in_color ),
  //  DrawVtxInfo( static_cast<float>(rt.x + 2) + 0.5f, rt.y + 0.5f, 0.0f, in_color )
  //};
  //
  //zzf_DrawPolygon(
  //  vtx_table,
  //  CPL_ARRAY_NUM(vtx_table),
  //  D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP );

  // color_frame
  auto sp_colorset_frame = GetColorParameterFrame();
  auto ptr_color_frame = &sp_colorset_frame->color_default;
  if( !IsEnable() )
  {
    ptr_color_frame = &sp_colorset_frame->color_invalid;
  }
  else
  if( sm_sp_ac_comp() == this->GetLinkMyself() )
  {
    if( WIN::Mouse::GetDownL() )
    {
      ptr_color_frame = &sp_colorset_frame->color_active;
    }
    else
    {
      ptr_color_frame = &sp_colorset_frame->color_highlight;
    }
  }

  auto rt_frame = in_rect;
  rt_frame.top += this->GetAllTabHeight();
  zzf_DrawFrameEx( rt_frame, ptr_color_frame->color );
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::On_DrawClient
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void TabWindow::On_DrawClient( _in<float4> in_rect )
{
  td_base::On_DrawClient( in_rect );
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::MouseEventInterface::On_MouseDown
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  TabWindow::On_MouseDown
    ( _in<sdptr<Component>> in_sp_component
    , _in<float           > in_mouse_x
    , _in<float           > in_mouse_y
    , _in<eMouseButton    > in_type_mouse_btn
    )
{
  if( in_sp_component == GetLinkMyself() )
  {
    ActivateTopOrder();
  }

  CPL_LOOP2( static_cast<int>(m_btn_list.size()), btn_idx )
  {
    if( in_sp_component == m_btn_list[ btn_idx ] )
    {
      // 
      TabChange( btn_idx );
    }
  }
  return eEventReturnID::SendParent_Position;
}


} // namespace GUC
} // namespace CPL

