/*
        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/>.
*/

// input.cpp - GUIInput object

#include <linux/input.h>
#include <pthread.h>
#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"
#include "../data.hpp"

GUIInput::GUIInput(xml_node<>* node)
	: GUIObject(node)
{
	xml_attribute<>* attr;
	xml_node<>* child;

	mInputText = NULL;
	mAction = NULL;
	mBackground = NULL;
	mCursor = NULL;
	mFont = NULL;
	mRendered = false;
	HasMask = false;
	DrawCursor = false;
	isLocalChange = true;
	HasAllowed = false;
	HasDisabled = false;
	skipChars = scrollingX = mFontHeight = mFontY = lastX = 0;
	mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = MinLen = MaxLen = 0;
	mCursorLocation = -1; // -1 is always the end of the string
	CursorWidth = 3;
	ConvertStrToColor("black", &mBackgroundColor);
	ConvertStrToColor("white", &mCursorColor);

	if (!node)
		return;

	// Load text directly from the node
	mInputText = new GUIText(node);
	// Load action directly from the node
	mAction = new GUIAction(node);

	if (mInputText->Render() < 0)
	{
		delete mInputText;
		mInputText = NULL;
	}

	// Load the background
	child = node->first_node("background");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mBackground = PageManager::FindResource(attr->value());
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mBackgroundColor);
		}
	}
	if (mBackground && mBackground->GetResource())
	{
		mBackgroundW = gr_get_width(mBackground->GetResource());
		mBackgroundH = gr_get_height(mBackground->GetResource());
	}

	// Load the cursor color
	child = node->first_node("cursor");
	if (child)
	{
		attr = child->first_attribute("resource");
		if (attr)
			mCursor = PageManager::FindResource(attr->value());
		attr = child->first_attribute("color");
		if (attr)
		{
			std::string color = attr->value();
			ConvertStrToColor(color, &mCursorColor);
		}
		attr = child->first_attribute("hasfocus");
		if (attr)
		{
			std::string color = attr->value();
			SetInputFocus(atoi(color.c_str()));
		}
		attr = child->first_attribute("width");
		if (attr)
		{
			std::string cwidth = gui_parse_text(attr->value());
			CursorWidth = atoi(cwidth.c_str());
		}
	}
	DrawCursor = HasInputFocus;

	// 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());
			mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
		}
	}

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

	child = node->first_node("data");
	if (child)
	{
		attr = child->first_attribute("name");
		if (attr)
			mVariable = attr->value();
		attr = child->first_attribute("default");
		if (attr)
			DataManager::SetValue(mVariable, attr->value());
		attr = child->first_attribute("mask");
		if (attr) {
			mMask = attr->value();
			HasMask = true;
		}
		attr = child->first_attribute("maskvariable");
		if (attr)
			mMaskVariable = attr->value();
		else
			mMaskVariable = mVariable;
	}

	// Load input restrictions
	child = node->first_node("restrict");
	if (child)
	{
		attr = child->first_attribute("minlen");
		if (attr) {
			std::string attrib = attr->value();
			MinLen = atoi(attrib.c_str());
		}
		attr = child->first_attribute("maxlen");
		if (attr) {
			std::string attrib = attr->value();
			MaxLen = atoi(attrib.c_str());
		}
		attr = child->first_attribute("allow");
		if (attr) {
			HasAllowed = true;
			AllowedList = attr->value();
		}
		attr = child->first_attribute("disable");
		if (attr) {
			HasDisabled = true;
			DisabledList = attr->value();
		}
	}

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

	if (mInputText && mFontHeight && mFontHeight < (unsigned)mRenderH) {
		mFontY = ((mRenderH - mFontHeight) / 2) + mRenderY;
		mInputText->SetRenderPos(mRenderX, mFontY);
	} else
		mFontY = mRenderY;

	if (mInputText)
		mInputText->SetMaxWidth(mRenderW);

	isLocalChange = false;
	HandleTextLocation(-3);
}

