/*
	Copyright 2017 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/types.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>

#include <string>
#include <sstream>

extern "C" {
#include "../twcommon.h"
}
#include "minuitwrp/minui.h"
#include "../twrp-functions.hpp"
#include "rapidxml.hpp"
#include "objects.hpp"

GUIPatternPassword::GUIPatternPassword(xml_node<>* node)
	: GUIObject(node)
{
	xml_node<>* child;

	// 3x3 is the default.
	mGridSize = 3;
	mDots = new Dot[mGridSize * mGridSize];
	mConnectedDots = new int[mGridSize * mGridSize];

	ResetActiveDots();
	mTrackingTouch = false;
	mNeedRender = true;

	ConvertStrToColor("blue", &mDotColor);
	ConvertStrToColor("white", &mActiveDotColor);
	ConvertStrToColor("blue", &mLineColor);

	mDotImage = mActiveDotImage = NULL;
	mDotCircle = mActiveDotCircle = NULL;
	mDotRadius = 50;
	mLineWidth = 35;

	mAction = NULL;
	mUpdate = 0;

	if (!node)
		return;

	LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH, &mPlacement);

	mAction = new GUIAction(node);

	child = FindNode(node, "dot");
	if (child)
	{
		mDotColor = LoadAttrColor(child, "color", mDotColor);
		mActiveDotColor = LoadAttrColor(child, "activecolor", mActiveDotColor);
		mDotRadius = LoadAttrIntScaleX(child, "radius", mDotRadius);

		mDotImage = LoadAttrImage(child, "image");
		mActiveDotImage = LoadAttrImage(child, "activeimage");
	}

	child = FindNode(node, "line");
	if (child)
	{
		mLineColor = LoadAttrColor(child, "color", mLineColor);
		mLineWidth = LoadAttrIntScaleX(child, "width", mLineWidth);
	}

	child = FindNode(node, "data");
	if (child)
		mPassVar = LoadAttrString(child, "name", "");

	child = FindNode(node, "size");
	if (child) {
		mSizeVar = LoadAttrString(child, "name", "");

		// Use the configured default, if set.
		size_t size = LoadAttrInt(child, "default", mGridSize);
		Resize(size);
	}

	if (!mDotImage || !mDotImage->GetResource() || !mActiveDotImage || !mActiveDotImage->GetResource())
	{
		mDotCircle = gr_render_circle(mDotRadius, mDotColor.red, mDotColor.green, mDotColor.blue, mDotColor.alpha);
		mActiveDotCircle = gr_render_circle(mDotRadius/2, mActiveDotColor.red, mActiveDotColor.green, mActiveDotColor.blue, mActiveDotColor.alpha);
	}
	else if (mDotImage && mDotImage->GetResource())
		mDotRadius = mDotImage->GetWidth()/2;

	SetRenderPos(mRenderX, mRenderY, mRenderW, mRenderH);
}

GUIPatternPassword::~GUIPatternPassword()
{
	delete mDotImage;
	delete mActiveDotImage;
	delete mAction;

	delete[] mDots;
	delete[] mConnectedDots;

	if (mDotCircle)
		gr_free_surface(mDotCircle);

	if (mActiveDotCircle)
		gr_free_surface(mActiveDotCircle);
}

void GUIPatternPassword::ResetActiveDots()
{
	mConnectedDotsLen = 0;
	mCurLineX = mCurLineY = -1;
	for (size_t i = 0; i < mGridSize * mGridSize; ++i)
		mDots[i].active = false;
}

int GUIPatternPassword::SetRenderPos(int x, int y, int w, int h)
{
	mRenderX = x;
	mRenderY = y;

	if (w || h)
	{
		mRenderW = w;
		mRenderH = h;

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

	CalculateDotPositions();
	return 0;
}

void GUIPatternPassword::CalculateDotPositions(void)
{
	const int num_gaps = mGridSize - 1;
	const int step_x = (mRenderW - mDotRadius*2) / num_gaps;
	const int step_y = (mRenderH - mDotRadius*2) / num_gaps;
	int x = mRenderX;
	int y = mRenderY;

	/* Order is important for keyphrase generation:
	 *
	 *   0    1    2    3 ...  n-1
	 *   n  n+1  n+2  n+3 ... 2n-1
	 *  2n 2n+1 2n+2 2n+3 ... 3n-1
	 *  3n 3n+1 3n+2 3n+3 ... 4n-1
	 *   :  :    :    :
	 *                       n*n-1
	 */

	for (size_t r = 0; r < mGridSize; ++r)
	{
		for (size_t c = 0; c < mGridSize; ++c)
		{
			mDots[mGridSize*r + c].x = x;
			mDots[mGridSize*r + c].y = y;
			x += step_x;
		}
		x = mRenderX;
		y += step_y;
	}
}

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

	gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha);
	for (size_t i = 1; i < mConnectedDotsLen; ++i) {
		const Dot& dp = mDots[mConnectedDots[i-1]];
		const Dot& dc = mDots[mConnectedDots[i]];
		gr_line(dp.x + mDotRadius, dp.y + mDotRadius, dc.x + mDotRadius, dc.y + mDotRadius, mLineWidth);
	}

	if (mConnectedDotsLen > 0 && mTrackingTouch) {
		const Dot& dc = mDots[mConnectedDots[mConnectedDotsLen-1]];
		gr_line(dc.x + mDotRadius, dc.y + mDotRadius, mCurLineX, mCurLineY, mLineWidth);
	}

	for (size_t i = 0; i < mGridSize * mGridSize; ++i) {
		if (mDotCircle) {
			gr_blit(mDotCircle, 0, 0, gr_get_width(mDotCircle), gr_get_height(mDotCircle), mDots[i].x, mDots[i].y);
			if (mDots[i].active) {
				gr_blit(mActiveDotCircle, 0, 0, gr_get_width(mActiveDotCircle), gr_get_height(mActiveDotCircle), mDots[i].x + mDotRadius/2, mDots[i].y + mDotRadius/2);
			}
		} else {
			if (mDots[i].active && mActiveDotImage && mActiveDotImage->GetResource()) {
				gr_blit(mActiveDotImage->GetResource(), 0, 0, mActiveDotImage->GetWidth(), mActiveDotImage->GetHeight(),
						mDots[i].x + (mDotRadius - mActiveDotImage->GetWidth()/2), mDots[i].y + (mDotRadius - mActiveDotImage->GetHeight()/2));
			} else if (mDotImage && mDotImage->GetResource()) {
				gr_blit(mDotImage->GetResource(), 0, 0, mDotImage->GetWidth(), mDotImage->GetHeight(), mDots[i].x, mDots[i].y);
			}
		}
	}
	return 0;
}

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

	int res = mNeedRender ? 2 : 1;
	mNeedRender = false;
	return res;
}

