/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <linux/input.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <errno.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 <sys/mount.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>

extern "C"
{
#include "../common.h"
#include "../roots.h"
#include "../minuitwrp/minui.h"
#include "../recovery_ui.h"
#include "../minzip/Zip.h"
#include <pixelflinger/pixelflinger.h>
}

#include "rapidxml.hpp"
#include "objects.hpp"
#include "../data.hpp"
#include "../variables.h"
#include "../partitions.hpp"
#include "../twrp-functions.hpp"
#include "blanktimer.hpp"

const static int CURTAIN_FADE = 32;

using namespace rapidxml;

// Global values
static gr_surface gCurtain = NULL;
static int gGuiInitialized = 0;
static int gGuiConsoleRunning = 0;
static int gGuiConsoleTerminate = 0;
static int gForceRender = 0;
pthread_mutex_t gForceRendermutex;
static int gNoAnimation = 1;
static int gGuiInputRunning = 0;
blanktimer blankTimer;

// Needed by pages.cpp too
int gGuiRunning = 0;

static int gRecorder = -1;

extern "C" void gr_write_frame_to_file (int fd);

void
flip (void)
{
  if (gRecorder != -1)
	{
	  timespec time;
	  clock_gettime (CLOCK_MONOTONIC, &time);
	  write (gRecorder, &time, sizeof (timespec));
	  gr_write_frame_to_file (gRecorder);
	}
  gr_flip ();
  return;
}

void
rapidxml::parse_error_handler (const char *what, void *where)
{
  fprintf (stderr, "Parser error: %s\n", what);
  fprintf (stderr, "  Start of string: %s\n", (char *) where);
  abort ();
}

static void
curtainSet ()
{
  gr_color (0, 0, 0, 255);
  gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
  gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain), gr_get_height (gCurtain),
		   0, 0);
  gr_flip ();
  return;
}

static void
curtainRaise (gr_surface surface)
{
  int sy = 0;
  int h = gr_get_height (gCurtain) - 1;
  int w = gr_get_width (gCurtain);
  int fy = 1;

  int msw = gr_get_width (surface);
  int msh = gr_get_height (surface);
  int CURTAIN_RATE = msh / 30;

  if (gNoAnimation == 0)
	{
	  for (; h > 0; h -= CURTAIN_RATE, sy += CURTAIN_RATE, fy += CURTAIN_RATE)
		{
		  gr_blit (surface, 0, 0, msw, msh, 0, 0);
		  gr_blit (gCurtain, 0, sy, w, h, 0, 0);
		  gr_flip ();
		}
	}
  gr_blit (surface, 0, 0, msw, msh, 0, 0);
  flip ();
  return;
}

void
curtainClose ()
{
#if 0
  int w = gr_get_width (gCurtain);
  int h = 1;
  int sy = gr_get_height (gCurtain) - 1;
  int fbh = gr_fb_height ();
  int CURTAIN_RATE = fbh / 30;

  if (gNoAnimation == 0)
	{
	  for (; h < fbh; h += CURTAIN_RATE, sy -= CURTAIN_RATE)
		{
		  gr_blit (gCurtain, 0, sy, w, h, 0, 0);
		  gr_flip ();
		}
	  gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain),
			   gr_get_height (gCurtain), 0, 0);
	  gr_flip ();

	  if (gRecorder != -1)
		close (gRecorder);

	  int fade;
	  for (fade = 16; fade < 255; fade += CURTAIN_FADE)
		{
		  gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain),
				   gr_get_height (gCurtain), 0, 0);
		  gr_color (0, 0, 0, fade);
		  gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
		  gr_flip ();
		}
	  gr_color (0, 0, 0, 255);
	  gr_fill (0, 0, gr_fb_width (), gr_fb_height ());
	  gr_flip ();
	}
#else
  gr_blit (gCurtain, 0, 0, gr_get_width (gCurtain), gr_get_height (gCurtain),
		   0, 0);
  gr_flip ();
#endif
  return;
}