GUIInput::~GUIInput()
{
	if (mInputText)	 	delete mInputText;
	if (mBackground)	delete mBackground;
	if (mCursor)		delete mCursor;
	if (mAction)		delete mAction;
}

int GUIInput::HandleTextLocation(int x)
{
	int textWidth;
	string displayValue, originalValue, insertChar;
	void* fontResource = NULL;

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

	DataManager::GetValue(mVariable, originalValue);
	displayValue = originalValue;
	if (HasMask) {
		int index, string_size = displayValue.size();
		string maskedValue;
		for (index=0; index<string_size; index++)
			maskedValue += mMask;
		displayValue = maskedValue;
	}
	textWidth = gr_measureEx(displayValue.c_str(), fontResource);
	if (textWidth <= mRenderW) {
		lastX = x;
		scrollingX = 0;
		skipChars = 0;
		mInputText->SkipCharCount(skipChars);
		mRendered = false;
		return 0;
	}

	if (skipChars && skipChars < displayValue.size())
		displayValue.erase(0, skipChars);

	textWidth = gr_measureEx(displayValue.c_str(), fontResource);
	mRendered = false;

	int deltaX, deltaText, newWidth;

	if (x < -1000) {
		// No change in scrolling
		if (x == -1003)
			mCursorLocation = -1;

		if (mCursorLocation == -1) {
			displayValue = originalValue;
			skipChars = 0;
			textWidth = gr_measureEx(displayValue.c_str(), fontResource);
			while (textWidth > mRenderW) {
				displayValue.erase(0, 1);
				skipChars++;
				textWidth = gr_measureEx(displayValue.c_str(), fontResource);
			}
			scrollingX = mRenderW - textWidth;
			mInputText->SkipCharCount(skipChars);
		} else if (x == -1001) {
			// Added a new character
			int adjust_scrollingX = 0;
			string cursorLocate;

			cursorLocate = displayValue;
			cursorLocate.resize(mCursorLocation);
			textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
			while (textWidth > mRenderW) {
				skipChars++;
				mCursorLocation--;
				cursorLocate.erase(0, 1);
				textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
				adjust_scrollingX = -1;
			}
			if (adjust_scrollingX) {
				scrollingX = mRenderW - textWidth;
				if (scrollingX < 0)
					scrollingX = 0;
			}
			mInputText->SkipCharCount(skipChars);
		} else if (x == -1002) {
			// Deleted a character
			while (-1) {
				if (skipChars == 0) {
					scrollingX = 0;
					mInputText->SkipCharCount(skipChars);
					return 0;
				}
				insertChar = originalValue.substr(skipChars - 1, 1);
				displayValue.insert(0, insertChar);
				newWidth = gr_measureEx(displayValue.c_str(), fontResource);
				deltaText = newWidth - textWidth;
				if (newWidth > mRenderW) {
					scrollingX = mRenderW - textWidth;
					if (scrollingX < 0)
						scrollingX = 0;
					mInputText->SkipCharCount(skipChars);
					return 0;
				} else {
					textWidth = newWidth;
					skipChars--;
					mCursorLocation++;
				}
			}
		} else
			LOGINFO("GUIInput::HandleTextLocation -> We really shouldn't ever get here...\n");
	} else if (x > lastX) {
		// Dragging to right, scrolling left
		while (-1) {
			deltaX = x - lastX + scrollingX;
			if (skipChars == 0 || deltaX == 0) {
				scrollingX = 0;
				lastX = x;
				mInputText->SkipCharCount(skipChars);
				return 0;
			}
			insertChar = originalValue.substr(skipChars - 1, 1);
			displayValue.insert(0, insertChar);
			newWidth = gr_measureEx(displayValue.c_str(), fontResource);
			deltaText = newWidth - textWidth;
			if (deltaText < deltaX) {
				lastX += deltaText;
				textWidth = newWidth;
				skipChars--;
			} else {
				scrollingX = deltaX;
				lastX = x;
				mInputText->SkipCharCount(skipChars);
				return 0;
			}
		}
	} else if (x < lastX) {
		// Dragging to left, scrolling right
		if (textWidth <= mRenderW) {
			lastX = x;
			scrollingX = mRenderW - textWidth;
			return 0;
		}
		if (scrollingX) {
			deltaX = lastX - x;
			if (scrollingX > deltaX) {
				scrollingX -= deltaX;
				lastX = x;
				return 0;
			} else {
				lastX -= deltaX;
				scrollingX = 0;
			}
		}
		while (-1) {
			deltaX = lastX - x;
			displayValue.erase(0, 1);
			skipChars++;
			newWidth = gr_measureEx(displayValue.c_str(), fontResource);
			deltaText = textWidth - newWidth;
			if (newWidth <= mRenderW) {
				scrollingX = mRenderW - newWidth;
				lastX = x;
				mInputText->SkipCharCount(skipChars);
				return 0;
			}
			if (deltaText < deltaX) {
				lastX -= deltaText;
				textWidth = newWidth;
			} else {
				scrollingX = deltaText - deltaX;
				lastX = x;
				mInputText->SkipCharCount(skipChars);
				return 0;
			}
		}
	}
	return 0;
}

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

	void* fontResource = NULL;
	if (mFont)  fontResource = mFont->GetResource();

	// First step, fill background
	gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255);
	gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);

	// Next, render the background resource (if it exists)
	if (mBackground && mBackground->GetResource())
	{
		mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2);
		mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2);
		gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY);
	}

	int ret = 0;

	// Render the text
	mInputText->SetRenderPos(mRenderX + scrollingX, mFontY);
	mInputText->SetMaxWidth(mRenderW - scrollingX);
	if (mInputText)	 ret = mInputText->Render();
	if (ret < 0)		return ret;

	if (HasInputFocus && DrawCursor) {
		// Render the cursor
		string displayValue;
		int cursorX;
		DataManager::GetValue(mVariable, displayValue);
		if (HasMask) {
			int index, string_size = displayValue.size();
			string maskedValue;
			for (index=0; index<string_size; index++)
				maskedValue += mMask;
			displayValue = maskedValue;
		}
		if (displayValue.size() == 0) {
			skipChars = 0;
			mCursorLocation = -1;
			cursorX = mRenderX;
		} else {
			if (skipChars && skipChars < displayValue.size()) {
				displayValue.erase(0, skipChars);
			}
			if (mCursorLocation == 0) {
				// Cursor is at the beginning
				cursorX = mRenderX;
			} else if (mCursorLocation > 0) {
				// Cursor is in the middle
				if (displayValue.size() > (unsigned)mCursorLocation) {
					string cursorDisplay;

					cursorDisplay = displayValue;
					cursorDisplay.resize(mCursorLocation);
					cursorX = gr_measureEx(cursorDisplay.c_str(), fontResource) + mRenderX;
				} else {
					// Cursor location is after the end of the text  - reset to -1
					mCursorLocation = -1;
					cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
				}
			} else {
				// Cursor is at the end (-1)
				cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX;
			}
		}
		cursorX += scrollingX;
		// Make sure that the cursor doesn't go past the boundaries of the box
		if (cursorX + (int)CursorWidth > mRenderX + mRenderW)
			cursorX = mRenderX + mRenderW - CursorWidth;

		// Set the color for the cursor
		gr_color(mCursorColor.red, mCursorColor.green, mCursorColor.blue, 255);
		gr_fill(cursorX, mFontY, CursorWidth, mFontHeight);
	}

	mRendered = true;
	return ret;
}

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

	int ret = 0;

	if (mInputText)		 ret = mInputText->Update();
	if (ret < 0)			return ret;

	return ret;
}

