/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <debug.h>
#include <dev/fbcon.h>
#include <target.h>
#include <mmc.h>
#include <partition_parser.h>
#include <stdlib.h>
#include <string.h>
#include <display_menu.h>
#include <qtimer.h>
#include "mdtp.h"
#include "mdtp_defs.h"
#include "mdtp_fs.h"

// Image releative locations
#define ERROR_MESSAGE_RELATIVE_Y_LOCATION   (0.18)
#define MAIN_TEXT_RELATIVE_Y_LOCATION       (0.33)
#define PIN_RELATIVE_Y_LOCATION             (0.47)
#define PIN_TEXT_RELATIVE_Y_LOCATION        (0.57)
#define OK_BUTTON_RELATIVE_Y_LOCATION       (0.75)
#define OK_TEXT_RELATIVE_Y_LOCATION         (0.82)

#define MDTP_PRESSING_DELAY_MSEC            (400)
#define MDTP_MAX_IMAGE_SIZE                 (1183000)  //size in bytes, includes some extra bytes since we round up to block size in read
#define RGB888_BLACK                        (0x000000)
#define BITS_PER_BYTE                       (8)


#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width)         (((screen_width)-(image_width))/2)

extern uint32_t target_volume_up();
extern uint32_t target_volume_down();
extern int msm_display_on();

struct mdtp_fbimage {
	uint32_t width;
	uint32_t height;
	uint8_t image[MDTP_MAX_IMAGE_SIZE];
};

/*----------------------------------------------------------------------------
 * Global Variables
 * -------------------------------------------------------------------------*/

static uint32_t g_pin_frames_x_location[MDTP_PIN_LEN] = {0};
static uint32_t g_pin_frames_y_location = 0;
static bool g_diplay_pin = false;

static bool g_initial_screen_displayed = false;

static struct mdtp_fbimage *g_mdtp_header = NULL;
static struct fbcon_config *fb_config = NULL;


/*----------------------------------------------------------------------------
 * Local Functions
 * -------------------------------------------------------------------------*/

/**
 * Allocate mdtp image
 */
static void alloc_mdtp_image() {
	if (!g_mdtp_header) {
		g_mdtp_header = (struct mdtp_fbimage *)malloc(sizeof(struct mdtp_fbimage));
		ASSERT(g_mdtp_header);
	}
}

/**
 * Free mdtp image
 */
void free_mdtp_image() {
	if (g_mdtp_header) {
		free(g_mdtp_header);
		g_mdtp_header = NULL;
	}
}

/**
 * Load images from EMMC
 */
static struct mdtp_fbimage* mdtp_read_mmc_image(uint32_t offset, uint32_t width, uint32_t height)
{
	int index = INVALID_PTN;
	unsigned long long ptn = 0;
	struct mdtp_fbimage *logo = g_mdtp_header;
	uint32_t block_size = mmc_get_device_blocksize();

	index = partition_get_index("mdtp");
	if (index == 0) {
		dprintf(CRITICAL, "ERROR: mdtp Partition table not found\n");
		return NULL;
	}

	ptn = partition_get_offset(index);
	if (ptn == 0) {
		dprintf(CRITICAL, "ERROR: mdtp Partition invalid\n");
		return NULL;
	}

	if (fb_config)
	{
		uint8_t *base = logo->image;
		unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);

		if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*bytes_per_bpp, block_size))) {
			fbcon_clear();
			dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
			return NULL;
		}

		logo->width = width;
		logo->height = height;
	}

	return logo;
}

/**
 * flush fbcon display
 *
 * The function is duplicated from fbcon.c
 */
static void fbcon_flush(void)
{
	if (fb_config->update_start)
		fb_config->update_start();
	if (fb_config->update_done)
		while (!fb_config->update_done());
}

/**
 * Clear complete section on the screen.
 * The section is of section_height, and is located from the y
 * coordinate and down.
 */
static void fbcon_clear_section(uint32_t y, uint32_t section_height)
{
	unsigned image_base;
	unsigned bytes_per_bpp;

	if (fb_config)
	{
		image_base = (y *(fb_config->width));
		bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);

		unsigned count = fb_config->width*section_height;
		memset(fb_config->base + image_base*bytes_per_bpp, RGB888_BLACK, count*bytes_per_bpp);

		fbcon_flush();
	}
	else
	{
		dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
		display_error_msg(); /* This will never return */
	}
}