static void *
input_thread (void *cookie)
{
  int drag = 0;
  static int touch_and_hold = 0, dontwait = 0, touch_repeat = 0, x = 0, y =
	0, lshift = 0, rshift = 0, key_repeat = 0;
  static struct timeval touchStart;
  HardwareKeyboard kb;

  //start screen timeout threads
  blankTimer.setTimerThread();

  for (;;)
	{

	  // wait for the next event
	  struct input_event ev;
	  int state = 0, ret = 0;

	  ret = ev_get (&ev, dontwait);

	  if (ret < 0)
		{
		  struct timeval curTime;
		  gettimeofday (&curTime, NULL);
		  long mtime, seconds, useconds;

		  seconds = curTime.tv_sec - touchStart.tv_sec;
		  useconds = curTime.tv_usec - touchStart.tv_usec;

		  mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5;
		  if (touch_and_hold && mtime > 500)
			{
			  touch_and_hold = 0;
			  touch_repeat = 1;
			  gettimeofday (&touchStart, NULL);
#ifdef _EVENT_LOGGING
			  LOGE ("TOUCH_HOLD: %d,%d\n", x, y);
#endif
			  PageManager::NotifyTouch (TOUCH_HOLD, x, y);
                          blankTimer.resetTimerAndUnblank();
			}
		  else if (touch_repeat && mtime > 100)
			{
#ifdef _EVENT_LOGGING
			  LOGE ("TOUCH_REPEAT: %d,%d\n", x, y);
#endif
			  gettimeofday (&touchStart, NULL);
			  PageManager::NotifyTouch (TOUCH_REPEAT, x, y);
                          blankTimer.resetTimerAndUnblank();
			}
		  else if (key_repeat == 1 && mtime > 500)
			{
#ifdef _EVENT_LOGGING
			  LOGE ("KEY_HOLD: %d,%d\n", x, y);
#endif
			  gettimeofday (&touchStart, NULL);
			  key_repeat = 2;
			  kb.KeyRepeat ();
                          blankTimer.resetTimerAndUnblank();
			}
		  else if (key_repeat == 2 && mtime > 100)
			{
#ifdef _EVENT_LOGGING
			  LOGE ("KEY_REPEAT: %d,%d\n", x, y);
#endif
			  gettimeofday (&touchStart, NULL);
			  kb.KeyRepeat ();
                          blankTimer.resetTimerAndUnblank();
			}
		}
	  else if (ev.type == EV_ABS)
		{

		  x = ev.value >> 16;
		  y = ev.value & 0xFFFF;

		  if (ev.code == 0)
			{
			  if (state == 0)
				{
#ifdef _EVENT_LOGGING
				  LOGE ("TOUCH_RELEASE: %d,%d\n", x, y);
#endif
				  PageManager::NotifyTouch (TOUCH_RELEASE, x, y);
				  blankTimer.resetTimerAndUnblank();
				  touch_and_hold = 0;
				  touch_repeat = 0;
				  if (!key_repeat)
					dontwait = 0;
				}
			  state = 0;
			  drag = 0;
			}
		  else
			{
			  if (!drag)
				{
#ifdef _EVENT_LOGGING
				  LOGE ("TOUCH_START: %d,%d\n", x, y);
#endif
				  if (PageManager::NotifyTouch (TOUCH_START, x, y) > 0)
					state = 1;
				  drag = 1;
				  touch_and_hold = 1;
				  dontwait = 1;
				  key_repeat = 0;
				  gettimeofday (&touchStart, NULL);
				  blankTimer.resetTimerAndUnblank();
				}
			  else
				{
				  if (state == 0)
					{
#ifdef _EVENT_LOGGING
					  LOGE ("TOUCH_DRAG: %d,%d\n", x, y);
#endif
					  if (PageManager::NotifyTouch (TOUCH_DRAG, x, y) > 0)
						state = 1;
					  key_repeat = 0;
					  blankTimer.resetTimerAndUnblank();
					}
				}
			}
		}
	  else if (ev.type == EV_KEY)
		{
		  // Handle key-press here
#ifdef _EVENT_LOGGING
		  LOGE ("TOUCH_KEY: %d\n", ev.code);
#endif
		  if (ev.value != 0)
			{
			  // This is a key press
			  if (kb.KeyDown (ev.code))
				{
				  key_repeat = 1;
				  touch_and_hold = 0;
				  touch_repeat = 0;
				  dontwait = 1;
				  gettimeofday (&touchStart, NULL);
				  blankTimer.resetTimerAndUnblank();
				}
			  else
				{
				  key_repeat = 0;
				  touch_and_hold = 0;
				  touch_repeat = 0;
				  dontwait = 0;
				  blankTimer.resetTimerAndUnblank();
				}
			}
		  else
			{
			  // This is a key release
			  kb.KeyUp (ev.code);
			  key_repeat = 0;
			  touch_and_hold = 0;
			  touch_repeat = 0;
			  dontwait = 0;
                          blankTimer.resetTimerAndUnblank();
			}
		}
	}
  return NULL;
}