int GUIInput::GetSelection(int x, int y)
{
	if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH) return -1;
	return (x - mRenderX);
}

int GUIInput::NotifyTouch(TOUCH_STATE state, int x, int y)
{
	static int startSelection = -1;
	int textWidth;
	string displayValue, originalValue;
	void* fontResource = NULL;

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

	if (!isConditionTrue())
		return -1;

	if (!HasInputFocus) {
		if (state != TOUCH_RELEASE)
			return 0; // Only change focus if touch releases within the input box
		if (GetSelection(x, y) >= 0) {
			// When changing focus, we don't scroll or change the cursor location
			PageManager::SetKeyBoardFocus(0);
			PageManager::NotifyKeyboard(0);
			SetInputFocus(1);
			DrawCursor = true;
			mRendered = false;
		}
	} else {
		switch (state) {
		case TOUCH_HOLD:
		case TOUCH_REPEAT:
			break;
		case TOUCH_START:
			startSelection = GetSelection(x,y);
			lastX = x;
			DrawCursor = false;
			mRendered = false;
			break;

		case TOUCH_DRAG:
			// Check if we dragged out of the selection window
			if (GetSelection(x, y) == -1) {
				lastX = 0;
				break;
			}

			DrawCursor = false;

			// Provide some debounce on initial touches
			if (startSelection != -1 && abs(x - lastX) < 6) {
				break;
			}

			startSelection = -1;
			if (lastX != x)
				HandleTextLocation(x);
			break;

		case TOUCH_RELEASE:
			// We've moved the cursor location
			int relativeX = x - mRenderX;

			mRendered = false;
			DrawCursor = true;
			DataManager::GetValue(mVariable, displayValue);
			if (HasMask) {
				int index, string_size = displayValue.size();
				string maskedValue;
				for (index=0; index<string_size; index++)
					maskedValue += mMask;
				displayValue = maskedValue;
			}
			if (displayValue.size() == 0) {
				skipChars = 0;
				mCursorLocation = -1;
				return 0;
			} else if (skipChars && skipChars < displayValue.size()) {
				displayValue.erase(0, skipChars);
			}

			string cursorString;
			int cursorX = 0;
			unsigned index = 0;

			for(index=0; index<displayValue.size(); index++)
			{
				cursorString = displayValue.substr(0, index);
				cursorX = gr_measureEx(cursorString.c_str(), fontResource) + mRenderX;
				if (cursorX > x) {
					if (index > 0)
						mCursorLocation = index - 1;
					else
						mCursorLocation = index;
					return 0;
				}
			}
			mCursorLocation = -1;
			break;
		}
	}
	return 0;
}

