// GptScroll.cpp
// copyright 1992 Pittsburgh Supercomputing Center
#include "gpt.h"

 // Scroller Constructor
Scroller::Scroller(WindowPt win, short xMax, short yMax)
	{
	RECT rect;
	FullSize = FALSE;
	nVscrollPos  = nHscrollPos = 0;
	MaxX = xMax;
	MaxY = yMax;
	XRatio = 1.0;
   YRatio = 1.0;
	this->win = win;
	this->hWnd  = win->GetHandle();
	GetClientRect( hWnd, (LPRECT) &rect );
	ixMax        = MaxX - rect.right;
	iyMax        = MaxY - rect.bottom;
	ixMin = 0;
	iyMin = 0;
	//GetClipBox(hDC, lpRect)
	SetScrollRange(hWnd,SB_HORZ,ixMin,ixMax,FALSE);    // triggers size message
	SetScrollPos(hWnd,SB_HORZ,nHscrollPos, FALSE);
	SetScrollRange(hWnd,SB_VERT,iyMin,iyMax,FALSE);
	SetScrollPos(hWnd,SB_VERT,nVscrollPos, FALSE);


	}
/* *****************
void Scroller::NewSize(short x, short y)
	{
	//MaxX=1024; MaxY = 714;
	ixMax        = MaxX - x;
	iyMax        = MaxY - y;

	BOOL repaint;
	repaint = FALSE;
	if (iyMax  < GetSystemMetrics(SM_CYHSCROLL)*XRatio && iyMax > 0)
		{repaint = TRUE; iyMax = 0; }
	nVscrollPos = max(0, min(nVscrollPos, iyMax));
	SetScrollRange(hWnd,SB_VERT,0,iyMax,repaint);
	SetScrollPos(hWnd,SB_HORZ,nHscrollPos, repaint);

	repaint = FALSE;
	if (ixMax  < GetSystemMetrics(SM_CXVSCROLL)*YRatio && ixMax > 0)
		{ repaint = TRUE; ixMax = 0; }

	nHscrollPos = max(0, min(nHscrollPos, ixMax));
	SetScrollRange(hWnd,SB_HORZ,0,ixMax, repaint);
	SetScrollPos(hWnd,SB_HORZ,nHscrollPos, repaint);
	if (ixMax== 0 && iyMax == 0) FullSize = TRUE;
	else FullSize = FALSE;
	}
*********************************** */
 void Scroller::NewSize(short x, short y)
	{
	float XPRat = 1.0;
	float YPRat = 1.0;
	if ( ixMax)
		XPRat = (float)(ixMax - nHscrollPos ) /(ixMax -ixMin);
		// P = max - (max - min)*R
		// R = (max - P) / (max - min)
	if (iyMax)
		YPRat = (float)(iyMax - nVscrollPos ) /(iyMax - iyMin);
	int SizeX = MaxX - x;     // Scroll Range in X ( == 0 at full size )
	int SizeY = MaxY - y;     // Scroll Range in Y ( == 0 at full size )

	// Siz = Max - Min
	// Rat = (Pos - Min) / Siz
	// Min = Pos - Rat*Siz
	if (ixMax == ixMin) nHscrollPos = 0;
	else  nHscrollPos = (float)nHscrollPos/(ixMax - ixMin) * SizeX;
	if (iyMax == iyMin) nVscrollPos = 0;
	else  nVscrollPos = (float)nVscrollPos/(iyMax - iyMin) * SizeY;

	ixMax = nHscrollPos  + (XPRat*SizeX);
	iyMax = nVscrollPos  + (YPRat*SizeY);
	if (ixMax > SizeX)  ixMax = SizeX;
	if (iyMax > SizeY) iyMax = SizeY;
	ixMin = ixMax - SizeX;
	iyMin = iyMax - SizeY;
	if (ixMin < 0) ixMin = 0;
	if (iyMin < 0) iyMin = 0;
	BOOL repaint;
	repaint = FALSE;
	if (iyMax  < GetSystemMetrics(SM_CYHSCROLL)*XRatio )
		{repaint = TRUE; iyMax = 0; }
	// Determine where position currently is relative to size
	nVscrollPos = max(0, min(nVscrollPos, iyMax));
	nVscrollPos = min( max(nVscrollPos, iyMin), iyMax);
	SetScrollRange(hWnd,SB_VERT,iyMin,iyMax,repaint);
	SetScrollPos(hWnd,SB_VERT,nVscrollPos, repaint);

	repaint = FALSE;
	if (ixMax  < GetSystemMetrics(SM_CXVSCROLL)*YRatio )
		{ repaint = TRUE; ixMax = 0; }

	nHscrollPos = max(0, min(nHscrollPos, ixMax));
	nHscrollPos = min( max(nHscrollPos, ixMin), ixMax);
	SetScrollRange(hWnd,SB_HORZ,ixMin,ixMax, repaint);
	SetScrollPos(hWnd,SB_HORZ,nHscrollPos, repaint);
	if (!SizeX && !SizeY) FullSize = TRUE;
	else FullSize = FALSE;
	}


 void Scroller::SetPos(short horz, short vert)
	{
	if (horz > ixMax) horz = ixMax;
	if (horz < ixMin) horz = ixMin;
	if (vert > iyMax) vert = iyMax;
	if (vert < iyMin) vert = iyMin;

	//nHscrollPos = max(0, min(horz, ixMax));
	//nVscrollPos = max(0, min(vert, ixMax));
	nHscrollPos = horz;
	nVscrollPos = vert;
	SetScrollPos(hWnd,SB_VERT, nVscrollPos,TRUE);
	SetScrollPos(hWnd,SB_HORZ, nHscrollPos,TRUE);
	}
 void Scroller::Scroll()
	{
	WORD wScrollType      = ((FrameWindowPt)win)->GetwParam();
	WORD wScrollDirection = ((FrameWindowPt)win)->GetiMessage();
	WORD wThumbPosition   = LOWORD(((FrameWindowPt)win)->GetlParam() );
	short iPos;
	short inc;
	RECT rect;
	GetClientRect( hWnd, (LPRECT) &rect );

	if (wScrollDirection == WM_VSCROLL)
		{
		iPos = nVscrollPos;
		inc  = (iyMax - iyMin)/10+1;
		}
	else
		{
		iPos = nHscrollPos;
		inc  = (ixMax - ixMin)/10+1;
		}
	switch ( wScrollType)
		{
		case SB_LINEUP:
		iPos -=inc;
		break;

		case SB_LINEDOWN:
		iPos +=inc;
		break;

		case SB_PAGEUP:
		iPos -= inc*3;
		break;

		case SB_PAGEDOWN:
		iPos += inc*3;
		break;

		case SB_THUMBPOSITION:
		iPos = wThumbPosition;
		break;

		default:
		break;
		}
	if (wScrollDirection == WM_VSCROLL)
		{
		if (iPos > iyMax) iPos = iyMax;
		if (iPos < iyMin) iPos = iyMin;
		nVscrollPos = iPos;
		if (nVscrollPos != GetScrollPos(hWnd, SB_VERT))
			{
			SetScrollPos(hWnd,SB_VERT, nVscrollPos,TRUE);
			InvalidateRect(hWnd, NULL, TRUE);
			//ScrollWindow(hWnd,0,nVscrollPos, NULL,NULL);
			//UpdateWindow(hWnd);
			}
		}
	else
		{
		if (iPos > ixMax) iPos = ixMax;
		if (iPos < ixMin) iPos = ixMin;
		nHscrollPos = iPos;
		if (nHscrollPos != GetScrollPos(hWnd, SB_HORZ))
			{
			SetScrollPos(hWnd,SB_HORZ, nHscrollPos, TRUE);
			InvalidateRect(hWnd, NULL, TRUE);
			//ScrollWindow(hWnd,nHscrollPos,0, NULL,NULL);
		  //	UpdateWindow(hWnd);
			}
		}
	}