/**
 * Put image at a specific (x,y) location on the screen.
 * Duplicated from fbcon.c, with modifications to allow (x,y) location (instead of a centered image),
 * and display bmp images properly (order of copying the lines to the screen was reversed)
 */
static void fbcon_putImage_in_location(struct mdtp_fbimage *fbimg, uint32_t x, uint32_t y)
{
	unsigned i = 0;
	unsigned bytes_per_bpp;
	unsigned image_base;
	unsigned width, pitch, height;
	unsigned char *logo_base = NULL;

	if (!fb_config) {
		dprintf(CRITICAL,"ERROR: NULL configuration, image cannot be displayed\n");
		return;
	}

	if(fbimg) {
		width = pitch = fbimg->width;
		height = fbimg->height;
		logo_base = (unsigned char *)fbimg->image;
	}
	else {
		dprintf(CRITICAL,"ERROR: invalid image struct\n");
		return;
	}

	bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);

#if DISPLAY_TYPE_MIPI
	if (bytes_per_bpp == 3)
	{
		if (fbimg->width == fb_config->width && fbimg->height == fb_config->height)
		{
			dprintf(CRITICAL,"ERROR: full screen image, cannot be displayed\n");
			return;
		}

		if (fbimg->width > fb_config->width || fbimg->height > fb_config->height ||
				(x > (fb_config->width - fbimg->width)) || (y > (fb_config->height - fbimg->height)))
		{
			dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen or exceeds its margins\n");
			return;
		}

		image_base = ( (y *(fb_config->width)) + x);
		for (i = 0; i < height; i++) {
			memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
					logo_base + ((height - 1 - i) * pitch * bytes_per_bpp), width * bytes_per_bpp);
		}
	}
	else
	{
		dprintf(CRITICAL,"ERROR: invalid bpp value\n");
		display_error_msg(); /* This will never return */
	}

	/* Flush the contents to memory before giving the data to dma */
	arch_clean_invalidate_cache_range((addr_t) fb_config->base, (fb_config->height * fb_config->width * bytes_per_bpp));

	fbcon_flush();
	msm_display_on();

#endif
}

/**
 * Display main error message
 */
static int display_error_message()
{
	struct mdtp_fbimage *fbimg;

	if (fb_config)
	{
		uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(ALERT_MESSAGE),fb_config->width);
		uint32_t y = ((fb_config->height)*ERROR_MESSAGE_RELATIVE_Y_LOCATION);
		fbimg = mdtp_read_mmc_image(get_image_offset(ALERT_MESSAGE),get_image_width(ALERT_MESSAGE), get_image_height(ALERT_MESSAGE));
		if (NULL == fbimg)
		{
			dprintf(CRITICAL,"ERROR: failed to read error image from mmc\n");
			return -1;
		}

		fbcon_putImage_in_location(fbimg, x, y);

		return 0;
	}
	else
	{
		dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
		return -1;
	}
}

/**
 * Read from mmc the image in the given offset, of the given width and height.
 * Then, display the image on the screen in the given (x,y) location.
 */
static void display_image(uint32_t offset, uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
	struct mdtp_fbimage *fbimg;

	if (fb_config)
	{
		fbimg = mdtp_read_mmc_image(offset, width, height);
		if (NULL == fbimg)
		{
			dprintf(CRITICAL,"ERROR: failed to read image from mmc\n");
			display_error_msg(); /* This will never return */
		}

		fbcon_putImage_in_location(fbimg, x, y);
	}
	else
	{
		dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
		display_error_msg(); /* This will never return */
	}
}

/**
 * Display initial delay message
 */
static void display_initial_delay()
{
	uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_5SECONDS),fb_config->width);
	uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
	display_image(get_image_offset(MAINTEXT_5SECONDS), get_image_width(MAINTEXT_5SECONDS), get_image_height(MAINTEXT_5SECONDS), x, y);
}

/**
 * Display "enter PIN" message
 */
static void display_enter_pin()
{
	uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_ENTERPIN),fb_config->width);
	uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;
	display_image(get_image_offset(MAINTEXT_ENTERPIN), get_image_width(MAINTEXT_ENTERPIN), get_image_height(MAINTEXT_ENTERPIN), x, y);
}

/**
 * Display invalid PIN message
 */