void GUIPatternPassword::Resize(size_t n) {
	if (mGridSize == n)
		return;

	delete[] mDots;
	delete[] mConnectedDots;

	mGridSize = n;
	mDots = new Dot[n*n];
	mConnectedDots = new int[n*n];

	ResetActiveDots();
	CalculateDotPositions();
	mTrackingTouch = false;
	mNeedRender = true;
}

static int pow(int x, int i)
{
	int result = 1;
	if (i<0)
		return 0;
	while(i-- > 0)
		result *= x;
	return result;
}

static bool IsInCircle(int x, int y, int ox, int oy, int r)
{
	return pow(x - ox, 2) + pow(y - oy, 2) <= pow(r, 2);
}

int GUIPatternPassword::InDot(int x, int y)
{
	for (size_t i = 0; i < mGridSize * mGridSize; ++i) {
		if (IsInCircle(x, y, mDots[i].x + mDotRadius, mDots[i].y + mDotRadius, mDotRadius*3))
			return i;
	}
	return -1;
}

bool GUIPatternPassword::DotUsed(int dot_idx)
{
	for (size_t i = 0; i < mConnectedDotsLen; ++i) {
		if (mConnectedDots[i] == dot_idx)
			return true;
	}
	return false;
}

void GUIPatternPassword::ConnectDot(int dot_idx)
{
	if (mConnectedDotsLen >= mGridSize * mGridSize)
	{
		LOGERR("mConnectedDots in GUIPatternPassword has overflown!\n");
		return;
	}

	mConnectedDots[mConnectedDotsLen++] = dot_idx;
	mDots[dot_idx].active = true;
}

