/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2010/X/X - 2016/12/18
/// 
/// @brief  ウィンドウコンポーネント関連。
/// 
/// ****************************************************************************

#include "CPL_GUC_Window.h"


namespace CPL {
namespace GUC {

// _____________________________________________________________________________
/// @brief クローズボタン用拡張
///
// *****************************************************************************
class CloseButton
  : public Button
{
  using td_base = Button;
  using td_self = CloseButton;
  friend Factory<td_self>;
  friend CallPrivateConstructor<td_self>;
protected:
  CloseButton( _in<sdptr<Component>> in_sp_component_for_parent, _in<float2> in_pos )
    : Button
      ( in_sp_component_for_parent
      , in_pos
      , float2(16,16)
      , CPL_GUC_DEF_STR("")
      , CPL_GUC_DEF_STR("")
      )
  {}
  CloseButton( cref<CloseButton> in_close_button )
    : td_base( in_close_button )
  {
  }
public:
  ~CloseButton(){}

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

  void On_DrawBackground( _in<float4> in_rect ) override {}
  void On_DrawFrame     ( _in<float4> in_rect ) override {}
  void On_DrawClient    ( _in<float4> in_rect ) override
  {
    DX::ColorType color = kCOLOR_RED;
    if( this->sm_sp_ac_comp() == this->GetLinkMyself() )
    {
      if( WIN::Mouse::GetDownL() )
      {
        color = kCOLOR_YELLOW;
      }
      else
      {
        color = kCOLOR_GREEN;
      }
    }

    zzf_DrawParts( float2(in_rect.x, in_rect.y), eImagePartsID::Circle, color );
    //zzf_DrawParts( float2(in_rect.x, in_rect.y), eImagePartsID::CircleShadow, COLOr_WHITE );
    zzf_DrawParts( float2(in_rect.x, in_rect.y), eImagePartsID::Cross, kCOLOR_BLACK );
  }
};

// _____________________________________________________________________________
/// @brief スタイルボタン用拡張
///
// *****************************************************************************
class StyleButton
  : public Button
{
  using td_base = Button;
  using td_self = StyleButton;
  friend Factory<StyleButton>;
  friend CallPrivateConstructor<StyleButton>;
protected:
  StyleButton( _in<sdptr<Component>> in_sp_component_for_parent, _in<float2> in_pos )
    : Button
      ( in_sp_component_for_parent
      , in_pos
      , float2(13,13)
      , CPL_GUC_DEF_STR("")
      , CPL_GUC_DEF_STR("")
      )
  {}
  StyleButton( cref<StyleButton> in_style_button )
    : td_base( in_style_button )
  {
  }
public:
  ~StyleButton()
  {}

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

  void On_DrawBackground( _in<float4> in_rect ) override {}
  void On_DrawFrame     ( _in<float4> in_rect ) override {}
  void On_DrawClient    ( _in<float4> in_rect ) override
  {
    DX::ColorType color = kCOLOR_YELLOW;
    if( this->sm_sp_ac_comp() == this->GetLinkMyself() )
    {
      color = kCOLOR_GREEN;
    }

    zzf_DrawParts( float2(in_rect.x, in_rect.y), eImagePartsID::TriangleLeft, color );
  }
};



// _____________________________________________________________________________
/// @brief コンストラクタ
/// 
/// @copydoc doxycomment::arg_in_sp_component_for_parent
/// @copydoc doxycomment::arg_in_position_for_component
/// @copydoc doxycomment::arg_in_size_for_component
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Window::Window
( _in<sdptr<Component>> in_sp_component_for_parent
, _in<float2          > in_position_for_component
, _in<float2          > in_size_for_component
) : RenderOwner
    ( in_sp_component_for_parent
    , in_position_for_component
    , in_size_for_component
    , float2( 2, 2 + GetTitleHeight() )
    , float2
      ( in_size_for_component.x > 1
          ? in_size_for_component.x - 1 /*default frame size*/
          : 10
      , in_size_for_component.y > 1
          ? in_size_for_component.y - 1 /*default frame size*/-GetTitleHeight()
          : 10
      )
    )
  , m_flag_sizing( 0 )
{
  //auto const frame_w = GetFrameSize();
  //auto const title_h = GetTitleHeight();
  //GetClient()->SetPosition( float2(frame_w, frame_w + title_h) );

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

  //
  On_Size( GetLinkMyself() );
}


// _____________________________________________________________________________
/// @brief コピーコンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Window::Window( cref<Window> in_window )
  : td_base( in_window )
  , m_title( in_window.m_title )
  , m_flag_sizing( in_window.m_flag_sizing )
  , m_flag_size_fixed( in_window.m_flag_size_fixed )
  , m_flags_title_position( in_window.m_flags_title_position )
  , m_pos_dd( in_window.m_pos_dd )
  , m_sp_btn_close
    { FindComponentT_by_UserID<Button>( in_window.m_sp_btn_close )
    }
  , m_sp_btn_style
    { FindComponentT_by_UserID<Button>( in_window.m_sp_btn_style )
    }
  , m_sp_menu_style
    { FindComponentT_by_UserID<ActiveMenu>( in_window.m_sp_menu_style )
    }
{
  CPL_SAFE_PTR(m_sp_btn_close )->SetAutoUserID();
  CPL_SAFE_PTR(m_sp_btn_style )->SetAutoUserID();
  CPL_SAFE_PTR(m_sp_menu_style)->SetAutoUserID();
}


// _____________________________________________________________________________
/// @brief デストラクタ
/// 
/// 特に何もしない。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Window::~Window()
{
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::CreateClone
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<Component>
  Window::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
      );
}




enum MENU_ID
{ IDM_TW_VIEW_TYPE
  , IDM_TW_CLOSE
  , IDM_TW_LOCATE
    , IDM_TW_LOCATE_FLOATING
    , IDM_TW_LOCATE_LEFT_FORM
    , IDM_TW_LOCATE_RIGHT_FORM
    , IDM_TW_LOCATE_BOTTOM_FORM
  , IDM_TW_MOVE
    , IDM_TW_MOVE_UP
    , IDM_TW_MOVE_DOWN
    , IDM_TW_MOVE_LEFT
    , IDM_TW_MOVE_RIGHT
  , IDM_TW_DYNAMIC_MODE
    , IDM_TW_DYNAMIC_NONE
    , IDM_TW_DYNAMIC_DOWN_LEFT
    , IDM_TW_DYNAMIC_DOWN_RIGHT
    , IDM_TW_DYNAMIC_UP_LEFT
    , IDM_TW_DYNAMIC_UP_RIGHT
};

// _____________________________________________________________________________
// ウィンドウ初期化処理。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::zzf_initializeWindow_()
{
  //
  float2     size_comp  = GetSize();
  auto const size_frame = GetFrameSize();
  m_sp_btn_close =
    Factory<CloseButton>::Create
      ( GetLinkMyself()
      , float2( size_comp.x-18, size_frame+2 )
      );

  zzf_SetInitializedLevel( zzf_GetClassLevel() );
}


// _____________________________________________________________________________
/// @brief デフォルトのウィンドウ背景カラー
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<DrawColorSet> Window::GetDefaultColor_WindowBG()
{
  static auto
    sp_color =
      CPL_MAKE_SHARED
        ( DrawColorSet
        , DX::RectColor4P(kCOLOR_LIGHTGRAY)
        , DX::RectColor4P(kCOLOR_LIGHTYELLOW) * DX::ColorType(1.0f, 1.0f, 1.0f, 0.65f)
        , DX::RectColor4P(kCOLOR_LIGHTBLUE)
        , DX::RectColor4P(kCOLOR_GRAY     )
        );
  return sp_color;
}



// _____________________________________________________________________________
/// @brief クライアントエリアの矩形座標を取得
/// 
/// @param[in] in_ptr_rect_comp
///   : クライアントコンテナが属するウィンドウの矩形座標を指定します。\n
///   : nullptrを指定すると、自身の座標が適用されます。           \n
///   : 基本的にはnullptrを指定します。                           \n
///   : 座標変更後のシミュレーション等で座標を指定します。
/// 
/// @return クライアント矩形座標をfloat4形式で返します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
float4 Window::GetClientRect( pin<float4> in_ptr_rect_comp ) const
{
  auto size_title = GetTitleHeight();
  auto size_frame = GetFrameSize();
  auto rect_comp  =
    in_ptr_rect_comp ? *in_ptr_rect_comp
                     : GetRectCoord();

  return
    float4
      ( size_frame
      , size_frame + size_title
      , rect_comp.Width() - size_frame
      , rect_comp.Height() - size_frame
      );
}


//// _____________________________________________________________________________
///// @copydoc CPL::GUC::Component::SetRectCoord
//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//bool
//  Window::SetRectCoord
//    ( _in<float4   > in_rect
//    , _in<eRectFlag> in_flag_element
//    ) noexcept
//{
//  auto const res =
//    cPL_GUC_WINDOW_BASE::SetRectCoord( in_rect, in_flag_element );
//
//  AutoRepositionItems();
//
//  return res;
//}

// _____________________________________________________________________________
/// @brief ウィンドウタイトル設定。
/// 
/// @param[in] in_title : タイトルを保持する文字列クラスへの参照。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::SetTitle( _in<td_DefString> in_title )
{
  m_title = in_title;

  Update();
}

// _____________________________________________________________________________
/// @brief ウィンドウのサイズ変更モードを設定
/// 
/// @param[in] in_flag_size_fixed
///   : ウィンドウのサイズ変更の可否の設定フラグを指定します。\n
///   : true  - ウィンドウサイズ固定\n
///   : false - ウィンドウサイズ可変
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::SetMode_SizeFixed( _in<bool> in_flag_size_fixed )
{
  m_flag_size_fixed = in_flag_size_fixed;
}

// _____________________________________________________________________________
/// @brief ウィンドウタイトル縦幅の設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::SetTitleHeight( _in<float> in_title_height )
{
  sm_title_height() = in_title_height;
}

//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//// ウィンドウのフレーム幅の設定
//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//void Window::SetFrameSize( _in<int> in_frame_size )
//{
//  sm_frame_size() = in_frame_size;
//}


// _____________________________________________________________________________
// デフォルトのクライアントサイズを計算する。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
float4 Window::zzz_calculateDefaultClientRect() const
{
  auto height_title = GetTitleHeight();
  auto size_frame   = GetFrameSize();
  auto size_win     = GetSize();

  return
    float4
      ( size_frame
      , size_frame + height_title
      , size_win.x - size_frame
      , size_win.y - size_frame
      );
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// タイトル背景の描画
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::zzf_drawTitleForm_( _in<float4> in_rect, _in<DX::ColorType> in_color )
{
  auto rect = in_rect;

  // タイトル背景
  rect.x++;
  rect.y++;
  //rect.z--;
  //rect.w--;
  //
  float a  = in_color.a;
  float r0 = in_color.r;
  float g0 = in_color.g;
  float b0 = in_color.b;
  float r1 = r0 / 4;
  float g1 = g0 / 4;
  float b1 = b0 / 2;
  DX::ColorType color[] =
  { DX::ColorType(r0,g0,b0, a)
  , DX::ColorType(r0,g0,b0, a)
  , DX::ColorType(r1,g1,b1, a)
  , DX::ColorType(r1,g1,b1, a)
  };

  zzf_DrawRectEx( rect, color );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// タイトルの描画
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  Window::zzf_drawTitle_
    ( _in<float4       > in_rect
    , _in<DX::ColorType> in_color
    , _in<U32          > in_flags_title_position 
    )
{
  if( m_title == CPL_GUC_DEF_STR("") )
  {
    return;
  }

  auto rect = in_rect;
  //int win_width = this->GetSize().x;
  auto const fw = GetFrameSize();

  rect.x += fw;
  rect.y += 2;
  rect.z -= (m_sp_btn_close->GetSize().x + fw * 2);
  zzf_DrawText
    ( rect
    , m_title
    , in_color
    , 0.0f
    , float2( 0, 0 )
    , in_flags_title_position
    );
}


// _____________________________________________________________________________
/// @brief タイトル描画イベント
/// 
/// @param[in] in_rect タイトル描画用の矩形座標が渡されます。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::On_DrawTitle( _in<float4> in_rect )
{
  CDI::ColorType title_color( 0.25f, 0.25f, 1.0f, 0.5f );
  if( GetLinkEnd() != this->GetLinkMyself() )
  {
    title_color.a *= sm_all_applied_draw_alpha();
    title_color.b *= sm_all_applied_draw_alpha();
  }
  zzf_drawTitleForm_( in_rect, title_color );
  zzf_drawTitle_( in_rect, kCOLOR_WHITE, m_flags_title_position );
}

// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::On_DrawBackground
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::On_DrawBackground( _in<float4> in_rect )
{
  auto sp_colorset_bg = GetColorParameterBG();
  auto ptr_color_bg = &sp_colorset_bg->color_default;
  if( sm_sp_capture() == this->GetLinkMyself() )
  {
    ptr_color_bg = &sp_colorset_bg->color_highlight;
  }
  else
  if( GetLinkEnd() == this->GetLinkMyself() )
  {
    ptr_color_bg = &sp_colorset_bg->color_active;
  }

  //zzf_DrawRect_DefaultComponentBG( in_rect, color );
  zzf_DrawRectEx( in_rect, ptr_color_bg->color );
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::On_DrawFrame
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::On_DrawFrame( _in<float4> in_rect )
{
  auto rect = in_rect;
  auto const frame_w = GetFrameSize();
  CDI::ColorType frame_color = kCOLOR_GRAY;

  if( sm_sp_capture() == this->GetLinkMyself() )
  {
    frame_color = kCOLOR_ORANGE;
  }
  else
  if( GetLinkEnd() == this->GetLinkMyself() )
  {
    frame_color = kCOLOR_BLUE;
  }

  if( m_flag_sizing )
  {
    DX::ColorType color[] =
    { (m_flag_sizing & BIT0) ? kCOLOR_RED : kCOLOR_BLACK // 上辺
    , (m_flag_sizing & BIT3) ? kCOLOR_RED : kCOLOR_BLACK // 右辺
    , (m_flag_sizing & BIT1) ? kCOLOR_RED : kCOLOR_BLACK // 下辺
    , (m_flag_sizing & BIT2) ? kCOLOR_RED : kCOLOR_BLACK // 左辺
    };
    zzf_DrawFrameEx( rect, color );
  }
  else
  {
    zzf_DrawFrame( rect, frame_color );
  }
  
  // title
  rect.x += frame_w;
  rect.z -= frame_w;
  rect.y += frame_w;
  rect.w = rect.y + GetTitleHeight();
  On_DrawTitle( rect );
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::On_DrawClient
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Window::On_DrawClient( _in<float4> in_rect )
{
//  Component::On_DrawBackground( in_rect );
  zzf_DrawRect( in_rect, kCOLOR_LIGHTGRAY );
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::Component::On_Size
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  Window::On_Size( _in<sdptr<Component>> in_sp_component )
{
  if( in_sp_component == this->GetLinkMyself()  &&
      GetInitialized() >= zzf_GetClassLevel() )
  {
    auto rect_client = zzz_calculateDefaultClientRect();
    AutoRepositionItems( &rect_client );
  }

  return eEventReturnID::SendParent_Position;
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::MouseEventInterface::On_MouseDown
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  Window::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 == this->GetLinkMyself() )
  {
    sm_sp_capture( this->GetLinkMyself() );
    sm_sp_focus  ( this->GetLinkMyself() );
    ActivateTopOrder(); // 最前面へ。

    m_pos_dd.x = in_mouse_x;
    m_pos_dd.y = in_mouse_y;

    sm_all_applied_draw_alpha() = 0.6f;
  }

  // 更新
  if( in_sp_component == this->GetLinkMyself() )
  {
    this->UpdateAllWindow();
  }
  else
  {
    //
    GetLinkEnd()->Update();
    Update();
  }

  return eEventReturnID::SendParent_Position;
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::MouseEventInterface::On_MouseUp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  Window::On_MouseUp
  ( _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 == this->GetLinkMyself() )
  {
    sm_sp_capture( nullptr );
    m_flag_sizing = false;
    sm_all_applied_draw_alpha() = 1.0f;

    // 
    this->UpdateAllWindow();
  }
  else
  if( in_sp_component == m_sp_btn_close )
  {
    On_Close( GetLinkMyself() );
    Update();
  }

  return eEventReturnID::SendParent_Position;
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::MouseEventInterface::On_MouseMove
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  Window::On_MouseMove
    ( _in<sdptr<Component>> in_sp_component
    , _in<float           > in_mouse_x
    , _in<float           > in_mouse_y
    )
{
  if( in_sp_component == this->GetLinkMyself() )
  {
    bool is_capture = (sm_sp_capture() == this->GetLinkMyself());
    // 移動またはサイズ変更中
    if( WIN::Mouse::GetDownL()  &&  is_capture )
    {

      //// x
      //if( new_pos.x < 0 )
      //{
      //  new_pos.x = 0;
      //}
      //else
      //if( new_pos.x + win_size.x > subject_win_size.x )
      //{
      //  new_pos.x = subject_win_size.x - win_size.x;
      //}

      //// y
      //if( new_pos.y < 0 )
      //{
      //  new_pos.y = 0;
      //}
      //else
      //if( new_pos.y + win_size.y > subject_win_size.y )
      //{
      //  new_pos.y = subject_win_size.y - win_size.y;
      //}

      if( this->m_flag_sizing == 0 ) // 移動
      {
        float2 mvpos( in_mouse_x - m_pos_dd.x, in_mouse_y - m_pos_dd.y );
        float2 subject_win_size =
          GetBelongComponent(eParentType::Position)->GetSize();
        auto rt = GetRectCoord() + float4{ mvpos, mvpos };
        rt.Revise( float4{0,0, subject_win_size.x, subject_win_size.y}, 0 );
        this->SetPosition( float2{rt.x, rt.y} );
      }
      else
      if( m_flag_size_fixed == false )
      {
        auto move_x = static_cast<short>(WIN::Mouse::GetMoveX());
        auto move_y = static_cast<short>(WIN::Mouse::GetMoveY());
        short4 rt = this->GetRectCoord();

        // 上辺
        if( this->m_flag_sizing & BIT0 )
        {
          rt.y += move_y;
          rt.y = Min<int>( rt.y, rt.w-20 );
        }
        // 下辺
        else
        if( this->m_flag_sizing & BIT1 )
        {
          rt.w += move_y;
          rt.w = Max<int>( rt.y+20, rt.w );
        }

        // 左辺
        if( this->m_flag_sizing & BIT2 )
        {
          rt.x += move_x;
          rt.x = Min<int>( rt.x, rt.z-20 );
        }
        // 右辺
        else
        if( this->m_flag_sizing & BIT3 )
        {
          rt.z += move_x;
          rt.z = Max<int>( rt.x+20, rt.z );
        }
        this->SetRectCoord( rt );
      }

      UpdateSubjectWindow();
    }
    else if( m_flag_size_fixed == false )
    {
      auto this_size  = GetSize();
      auto frame_size = GetFrameSize() + 1;
      auto old_flag   = m_flag_sizing;

      m_flag_sizing = 0;
      // 左辺
      if( in_mouse_x <= frame_size )
      {
        m_flag_sizing |= BIT2;
      }
      // 右辺
      if( in_mouse_x >= this_size.x - frame_size )
      {
        m_flag_sizing |= BIT3;
      }
      // 上辺
      if( in_mouse_y <= frame_size )
      {
        m_flag_sizing |= BIT0;
      }
      // 下辺
      if( in_mouse_y >= this_size.y - frame_size )
      {
        m_flag_sizing |= BIT1;
      }

      if( m_flag_sizing != old_flag )
      {
        Update();
      }
    }
  }

  return eEventReturnID::SendParent_Position;
}


// _____________________________________________________________________________
/// @copydoc CPL::GUC::MouseEventInterface::On_MouseLeave
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eEventReturnID
  Window::On_MouseLeave
    ( _in<sdptr<Component>> in_sp_comp_leave
    , _in<sdptr<Component>> in_sp_comp_enter
    )
{
  if( in_sp_comp_leave == this->GetLinkMyself() )
  {
    m_flag_sizing = 0;
    Update();
  }

  return eEventReturnID::SendParent_Position;
}


//// _____________________________________________________________________________
///// @copydoc CPL::GUC::Component::GetAdjustSize
//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//float2 Window::GetAdjustSize( _in<BOOL> in_flag_show ) const noexcept
//{
//  float2 adj_size0 = GetComponent_ClientLayer()->GetAdjustSize( in_flag_show );
//  //float2 adj_size1 = GetComponent_ArrangeLayer()->GetAdjustSize( in_flag_show );
//  //float2 adj_size( Max(adj_size0.x, adj_size1.x), Max(adj_size0.y, adj_size1.y) );
//  float2 adj_size = adj_size0;
//
//  adj_size += GetComponent_ClientLayer()->GetPosition();
//  adj_size += GetFrameSize() * IsDrawFrame();
//
//  return adj_size;
//}


// _____________________________________________________________________________
/// @brief アイテムコンポーネントの再配置
/// 
/// サイズ変更時等に再配置の必要のあるコンポーネントを自動位置調整します。
/// 基本的には内部的に呼び出される関数です。
/// 
/// @param[in] in_ptr_rect_client
///   : クライアント領域を表す４点座標（float4型）のアドレスを指定します。\n
///   : クライアント領域も設定する場合に指定します。
///   : nullptrを指定すると、現在のクライアント矩形全体が使用されます。
/// @param[in] in_ptr_rect_work
///   : ワークエリア領域を表す４点座標（float4型）のアドレスを指定します。\n
///   : nullptrを指定すると、現在のワークエリア矩形が使用されます。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  Window::AutoRepositionItems
    ( pin<float4> in_ptr_rect_client
    , pin<float4> in_ptr_rect_work
    )
{
  float2 size_comp = GetSize();
  auto const size_frame = GetFrameSize() * IsDrawFrame();
  float const title_h   = GetTitleHeight();
  float4 rect_client;

  if( in_ptr_rect_client )
  {
    rect_client = *in_ptr_rect_client;
    // クライアント矩形エリアが指定されている場合、レンダリング領域も変更。
    GetComponent_RenderBox()->SetRectCoord( rect_client );
  }
  else
  {
    rect_client = GetClientRect();
  }

  // ボタン位置変更
  m_sp_btn_close->SetPosition
    ( float2
        ( size_comp.x - m_sp_btn_close->GetSize().x - size_frame
        , 2 + size_frame
        )
    );

  // スクロールバー調整のため呼び出し。
  if( in_ptr_rect_work )
  {
    SetupWorkingArea( rect_client, *in_ptr_rect_work );
  }
  else
  {
    SetupWorkingArea( rect_client, GetSize_WorkingArea() );
  }

  Update();
}


} // namespace GUC
} // namespace CPL
