/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2016/11/27
/// 
/// @brief  メニューを簡易的に扱う。
/// 
/// ****************************************************************************


#include "CPL_WIN_Scrollbar.h"


namespace CPL {
namespace WIN {

// _____________________________________________________________________________
/// @brief コンストラクタ スクロールバー生成
/// 
/// @copydetails doxycomment::arg_in_hdl_win_parent
/// @copydetails doxycomment::arg_in_pos
/// @copydetails doxycomment::arg_in_size
/// @param[in] in_flag_h
///   : スクロールバーの方向を指定します。\n
///   : true  - 横スクロールバー\n
///   : false - 縦スクロールバー
/// @param[in] in_ID : コンポーネントIDを指定します。
/// 
/// @return 
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ScrollBar::ScrollBar
( _in<HWND     > in_hdl_win_parent
, _in<td_Coord2> in_pos
, _in<td_Coord2> in_size
, _in<int      > in_flag_h
, _in<int      > in_ID
) : Component( 1 )
{
  LONG_PTR style = WS_CHILD;
  if( in_flag_h )
  {
    style = style | SBS_HORZ;
  }
  else
  {
    style = style | SBS_VERT;
  }
  if( !zzf_Create( in_hdl_win_parent, SwS(""), in_pos, in_size, in_ID, style, 0, this ) )
  {
    CPL_THROW( CPL_WIN_MSG_NOT_CREATE_SCROLLBAR );
  }

  // 値を初期化
  ::memset( &m_scroll_info, 0, sizeof(SCROLLINFO) );
  m_scroll_info.cbSize = sizeof(m_scroll_info);
  m_scroll_info.fMask  = SIF_PAGE | SIF_POS | SIF_RANGE;
  m_scroll_info.nMax   =  1000000000;
  m_scroll_info.nMin   = -1000000000;
  m_scroll_info.nPage  = 1;
  ::SetScrollInfo( m_hdl_window, SB_CTL, &m_scroll_info, true );

  m_flag_auto = true;
}



// _____________________________________________________________________________
/// @brief 値設定
/// 
/// @param[in] in_pos_value : スクロールバーの値を指定します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ScrollBar::SetPos( _in<int> in_pos_value )
{
  m_scroll_info.nPos = in_pos_value;
  int max = Max<int>(GetMax() - GetPage() + 1, GetMin());
//  int min = m_scroll_info.nMin;
  if( m_scroll_info.nPos > max )
  {
    m_scroll_info.nPos = max;
  }
  else
  if( GetPos() < GetMin() )
  {
    m_scroll_info.nPos = GetMin();
  }

  ::SetScrollInfo( m_hdl_window, SB_CTL, &m_scroll_info, true );
}


// _____________________________________________________________________________
/// @brief 最大値設定
/// 
/// @param[in] in_value_of_maximum : スクロールバーの最大値を指定します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ScrollBar::SetMax( _in<int> in_value_of_maximum )
{
  m_scroll_info.nMax = in_value_of_maximum;
  if( GetMax() < GetMin() )
  {
    m_scroll_info.nMax = GetMin();
  }
  // 現在位置調整
//  int max = m_scroll_info.nMax - m_scroll_info.nPage;
  if( GetPos() > GetMax() )
  {
    m_scroll_info.nPos = GetMax();
  }

  ::SetScrollInfo( m_hdl_window, SB_CTL, &m_scroll_info, true );
}


// _____________________________________________________________________________
/// @brief 最小値設定
/// 
/// @param[in] in_value_of_minimum : スクロールバーの最小値を指定します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ScrollBar::SetMin( _in<int> in_value_of_minimum )
{
  m_scroll_info.nMin = in_value_of_minimum;
  if( GetMin() > GetMax() )
  {
    m_scroll_info.nMin = GetMax();
  }
  if( GetPos() < GetMin() )
  {
    m_scroll_info.nPos = GetMin();
  }

  ::SetScrollInfo( m_hdl_window, SB_CTL, &m_scroll_info, true );
}


// _____________________________________________________________________________
/// @brief 値の増減
/// 
/// @param[in] in_add_value : 現在値に追加する値を指定します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ScrollBar::AddPos( _in<int> in_add_value )
{
  m_scroll_info.nPos += in_add_value;
  SetPos( m_scroll_info.nPos );
}


// _____________________________________________________________________________
/// @brief 複数のパラメタ設定
/// 
/// @param[in] in_pos_value : スクロールバーの値を指定します。
/// @param[in] in_value_of_minimum : 最小値を設定します。
/// @param[in] in_value_of_maximum : 最大値を設定します。
/// @param[in] in_page_size : ページ移動量を指定します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  ScrollBar::SetParameter
    ( _in<int> in_pos_value
    , _in<int> in_value_of_minimum
    , _in<int> in_value_of_maximum
    , _in<int> in_page_size
    )
{
  SetMin( in_value_of_minimum );
  SetMax( in_value_of_maximum );
  SetPos( in_pos_value );
  SetPage( in_page_size );
}


// _____________________________________________________________________________
/// @brief 複数のパラメタ設定
/// 
/// @param[in] in_page_size : ページ移動量を指定します。
/// 
/// @return なし。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ScrollBar::SetPage( _in<int> in_page_size )
{
  if( in_page_size > GetMax() )
  {
    m_scroll_info.nPage = GetMax();
  }
  else
  {
    m_scroll_info.nPage = in_page_size;
  }
  ::SetScrollInfo( m_hdl_window, SB_CTL, &m_scroll_info, true );
//  SetRange( in_page_size );
  if( GetPos() + GetPage() > GetMax() )
  {
    SetPos( GetPos() + GetPage() );
  }
}


} // namespace WIN
} // namespace CPL

