/*
        Copyright 2012 bigbiff/Dees_Troy TeamWin
        This file is part of TWRP/TeamWin Recovery Project.

        TWRP 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.

        TWRP 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 TWRP.  If not, see <http://www.gnu.org/licenses/>.
*/

#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 "../data.hpp"

#include <string>

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

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

GUIKeyboard::GUIKeyboard(xml_node<>* node)
	: GUIObject(node)
{
	int layoutindex, rowindex, keyindex, Xindex, Yindex, keyHeight = 0, keyWidth = 0;
	rowY = colX = -1;
	highlightRenderCount = hasHighlight = hasCapsHighlight = 0;
	char resource[10], layout[8], row[5], key[6], longpress[7];
	xml_attribute<>* attr;
	xml_node<>* child;
	xml_node<>* keylayout;
	xml_node<>* keyrow;

	for (layoutindex=0; layoutindex<MAX_KEYBOARD_LAYOUTS; layoutindex++)
		keyboardImg[layoutindex] = NULL;

	mRendered = false;
	currentLayout = 1;
	mAction = NULL;
	KeyboardHeight = KeyboardWidth = 0;

	if (!node)  return;

	// Load the action
	child = node->first_node("action");
	if (child)
	{
		mAction = new GUIAction(node);
	}

	memset(&mHighlightColor, 0, sizeof(COLOR));
	child = node->first_node("highlight");
	if (child) {
		attr = child->first_attribute("color");
		if (attr) {
			hasHighlight = 1;
			std::string color = attr->value();
			ConvertStrToColor(color, &mHighlightColor);
		}
	}

	memset(&mCapsHighlightColor, 0, sizeof(COLOR));
	child = node->first_node("capshighlight");
	if (child) {
		attr = child->first_attribute("color");
		if (attr) {
			hasCapsHighlight = 1;
			std::string color = attr->value();
			ConvertStrToColor(color, &mCapsHighlightColor);
		}
	}

	// Load the images for the different layouts
	child = node->first_node("layout");
	if (child)
	{
		layoutindex = 1;
		strcpy(resource, "resource1");
		attr = child->first_attribute(resource);
		while (attr && layoutindex < (MAX_KEYBOARD_LAYOUTS + 1)) {
			keyboardImg[layoutindex - 1] = PageManager::FindResource(attr->value());

			layoutindex++;
			resource[8] = (char)(layoutindex + 48);
			attr = child->first_attribute(resource);
		}
	}

	// Check the first image to get height and width
	if (keyboardImg[0] && keyboardImg[0]->GetResource())
	{
		KeyboardWidth = gr_get_width(keyboardImg[0]->GetResource());
		KeyboardHeight = gr_get_height(keyboardImg[0]->GetResource());
	}

	// Load all of the layout maps
	layoutindex = 1;
	strcpy(layout, "layout1");
	keylayout = node->first_node(layout);
	while (keylayout)
	{
		if (layoutindex > MAX_KEYBOARD_LAYOUTS) {
			LOGERR("Too many layouts defined in keyboard.\n");
			return;
		}

		child = keylayout->first_node("keysize");
		if (child) {
			attr = child->first_attribute("height");
			if (attr)
				keyHeight = scale_theme_y(atoi(attr->value()));
			else
				keyHeight = 0;
			attr = child->first_attribute("width");
			if (attr)
				keyWidth = scale_theme_x(atoi(attr->value()));
			else
				keyWidth = 0;
			attr = child->first_attribute("capslock");
			if (attr)
				caps_tracking[layoutindex - 1].capslock = atoi(attr->value());
			else
				caps_tracking[layoutindex - 1].capslock = 1;
			attr = child->first_attribute("revert_layout");
			if (attr)
				caps_tracking[layoutindex - 1].revert_layout = atoi(attr->value());
			else
				caps_tracking[layoutindex - 1].revert_layout = -1;
		}

		rowindex = 1;
		Yindex = 0;
		strcpy(row, "row1");
		keyrow = keylayout->first_node(row);
		while (keyrow)
		{
			if (rowindex > MAX_KEYBOARD_ROWS) {
				LOGERR("Too many rows defined in keyboard.\n");
				return;
			}

			Yindex += keyHeight;
			row_heights[layoutindex - 1][rowindex - 1] = Yindex;

			keyindex = 1;
			Xindex = 0;
			strcpy(key, "key01");
			attr = keyrow->first_attribute(key);

			while (attr) {
				if (keyindex > MAX_KEYBOARD_KEYS) {
					LOGERR("Too many keys defined in a keyboard row.\n");
					return;
				}

				const char* keyinfo = attr->value();

				if (strlen(keyinfo) == 0) {
					LOGERR("No key info on layout%i, row%i, key%dd.\n", layoutindex, rowindex, keyindex);
					return;
				}

				if (ParseKey(keyinfo, keyboard_keys[layoutindex - 1][rowindex - 1][keyindex - 1], Xindex, keyWidth, false))
					LOGERR("Invalid key info on layout%i, row%i, key%02i.\n", layoutindex, rowindex, keyindex);


				// PROCESS LONG PRESS INFO IF EXISTS
				sprintf(longpress, "long%02i", keyindex);
				attr = keyrow->first_attribute(longpress);
				if (attr) {
					const char* keyinfo = attr->value();

					if (strlen(keyinfo) == 0) {
						LOGERR("No long press info on layout%i, row%i, long%dd.\n", layoutindex, rowindex, keyindex);
						return;
					}

					if (ParseKey(keyinfo, keyboard_keys[layoutindex - 1][rowindex - 1][keyindex - 1], Xindex, keyWidth, true))
						LOGERR("Invalid long press key info on layout%i, row%i, long%02i.\n", layoutindex, rowindex, keyindex);
				}
				keyindex++;
				sprintf(key, "key%02i", keyindex);
				attr = keyrow->first_attribute(key);
			}
			rowindex++;
			row[3] = (char)(rowindex + 48);
			keyrow = keylayout->first_node(row);
		}
		layoutindex++;
		layout[6] = (char)(layoutindex + 48);
		keylayout = node->first_node(layout);
	}

	int x, y, w, h;
	// Load the placement
	LoadPlacement(node->first_node("placement"), &x, &y, &w, &h);
	SetActionPos(x, y, KeyboardWidth, KeyboardHeight);
	SetRenderPos(x, y, w, h);
	return;
}

