/*	XGPopMenuView.cpp
 *
 *		The code which handles the popup menu view
 */

/*  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 <XConfig.h>			// must be first to optimize compile on MSVC++
#include <XDraw.h>
#include <XPopup.h>

/************************************************************************/
/*																		*/
/*	Globals																*/
/*																		*/
/************************************************************************/

static XGSViewInitRecord MenuInitRecord = {
	'****', 1, 0,
	0, 0, 0, 0,
	true, true, true, true,
	true, true, false
};

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

/*	@F"XGPopMenuView::XGPopMenuView" @I
 *
 *		Create me
 */

XGPopMenuView::XGPopMenuView(XGStringList *l, short f, short d) : 
		XGView(NULL,MenuInitRecord)
{
	fDefault = d;
	fList = l;
	fFont = f;
	fLocation = fDefault;
}

/*	@F"XGPopMenuView::~XGPopMenuView" @I
 *
 *		Go away
 */

XGPopMenuView::~XGPopMenuView()
{
}

/************************************************************************/
/*																		*/
/*	Size preflight														*/
/*																		*/
/************************************************************************/

/*	@F"XGPopMenuView::GetPopSize" @I
 *
 *		The drawing object I'm handed is already initialized. All I
 *	do is figure out how big my menu should be.
 *
 *		Dimensions:
 *
 *			| <-20-> MENUNAME <-5-> ACCEL <-5-> |
 */

Point XGPopMenuView::GetPopSize(XGDraw &draw)
{
	Point size;
	int i,len;
	int width;
	int x;
	char item[256];
	
	/*
	 *	Find height 
	 */
	
	len = fList->GetNumStrings();
	size.v = (draw.GetFontHeight()) * len;

	/*
	 *	Find width 
	 */
	
	width = 20;
	for (i = 0; i < len; i++) {
		fList->GetString(i,item);
		x = draw.StringWidth(item) + 30;
		if (width < x) width = x;
	}
	size.h = width;
	
	/*
	 *	Now bump for the border
	 */
	
	size.h += 6;
	size.v += 6;
	return size;
}

/************************************************************************/
/*																		*/
/*	Event Processing													*/
/*																		*/
/************************************************************************/

/*	@F"XGPopMenuView::DoDrawView" @I
 *
 *		Draw the contents of this view
 */

void XGPopMenuView::DoDrawView(Rect)
{
	Rect r;
	int i;
	XGDraw draw(this);
	draw.SetFont(XGFont::LoadFont(fFont));

	r = GetContentRect();	
	draw.Draw3DRect(r,KXGEBackground);
	draw.Draw3DRect(r,KXGEFrame);
	::InsetRect(&r,1,1);
	draw.Draw3DRect(r,KXGEOutset);
	::InsetRect(&r,1,1);

	for (i = 0; i < fList->GetNumStrings(); i++) {
		DrawLine(draw,i,(i == fLocation));
	}
}

/*	@F"XGPopMenuView::DoMouseMove" @I
 *
 *		Handle mouse move. I assume this is down
 */

void XGPopMenuView::DoMouseMove(Point where,short)
{
	short h;
	XGDraw draw(this);
	draw.SetFont(XGFont::LoadFont(fFont));
	
	if (where.v < 3) {
		h = fDefault;
	} else {
		h = draw.GetFontHeight();
		h = (where.v - 3) / h;
	
		if ((h < 0) || (h >= fList->GetNumStrings())) h = fDefault;
	}
	if (fLocation == h) return;
	
	/*
	 *	Redraw the two items
	 */
	
	if (fLocation != -1) DrawLine(draw,fLocation,false);
	if (h != -1) DrawLine(draw,h,true);
	fLocation = h;
}


/************************************************************************/
/*																		*/
/*	Low level															*/
/*																		*/
/************************************************************************/

/*	@F"XGPopMenuView::DrawLine" @I
 *
 *		Draw the text line
 */

void XGPopMenuView::DrawLine(XGDraw &draw, short line, bool hilite)
{
	Rect r;
	int h;
	char item[256];
	
	r = GetContentRect();
	::InsetRect(&r,3,3);
	h = draw.GetFontHeight();
	r.top = line * h + 3;
	r.bottom = r.top + h;
	
	h = r.bottom - 1 - draw.GetFontDescent();
	
	/*
	 *	Draw the dsabled text line (if the line is disabled)
	 */

	fList->GetString(line,item);
	
	if (item[0] == 0) {
		Rect s;
		
		/*
		 *	Separator
		 */
		
		draw.Draw3DRect(r,KXGEBackground);
		s = r;
		s.top = (r.top + r.bottom) / 2;
		s.bottom = s.top + 1;
		draw.FillRect(s,KXGColorBtnShadow);
		s.top++;
		s.bottom++;
		draw.FillRect(s,KXGColorBtnHilite);
		return;
	}
		
	/*
	 *	Draw the hilite
	 */
	
	draw.MoveTo(20,h);
	if (hilite) {
		draw.FillRect(r,KXGColorMHilite);
		draw.SetForeColor(KXGColorMHiliteText);
	} else {
		draw.SetForeColor(KXGColorBlack);
		draw.Draw3DRect(r,KXGEBackground);
	}
	
	/*
	 *	Draw the line
	 */
			
	draw.DrawString(item);
}