// This special function will return immediately the first time, but then
// always returns 1/30th of a second (or immediately if called later) from
// the last time it was called
static void
loopTimer (void)
{
  static timespec lastCall;
  static int initialized = 0;

  if (!initialized)
	{
	  clock_gettime (CLOCK_MONOTONIC, &lastCall);
	  initialized = 1;
	  return;
	}

  do
	{
	  timespec curTime;
	  clock_gettime (CLOCK_MONOTONIC, &curTime);

	  timespec diff = TWFunc::timespec_diff (lastCall, curTime);

	  // This is really 30 times per second
	  if (diff.tv_sec || diff.tv_nsec > 33333333)
		{
		  lastCall = curTime;
		  return;
		}

	  // We need to sleep some period time microseconds
	  unsigned int sleepTime = 33333 - (diff.tv_nsec / 1000);
	  usleep (sleepTime);
	}
  while (1);
  return;
}

static int
runPages (void)
{
  // Raise the curtain
  if (gCurtain != NULL)
	{
	  gr_surface surface;

	  PageManager::Render ();
	  gr_get_surface (&surface);
	  curtainRaise (surface);
	  gr_free_surface (surface);
	}

  gGuiRunning = 1;

  DataManager::SetValue ("tw_loaded", 1);

  for (;;)
	{
	  loopTimer ();

	  if (!gForceRender)
		{
		  int ret;

		  ret = PageManager::Update ();
		  if (ret > 1)
			PageManager::Render ();

		  if (ret > 0)
			flip ();
		}
	  else
		{
		  pthread_mutex_lock(&gForceRendermutex);
		  gForceRender = 0;
		  pthread_mutex_unlock(&gForceRendermutex);
		  PageManager::Render ();
		  flip ();
		}
		if (DataManager::GetIntValue("tw_gui_done") != 0)
		{
			break;
		}
	}

  gGuiRunning = 0;
  return 0;
}

static int
runPage (const char *page_name)
{
  gui_changePage (page_name);

  // Raise the curtain
  if (gCurtain != NULL)
	{
	  gr_surface surface;

	  PageManager::Render ();
	  gr_get_surface (&surface);
	  curtainRaise (surface);
	  gr_free_surface (surface);
	}

  gGuiRunning = 1;

  DataManager::SetValue ("tw_loaded", 1);

  for (;;)
	{
	  loopTimer ();

	  if (!gForceRender)
		{
		  int ret;

		  ret = PageManager::Update ();
		  if (ret > 1)
			PageManager::Render ();

		  if (ret > 0)
			flip ();
		}
	  else
		{
		  pthread_mutex_lock(&gForceRendermutex);
		  gForceRender = 0;
		  pthread_mutex_unlock(&gForceRendermutex);
		  PageManager::Render ();
		  flip ();
		}
	  if (DataManager::GetIntValue ("tw_page_done") != 0)
		{
		  gui_changePage ("main");
		  break;
		}
	}

  gGuiRunning = 0;
  return 0;
}

int
gui_forceRender (void)
{
  pthread_mutex_lock(&gForceRendermutex);
  gForceRender = 1;
  pthread_mutex_unlock(&gForceRendermutex);
  return 0;
}

int
gui_changePage (std::string newPage)
{
  LOGI ("Set page: '%s'\n", newPage.c_str ());
  PageManager::ChangePage (newPage);
  pthread_mutex_lock(&gForceRendermutex);
  gForceRender = 1;
  pthread_mutex_unlock(&gForceRendermutex);
  return 0;
}

int
gui_changeOverlay (std::string overlay)
{
  PageManager::ChangeOverlay (overlay);
  pthread_mutex_lock(&gForceRendermutex);
  gForceRender = 1;
  pthread_mutex_unlock(&gForceRendermutex);
  return 0;
}

int
gui_changePackage (std::string newPackage)
{
  PageManager::SelectPackage (newPackage);
  pthread_mutex_lock(&gForceRendermutex);
  gForceRender = 1;
  pthread_mutex_unlock(&gForceRendermutex);
  return 0;
}

std::string gui_parse_text (string inText)
{
  // Copied from std::string GUIText::parseText(void)
  // This function parses text for DataManager values encompassed by %value% in the XML
  static int counter = 0;
  std::string str = inText;
  size_t pos = 0;
  size_t next = 0, end = 0;

  while (1)
	{
	  next = str.find ('%', pos);
	  if (next == std::string::npos)
		return str;
	  end = str.find ('%', next + 1);
	  if (end == std::string::npos)
		return str;

	  // We have a block of data
	  std::string var = str.substr (next + 1, (end - next) - 1);
	  str.erase (next, (end - next) + 1);

	  if (next + 1 == end)
		{
		  str.insert (next, 1, '%');
		}
	  else
		{
		  std::string value;
		  if (DataManager::GetValue (var, value) == 0)
			str.insert (next, value);
		}

	  pos = next + 1;
	}
}