void GUIPatternPassword::ConnectIntermediateDots(int next_dot_idx)
{
	if (mConnectedDotsLen == 0)
		return;

	const int prev_dot_idx = mConnectedDots[mConnectedDotsLen-1];

	int px = prev_dot_idx % mGridSize;
	int py = prev_dot_idx / mGridSize;

	int nx = next_dot_idx % mGridSize;
	int ny = next_dot_idx / mGridSize;

	/*
	 * We connect all dots that are in a straight line between the previous dot
	 * and the next one. This is simple for 3x3, but is more complicated for
	 * larger grids.
	 *
	 * Weirdly, Android doesn't do the logical thing when it comes to connecting
	 * dots between two points. Rather than simply adding all points that lie
	 * on the line between the start and end points, it instead only connects
	 * dots that are adjacent in only three directions -- horizontal, vertical
	 * and diagonal (45°).
	 *
	 * So we can just iterate over the correct axes, taking care to ensure that
	 * the order in which the intermediate points are added to the pattern is
	 * correct.
	 */

	int x = px;
	int y = py;

	int Dx = (nx > px) ? 1 : -1;
	int Dy = (ny > py) ? 1 : -1;

	// Vertical lines.
	if (px == nx)
		Dx = 0;

	// Horizontal lines.
	else if (py == ny)
		Dy = 0;

	// Diagonal lines (|∆x| = |∆y|).
	else if (abs(px - nx) == abs(py - ny))
		;

	// No valid intermediate dots.
	else
		return;

	// Iterate along axis, adding dots in the correct order.
	while ((Dy == 0 || y != ny - Dy) && (Dx == 0 || x != nx - Dx)) {
		x += Dx;
		y += Dy;

		int idx = mGridSize * y + x;
		if (!DotUsed(idx))
			ConnectDot(idx);
	}
}

int GUIPatternPassword::NotifyTouch(TOUCH_STATE state, int x, int y)
{
	if (!isConditionTrue())
		return -1;

	switch (state)
	{
		case TOUCH_START:
		{
			const int dot_idx = InDot(x, y);
			if (dot_idx == -1)
				break;

			mTrackingTouch = true;
			ResetActiveDots();
			ConnectDot(dot_idx);

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

			mCurLineX = x;
			mCurLineY = y;
			mNeedRender = true;
			break;
		}
		case TOUCH_DRAG:
		{
			if (!mTrackingTouch)
				break;

			const int dot_idx = InDot(x, y);
			if (dot_idx != -1 && !DotUsed(dot_idx))
			{
				ConnectIntermediateDots(dot_idx);
				ConnectDot(dot_idx);

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

			}

			mCurLineX = x;
			mCurLineY = y;
			mNeedRender = true;
			break;
		}
		case TOUCH_RELEASE:
		{
			if (!mTrackingTouch)
				break;

			mNeedRender = true;
			mTrackingTouch = false;
			PatternDrawn();
			ResetActiveDots();
			break;
		}
		default:
			break;
	}
	return 0;
}

int GUIPatternPassword::NotifyVarChange(const std::string& varName, const std::string& value)
{
	if (!isConditionTrue())
		return 0;

	if (varName == mSizeVar) {
		Resize(atoi(value.c_str()));
		mUpdate = true;
	}
	return 0;
}

static unsigned int getSDKVersion(void) {
	unsigned int sdkver = 23;
	string sdkverstr = TWFunc::System_Property_Get("ro.build.version.sdk");
	if (!sdkverstr.empty()) {
		sdkver = (unsigned int)strtoull(sdkverstr.c_str(), NULL, 10);
		sdkver = (sdkver != 0) ? sdkver : 23;
	}
	LOGINFO("sdk version is %u\n", sdkver);
	return sdkver;
}

std::string GUIPatternPassword::GeneratePassphrase()
{
	char pattern[mConnectedDotsLen];
	for (size_t i = 0; i < mConnectedDotsLen; i++) {
		pattern[i] = (char) mConnectedDots[i];
	}

	std::stringstream pass;
	char buffer[3] = {0};

	if ((mGridSize == 3) || (getSDKVersion() >= 23)) {
		// Marshmallow uses a consistent method
		for (size_t i = 0; i < mConnectedDotsLen; i++) {
			buffer[0] = (pattern[i] & 0xff) + '1';
			pass << std::string(buffer);
		}
	} else {
		/*
		 * Okay, rant time for pre-Marshmallow ROMs.
		 * It turns out that Android and CyanogenMod have *two* separate methods
		 * for generating passphrases from patterns. This is a legacy issue, as
		 * Android only supports 3x3 grids, and so we need to support both.
		 * Luckily, CyanogenMod is in the same boat as us and needs to support
		 * Android's 3x3 encryption style.
		 *
		 * In order to generate a 3x3 passphrase, add 1 to each dot index
		 * and concatenate the string representation of the integers. No
		 * padding should be added.
		 *
		 * For *all* other NxN passphrases (until a 16x16 grid comes along),
		 * they are generated by taking "%.2x" for each dot index and
		 * concatenating the results (without adding 1).
		 */
		for (size_t i = 0; i < mConnectedDotsLen; i++) {
			snprintf(buffer, 3, "%.2x", pattern[i] & 0xff);
			pass << std::string(buffer);
		}
	}

	return pass.str();
}

void GUIPatternPassword::PatternDrawn()
{
	if (!mPassVar.empty() && mConnectedDotsLen > 0)
		DataManager::SetValue(mPassVar, GeneratePassphrase());

	if (mAction)
		mAction->doActions();
}
