// text.cpp - GUIText object

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>

#include <string>

extern "C" {
#include "../twcommon.h"
#include "../minuitwrp/minui.h"
}

#include "rapidxml.hpp"
#include "objects.hpp"

GUIText::GUIText(xml_node<>* node)
	: Conditional(node)
{
	xml_attribute<>* attr;
	xml_node<>* child;

	mFont = NULL;
	mIsStatic = 1;
	mVarChanged = 0;
	mFontHeight = 0;
	maxWidth = 0;
	charSkip = 0;
	isHighlighted = false;
	hasHighlightColor = false;

	if (!node)
		return;

	// Initialize color to solid black
	memset(&mColor, 0, sizeof(COLOR));
	mColor.alpha = 255;
	memset(&mHighlightColor, 0, sizeof(COLOR));
	mHighlightColor.alpha = 255;

	attr = node->first_attribute("color");
	if (attr)
	{
		std::string color = attr->value();
		ConvertStrToColor(color, &mColor);
	}
	attr = node->first_attribute("highlightcolor");
	if (attr)
	{
		std::string color = attr->value();
		ConvertStrToColor(color, &mHighlightColor);
		hasHighlightColor = true;
	}

	// Load the font, and possibly override the color
	child = node->first_node("font");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mFont = PageManager::FindResource(attr->value());

		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mColor);
		}

		attr = child->first_attribute("highlightcolor");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mHighlightColor);
			hasHighlightColor = true;
		}
	}

	// Load the placement
	LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH, &mPlacement);

	child = node->first_node("text");
	if (child)  mText = child->value();

	// Simple way to check for static state
	mLastValue = parseText();
	if (mLastValue != mText)   mIsStatic = 0;

	gr_getFontDetails(mFont ? mFont->GetResource() : NULL, (unsigned*) &mFontHeight, NULL);
	return;
}

int GUIText::Render(void)
{
	if (!isConditionTrue())
		return 0;

	void* fontResource = NULL;
	string displayValue;

	if (mFont)
		fontResource = mFont->GetResource();

	mLastValue = parseText();
	displayValue = mLastValue;

	if (charSkip)
		displayValue.erase(0, charSkip);

	mVarChanged = 0;

	int x = mRenderX, y = mRenderY;
	int width = gr_measureEx(displayValue.c_str(), fontResource);

	if (mPlacement != TOP_LEFT && mPlacement != BOTTOM_LEFT)
	{
		if (mPlacement == CENTER || mPlacement == CENTER_X_ONLY)
			x -= (width / 2);
		else
			x -= width;
	}
	if (mPlacement != TOP_LEFT && mPlacement != TOP_RIGHT)
	{
		if (mPlacement == CENTER)
			y -= (mFontHeight / 2);
		else if (mPlacement == BOTTOM_LEFT || mPlacement == BOTTOM_RIGHT)
			y -= mFontHeight;
	}

	if (hasHighlightColor && isHighlighted)
		gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha);
	else
		gr_color(mColor.red, mColor.green, mColor.blue, mColor.alpha);

	if (maxWidth)
		gr_textExW(x, y, displayValue.c_str(), fontResource, maxWidth + x);
	else
		gr_textEx(x, y, displayValue.c_str(), fontResource);
	return 0;
}

int GUIText::Update(void)
{
	if (!isConditionTrue())
		return 0;

	static int updateCounter = 3;

	// This hack just makes sure we update at least once a minute for things like clock and battery
	if (updateCounter)  updateCounter--;
	else
	{
		mVarChanged = 1;
		updateCounter = 3;
	}

	if (mIsStatic || !mVarChanged)
		return 0;

	std::string newValue = parseText();
	if (mLastValue == newValue)
		return 0;
	else
		mLastValue = newValue;
	return 2;
}

int GUIText::GetCurrentBounds(int& w, int& h)
{
	void* fontResource = NULL;

	if (mFont)
		fontResource = mFont->GetResource();

	h = mFontHeight;
	mLastValue = parseText();
	w = gr_measureEx(mLastValue.c_str(), fontResource);
	return 0;
}

std::string GUIText::parseText(void)
{
	static int counter = 0;
	std::string str = mText;
	size_t pos = 0;
	size_t next = 0, end = 0;

	while (1)
	{
		next = str.find('%', pos);
		if (next == std::string::npos) return str;
		end = str.find('%', next + 1);
		if (end == std::string::npos) return str;

		// We have a block of data
		std::string var = str.substr(next + 1, (end - next) - 1);
		str.erase(next, (end - next) + 1);

		if (next + 1 == end)
		{
			str.insert(next, 1, '%');
		}
		else
		{
			std::string value;
			if (DataManager::GetValue(var, value) == 0)
				str.insert(next, value);
		}

		pos = next + 1;
	}
}

int GUIText::NotifyVarChange(std::string varName, std::string value)
{
	mVarChanged = 1;
	return 0;
}

int GUIText::SetMaxWidth(unsigned width)
{
	maxWidth = width;
	mVarChanged = 1;
	return 0;
}

int GUIText::SkipCharCount(unsigned skip)
{
	charSkip = skip;
	mVarChanged = 1;
	return 0;
}