static void display_invalid_pin()
{
	uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(MAINTEXT_INCORRECTPIN),fb_config->width);
	uint32_t y = (fb_config->height)*MAIN_TEXT_RELATIVE_Y_LOCATION;

	display_image(get_image_offset(MAINTEXT_INCORRECTPIN), get_image_width(MAINTEXT_INCORRECTPIN), get_image_height(MAINTEXT_INCORRECTPIN), x, y);
}

/**
 * Clear digits instructions
 */
static void display_digits_instructions()
{
	uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(PINTEXT),fb_config->width);
	uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;

	display_image(get_image_offset(PINTEXT), get_image_width(PINTEXT), get_image_height(PINTEXT), x, y);
}

/**
 * Clear digits instructions
 */
static void clear_digits_instructions()
{
	uint32_t y = (fb_config->height)*PIN_TEXT_RELATIVE_Y_LOCATION;
	fbcon_clear_section(y, get_image_height(PINTEXT));
}

/**
 * Display a digit as un-selected.
 */
static void display_digit(uint32_t x, uint32_t y, uint32_t digit)
{
	if (g_diplay_pin == false)
		return;

	display_image(get_image_offset(PIN_UNSELECTED_0 + digit),
			get_image_width(PIN_UNSELECTED_0 + digit), get_image_height(PIN_UNSELECTED_0 + digit), x, y);
}

/**
 * Display a digit as selected.
 */
static void display_selected_digit(uint32_t x, uint32_t y, uint32_t digit)
{
	if (g_diplay_pin == false)
		return;

	display_image(get_image_offset(PIN_SELECTED_0 + digit),
			get_image_width(PIN_SELECTED_0 + digit),
			get_image_height(PIN_SELECTED_0 + digit), x, y);
}

/**
 * Display OK button as un-selected.
 */
static void display_ok_button()
{
	uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(get_image_width(BTN_OK_OFF),fb_config->width);
	uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;

	display_image(get_image_offset(BTN_OK_OFF), get_image_width(BTN_OK_OFF),get_image_height(BTN_OK_OFF), ok_x, ok_y);
}

/**
 * Display OK button as selected.
 */
static void display_selected_ok_button()
{
	uint32_t ok_x = CENTER_IMAGE_ON_X_AXIS(get_image_width(BTN_OK_ON),fb_config->width);
	uint32_t ok_y = (fb_config->height)*OK_BUTTON_RELATIVE_Y_LOCATION;

	display_image(get_image_offset(BTN_OK_ON), get_image_width(BTN_OK_ON), get_image_height(BTN_OK_ON),  ok_x, ok_y);
}


/**
 * Display the instructions for the OK button.
 */
static void display_pin_instructions()
{
	uint32_t x = CENTER_IMAGE_ON_X_AXIS(get_image_width(ACCEPTEDIT_TEXT),fb_config->width);
	uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;

	display_image(get_image_offset(ACCEPTEDIT_TEXT), get_image_width(ACCEPTEDIT_TEXT), get_image_height(ACCEPTEDIT_TEXT), x, y);
}

/**
 * Clear the instructions for the OK button.
 */
static void clear_pin_message()
{
	uint32_t y = (fb_config->height)*OK_TEXT_RELATIVE_Y_LOCATION;

	fbcon_clear_section(y,get_image_height(ACCEPTEDIT_TEXT));
}

/**
 * Initialize data structures required for MDTP UI.
 */
static void init_mdtp_ui_data()
{
	fb_config = fbcon_display();
	alloc_mdtp_image();
}

/**
 * Display the basic layout of the screen (done only once).
 */
static void display_initial_screen(uint32_t pin_length)
{
	if (g_initial_screen_displayed == true)
		return;

	init_mdtp_ui_data();

	if (fb_config)
	{
		fbcon_clear();

		if (display_error_message())
			display_error_msg(); /* This will never return */
		display_initial_delay();

		mdelay(INITIAL_DELAY_MSECONDS);

		g_pin_frames_y_location = ((fb_config->height)*PIN_RELATIVE_Y_LOCATION);

		uint32_t total_pin_length = pin_length*get_image_width(PIN_UNSELECTED_0) + mdtp_fs_get_param(DIGIT_SPACE)*(pin_length - 1);

		if (fb_config->width > total_pin_length)
		{
			g_diplay_pin = true;

			uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;

			for (uint32_t i=0; i<pin_length; i++)
			{
				g_pin_frames_x_location[i] = complete_pin_centered + i*(mdtp_fs_get_param(DIGIT_SPACE) + get_image_width(PIN_UNSELECTED_0));
			}

			for (uint32_t i=0; i<pin_length; i++)
			{
				display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0);
			}
		}
		else
		{
			dprintf(CRITICAL,"ERROR: screen is not wide enough, PIN digits can't be displayed\n");
		}

		display_ok_button();

		g_initial_screen_displayed = true;
	}
	else
	{
		dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
		display_error_msg(); /* This will never return */
	}
}

