/*
	ZButton class	V0.1alpha
*/

#include <InterfaceKit.h>
#include "ZButton.h"


ZButton::
ZButton(
	BRect 		 frame,
	const char 	*name,
	const char 	*label,
	int32 		pictype,
	BMessage 	*message,
	uint32 resizeMask,
	uint32 flags):
BControl(frame,name,label,message,resizeMask,flags)
{
	SetMessage(message);
	SetFlags(Flags()|B_NAVIGABLE);
	msg=message;
	pictyp=pictype;
	marked=FALSE;
	bitmap=0; 
}

void ZButton::DrawExtra(bool selected)
{
	struct font_height 	fi;
	BRect				temp;
	BPoint				foo;
	float				bar,add;
	if(Window()->Lock())
	{
	
		SetFont(be_plain_font);
		SetFontSize(10.0);
	
		if(!selected) 	SetHighColor(222,222,222);
		else			SetHighColor(188,188,188);
		if(!selected) 	SetLowColor(222,222,222);
		else			SetLowColor(188,188,188);

		if(marked)
		{
			SetHighColor(100,166,222);
			SetLowColor(100,166,222);
		}
		
		FillRect(Bound);
	
		if(!selected)	SetHighColor(128,128,128);
		else			SetHighColor(128,128,128);

		StrokeRect(BRect(BPoint(0,0),BPoint(0,Bound.Height()-1)));
		StrokeRect(BRect(BPoint(0,0),BPoint(Bound.Width()-1,0)));

		if(!selected)	SetHighColor(255,255,255);
		else			SetHighColor(192,192,192);

		StrokeRect(BRect(BPoint(1,1),BPoint(1,Bound.Height()-2)));
		StrokeRect(BRect(BPoint(1,1),BPoint(Bound.Width()-2,1)));

		if(!selected)	SetHighColor(192,192,192);
		else			SetHighColor(255,255,255);
	
		StrokeRect(BRect(BPoint(1,Bound.Height()-1),BPoint(Bound.Width()-1,Bound.Height()-1)));
		StrokeRect(BRect(BPoint(Bound.Width()-1,1),BPoint(Bound.Width()-1,Bound.Height()-1)));

		GetFontHeight(&fi);
		
		if(!selected)	SetHighColor(128,128,128);
		else			SetHighColor(128,128,128);
		
		StrokeRect(BRect(BPoint(0,Bound.Height()),BPoint(Bound.Width(),Bound.Height())));
		StrokeRect(BRect(BPoint(Bound.Width(),0),BPoint(Bound.Width(),Bound.Height())));
		
		SetHighColor(0,0,0);

		SetDrawingMode(B_OP_COPY);
	
		if(!IsEnabled()) SetHighColor(128,128,128);
	
		if(selected)add=1;else add=0;
	
		if(bitmap)
		{
			BRect rect=bitmap->Bounds();
			BPoint pos;
			
			pos.x=(Bound.Width()-rect.Width())/2+add;
			pos.y=(Bound.Height()-rect.Height())/2+add;
			
			SetDrawingMode(B_OP_OVER);
			DrawBitmap(bitmap,pos);
			SetDrawingMode(B_OP_COPY);

			if(!IsEnabled())
			{
				rect.OffsetTo(pos);

				if(!selected) 	SetHighColor(222,222,222);
				else			SetHighColor(188,188,188);
				if(marked)		SetHighColor(100,166,222);
				
				SetDrawingMode(B_OP_OVER);
				FillRect(rect,B_MIXED_COLORS);
				SetDrawingMode(B_OP_COPY);
			}
		}
		else if(pictyp)
		{
			switch(pictyp)
			{
				case	PICTURE_PLAY:
						foo=BPoint(((Bound.Width()-(Bound.Height()-4))/2)+2+add,4+add);
						bar=Bound.Height()-7;
						FillTriangle(foo,foo+BPoint(0,bar),foo+BPoint(bar,bar/2));
						break;					
				case	PICTURE_STOP:
						temp=BRect(BPoint(0,0),BPoint(Bound.Height()-10,Bound.Height()-9));
						temp.OffsetTo((Bound.Width()-(Bound.Height()-10))/2+add,5+add);
						FillRect(temp);
						break;
				case	PICTURE_NEXT:
						foo=BPoint(((Bound.Width()-(Bound.Height()-8))/2)-2+add,4+add);
						bar=Bound.Height()-7;
						FillTriangle(foo,foo+BPoint(0,bar),foo+BPoint(bar/2,bar/2));
						FillTriangle(foo+BPoint(bar/2,0),foo+BPoint(bar/2,bar),foo+BPoint(bar,bar/2));
						FillRect(BRect(foo+BPoint(bar+1,0),foo+BPoint(bar+3,bar)));
						break;
				case	PICTURE_BACK:
						foo=BPoint(((Bound.Width()-(Bound.Height()-8))/2)-2+add,4+add);
						bar=Bound.Height()-7;
						FillTriangle(foo+BPoint(bar+3-bar/2,0),foo+BPoint(bar+3-bar/2,bar),foo+BPoint(3,bar/2));
						FillTriangle(foo+BPoint(bar+3,0),foo+BPoint(bar+3,bar),foo+BPoint(3+bar/2,bar/2));
						FillRect(BRect(foo+BPoint(0,0),foo+BPoint(2,bar)));
						break;
				case	PICTURE_TNEXT:
						foo=BPoint(((Bound.Width()-(Bound.Height()-8))/2)-2+add,4+add);
						bar=Bound.Height()-7;
						FillTriangle(foo,foo+BPoint(0,bar),foo+BPoint(bar,bar/2));
						FillRect(BRect(foo+BPoint(bar,0),foo+BPoint(bar+3,bar)));
						break;
				case	PICTURE_TBACK:
						foo=BPoint(((Bound.Width()-(Bound.Height()-8))/2)-2+add,4+add);
						bar=Bound.Height()-7;
						FillTriangle(foo+BPoint(bar+3,0),foo+BPoint(bar+3,bar),foo+BPoint(4,bar/2));
						FillRect(BRect(foo,foo+BPoint(3,bar)));
						break;
				case	PICTURE_PAUSE:
						temp=BRect(BPoint(0,0),BPoint((float)((int)((Bound.Height()-10)/3)),Bound.Height()-9));
						temp.OffsetTo((Bound.Width()-(Bound.Height()-10))/2+add,5+add);
						FillRect(temp);
						temp.OffsetBy(BPoint((float)((int)(((Bound.Height()-10)/3)*2)),0));
						FillRect(temp);
						break;
			}
		}
		else
		{
			MovePenTo(BPoint(((Bound.Width()-StringWidth(Label()))/2)+add+1,(Bound.Height()+(10.0-fi.descent-fi.leading))/2+add));
			DrawString(Label());	
		}

		if(IsFocus())
		{
			BRect r=Bound;	
			r.left+=2;
			r.top+=2;
			r.right-=2;
			r.bottom-=2;
			SetHighColor(66,66,66);
			StrokeRect(r,B_MIXED_COLORS);
		}

		Sync();
		Window()->Unlock();
	}
}

