////////////////////////////////////////////////////////////////////////////
// CScrollMgr クラスのインプリメンテーション
//
////////////////////////////////////////////////////////////////////////////

#include "ScrollMgr.h"

////////////////////////////////////////////////////////////////////////////
// 構築/破棄
////////////////////////////////////////////////////////////////////////////

CScrollMgr::CScrollMgr() :
	m_Scr( NULL ) ,
	pEventHandler( NULL ),
	m_Min( 0 ),
	m_Max( 1 ),
	m_PageSize( 1 ),
	m_MinChickSize( 1 ),
	MinPadding( 0 ),
	MaxPadding( 0 )
{

}

CScrollMgr::~CScrollMgr()
{

}

////////////////////////////////////////////////////////////////////////////
// メソッド
////////////////////////////////////////////////////////////////////////////

// パディングを設定
void CScrollMgr::SetPadding( unsigned int argMin, unsigned int argMax )
{
	MinPadding = argMin;
	MaxPadding = argMax;
	m_Min = m_Min - MinPadding;
	m_Max = m_Max + MaxPadding;
}

// スクロールバーのイベントハンドラを設定
void CScrollMgr::SetEventHandler( CScrEventHandler *pArg )
{
	pEventHandler = pArg;
}

// 最小値を設定
void CScrollMgr::SetMin( int argMin )
{
	m_Min = argMin - MinPadding;
	SetResource();
}

// 最大値を設定
void CScrollMgr::SetMax( int argMax )
{
	m_Max = argMax + MaxPadding;
	SetResource();
}

// ページサイズを設定
// ページサイズを設定した際、現在の値+ページサイズが最大値を超える場合は、
// *pRequireValueに現在の値として設定すべき値を返す。
bool CScrollMgr::SetPageSize( int argPageSize, int *pRequireValue )
{
	assert( NULL != this );

	// 1未満の値が指定されたら、とりあえず1にする。
	if ( argPageSize < 1 ) argPageSize = 1;

	// 現在と同じ値が指定されたら、なにもすることはない
	if ( argPageSize == m_PageSize )
		return true;

	int wValue = GetValue();	// 現在の値を取得

	if ( wValue + argPageSize > m_Max ) {
		if ( pRequireValue ) {
			(*pRequireValue) = m_Max - argPageSize;
			if ( (*pRequireValue) < 0 ) (*pRequireValue) = 0;
			return false;	// やり直し
		}
	}

	m_PageSize = argPageSize;
	SetResource();
	return true;	// 成功
}

// 最小刻みを設定
void CScrollMgr::SetMinChickSize( int argMinChick )
{
	m_MinChickSize = argMinChick;
	SetResource();
}

// 値を設定
void CScrollMgr::SetValue( int argValue )
{
	int ac = 0;
	Arg al[2];

	if ( m_Max - m_PageSize < argValue ) argValue = m_Max - m_PageSize;
	if ( m_Min > argValue ) argValue = m_Min;
	XtSetArg( al[ac], XmNvalue, argValue ); ac++;
	XtSetValues( m_Scr, al, ac );
}

// 現在の値を取得
int CScrollMgr::GetValue() const
{
	int ac = 0;
	Arg al[2];
	int r = 0;

	XtSetArg( al[ac], XmNvalue, &r ); ac++;
	XtGetValues( m_Scr, al, ac );
	return r;
}

// 画面に表示されているか否か
bool CScrollMgr::IsManaged() const
{
	if ( NULL == m_Scr ) return false;
	if ( !XtIsManaged( m_Scr ) ) return false;
	if ( !XtIsRealized( m_Scr ) ) return false;
	return true;
}

// 現在の値を一番小さい値に設定
void CScrollMgr::SetToMin()
{
	SetValue( m_Min );
}

void CScrollMgr::OnCreate( Widget argWgt, XtPointer user_data )
{

}

void CScrollMgr::OnDecrement( Widget argWgt, XtPointer user_data )
{
	pEventHandler->OnScrValueChange( this, GetValue(), true );
}

void CScrollMgr::OnIncrement( Widget argWgt, XtPointer user_data )
{
	pEventHandler->OnScrValueChange( this, GetValue(), true );
}

void CScrollMgr::OnPageDown( Widget argWgt, XtPointer user_data )
{
	pEventHandler->OnScrValueChange( this, GetValue(), true );
}

void CScrollMgr::OnPageUp( Widget argWgt, XtPointer user_data )
{
	pEventHandler->OnScrValueChange( this, GetValue(), true );
}

void CScrollMgr::OnDrag( Widget argWgt, XtPointer user_data )
{
	pEventHandler->OnScrValueChange( this, GetValue(), true );
}

void CScrollMgr::ToBottom( Widget argWgt, XtPointer user_data )
{
	pEventHandler->OnScrValueChange( this, GetValue(), true );
}

void CScrollMgr::ToTop( Widget argWgt, XtPointer user_data )
{
	pEventHandler->OnScrValueChange( this, GetValue(), true );
}

void CScrollMgr::OnChangeValue( Widget argWgt, XtPointer user_data )
{
}

// ウィジットに値を設定
void CScrollMgr::SetResource() const
{
	int ac = 0;
	Arg al[6];

	if ( m_Max - m_Min <= m_PageSize ) {
		XtSetArg( al[ac], XmNsensitive, false ); ac++;
		XtSetArg( al[ac], XmNminimum, -MinPadding ); ac++;
		XtSetArg( al[ac], XmNmaximum, MaxPadding + 1 ); ac++;
		XtSetArg( al[ac], XmNsliderSize, 1 ); ac++;
		XtSetArg( al[ac], XmNincrement, 1 ); ac++;
		XtSetArg( al[ac], XmNvalue, -MinPadding ); ac++;
	}
	else {
		XtSetArg( al[ac], XmNsensitive, true ); ac++;
		XtSetArg( al[ac], XmNminimum, m_Min ); ac++;
		XtSetArg( al[ac], XmNmaximum, m_Max ); ac++;
		XtSetArg( al[ac], XmNsliderSize, m_PageSize ); ac++;
		XtSetArg( al[ac], XmNincrement, m_MinChickSize ); ac++;
	}

	XtSetValues( m_Scr, al, ac );
}