/**
 * Display the recovery PIN screen and set received buffer
 * with the PIN the user has entered.
 * The entered PIN will be validated by the calling function.
 */
static void display_get_pin_interface(char *entered_pin, uint32_t pin_length)
{
	uint32_t previous_position = 0, current_position = 0;

	display_initial_screen(pin_length);
	display_enter_pin();

	// Convert ascii to digits
	for (uint32_t i=0; i<pin_length; i++)
	{
		entered_pin[i] -= '0';
	}
	display_selected_digit(g_pin_frames_x_location[0], g_pin_frames_y_location, entered_pin[0]);
	display_digits_instructions();

	while (1)
	{
		if (target_volume_up())
		{
			// current position is the OK button
			if (current_position == pin_length)
			{
				// Convert digits to ascii and
				// validate entered PIN in the calling function
				for (uint32_t i=0; i<pin_length; i++)
				{
					entered_pin[i] += '0';
				}
				return;
			}

			// current position is a PIN slot
			entered_pin[current_position] = (entered_pin[current_position]+1) % 10;
			display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
			mdelay(MDTP_PRESSING_DELAY_MSEC);
		}
		if (target_volume_down())
		{
			previous_position = current_position;
			current_position = (current_position+1) % (pin_length+1);

			// previous position was the OK button
			if (previous_position == pin_length)
			{
				clear_pin_message();
				display_ok_button();

				display_digits_instructions();
				display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);

			}

			// current position is the OK button
			else if (current_position == pin_length)
			{
				display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);
				clear_digits_instructions();

				display_selected_ok_button();
				display_pin_instructions();
			}

			// both the previous and the current positions are PIN slots
			else
			{
				display_digit(g_pin_frames_x_location[previous_position], g_pin_frames_y_location, entered_pin[previous_position]);

				display_selected_digit(g_pin_frames_x_location[current_position], g_pin_frames_y_location, entered_pin[current_position]);
			}

			mdelay(MDTP_PRESSING_DELAY_MSEC);
		}
	}
}

/*----------------------------------------------------------------------------
 * External Functions
 * -------------------------------------------------------------------------*/

/**
 * Display the recovery PIN screen and set received buffer
 * with the PIN the user has entered.
 */
void get_pin_from_user(char *entered_pin, uint32_t pin_length)
{
	display_get_pin_interface(entered_pin, pin_length);

	return;
}

/**
 * User has entered invalid PIN, display error message and
 * allow the user to try again.
 */
void display_invalid_pin_msg()
{
	clear_pin_message();
	display_ok_button();

	display_invalid_pin();

	mdelay(INVALID_PIN_DELAY_MSECONDS);
}

/**
 *  Display error message and stop boot process.
 */
void display_error_msg()
{
	init_mdtp_ui_data();

	if (fb_config)
	{
		fbcon_clear();
		display_error_message();   // No point in checking the return value here
	}

	// Invalid state. Nothing to be done but contacting the OEM.
	// Stop boot process.
	dprintf(CRITICAL,"ERROR: blocking boot process\n");
	for(;;);
}

/**
 *  Display error message in case mdtp image is corrupted and stop boot process.
 */
void display_error_msg_mdtp()
{
	int big_factor = 8; // Font size
	char* str = "Device unable to boot";
	char* str2 = "\nError - mdtp image is corrupted\n";
	fbcon_clear();
	while(*str != 0) {
		fbcon_putc_factor(*str++, FBCON_COMMON_MSG, big_factor);
	}
	fbcon_draw_line(FBCON_COMMON_MSG);
	while(*str2 != 0) {
		fbcon_putc_factor(*str2++, FBCON_COMMON_MSG, big_factor);
	}
	fbcon_draw_line(FBCON_COMMON_MSG);

	// Invalid state. Nothing to be done but contacting the OEM.
	// Stop boot process.
	dprintf(CRITICAL,"ERROR: blocking boot process - mdtp image corrupted\n");
	for(;;);

}

