/*
        Copyright 2012 to 2020 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 <linux/input.h>
#include <stdlib.h>
#include <string.h>
#include "../data.hpp"

#include <string>

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

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

bool GUIKeyboard::CtrlActive = false;

GUIKeyboard::GUIKeyboard(xml_node<>* node)
	: GUIObject(node)
{
	int layoutindex, rowindex, keyindex, Xindex, Yindex, keyHeight = 0, keyWidth = 0;
	currentKey = NULL;
	highlightRenderCount = 0;
	hasHighlight = hasCapsHighlight = hasCtrlHighlight = false;
	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++) {
		layouts[layoutindex].keyboardImg = NULL;
		memset(layouts[layoutindex].keys, 0, sizeof(Layout::keys));
		memset(layouts[layoutindex].row_end_y, 0, sizeof(Layout::row_end_y));
	}

	mRendered = false;
	currentLayout = 1;
	CapsLockOn = false;

	if (!node)  return;

	mHighlightColor = LoadAttrColor(FindNode(node, "highlight"), "color", &hasHighlight);
	mCapsHighlightColor = LoadAttrColor(FindNode(node, "capshighlight"), "color", &hasCapsHighlight);
	mCtrlHighlightColor = LoadAttrColor(FindNode(node, "ctrlhighlight"), "color", &hasCtrlHighlight);

	child = FindNode(node, "keymargin");
	mKeyMarginX = LoadAttrIntScaleX(child, "x", 0);
	mKeyMarginY = LoadAttrIntScaleY(child, "y", 0);

	child = FindNode(node, "background");
	mBackgroundColor = LoadAttrColor(child, "color", COLOR(32,32,32,255));

	child = FindNode(node, "key-alphanumeric");
	mFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel"));
	mFontColor = LoadAttrColor(child, "textcolor", COLOR(255,255,255,255));
	mKeyColorAlphanumeric = LoadAttrColor(child, "color", COLOR(0,0,0,0));

	child = FindNode(node, "key-other");
	mSmallFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel-small"));
	mFontColorSmall = LoadAttrColor(child, "textcolor", COLOR(192,192,192,255));
	mKeyColorOther = LoadAttrColor(child, "color", COLOR(0,0,0,0));

	child = FindNode(node, "longpress");
	mLongpressFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel-longpress"));
	mLongpressFontColor = LoadAttrColor(child, "textcolor", COLOR(128,128,128,255));
	LoadPlacement(child, &longpressOffsetX, &longpressOffsetY);

	LoadKeyLabels(node, 0); // load global key labels

	// compatibility ugliness: resources should be specified in the layouts themselves instead
	// Load the images for the different layouts
	child = FindNode(node, "layout");
	if (child)
	{
		layoutindex = 1;
		strcpy(resource, "resource1");
		attr = child->first_attribute(resource);
		while (attr && layoutindex < (MAX_KEYBOARD_LAYOUTS + 1)) {
			layouts[layoutindex - 1].keyboardImg = LoadAttrImage(child, resource);

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

	// Check the first image to get height and width
	if (layouts[0].keyboardImg && layouts[0].keyboardImg->GetResource())
	{
		mRenderW = layouts[0].keyboardImg->GetWidth();
		mRenderH = layouts[0].keyboardImg->GetHeight();
	}

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

		LoadKeyLabels(keylayout, layoutindex); // load per-layout key labels

		Layout& lay = layouts[layoutindex - 1];

		child = keylayout->first_node("keysize");
		keyHeight = LoadAttrIntScaleY(child, "height", 0);
		keyWidth = LoadAttrIntScaleX(child, "width", 0);
		// compatibility ugliness: capslock="0" means that this is the caps layout. Also it has nothing to do with keysize.
		lay.is_caps = (LoadAttrInt(child, "capslock", 1) == 0);
		// compatibility ugliness: revert_layout has nothing to do with keysize.
		lay.revert_layout = LoadAttrInt(child, "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;
			lay.row_end_y[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, lay.keys[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, lay.keys[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 = FindNode(node, layout);
	}

	int x, y;
	// Load the placement
	LoadPlacement(FindNode(node, "placement"), &x, &y, &mRenderW, &mRenderH);
	SetRenderPos(x, y, mRenderW, mRenderH);
	return;
}

GUIKeyboard::~GUIKeyboard()
{
}

int GUIKeyboard::ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWidth, bool longpress)
{
	key.layout = 0;
	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 == 'k') {  // This is a Linux keycode from input.h: "k:{number}"
			keychar = -atoi(ptr + 2);
		} else if (*ptr == 'l') {  // This is a different layout: "layout{number}"
			key.layout = atoi(ptr + 6);
		} else if (*ptr == 'a') {  // This is an action: "action" (the Enter key)
			keychar = KEYBOARD_ACTION;
		} else
			return -1;
	}

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

	return 0;
}

void GUIKeyboard::LoadKeyLabels(xml_node<>* parent, int layout)
{
	for (xml_node<>* child = parent->first_node(); child; child = child->next_sibling()) {
		std::string name = child->name();
		if (name == "keylabel") {
			std::string keydef = LoadAttrString(child, "key", "");
			Key tempkey;
			int dummyX;
			if (ParseKey(keydef.c_str(), tempkey, dummyX, 0, false) == 0) {
				KeyLabel keylabel;
				keylabel.key = tempkey.key;
				keylabel.layout_from = layout;
				keylabel.layout_to = tempkey.layout;
				keylabel.text = LoadAttrString(child, "text", "");
				keylabel.image = LoadAttrImage(child, "resource");
				mKeyLabels.push_back(keylabel);
			} else {
				LOGERR("Ignoring invalid keylabel in layout %d: '%s'.\n", layout, keydef.c_str());
			}
		}
	}
}

void GUIKeyboard::DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH)
{
	int keychar = key.key;
	if (!keychar && !key.layout)
		return;

	// key background
	COLOR& c = (keychar >= 32 && keychar < 127) ? mKeyColorAlphanumeric : mKeyColorOther;
	gr_color(c.red, c.green, c.blue, c.alpha);
	keyX += mKeyMarginX;
	keyY += mKeyMarginY;
	keyW -= mKeyMarginX * 2;
	keyH -= mKeyMarginY * 2;
	gr_fill(keyX, keyY, keyW, keyH);

	// key label
	FontResource* labelFont = mFont;
	string labelText;
	ImageResource* labelImage = NULL;
	if (keychar > 32 && keychar < 127) {
		// TODO: this will eventually need UTF-8 support
		labelText = (char) keychar;
		if (CtrlActive) {
			int ctrlchar = KeyCharToCtrlChar(keychar);
			if (ctrlchar != keychar)
				labelText = std::string("^") + (char)(ctrlchar + 64);
		}
		gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha);
	}
	else {
		// search for a special key label
		for (std::vector<KeyLabel>::iterator it = mKeyLabels.begin(); it != mKeyLabels.end(); ++it) {
			if (it->layout_from > 0 && it->layout_from != currentLayout)
				continue; // this label is for another layout
			if (it->key == key.key && it->layout_to == key.layout)
			{
				// found a label
				labelText = it->text;
				labelImage = it->image;
				break;
			}
		}
		labelFont = mSmallFont;
		gr_color(mFontColorSmall.red, mFontColorSmall.green, mFontColorSmall.blue, mFontColorSmall.alpha);
	}

	if (labelImage && labelImage->GetResource())
	{
		int w = labelImage->GetWidth();
		int h = labelImage->GetHeight();
		int x = keyX + (keyW - w) / 2;
		int y = keyY + (keyH - h) / 2;
		gr_blit(labelImage->GetResource(), 0, 0, w, h, x, y);
	}
	else if (!labelText.empty() && labelFont && labelFont->GetResource())
	{
		void* fontResource = labelFont->GetResource();
		int textW = twrpTruetype::gr_ttf_measureEx(labelText.c_str(), fontResource);
		int textH = labelFont->GetHeight();
		int textX = keyX + (keyW - textW) / 2;
		int textY = keyY + (keyH - textH) / 2;
		gr_textEx_scaleW(textX, textY, labelText.c_str(), fontResource, keyW, TOP_LEFT, 0);
	}

	// longpress key label (only if font is defined)
	keychar = key.longpresskey;
	if (keychar > 32 && keychar < 127 && mLongpressFont && mLongpressFont->GetResource()) {
		void* fontResource = mLongpressFont->GetResource();
		gr_color(mLongpressFontColor.red, mLongpressFontColor.green, mLongpressFontColor.blue, mLongpressFontColor.alpha);
		string text(1, keychar);
		int textW = twrpTruetype::gr_ttf_measureEx(text.c_str(), fontResource);
		int textX = keyX + keyW - longpressOffsetX - textW;
		int textY = keyY + longpressOffsetY;
		gr_textEx_scaleW(textX, textY, text.c_str(), fontResource, keyW, TOP_LEFT, 0);
	}
}

int GUIKeyboard::KeyCharToCtrlChar(int key)
{
	// convert upper and lower case to ctrl chars
	// Ctrl+A to Ctrl+_ (we don't support entering null bytes)
	if (key >= 65 && key <= 127 && key != 96)
		return key & 0x1f;
	return key; // pass on others (already ctrl chars, numbers, etc.) unchanged
}

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

	Layout& lay = layouts[currentLayout - 1];

	bool drawKeys = false;
	if (lay.keyboardImg && lay.keyboardImg->GetResource())
		// keyboard is image based
		gr_blit(lay.keyboardImg->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY);
	else {
		// keyboard is software drawn
		// fill background
		gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, mBackgroundColor.alpha);
		gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
		drawKeys = true;
	}

	// draw keys
	int y1 = 0;
	for (int row = 0; row < MAX_KEYBOARD_ROWS; ++row) {
		int rowY = mRenderY + y1;
		int rowH = lay.row_end_y[row] - y1;
		y1 = lay.row_end_y[row];
		int x1 = 0;
		for (int col = 0; col < MAX_KEYBOARD_KEYS; ++col) {
			Key& key = lay.keys[row][col];
			int keyY = rowY;
			int keyH = rowH;
			int keyX = mRenderX + x1;
			int keyW = key.end_x - x1;
			x1 = key.end_x;

			// Draw key for software drawn keyboard
			if (drawKeys)
				DrawKey(key, keyX, keyY, keyW, keyH);

			// Draw highlight for capslock
			if (hasCapsHighlight && lay.is_caps && CapsLockOn && key.layout > 0 && key.layout == lay.revert_layout) {
				gr_color(mCapsHighlightColor.red, mCapsHighlightColor.green, mCapsHighlightColor.blue, mCapsHighlightColor.alpha);
				gr_fill(keyX, keyY, keyW, keyH);
			}

			// Draw highlight for control
			if (hasCtrlHighlight && key.key == -KEY_LEFTCTRL && CtrlActive) {
				gr_color(mCtrlHighlightColor.red, mCtrlHighlightColor.green, mCtrlHighlightColor.blue, mCtrlHighlightColor.alpha);
				gr_fill(keyX, keyY, keyW, keyH);
			}

			// Highlight current key
			if (hasHighlight && &key == currentKey && highlightRenderCount != 0) {
				gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha);
				gr_fill(keyX, keyY, keyW, keyH);
			}
		}
	}

	if (!hasHighlight || highlightRenderCount == 0)
		mRendered = true;
	else if (highlightRenderCount > 0)
		highlightRenderCount--;
	return 0;
}

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)
{
	RenderObject::SetRenderPos(x, y, w, h);
	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
	return 0;
}

GUIKeyboard::Key* GUIKeyboard::HitTestKey(int x, int y)
{
	if (!IsInRegion(x, y))
		return NULL;

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

	Layout& lay = layouts[currentLayout - 1];

	// Find the correct row
	int row;
	for (row = 0; row < MAX_KEYBOARD_ROWS; ++row) {
		if (lay.row_end_y[row] > rely)
			break;
	}
	if (row == MAX_KEYBOARD_ROWS)
		return NULL;

	// Find the correct key (column)
	int col;
	int x1 = 0;
	for (col = 0; col < MAX_KEYBOARD_KEYS; ++col) {
		Key& key = lay.keys[row][col];
		if (x1 <= relx && relx < key.end_x && (key.key != 0 || key.layout != 0)) {
			// This is the key that was pressed!
			return &key;
		}
		x1 = key.end_x;
	}
	return NULL;
}

int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y)
{
	static int was_held = 0, startX = 0;

	if (!isConditionTrue())	 return -1;

	switch (state)
	{
	case TOUCH_START:
		was_held = 0;
		startX = x;
		currentKey = HitTestKey(x, y);
		if (currentKey)
			highlightRenderCount = -1;
		else
			highlightRenderCount = 0;
		mRendered = false;
		break;

	case TOUCH_DRAG:
		break;

	case TOUCH_RELEASE:
		// TODO: we might want to notify of key releases here
		if (x < startX - (mRenderW * 0.5)) {
			if (highlightRenderCount != 0) {
				highlightRenderCount = 0;
				mRendered = false;
			}
			PageManager::NotifyCharInput(KEYBOARD_SWIPE_LEFT);
			return 0;
		} else if (x > startX + (mRenderW * 0.5)) {
			if (highlightRenderCount != 0) {
				highlightRenderCount = 0;
				mRendered = false;
			}
			PageManager::NotifyCharInput(KEYBOARD_SWIPE_RIGHT);
			return 0;
		}
		// fall through
	case TOUCH_HOLD:
	case TOUCH_REPEAT:
		if (!currentKey) {
			if (highlightRenderCount != 0) {
				highlightRenderCount = 0;
				mRendered = false;
			}
			return 0;
		}

		if (highlightRenderCount != 0) {
			if (state == TOUCH_RELEASE)
				highlightRenderCount = 2;
			else
				highlightRenderCount = -1;
			mRendered = false;
		}

		if (HitTestKey(x, y) != currentKey) {
			// We dragged off of the starting key
			currentKey = NULL;
			if (highlightRenderCount != 0) {
				highlightRenderCount = 0;
				mRendered = false;
			}
			return 0;
		} else {
			Key& key = *currentKey;
			bool repeatKey = false;
			Layout& lay = layouts[currentLayout - 1];
			if (state == TOUCH_RELEASE && was_held == 0) {

#ifndef TW_NO_HAPTICS
				DataManager::Vibrate("tw_keyboard_vibrate");
#endif

				if (key.layout > 0) {
					// Switch layouts
					if (lay.is_caps && key.layout == lay.revert_layout && !CapsLockOn) {
						CapsLockOn = true; // Set the caps lock
					} else {
						CapsLockOn = false; // Unset the caps lock and change layouts
						currentLayout = key.layout;
					}
					mRendered = false;
				} else if (key.key == KEYBOARD_ACTION) {
					// Action
					highlightRenderCount = 0;
					// Send action notification
					PageManager::NotifyCharInput(key.key);
				} else if (key.key == -KEY_LEFTCTRL) {
					CtrlActive = !CtrlActive; // toggle Control key state
					mRendered = false; // render Ctrl key highlight
				} else if (key.key != 0) {
					// Regular key
					if (key.key > 0) {
						// ASCII code or character
						int keycode = key.key;
						if (CtrlActive) {
							CtrlActive = false;
							mRendered = false;
							keycode = KeyCharToCtrlChar(key.key);
						}
						PageManager::NotifyCharInput(keycode);
					} else {
						// Linux key code
						PageManager::NotifyKey(-key.key, true);
						PageManager::NotifyKey(-key.key, false);
					}
					if (!CapsLockOn && lay.is_caps) {
						// caps lock was not set, change layouts
						currentLayout = lay.revert_layout;
						mRendered = false;
					}
				}
			} else if (state == TOUCH_HOLD) {
				was_held = 1;
				if (key.longpresskey > 0) {
					// Long Press Key

#ifndef TW_NO_HAPTICS
					DataManager::Vibrate("tw_keyboard_vibrate");
#endif

					PageManager::NotifyCharInput(key.longpresskey);
				}
				else
					repeatKey = true;
			} else if (state == TOUCH_REPEAT) {
				was_held = 1;
				repeatKey = true;
			}
			if (repeatKey) {
				if (key.key == KEYBOARD_BACKSPACE) {
					// Repeat backspace
					PageManager::NotifyCharInput(key.key);
				}
				switch (key.key)
				{
					// Repeat arrows
					case -KEY_LEFT:
					case -KEY_RIGHT:
					case -KEY_UP:
					case -KEY_DOWN:
						PageManager::NotifyKey(-key.key, true);
						PageManager::NotifyKey(-key.key, false);
						break;
				}
			}
		}
		break;
	}

	return 0;
}

void GUIKeyboard::SetPageFocus(int inFocus)
{
	if (inFocus)
		CtrlActive = false;
}
