//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "ScrollViewUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall TScrollView::TScrollView(TComponent* Owner)
		: TPanelDB( Owner )
{
	m_ScrollBar 	= NULL;
	m_iTotalLine 	= 0;
	m_iTopLine 		= 0;
	m_iShowLine 	= 0;

	FBorder         = 0;
	FScrollBarWidth = 0;
}
//---------------------------------------------------------------------------
__fastcall TScrollView::~TScrollView()
{
	SAFE_DELETE(m_ScrollBar)
}
//---------------------------------------------------------------------------
void __fastcall TScrollView::WMEraseBkgnd(TWMEraseBkgnd &Message)
{
	Message.Result = true;
}
//---------------------------------------------------------------------------
void __fastcall TScrollView::WMSize(Winapi::Messages::TWMSize &Message)
{
	TPanelDB::WMSize(Message);

	SBSizeChange();

	if( FChangeSize )
		FChangeSize(this, m_RtContent);
}
//---------------------------------------------------------------------------
void __fastcall TScrollView::WMVScroll(Winapi::Messages::TWMScroll &Message)
{
	if( !m_ScrollBar ) return;

	int minpos, maxpos, page, curpos;
	m_ScrollBar->GetScrollRange(&minpos, &maxpos);
	page = m_ScrollBar->GetPageSize();
	// Get the current position of scroll box.
	curpos = m_ScrollBar->GetScrollPos();

	// Determine the new position of scroll box.
	switch (Message.ScrollCode)
	{
	case SB_TOP:      // Scroll to far top.
		curpos = minpos;
		break;

	case SB_BOTTOM:      // Scroll to far bottom.
		curpos = maxpos-page+1;
		break;

	case SB_ENDSCROLL:   // End scroll.
		break;

	case SB_LINEUP:      // Scroll left.
		if (curpos > minpos)
			curpos--;
		break;

	case SB_LINEDOWN:   // Scroll right.
		if (curpos < maxpos-page+1)
			curpos++;
		break;

	case SB_PAGEUP:    // Scroll one page left.
		if (curpos > minpos)
			curpos = (minpos > curpos-page) ? minpos : curpos-page;
			//max(minpos, curpos-page);
		break;

	case SB_PAGEDOWN:      // Scroll one page right.
		if( curpos<maxpos )
			curpos = (maxpos-page+1 < curpos+page) ? maxpos-page+1 : curpos+page;
			//min(maxpos-page+1, curpos+page);
		break;

	case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
		curpos = Message.Pos;      // of the scroll box at the end of the drag operation.
		break;

	case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is the
		curpos = Message.Pos;     // position that the scroll box has been dragged to.
		break;
	}

	// Set the new position of the thumb (scroll box).
	if( Message.ScrollBar!=m_ScrollBar->Handle ){
		m_ScrollBar->SetPosition(curpos);
	}
	if( m_iTopLine != curpos ){
		m_iTopLine = curpos;
	}

	Message.Result = true;

	if( OnChangeSBPos ) OnChangeSBPos( this, Message.ScrollCode, m_iTopLine );
	if( FOnMouseWheel ) FOnMouseWheel(this);
}
//---------------------------------------------------------------------------
void __fastcall TScrollView::WMMouseWheel(TWMMouseWheel &Message)
{
	if( m_ScrollBar && m_ScrollBar->Visible ){

		UINT nSBCode;

		if( Message.WheelDelta>0 ) nSBCode = SB_LINEUP;
		else nSBCode = SB_LINEDOWN;

		Perform( WM_VSCROLL, MAKELONG(nSBCode,0), NULL );
	}
}
//---------------------------------------------------------------------------
void __fastcall TScrollView::SBSizeChange()
{
	int nTitle  = 0;
	int nBottom = 0;
	if( FOnHgtTitle )  nTitle  = FOnHgtTitle(this);
	if( FOnHgtBottom ) nBottom = FOnHgtBottom(this);

	if(m_ScrollBar && m_iTotalLine>m_iShowLine && m_iTotalLine && m_iShowLine ){

		m_ScrollBar->Left     = Width - m_ScrollBar->Width - FBorder;
		if(0==nTitle) {
			m_ScrollBar->Top = FBorder;
		}
		else {
			m_ScrollBar->Top = nTitle;
		}

		if(0==nBottom)
			m_ScrollBar->Height = Height-m_ScrollBar->Top-FBorder;
		else
			m_ScrollBar->Height = Height-m_ScrollBar->Top-nBottom;

		m_RtContent = TRect(FBorder, m_ScrollBar->Top,
			FBorder+Width-2*FBorder-m_ScrollBar->Width,
			m_ScrollBar->Top+m_ScrollBar->Height);

	}else {

		int iLeft, iTop, iWidth, iHeight;

		if(0==nTitle)
			iTop = FBorder;
		else
			iTop = nTitle;

		if(0==nBottom)
			iHeight = Height-iTop-FBorder;
		else
			iHeight = Height-iTop-nBottom;

		m_RtContent = TRect(FBorder, iTop, FBorder+Width-2*FBorder, iTop+iHeight);
	}
}
//---------------------------------------------------------------------------
bool __fastcall TScrollView::SetSB(int iTotalLine, int iShowLine, int iTopLine)
{
	bool bSucess = false;

	if( !m_ScrollBar ) {
		m_ScrollBar 			= new TSkinScrollBar(this);
		m_ScrollBar->m_pWndCtrl = this;
		m_ScrollBar->Parent 	= this;
	}
	m_iTotalLine = iTotalLine;
	m_iShowLine  = iShowLine;
	m_iTopLine   = iTopLine;
	SBSizeChange();

	if( m_iTotalLine>m_iShowLine  )
	{
		m_ScrollBar->SetRange(0, iTotalLine-1);
		m_ScrollBar->SetPageSize(iShowLine);
		if(iTopLine>iTotalLine-iShowLine+1) {
         	iTopLine = iTotalLine-iShowLine+1;
		}
		m_ScrollBar->SetPosition(iTopLine);
		m_ScrollBar->Visible 	= true;
		m_ScrollBar->Invalidate();

		bSucess = true;

	}else{
		if(m_ScrollBar) m_ScrollBar->Visible = false;
	}

	FScrollBarWidth = m_ScrollBar->Width;

	return bSucess;
}
//---------------------------------------------------------------------------