void ZButton::SetMark(bool state)
{
	marked=state;
	Draw(Bound);
}

bool ZButton::IsMarked(void)
{
	return marked;
}

void ZButton::AttachedToWindow(void)
{
	Bound=Bounds();	
}

ZButton::~ZButton()
{
}

void ZButton::SetPictureType(int32 type)
{
	pictyp=type;
	Draw(Bound);
}

void ZButton::Draw(BRect updateRect)
{
	DrawExtra(FALSE);	
}

void ZButton::KeyDown(const char *data, int32 num)
{
	switch(data[0])
	{
		case	B_ENTER:
				DrawExtra(TRUE);
				if(IsEnabled())Window()->PostMessage(msg);
				snooze(50000);
				DrawExtra(FALSE);
				break;
				
		case	B_FUNCTION_KEY:
		case	B_LEFT_ARROW:
		case	B_RIGHT_ARROW:
		case	's':
		case	'S':
		case	B_ESCAPE:
		case	'P':
		case	'p':
				if(Parent())Parent()->KeyDown(data,num);
				break;

		default:
				BControl::KeyDown(data,num);
				break;
	}
}

void ZButton::MouseDown(BPoint point)
{
	uint32 	buttons;
	bool	selected=TRUE,oldsel=FALSE;
	
	if(!IsEnabled())return;
	
	DrawExtra(TRUE);
	MakeFocus();
	do 
	{
		snooze(30000);
		if
		(
			  (point.x>(Bound.RightBottom().x))
			||(point.y>(Bound.RightBottom().y))
			||(point.x<(Bound.LeftTop().x))
			||(point.y<(Bound.LeftTop().y))
		)
		{
			selected=FALSE;
			if(oldsel==TRUE)
			{
				DrawExtra(FALSE);
				oldsel=FALSE;
			}
		}
		else
		{
			selected=TRUE;
			if(oldsel==FALSE)
			{
				DrawExtra(TRUE);
				oldsel=TRUE;
			}
		}
		GetMouse(&point, &buttons);
	} 
	while ( buttons );
	
	DrawExtra(FALSE);
	
	if(selected)
	{
		if(IsEnabled())Invoke();
	}
}