extern "C" int
gui_init ()
{
  int fd;

  gr_init ();

  if (res_create_surface ("/res/images/curtain.jpg", &gCurtain))
	{
	  printf
		("Unable to locate '/res/images/curtain.jpg'\nDid you set a DEVICE_RESOLUTION in your config files?\n");
	  return -1;
	}

  curtainSet ();

  ev_init ();
  return 0;
}

extern "C" int
gui_loadResources ()
{
//    unlink("/sdcard/video.last");
//    rename("/sdcard/video.bin", "/sdcard/video.last");
//    gRecorder = open("/sdcard/video.bin", O_CREAT | O_WRONLY);

  int check = 0;
  DataManager::GetValue (TW_IS_ENCRYPTED, check);
  if (check)
	{
	  if (PageManager::LoadPackage ("TWRP", "/res/ui.xml", "decrypt"))
		{
		  LOGE ("Failed to load base packages.\n");
		  goto error;
		}
	  else
		check = 1;
	}
  if (check == 0
	  && PageManager::LoadPackage ("TWRP", "/script/ui.xml", "main"))
	{
	  std::string theme_path;

	  theme_path = DataManager::GetSettingsStoragePath ();
	  if (!PartitionManager.Mount_Settings_Storage (false))
		{
		  int retry_count = 5;
		  while (retry_count > 0
				 && !PartitionManager.Mount_Settings_Storage (false))
			{
			  usleep (500000);
			  retry_count--;
			}
		  if (!PartitionManager.Mount_Settings_Storage (false))
			{
			  LOGE ("Unable to mount %s during GUI startup.\n",
					theme_path.c_str ());
			  check = 1;
			}
		}

	  theme_path += "/TWRP/theme/ui.zip";
	  if (check || PageManager::LoadPackage ("TWRP", theme_path, "main"))
		{
		  if (PageManager::LoadPackage ("TWRP", "/res/ui.xml", "main"))
			{
			  LOGE ("Failed to load base packages.\n");
			  goto error;
			}
		}
	}

  // Set the default package
  PageManager::SelectPackage ("TWRP");

  gGuiInitialized = 1;
  return 0;

error:
  LOGE ("An internal error has occurred.\n");
  gGuiInitialized = 0;
  return -1;
}

extern "C" int
gui_start ()
{
  if (!gGuiInitialized)
	return -1;

  gGuiConsoleTerminate = 1;
  while (gGuiConsoleRunning)
	loopTimer ();

  // Set the default package
  PageManager::SelectPackage ("TWRP");

  if (!gGuiInputRunning)
	{
	  // Start by spinning off an input handler.
	  pthread_t t;
	  pthread_create (&t, NULL, input_thread, NULL);
	  gGuiInputRunning = 1;
	}

  return runPages ();
}

extern "C" int
gui_startPage (const char *page_name)
{
  if (!gGuiInitialized)
	return -1;

  gGuiConsoleTerminate = 1;
  while (gGuiConsoleRunning)
	loopTimer ();

  // Set the default package
  PageManager::SelectPackage ("TWRP");

  if (!gGuiInputRunning)
	{
	  // Start by spinning off an input handler.
	  pthread_t t;
	  pthread_create (&t, NULL, input_thread, NULL);
	  gGuiInputRunning = 1;
	}

  DataManager::SetValue ("tw_page_done", 0);
  return runPage (page_name);
}

static void *
console_thread (void *cookie)
{
  PageManager::SwitchToConsole ();

  while (!gGuiConsoleTerminate)
	{
	  loopTimer ();

	  if (!gForceRender)
		{
		  int ret;

		  ret = PageManager::Update ();
		  if (ret > 1)
			PageManager::Render ();

		  if (ret > 0)
			flip ();

		  if (ret < 0)
			LOGE ("An update request has failed.\n");
		}
	  else
		{
		  pthread_mutex_lock(&gForceRendermutex);
		  gForceRender = 0;
		  pthread_mutex_unlock(&gForceRendermutex);
		  PageManager::Render ();
		  flip ();
		}
	}
  gGuiConsoleRunning = 0;
  return NULL;
}

extern "C" int
gui_console_only ()
{
  if (!gGuiInitialized)
	return -1;

  gGuiConsoleTerminate = 0;
  gGuiConsoleRunning = 1;

  // Start by spinning off an input handler.
  pthread_t t;
  pthread_create (&t, NULL, console_thread, NULL);

  return 0;
}
