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

using namespace std;
#include "rapidxml.hpp"
using namespace rapidxml;
extern "C" {
#include "../minzip/Zip.h"
#include "../minuitwrp/minui.h"
}
#include <string>
#include <vector>
#include <map>
#include "resources.hpp"
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <pixelflinger/pixelflinger.h>
#include <linux/kd.h>
#include <linux/fb.h>
#include <sstream>
#include "pages.hpp"
#include "blanktimer.hpp"
#include "../data.hpp"
extern "C" {
#include "../common.h"
#include "../recovery_ui.h"
}
#include "../twrp-functions.hpp"
#include "../variables.h"

blanktimer::blanktimer(void) {
	blanked = 0;
	orig_brightness = getBrightness();
}

void blanktimer::setTime(int newtime) {
	sleepTimer = newtime;
}

int blanktimer::setTimerThread(void) {
	pthread_t thread;
	ThreadPtr blankptr = &blanktimer::setClockTimer;
	PThreadPtr p = *(PThreadPtr*)&blankptr;
	pthread_create(&thread, NULL, p, this);
	return 0;
}

void blanktimer::setBlank(int blank) {
	pthread_mutex_lock(&blankmutex);
	conblank = blank;
	pthread_mutex_unlock(&blankmutex);
}

int blanktimer::getBlank(void) {
	return conblank;
}

void blanktimer::setTimer(void) {
	pthread_mutex_lock(&timermutex);
	clock_gettime(CLOCK_MONOTONIC, &btimer);
	pthread_mutex_unlock(&timermutex);
}

timespec blanktimer::getTimer(void) {
	return btimer;
}

int  blanktimer::setClockTimer(void) {
	timespec curTime, diff;
	while(1) {
		usleep(1000);
		clock_gettime(CLOCK_MONOTONIC, &curTime);
		diff = TWFunc::timespec_diff(btimer, curTime);
		if (sleepTimer && diff.tv_sec > sleepTimer && conblank != 1) {
			orig_brightness = getBrightness();
			setBlank(1);
			PageManager::ChangeOverlay("lock");
		}
		if (conblank == 1 && blanked != 1) {
			blanked = 1;
			gr_fb_blank(conblank);
			setBrightness(0);
		}
	}
	return -1;
}

int blanktimer::getBrightness(void) {
	string results;
	string brightness_path = EXPAND(TW_BRIGHTNESS_PATH);
	if ((TWFunc::read_file(brightness_path, results)) != 0)
		return -1;
	return atoi(results.c_str());

}

int blanktimer::setBrightness(int brightness) {
	string brightness_path = EXPAND(TW_BRIGHTNESS_PATH);
	string bstring;
	char buff[100];
	sprintf(buff, "%d", brightness);
	bstring = buff;
	if ((TWFunc::write_file(brightness_path, bstring)) != 0)
		return -1;
	return 0;
}

void blanktimer::resetTimerAndUnblank(void) {
	setTimer();
	if (blanked) {
		setBrightness(orig_brightness);
		blanked = 0;
		setBlank(0);
		gr_fb_blank(conblank);
		gui_forceRender();
	}
}
