// 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 "../common.h"
#include "../minuitwrp/minui.h"
#include "../recovery_ui.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;
    return 2;
}

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

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

    h = mFontHeight;
    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;
}