GUIKeyboard::~GUIKeyboard()
{
}

int GUIKeyboard::ParseKey(const char* keyinfo, keyboard_key_class& key, int& Xindex, int keyWidth, bool longpress)
{
	int keychar = 0;
	if (strlen(keyinfo) == 1) {
		// This is a single key, simple definition
		keychar = keyinfo[0];
	} else {
		// This key has extra data: {keywidth}:{what_the_key_does}
		keyWidth = scale_theme_x(atoi(keyinfo));

		const char* ptr = keyinfo;
		while (*ptr > 32 && *ptr != ':')
			ptr++;
		if (*ptr != ':')
			return -1;  // no colon is an error
		ptr++;

		if (*ptr == 0) {  // This is an empty area
			keychar = 0;
		} else if (strlen(ptr) == 1) {  // This is the character that this key uses
			keychar = *ptr;
		} else if (*ptr == 'c') {  // This is an ASCII character code: "c:{number}"
			keychar = atoi(ptr + 2);
		} else if (*ptr == 'l') {  // This is a different layout: "layout{number}"
			keychar = KEYBOARD_LAYOUT;
			key.layout = atoi(ptr + 6);
		} else if (*ptr == 'a') {  // This is an action: "action"
			keychar = KEYBOARD_ACTION;
		} else
			return -1;
	}

	if (longpress) {
		key.longpresskey = keychar;
	} else {
		key.key = keychar;
		Xindex += keyWidth;
		key.end_x = Xindex - 1;
	}

	return 0;
}

