/*	XGStdStaticText.cpp
 *
 *		this is my internal implementation of a static text object.
 *	This is something I simply roll myself
 */

/*  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 <string.h>
#include <XError.h>
#include <XTextControls.h>
#include <XDataUtil.h>
#include <XDraw.h>
#include <ctype.h>

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

/*	@F"XGStaticText::XGStaticText" @I
 *
 *		Initialize me
 */

XGStaticText::XGStaticText(XGOwner *v, XGArgStream &s) : XGView(v,s)
{
	char buffer[256];
	s.ReadString(buffer);
	Init(buffer,s.ReadInteger());
}

XGStaticText::XGStaticText(XGOwner *v, XGSTextInitRecord &s) : XGView(v,s.v)
{
	Init(s.text,s.font);
}

/*	@F"XGStaticText::~XGStaticText" @I
 *
 *		Delete me
 */

XGStaticText::~XGStaticText()
{
	fFontPtr->Detach();
}

/************************************************************************/
/*																		*/
/*	Text Drawing														*/
/*																		*/
/************************************************************************/

/*	@F"XGStaticText::GetTitle" @I
 *
 *		Get the text contents of this
 */

void XGStaticText::GetTitle(char *text) const
{
	strcpy(text,fString.Get());
}

/*	@F"XGStaticText::SetTitle" @I
 *
 *		Set the text and force a redraw
 */

void XGStaticText::SetTitle(const char *text)
{
	fString = text;
	InvalView();
}

/************************************************************************/
/*																		*/
/*	Static Control Drawing												*/
/*																		*/
/************************************************************************/

/*	@F"XGStaticText::DoDrawView" @I
 *
 *		Draw this thing
 */

void XGStaticText::DoDrawView(Rect)
{
	XGDraw draw(this);
	Rect r;
	const char *text = fString.Get();
	
	r = GetContentRect();
	
	if (!IsEnabled()) draw.SetForeColor(KXGColorBtnShadow);
	fFontPtr->Attach();		
	draw.SetFont(fFontPtr);
	DrawLines(draw,text,r.left + 1,r.top,r.right-r.left - 2);
}

/************************************************************************/
/*																		*/
/*	Static Control Drawing												*/
/*																		*/
/************************************************************************/

/*	XGStaticText::Init
 *
 *		This handles the initialization
 */

void XGStaticText::Init(char *buffer, short font)
{
	fFontPtr = XGFont::LoadFont(font);
	fString = buffer;
}

/************************************************************************/
/*																		*/
/*	Line Wrap Support													*/
/*																		*/
/************************************************************************/

/*	XGStaticText::SkipSpace
 *
 *		Skip spaces
 */

short XGStaticText::SkipSpace(const char *str, short x)
{
	str += x;
	while (isspace(*str) && (*str != '\n')) x++, str++;
	return x;
}

/*	XGStaticText::NextWord
 *
 *		Width of a word
 */

short XGStaticText::NextWord(const char *str, short x)
{
	str += x;
	while (!isspace(*str) && (*str)) x++, str++;
	return x;
}

/*	XGStaticText::CharWidth
 *
 *		Given the pixel width to keep the string wrapped at, and the
 *	character pointer to the start of the string, this returns the
 *	number of characters that will fit into that width, adjusted for
 *	line breaks.
 */

short XGStaticText::CharWidth(XGDraw &draw, const char *str, short pwidth)
{
	short w;
	short n;
	
	w = SkipSpace(str,0);
	w = NextWord(str,w);				/* Draw at least one word */
	for (;;) {
		if (str[w] == 0) return w;
		if (str[w] == '\n') return w;
		n = SkipSpace(str,w);
		if (str[n] == 0) return n;
		if (str[n] == '\n') return n;
		n = NextWord(str,n);
		if (draw.StringWidthA(str,n) > pwidth) return w;
		w = n;
	}
}

/*	XGStaticText::DrawLines
 *
 *		Draw the lines that are in this string
 */

void XGStaticText::DrawLines(XGDraw &draw, const char *str, 
							 short x, short y, short pwidth)
{
	short h;
	short w;
	
	h = draw.GetFontHeight();
	y += draw.GetFontAscent();
	for (;;) {
		w = CharWidth(draw,str,pwidth);
		draw.MoveTo(x,y);
		draw.DrawStringA(str,w);
		str += w;
		while (isspace(*str)) str++;
		if (*str == '\0') return;
		y += h;
	}
}

