/*
 *  ppui/StaticText.cpp
 *
 *  Copyright 2009 Peter Barth
 *
 *  This file is part of Milkytracker.
 *
 *  Milkytracker is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Milkytracker is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Milkytracker.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "StaticText.h"
#include "Event.h"
#include "GraphicsAbstract.h"
#include "Font.h"
#include "Tools.h"
#include "PPUIConfig.h"

PPStaticText::PPStaticText(pp_int32 id,	PPScreen* parentScreen, EventListenerInterface* eventListener, 
						   const PPPoint& location, 
						   const PPString& text, 
						   bool drawShadow /*= false*/, 
						   bool drawUnderlined /*= false*/,
						   bool autoShrink /*= false*/) :
	PPControl(id, parentScreen, eventListener, location, PPSize(0,0)),
	color(&PPUIConfig::getInstance()->getColor(PPUIConfig::ColorStaticText)),
	drawShadow(drawShadow),
	underlined(drawUnderlined),
	autoShrink(autoShrink),
	shadowColor(0,0,0),
	text(text),
	extent(-1, -1)
{
	font = PPFont::getFont(PPFont::FONT_SYSTEM);		

	calcExtent();
}

PPStaticText::~PPStaticText()
{
}

void PPStaticText::paint(PPGraphicsAbstract* g)
{
	if (!isVisible())
		return;

	g->setFont(font);

	if (extent.width != -1 && extent.height != -1)
		g->setRect(location.x, location.y, location.x + extent.width, location.y + extent.height+1);
	else
		g->setRect(location.x, location.y, location.x + size.width, location.y + size.height+1);

	const char* text = this->text;
	
	char* temp = NULL;
	if (autoShrink && (signed)font->getStrWidth(text) > extent.width)
	{
		pp_uint32 numchars = extent.width / font->getCharWidth();
		
		temp = new char[numchars+1];
		
		pp_uint32 i;
		for (i = 0; i < (numchars / 2); i++)
			temp[i] = text[i];
			
		temp[i] = '\xef';
	
		pp_uint32 j = i+1;
		for (i = strlen(text)-(numchars / 2); i < strlen(text); i++, j++)
			temp[j] = text[i];
			
		temp[j] = '\0';
		
		text = temp;
	}

	if (drawShadow)
	{
		if (enabled)
			g->setColor(shadowColor);
		else
		{
			PPColor col(shadowColor);
			col.r+=color->r;
			col.g+=color->g;
			col.b+=color->b;
			col.scaleFixed(8192);
			g->setColor(col);
		}

		g->drawString(text, location.x+1, location.y+1, underlined);
	}
	
	if (enabled)
		g->setColor(*color);
	else
	{
		PPColor col(*color);
		col.scaleFixed(40000);
		g->setColor(col);
	}

	g->drawString(text, location.x, location.y, underlined);
	
	if (temp)
		delete[] temp;
}

pp_int32 PPStaticText::dispatchEvent(PPEvent* event)
{ 
	if (!eventListener)
		return -1;

	switch (event->getID())
	{
		case eLMouseDown:
			if (hit(*reinterpret_cast<const PPPoint*>(event->getDataPtr())))
			{
				PPEvent e(eCommand);
				return eventListener->handleEvent(reinterpret_cast<PPObject*>(this), &e); 
			}

			return 0;
	}

	return -1;
}

void PPStaticText::setText(const PPString& text)
{
	this->text = text;

	calcExtent();
}

void PPStaticText::setIntValue(pp_int32 value, pp_uint32 numDecDigits/* = 0*/, bool negative/*= false*/)
{
	
	/*char text[15];	

	_itoa(value, text, 10);
	
	setText(text);*/

	if (numDecDigits == 0)
	{
		if (negative)
		{
			numDecDigits = PPTools::getDecNumDigits(abs(value));
			numDecDigits++;
		}
		else
		{
			numDecDigits = PPTools::getDecNumDigits(value);
		}
	}

	// enough memory to hold 32bit Dec value
	char Dec[15];

	if (negative)
	{
		PPTools::convertToDec(Dec+1, abs(value), numDecDigits-1);
		if (value < 0)
			Dec[0] = '-';
		else	
			Dec[0] = '+';
	}
	else
	{
		PPTools::convertToDec(Dec, value, numDecDigits);
	}

	setText(Dec);
}

void PPStaticText::setValue(pp_int32 value, bool hex, pp_uint32 numDigits/* = 0*/, bool negative/* = false*/)
{
	if (hex)
		setHexValue(value, numDigits);
	else
		setIntValue(value, numDigits, negative);
}

void PPStaticText::setHexValue(pp_int32 value, pp_uint32 numHexDigits/*= 0*/)
{
	if (numHexDigits == 0)
		numHexDigits = PPTools::getHexNumDigits(value);

	// enough memory to hold 32bit hex value
	char hex[10];

	PPTools::convertToHex(hex, value, numHexDigits);

	setText(hex);
}

void PPStaticText::calcExtent()
{	
	size.height = font->getCharHeight()*text.countLines() + (drawShadow?1:0);
	size.width = font->getStrWidth(text) + (drawShadow?1:0);	
}