int GUIKeyboard::Render(void)
{
	if (!isConditionTrue())
	{
		mRendered = false;
		return 0;
	}

	int ret = 0;

	if (keyboardImg[currentLayout - 1] && keyboardImg[currentLayout - 1]->GetResource())
		gr_blit(keyboardImg[currentLayout - 1]->GetResource(), 0, 0, KeyboardWidth, KeyboardHeight, mRenderX, mRenderY);

	// Draw highlight for capslock
	if (hasCapsHighlight && caps_tracking[currentLayout - 1].capslock == 0 && caps_tracking[currentLayout - 1].set_capslock) {
		int boxheight, boxwidth, x;
		gr_color(mCapsHighlightColor.red, mCapsHighlightColor.green, mCapsHighlightColor.blue, mCapsHighlightColor.alpha);
		for (int indexy=0; indexy<MAX_KEYBOARD_ROWS; indexy++) {
			for (int indexx=0; indexx<MAX_KEYBOARD_KEYS; indexx++) {
				if ((int)keyboard_keys[currentLayout - 1][indexy][indexx].key == KEYBOARD_LAYOUT && (int)keyboard_keys[currentLayout - 1][indexy][indexx].layout == caps_tracking[currentLayout - 1].revert_layout) {
					if (indexy == 0)
						boxheight = row_heights[currentLayout - 1][indexy];
					else
						boxheight = row_heights[currentLayout - 1][indexy] - row_heights[currentLayout - 1][indexy - 1];
					if (indexx == 0) {
						x = mRenderX;
						boxwidth = keyboard_keys[currentLayout - 1][indexy][indexx].end_x;
					} else {
						x = mRenderX + keyboard_keys[currentLayout - 1][indexy][indexx - 1].end_x;
						boxwidth = keyboard_keys[currentLayout - 1][indexy][indexx].end_x - keyboard_keys[currentLayout - 1][indexy][indexx - 1].end_x;
					}
					gr_fill(x, mRenderY + row_heights[currentLayout - 1][indexy - 1], boxwidth, boxheight);
				}
			}
		}
	}

	if (hasHighlight && highlightRenderCount != 0) {
		int boxheight, boxwidth, x;
		if (rowY == 0)
			boxheight = row_heights[currentLayout - 1][rowY];
		else
			boxheight = row_heights[currentLayout - 1][rowY] - row_heights[currentLayout - 1][rowY - 1];
		if (colX == 0) {
			x = mRenderX;
			boxwidth = keyboard_keys[currentLayout - 1][rowY][colX].end_x;
		} else {
			x = mRenderX + keyboard_keys[currentLayout - 1][rowY][colX - 1].end_x;
			boxwidth = keyboard_keys[currentLayout - 1][rowY][colX].end_x - keyboard_keys[currentLayout - 1][rowY][colX - 1].end_x;
		}
		gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha);
		gr_fill(x, mRenderY + row_heights[currentLayout - 1][rowY - 1], boxwidth, boxheight);
		if (highlightRenderCount > 0)
			highlightRenderCount--;
	} else
		mRendered = true;

	return ret;
}

int GUIKeyboard::Update(void)
{
	if (!isConditionTrue())	 return (mRendered ? 2 : 0);
	if (!mRendered)			 return 2;

	return 0;
}

int GUIKeyboard::SetRenderPos(int x, int y, int w, int h)
{
	mRenderX = x;
	mRenderY = y;
	if (w || h)
	{
		mRenderW = KeyboardWidth;
		mRenderH = KeyboardHeight;
	}

	if (mAction)		mAction->SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
	return 0;
}

int GUIKeyboard::GetSelection(int x, int y)
{
	if (x < mRenderX || x - mRenderX > (int)KeyboardWidth || y < mRenderY || y - mRenderY > (int)KeyboardHeight) return -1;
	return 0;
}

