/*
	Copyright 2013 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 <string.h>

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

#include "rapidxml.hpp"
#include "objects.hpp"
#include "../data.hpp"

const float SCROLLING_SPEED_DECREMENT = 0.9; // friction
const int SCROLLING_FLOOR = 2; // minimum pixels for scrolling to stop
const float SCROLLING_SPEED_LIMIT = 2.5; // maximum number of items to scroll per update

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

	firstDisplayedItem = mItemSpacing = mFontHeight = mSeparatorH = y_offset = scrollingSpeed = 0;
	maxIconWidth = maxIconHeight =  mHeaderIconHeight = mHeaderIconWidth = 0;
	mHeaderSeparatorH = mHeaderH = actualItemHeight = 0;
	mHeaderIsStatic = false;
	mBackground = mHeaderIcon = NULL;
	mFont = NULL;
	mBackgroundW = mBackgroundH = 0;
	mFastScrollW = mFastScrollLineW = mFastScrollRectW = mFastScrollRectH = 0;
	lastY = last2Y = fastScroll = 0;
	mUpdate = 0;
	touchDebounce = 6;
	ConvertStrToColor("black", &mBackgroundColor);
	ConvertStrToColor("black", &mHeaderBackgroundColor);
	ConvertStrToColor("black", &mSeparatorColor);
	ConvertStrToColor("black", &mHeaderSeparatorColor);
	ConvertStrToColor("white", &mFontColor);
	ConvertStrToColor("white", &mHeaderFontColor);
	ConvertStrToColor("white", &mFastScrollLineColor);
	ConvertStrToColor("white", &mFastScrollRectColor);
	hasHighlightColor = false;
	selectedItem = NO_ITEM;

	// Load header text
	child = node->first_node("text");
	if (child)  mHeaderText = child->value();
	// Simple way to check for static state
	mLastHeaderValue = gui_parse_text(mHeaderText);
	mHeaderIsStatic = (mLastHeaderValue == mHeaderText);

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

	child = node->first_node("background");
	if (child)
	{
		mBackground = LoadAttrImage(child, "resource");
		mBackgroundColor = LoadAttrColor(child, "color");
	}

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

	// Load the font, and possibly override the color
	child = node->first_node("font");
	if (child)
	{
		mFont = LoadAttrFont(child, "resource");
		mFontColor = LoadAttrColor(child, "color");
		mFontHighlightColor = LoadAttrColor(child, "highlightcolor", mFontColor);
		mItemSpacing = LoadAttrIntScaleY(child, "spacing");
	}

	// Load the separator if it exists
	child = node->first_node("separator");
	if (child)
	{
		mSeparatorColor = LoadAttrColor(child, "color");
		mSeparatorH = LoadAttrIntScaleY(child, "height");
	}

	// Fast scroll
	child = node->first_node("fastscroll");
	if (child)
	{
		mFastScrollLineColor = LoadAttrColor(child, "linecolor");
		mFastScrollRectColor = LoadAttrColor(child, "rectcolor");

		mFastScrollW = LoadAttrIntScaleX(child, "w");
		mFastScrollLineW = LoadAttrIntScaleX(child, "linew");
		mFastScrollRectW = LoadAttrIntScaleX(child, "rectw");
		mFastScrollRectH = LoadAttrIntScaleY(child, "recth");
	}

	// Retrieve the line height
	mFontHeight = mFont->GetHeight();
	actualItemHeight = mFontHeight + mItemSpacing + mSeparatorH;

	// Load the header if it exists
	child = node->first_node("header");
	if (child)
	{
		mHeaderH = mFontHeight;
		mHeaderIcon = LoadAttrImage(child, "icon");
		mHeaderBackgroundColor = LoadAttrColor(child, "background", mBackgroundColor);
		mHeaderFontColor = LoadAttrColor(child, "textcolor", mFontColor);
		mHeaderSeparatorColor = LoadAttrColor(child, "separatorcolor", mSeparatorColor);
		mHeaderSeparatorH = LoadAttrIntScaleY(child, "separatorheight", mSeparatorH);

		if (mHeaderIcon && mHeaderIcon->GetResource())
		{
			mHeaderIconWidth = mHeaderIcon->GetWidth();
			mHeaderIconHeight = mHeaderIcon->GetHeight();
			if (mHeaderIconHeight > mHeaderH)
				mHeaderH = mHeaderIconHeight;
			if (mHeaderIconWidth > maxIconWidth)
				maxIconWidth = mHeaderIconWidth;
		}

		mHeaderH += mItemSpacing + mHeaderSeparatorH;
		if (mHeaderH < actualItemHeight)
			mHeaderH = actualItemHeight;
	}

	if (actualItemHeight / 3 > 6)
		touchDebounce = actualItemHeight / 3;

	if (mBackground && mBackground->GetResource())
	{
		mBackgroundW = mBackground->GetWidth();
		mBackgroundH = mBackground->GetHeight();
	}
}

GUIScrollList::~GUIScrollList()
{
}

void GUIScrollList::SetMaxIconSize(int w, int h)
{
	if (w > maxIconWidth)
		maxIconWidth = w;
	if (h > maxIconHeight)
		maxIconHeight = h;
	if (maxIconHeight > mFontHeight) {
		actualItemHeight = maxIconHeight + mItemSpacing + mSeparatorH;
		if (mHeaderH > 0 && actualItemHeight > mHeaderH)
			mHeaderH = actualItemHeight;
	}
}

void GUIScrollList::SetVisibleListLocation(size_t list_index)
{
	// This will make sure that the item indicated by list_index is visible on the screen
	size_t lines = GetDisplayItemCount(), listSize = GetItemCount();

	if (list_index <= (unsigned)firstDisplayedItem) {
		// list_index is above the currently displayed items, put the selected item at the very top
		firstDisplayedItem = list_index;
		y_offset = 0;
	} else if (list_index >= firstDisplayedItem + lines) {
		// list_index is below the currently displayed items, put the selected item at the very bottom
		firstDisplayedItem = list_index - lines + 1;
		if (GetDisplayRemainder() != 0) {
			// There's a partial row displayed, set the scrolling offset so that the selected item really is at the very bottom
			firstDisplayedItem--;
			y_offset = GetDisplayRemainder() - actualItemHeight;
		} else {
			// There's no partial row so zero out the offset
			y_offset = 0;
		}
	}
	scrollingSpeed = 0; // stop kinetic scrolling on setting visible location
	mUpdate = 1;
}

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

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

	// don't paint outside of the box
	gr_clip(mRenderX, mRenderY, mRenderW, mRenderH);

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

	// This tells us how many full lines we can actually render
	size_t lines = GetDisplayItemCount();

	size_t listSize = GetItemCount();
	int listW = mRenderW;

	if (listSize <= lines) {
		hasScroll = false;
		scrollingSpeed = 0;
		lines = listSize;
		y_offset = 0;
	} else {
		hasScroll = true;
		listW -= mFastScrollW; // space for fast scroll
		lines++;
		if (lines < listSize)
			lines++;
	}

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

	int yPos = mRenderY + mHeaderH + y_offset;
	int fontOffsetY = (int)((actualItemHeight - mFontHeight) / 2);

	// render all visible items
	for (size_t line = 0; line < lines; line++)
	{
		size_t itemindex = line + firstDisplayedItem;
		if (itemindex >= listSize)
			break;

		// get item data
		ImageResource* icon;
		std::string label;
		if (GetListItem(itemindex, icon, label))
			break;

		if (hasHighlightColor && itemindex == selectedItem) {
			// Highlight the item background of the selected item
			gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha);
			gr_fill(mRenderX, yPos, mRenderW, actualItemHeight);
		}

		if (itemindex == selectedItem) {
			// Use the highlight color for the font
			gr_color(mFontHighlightColor.red, mFontHighlightColor.green, mFontHighlightColor.blue, mFontHighlightColor.alpha);
		} else {
			// Set the color for the font
			gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha);
		}

		// render icon
		if (icon && icon->GetResource()) {
			int currentIconHeight = icon->GetHeight();
			int currentIconWidth = icon->GetWidth();
			int currentIconOffsetY = (actualItemHeight - currentIconHeight) / 2;
			int currentIconOffsetX = (maxIconWidth - currentIconWidth) / 2;
			int image_y = (yPos + currentIconOffsetY);
			gr_blit(icon->GetResource(), 0, 0, currentIconWidth, currentIconHeight, mRenderX + currentIconOffsetX, image_y);
		}

		// render label text
		gr_textEx(mRenderX + maxIconWidth + 5, yPos + fontOffsetY, label.c_str(), fontResource);

		// Add the separator
		gr_color(mSeparatorColor.red, mSeparatorColor.green, mSeparatorColor.blue, mSeparatorColor.alpha);
		gr_fill(mRenderX, yPos + actualItemHeight - mSeparatorH, listW, mSeparatorH);

		// Move the yPos
		yPos += actualItemHeight;
	}

	// Render the Header (last so that it overwrites the top most row for per pixel scrolling)
	yPos = mRenderY;
	if (mHeaderH > 0) {
		// First step, fill background
		gr_color(mHeaderBackgroundColor.red, mHeaderBackgroundColor.green, mHeaderBackgroundColor.blue, mHeaderBackgroundColor.alpha);
		gr_fill(mRenderX, mRenderY, mRenderW, mHeaderH);

		int mIconOffsetX = 0;

		// render the icon if it exists
		ImageResource* headerIcon = mHeaderIcon;
		if (headerIcon && headerIcon->GetResource())
		{
			gr_blit(headerIcon->GetResource(), 0, 0, mHeaderIconWidth, mHeaderIconHeight, mRenderX + ((mHeaderIconWidth - maxIconWidth) / 2), (yPos + (int)((mHeaderH - mHeaderIconHeight) / 2)));
			mIconOffsetX = maxIconWidth;
		}

		// render the text
		gr_color(mHeaderFontColor.red, mHeaderFontColor.green, mHeaderFontColor.blue, mHeaderFontColor.alpha);
		gr_textEx(mRenderX + mIconOffsetX + 5, yPos + (int)((mHeaderH - mFontHeight) / 2), mLastHeaderValue.c_str(), fontResource);

		// Add the separator
		gr_color(mHeaderSeparatorColor.red, mHeaderSeparatorColor.green, mHeaderSeparatorColor.blue, mHeaderSeparatorColor.alpha);
		gr_fill(mRenderX, yPos + mHeaderH - mHeaderSeparatorH, mRenderW, mHeaderSeparatorH);
	}

	// render fast scroll
	lines = GetDisplayItemCount();
	if (hasScroll) {
		int startX = listW + mRenderX;
		int fWidth = mRenderW - listW;
		int fHeight = mRenderH - mHeaderH;

		// line
		gr_color(mFastScrollLineColor.red, mFastScrollLineColor.green, mFastScrollLineColor.blue, mFastScrollLineColor.alpha);
		gr_fill(startX + fWidth/2, mRenderY + mHeaderH, mFastScrollLineW, mRenderH - mHeaderH);

		// rect
		int pct = 0;
		if (GetDisplayRemainder() != 0) {
			// Properly handle the percentage if a partial line is present
			int partial_line_size = actualItemHeight - GetDisplayRemainder();
			pct = ((firstDisplayedItem*actualItemHeight - y_offset)*100)/(listSize*actualItemHeight-((lines + 1)*actualItemHeight) + partial_line_size);
		} else {
			pct = ((firstDisplayedItem*actualItemHeight - y_offset)*100)/(listSize*actualItemHeight-lines*actualItemHeight);
		}
		int mFastScrollRectX = startX + (fWidth - mFastScrollRectW)/2;
		int mFastScrollRectY = mRenderY+mHeaderH + ((fHeight - mFastScrollRectH)*pct)/100;

		gr_color(mFastScrollRectColor.red, mFastScrollRectColor.green, mFastScrollRectColor.blue, mFastScrollRectColor.alpha);
		gr_fill(mFastScrollRectX, mFastScrollRectY, mFastScrollRectW, mFastScrollRectH);
	}
	mUpdate = 0;
	// reset clipping
	gr_noclip();
	return 0;
}

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

	if (!mHeaderIsStatic) {
		std::string newValue = gui_parse_text(mHeaderText);
		if (mLastHeaderValue != newValue) {
			mLastHeaderValue = newValue;
			mUpdate = 1;
		}
	}

	// Handle kinetic scrolling
	int maxScrollDistance = actualItemHeight * SCROLLING_SPEED_LIMIT;
	int oldScrollingSpeed = scrollingSpeed;
	if (scrollingSpeed == 0) {
		// Do nothing
		return 0;
	} else if (scrollingSpeed > 0) {
		if (scrollingSpeed < maxScrollDistance)
			y_offset += scrollingSpeed;
		else
			y_offset += maxScrollDistance;
		scrollingSpeed *= SCROLLING_SPEED_DECREMENT;
		if (scrollingSpeed == oldScrollingSpeed)
			--scrollingSpeed;
	} else if (scrollingSpeed < 0) {
		if (abs(scrollingSpeed) < maxScrollDistance)
			y_offset += scrollingSpeed;
		else
			y_offset -= maxScrollDistance;
		scrollingSpeed *= SCROLLING_SPEED_DECREMENT;
		if (scrollingSpeed == oldScrollingSpeed)
			++scrollingSpeed;
	}
	if (abs(scrollingSpeed) < SCROLLING_FLOOR)
		scrollingSpeed = 0;
	HandleScrolling();
	mUpdate = 1;

	return 0;
}

size_t GUIScrollList::HitTestItem(int x, int y)
{
	// We only care about y position
	if (y < mRenderY || y - mRenderY <= mHeaderH || y - mRenderY > mRenderH)
		return NO_ITEM;

	int startSelection = (y - mRenderY - mHeaderH);

	// Locate the correct item
	size_t actualSelection = firstDisplayedItem;
	int selectY = y_offset;
	while (selectY + actualItemHeight < startSelection) {
		selectY += actualItemHeight;
		actualSelection++;
	}

	if (actualSelection < GetItemCount())
		return actualSelection;

	return NO_ITEM;
}

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

	switch (state)
	{
	case TOUCH_START:
		if (hasScroll && x >= mRenderX + mRenderW - mFastScrollW)
			fastScroll = 1; // Initial touch is in the fast scroll region
		if (scrollingSpeed != 0) {
			selectedItem = NO_ITEM; // this allows the user to tap the list to stop the scrolling without selecting the item they tap
			scrollingSpeed = 0; // stop scrolling on a new touch
		} else if (!fastScroll) {
			// find out which item the user touched
			selectedItem = HitTestItem(x, y);
		}
		if (selectedItem != NO_ITEM)
			mUpdate = 1;
		lastY = last2Y = y;
		break;

	case TOUCH_DRAG:
		if (fastScroll)
		{
			int pct = ((y-mRenderY-mHeaderH)*100)/(mRenderH-mHeaderH);
			int totalSize = GetItemCount();
			int lines = GetDisplayItemCount();

			float l = float((totalSize-lines)*pct)/100;
			if(l + lines >= totalSize)
			{
				firstDisplayedItem = totalSize - lines;
				if (GetDisplayRemainder() != 0) {
					// There's a partial row displayed, set the scrolling offset so that the last item really is at the very bottom
					firstDisplayedItem--;
					y_offset = GetDisplayRemainder() - actualItemHeight;
				} else {
					// There's no partial row so zero out the offset
					y_offset = 0;
				}
			}
			else
			{
				if (l < 0)
					l = 0;
				firstDisplayedItem = l;
				y_offset = -(l - int(l))*actualItemHeight;
				if (GetDisplayRemainder() != 0) {
					// There's a partial row displayed, make sure y_offset doesn't go past the max
					if (firstDisplayedItem == totalSize - lines - 1 && y_offset < GetDisplayRemainder() - actualItemHeight)
						y_offset = GetDisplayRemainder() - actualItemHeight;
				} else if (firstDisplayedItem == totalSize - lines)
					y_offset = 0;
			}

			selectedItem = NO_ITEM;
			mUpdate = 1;
			scrollingSpeed = 0; // prevent kinetic scrolling when using fast scroll
			break;
		}

		// Provide some debounce on initial touches
		if (selectedItem != NO_ITEM && abs(y - lastY) < touchDebounce) {
			mUpdate = 1;
			break;
		}

		selectedItem = NO_ITEM; // nothing is selected because we dragged too far
		// Handle scrolling
		if (hasScroll) {
			y_offset += y - lastY; // adjust the scrolling offset based on the difference between the starting touch and the current touch
			last2Y = lastY; // keep track of previous y locations so that we can tell how fast to scroll for kinetic scrolling
			lastY = y; // update last touch to the current touch so we can tell how far and what direction we scroll for the next touch event

			HandleScrolling();
		} else
			y_offset = 0;
		mUpdate = 1;
		break;

	case TOUCH_RELEASE:
		fastScroll = 0;
		if (selectedItem != NO_ITEM) {
			// We've selected an item!
			NotifySelect(selectedItem);
			mUpdate = 1;

			DataManager::Vibrate("tw_button_vibrate");
			selectedItem = NO_ITEM;
		} else {
			// Start kinetic scrolling
			scrollingSpeed = lastY - last2Y;
			if (abs(scrollingSpeed) < touchDebounce)
				scrollingSpeed = 0;
		}
	case TOUCH_REPEAT:
	case TOUCH_HOLD:
		break;
	}
	return 0;
}

void GUIScrollList::HandleScrolling()
{
	// handle dragging downward, scrolling upward
	// the offset should always be <= 0 and > -actualItemHeight, adjust the first display row and offset as needed
	while(firstDisplayedItem && y_offset > 0) {
		firstDisplayedItem--;
		y_offset -= actualItemHeight;
	}
	if (firstDisplayedItem == 0 && y_offset > 0) {
		y_offset = 0; // user kept dragging downward past the top of the list, so always reset the offset to 0 since we can't scroll any further in this direction
		scrollingSpeed = 0; // stop kinetic scrolling
	}

	// handle dragging upward, scrolling downward
	int totalSize = GetItemCount();
	int lines = GetDisplayItemCount(); // number of full lines our list can display at once
	int bottom_offset = GetDisplayRemainder() - actualItemHeight; // extra display area that can display a partial line for per pixel scrolling

	// the offset should always be <= 0 and > -actualItemHeight, adjust the first display row and offset as needed
	while (firstDisplayedItem + lines + (bottom_offset ? 1 : 0) < totalSize && abs(y_offset) > actualItemHeight) {
		firstDisplayedItem++;
		y_offset += actualItemHeight;
	}
	// Check if we dragged too far, set the list at the bottom and adjust offset as needed
	if (bottom_offset != 0 && firstDisplayedItem + lines + 1 >= totalSize && y_offset <= bottom_offset) {
		firstDisplayedItem = totalSize - lines - 1;
		y_offset = bottom_offset;
		scrollingSpeed = 0; // stop kinetic scrolling
	} else if (firstDisplayedItem + lines >= totalSize && y_offset < 0) {
		firstDisplayedItem = totalSize - lines;
		y_offset = 0;
		scrollingSpeed = 0; // stop kinetic scrolling
	}
}

int GUIScrollList::GetDisplayItemCount()
{
	return (mRenderH - mHeaderH) / (actualItemHeight);
}

int GUIScrollList::GetDisplayRemainder()
{
	return (mRenderH - mHeaderH) % actualItemHeight;
}

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

	if(!isConditionTrue())
		return 0;

	if (!mHeaderIsStatic) {
		std::string newValue = gui_parse_text(mHeaderText);
		if (mLastHeaderValue != newValue) {
			mLastHeaderValue = newValue;
			firstDisplayedItem = 0;
			y_offset = 0;
			scrollingSpeed = 0; // stop kinetic scrolling on variable changes
			mUpdate = 1;
		}
	}
	return 0;
}

int GUIScrollList::SetRenderPos(int x, int y, int w /* = 0 */, int h /* = 0 */)
{
	mRenderX = x;
	mRenderY = y;
	if (w || h)
	{
		mRenderW = w;
		mRenderH = h;
	}
	SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
	mUpdate = 1;
	return 0;
}

void GUIScrollList::SetPageFocus(int inFocus)
{
	if (inFocus) {
		NotifyVarChange("", ""); // This forces a check for the header text
		scrollingSpeed = 0; // stop kinetic scrolling on page changes
		mUpdate = 1;
	}
}
