/*	XStatusBar.cpp
 *
 *		This is the code which actually displays my status bar.
 */

/*  YAAF - Yet another application framework
 *  Copyright (C) 1997, 1998 William Edward Woody
 *  
 *  This library is free software; you can redistribute it
 *  and/or modify it under the terms of the GNU Library
 *  General Public License as published by the Free Software
 *  Foundation; either version 2 of the License, or any
 *  later version.
 *  
 *  This library is distributed in the hope that it will be
 *  useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABIILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE. See the GNU Library General Public License for
 *  more details.
 *  
 *  You should have received a copy of the GNU Library General
 *  Public License along with this library; if not, write to the
 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *  Boston, MA 02111-1307, USA.
 *  
 *  To contact the author, either e-mail me at woody@pandawave.com, 
 *	or write to
 *  
 *          William Edward Woody
 *          In Phase Consulting
 *          1545 Ard Eevin Avenue
 *          Glendale, CA 91202
 *
 *	Or visit us on the web at http://www.pandawave.com
 */

#include <XStatusBar.h>
#include <XDraw.h>

/************************************************************************/
/*																		*/
/*	Construction/Destruction											*/
/*																		*/
/************************************************************************/

/*	@F"XGStatusBar::XGStatusBar" @I
 *
 *		Construct me
 */

XGStatusBar::XGStatusBar(XGOwner *parent, XGArgStream &s) : XGSlider(parent,s)
{
	fCurValue = s.ReadInteger();
	fMinValue = s.ReadInteger();
	fMaxValue = s.ReadInteger();
	fUpdate = false;
}

/*	@F"XGStatusBar::~XGStatusBar" @I
 *
 *		Go the way of the dodo
 */

XGStatusBar::~XGStatusBar()
{
}

/************************************************************************/
/*																		*/
/*	Events																*/
/*																		*/
/************************************************************************/

/*	@F"XGStatusBar::DoDrawView" @I
 *
 *		Draw the view immediately
 */

void XGStatusBar::DoDrawView(Rect)
{
	DrawStatusBar();
}

/************************************************************************/
/*																		*/
/*	Bar drawing															*/
/*																		*/
/************************************************************************/

/*	@F"XGStatusBar::DrawStatusBar" @I
 *
 *		Draw the status bar immediately
 */

void XGStatusBar::DrawStatusBar(void)
{
	long min,max,val;
	long offset;
	Rect r;
	Rect s;
	
	XGDraw draw(this);
	r = GetContentRect();
	fUpdate = false;

	/* Reduce the min,max values to prevent overflow */
	min = fMinValue;
	max = fMaxValue;
	val = fCurValue;
	if (min >= max) {
		/* Huh? Don't display a thing */
		
//		draw.Draw3DRect(r,KXGEInset);
//		::InsetRect(&r,1,1);
		draw.Draw3DRect(r,KXGEBackground);
		return;
	}
	
	/* Frame the slider */	
	draw.Draw3DRect(r,KXGEFrame);
	::InsetRect(&r,1,1);
	
	while ((max - min) > 65536L) {
		max >>= 1;
		min >>= 1;
		val >>= 1;
	}
	
	/* Figure out if this is wider or taller and draw it */
	if (r.right - r.left > r.bottom - r.top) {
		/* Wide */
		offset = ((r.right - r.left) * (val - min)) / (max - min) + r.left;
		if (offset < r.left) offset = r.left;
		if (offset > r.right) offset = r.right;
		
		/* Draw the outset part of this thing */
		s = r;
		s.right = offset;
		if (s.right > s.left) {
			draw.Draw3DRect(s,KXGEOutset);
			::InsetRect(&s,1,1);
			draw.Draw3DRect(s,KXGEOutset);
			::InsetRect(&s,1,1);
			draw.Draw3DRect(s,KXGEBackground);
		}
		
		/* Draw the inset part of this thing */
		s = r;
		s.left = offset;
		if (s.left < s.right) {
			draw.Draw3DRect(s,KXGEInset);
			::InsetRect(&s,1,1);
			draw.Draw3DRect(s,KXGEBackground);
		}
	} else {
		/* Tall */
		offset = ((r.top - r.bottom) * (val - min)) / (max - min) + r.bottom;
		if (offset < r.top) offset = r.top;
		if (offset > r.bottom) offset = r.bottom;
		
		
		/* Draw the outset part of this thing */
		s = r;
		s.top = offset;
		if (s.bottom > s.top) {
			draw.Draw3DRect(s,KXGEOutset);
			::InsetRect(&s,1,1);
			draw.Draw3DRect(s,KXGEOutset);
			::InsetRect(&s,1,1);
			draw.Draw3DRect(s,KXGEBackground);
		}
		
		/* Draw the inset part of this thing */
		s = r;
		s.bottom = offset;
		if (s.top < s.bottom) {
			draw.Draw3DRect(s,KXGEInset);
			::InsetRect(&s,1,1);
			draw.Draw3DRect(s,KXGEBackground);
		}
	}
}



/************************************************************************/
/*																		*/
/*	Value management													*/
/*																		*/
/************************************************************************/

/*	@F"XGStatusBar::GetMinValue" @I
 *
 *		Get my minimum value
 */

long XGStatusBar::GetMinValue()
{
	return fMinValue;
}

/*	@F"XGStatusBar::GetMaxValue" @I
 *
 *		Get my maximum value
 */

long XGStatusBar::GetMaxValue()
{
	return fMaxValue;
}

/*	@F"XGStatusBar::GetValue" @I
 8
 *		Get my current value
 */

long XGStatusBar::GetValue()
{
	return fCurValue;
}

/*	@F"XGStatusBar::SetMinValue" @I
 *
 *		Set my minimum value.
 */

void XGStatusBar::SetMinValue(long value)
{
	if (fMinValue == value) return;
	fMinValue = value;
	fUpdate = true;
	InvalView();
}

/*	@F"XGStatusBar::SetMaxValue" @I
 *
 *		Set my maximum value
 */

void XGStatusBar::SetMaxValue(long value)
{
	if (fMaxValue == value) return;
	fMaxValue = value;
	fUpdate = true;
	InvalView();
}

/*	@F"XGStatusBar::SetValue" @I
 *
 *		Set my value. This draws the status bar immediately. The
 *	'fUpdate' flag is used to determine if I should update when the
 *	value is the same; that's set when the min or max values are changed.
 */

void XGStatusBar::SetValue(long value)
{
	if ((fCurValue == value) && !fUpdate) return;
	fCurValue = value;
	DrawStatusBar();
}