int GUIInput::NotifyVarChange(const std::string& varName, const std::string& value)
{
	GUIObject::NotifyVarChange(varName, value);

	if (varName == mVariable && !isLocalChange) {
		HandleTextLocation(-1003);
		return 0;
	}
	return 0;
}

int GUIInput::NotifyKeyboard(int key)
{
	string variableValue;

	if (HasInputFocus) {
		if (key == KEYBOARD_BACKSPACE) {
			//Backspace
			DataManager::GetValue(mVariable, variableValue);
			if (variableValue.size() > 0 && (mCursorLocation + skipChars != 0 || mCursorLocation == -1)) {
				if (mCursorLocation == -1) {
					variableValue.resize(variableValue.size() - 1);
				} else {
					variableValue.erase(mCursorLocation + skipChars - 1, 1);
					if (mCursorLocation > 0)
						mCursorLocation--;
					else if (skipChars > 0)
						skipChars--;
				}
				isLocalChange = true;
				DataManager::SetValue(mVariable, variableValue);
				isLocalChange = false;

				if (HasMask) {
					int index, string_size = variableValue.size();
					string maskedValue;
					for (index=0; index<string_size; index++)
						maskedValue += mMask;
					DataManager::SetValue(mMaskVariable, maskedValue);
				}
				HandleTextLocation(-1002);
			}
		} else if (key == KEYBOARD_SWIPE_LEFT) {
			// Delete all
			isLocalChange = true;
			if (mCursorLocation == -1) {
				DataManager::SetValue (mVariable, "");
				if (HasMask)
					DataManager::SetValue(mMaskVariable, "");
				mCursorLocation = -1;
			} else {
				DataManager::GetValue(mVariable, variableValue);
				variableValue.erase(0, mCursorLocation + skipChars);
				DataManager::SetValue(mVariable, variableValue);
				if (HasMask) {
					DataManager::GetValue(mMaskVariable, variableValue);
					variableValue.erase(0, mCursorLocation + skipChars);
					DataManager::SetValue(mMaskVariable, variableValue);
				}
				mCursorLocation = 0;
			}
			skipChars = 0;
			scrollingX = 0;
			mInputText->SkipCharCount(skipChars);
			isLocalChange = false;
			mRendered = false;
			return 0;
		} else if (key == KEYBOARD_ARROW_LEFT) {
			if (mCursorLocation == 0 && skipChars == 0)
				return 0; // we're already at the beginning
			if (mCursorLocation == -1) {
				DataManager::GetValue(mVariable, variableValue);
				if (variableValue.size() == 0)
					return 0;
				mCursorLocation = variableValue.size() - skipChars - 1;
			} else if (mCursorLocation == 0) {
				skipChars--;
				HandleTextLocation(-1002);
			} else {
				mCursorLocation--;
				HandleTextLocation(-1002);
			}
			mRendered = false;
			return 0;
		} else if (key == KEYBOARD_ARROW_RIGHT) {
			if (mCursorLocation == -1)
				return 0; // we're already at the end
			mCursorLocation++;
			DataManager::GetValue(mVariable, variableValue);
			if (variableValue.size() <= mCursorLocation + skipChars)
				mCursorLocation = -1;
			HandleTextLocation(-1001);
			mRendered = false;
			return 0;
		} else if (key == KEYBOARD_HOME || key == KEYBOARD_ARROW_UP) {
			DataManager::GetValue(mVariable, variableValue);
			if (variableValue.size() == 0)
				return 0;
			mCursorLocation = 0;
			skipChars = 0;
			mRendered = false;
			HandleTextLocation(-1002);
			return 0;
		} else if (key == KEYBOARD_END || key == KEYBOARD_ARROW_DOWN) {
			mCursorLocation = -1;
			mRendered = false;
			HandleTextLocation(-1003);
			return 0;
		} else if (key < KEYBOARD_SPECIAL_KEYS && key > 0) {
			// Regular key
			if (HasAllowed && AllowedList.find((char)key) == string::npos) {
				return 0;
			}
			if (HasDisabled && DisabledList.find((char)key) != string::npos) {
				return 0;
			}
			DataManager::GetValue(mVariable, variableValue);
			if (MaxLen != 0 && variableValue.size() >= MaxLen) {
				return 0;
			}
			if (mCursorLocation == -1) {
				variableValue += key;
			} else {
				const char newchar = (char)key;
				const char* a = &newchar;
				string newstring = a;
				newstring.resize(1);
				variableValue.insert(mCursorLocation + skipChars, newstring);
				mCursorLocation++;
			}
			isLocalChange = true;
			DataManager::SetValue(mVariable, variableValue);
			HandleTextLocation(-1001);
			isLocalChange = false;

			if (HasMask) {
				int index, string_size = variableValue.size();
				string maskedValue;
				for (index=0; index<string_size; index++)
					maskedValue += mMask;
				DataManager::SetValue(mMaskVariable, maskedValue);
			}
		} else if (key == KEYBOARD_ACTION) {
			// Action
			DataManager::GetValue(mVariable, variableValue);
			if (mAction) {
				unsigned inputLen = variableValue.length();
				if (inputLen < MinLen)
					return 0;
				else if (MaxLen != 0 && inputLen > MaxLen)
					return 0;
				else
					return (mAction ? mAction->NotifyTouch(TOUCH_RELEASE, mRenderX, mRenderY) : 1);
			}
		}
		return 0;
	} else {
		if (key == 0) {
			// Somewhat ugly hack-ish way to tell the box to redraw after losing focus to remove the cursor
			mRendered = false;
			return 1;
		}
	}
	return 1;
}