int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y)
{
	static int startSelection = -1, was_held = 0, startX = 0;
	static unsigned char initial_key = 0;
	int indexy, indexx, rely, relx, rowIndex = 0;

	rely = y - mRenderY;
	relx = x - mRenderX;

	if (!isConditionTrue())	 return -1;

	switch (state)
	{
	case TOUCH_START:
		if (GetSelection(x, y) == 0) {
			startSelection = -1;
			was_held = 0;
			startX = x;
			// Find the correct row
			for (indexy=0; indexy<MAX_KEYBOARD_ROWS; indexy++) {
				if (row_heights[currentLayout - 1][indexy] > rely) {
					rowIndex = indexy;
					rowY = indexy;
					indexy = MAX_KEYBOARD_ROWS;
				}
			}

			// Find the correct key (column)
			for (indexx=0; indexx<MAX_KEYBOARD_KEYS; indexx++) {
				if (keyboard_keys[currentLayout - 1][rowIndex][indexx].end_x > relx) {
					// This is the key that was pressed!
					initial_key = keyboard_keys[currentLayout - 1][rowIndex][indexx].key;
					colX = indexx;
					indexx = MAX_KEYBOARD_KEYS;
				}
			}
			if (initial_key != 0)
				highlightRenderCount = -1;
			else
				highlightRenderCount = 0;
			mRendered = false;
		} else {
			if (highlightRenderCount != 0)
				mRendered = false;
			highlightRenderCount = 0;
			startSelection = 0;
		}
		break;
	case TOUCH_DRAG:
		break;
	case TOUCH_RELEASE:
		if (x < startX - (KeyboardWidth * 0.5)) {
			if (highlightRenderCount != 0) {
				highlightRenderCount = 0;
				mRendered = false;
			}
			PageManager::NotifyKeyboard(KEYBOARD_SWIPE_LEFT);
			return 0;
		} else if (x > startX + (KeyboardWidth * 0.5)) {
			if (highlightRenderCount != 0) {
				highlightRenderCount = 0;
				mRendered = false;
			}
			PageManager::NotifyKeyboard(KEYBOARD_SWIPE_RIGHT);
			return 0;
		}

	case TOUCH_HOLD:
	case TOUCH_REPEAT:

		if (startSelection == 0 || GetSelection(x, y) == -1) {
			if (highlightRenderCount != 0) {
				highlightRenderCount = 0;
				mRendered = false;
			}
			return 0;
		} else if (highlightRenderCount != 0) {
			if (state == TOUCH_RELEASE)
				highlightRenderCount = 2;
			else
				highlightRenderCount = -1;
			mRendered = false;
		}

		// Find the correct row
		for (indexy=0; indexy<MAX_KEYBOARD_ROWS; indexy++) {
			if (row_heights[currentLayout - 1][indexy] > rely) {
				rowIndex = indexy;
				indexy = MAX_KEYBOARD_ROWS;
			}
		}

		// Find the correct key (column)
		for (indexx=0; indexx<MAX_KEYBOARD_KEYS; indexx++) {
			keyboard_key_class& key = keyboard_keys[currentLayout - 1][rowIndex][indexx];
			if (key.end_x > relx) {
				// This is the key that was pressed!
				if (key.key != initial_key) {
					// We dragged off of the starting key
					startSelection = 0;
					break;
				} else if (state == TOUCH_RELEASE && was_held == 0) {
					DataManager::Vibrate("tw_keyboard_vibrate");
					if ((int)key.key < KEYBOARD_SPECIAL_KEYS && (int)key.key > 0) {
						// Regular key
						PageManager::NotifyKeyboard(key.key);
						if (caps_tracking[currentLayout - 1].capslock == 0 && !caps_tracking[currentLayout - 1].set_capslock) {
							// caps lock was not set, change layouts
							currentLayout = caps_tracking[currentLayout - 1].revert_layout;
							mRendered = false;
						}
					} else if ((int)key.key == KEYBOARD_LAYOUT) {
						// Switch layouts
						if (caps_tracking[currentLayout - 1].capslock == 0 && key.layout == caps_tracking[currentLayout - 1].revert_layout) {
							if (!caps_tracking[currentLayout - 1].set_capslock) {
								caps_tracking[currentLayout - 1].set_capslock = 1; // Set the caps lock
							} else {
								caps_tracking[currentLayout - 1].set_capslock = 0; // Unset the caps lock and change layouts
								currentLayout = key.layout;
							}
						} else {
							currentLayout = key.layout;
						}
						mRendered = false;
					} else if ((int)key.key == KEYBOARD_ACTION) {
						// Action
						highlightRenderCount = 0;
						if (mAction) {
							// Keyboard has its own action defined
							return (mAction ? mAction->NotifyTouch(state, x, y) : 1);
						} else {
							// Send action notification
							PageManager::NotifyKeyboard(key.key);
						}
					}
				} else if (state == TOUCH_HOLD) {
					was_held = 1;
					if ((int)key.key == KEYBOARD_BACKSPACE) {
						// Repeat backspace
						PageManager::NotifyKeyboard(key.key);
					} else if ((int)key.longpresskey < KEYBOARD_SPECIAL_KEYS && (int)key.longpresskey > 0) {
						// Long Press Key
						DataManager::Vibrate("tw_keyboard_vibrate");
						PageManager::NotifyKeyboard(key.longpresskey);
					}
				} else if (state == TOUCH_REPEAT) {
					was_held = 1;
					if ((int)key.key == KEYBOARD_BACKSPACE) {
						// Repeat backspace
						PageManager::NotifyKeyboard(key.key);
					}
				}
				indexx = MAX_KEYBOARD_KEYS;
			}
		}
		break;
	}

	return 0;
}
