#include "TZ_Vendor_tl.h"
#include "TZ_Vendor_debug_tl.h"
#include "TuiScreenResource.h"

uint8_t* screen_resource[SCREEN_COUNT];
uint32_t screen_sizes[SCREEN_COUNT];

uint8_t* font_01_resource[FONT_01_COUNT];
uint32_t font_01_sizes[FONT_01_COUNT];
uint8_t* font_02_resource[FONT_02_COUNT];
uint32_t font_02_sizes[FONT_02_COUNT];
uint8_t* font_03_resource[FONT_03_COUNT];
uint32_t font_03_sizes[FONT_03_COUNT];
uint8_t* font_04_resource[FONT_04_COUNT];
uint32_t font_04_sizes[FONT_04_COUNT];
uint8_t* font_07_resource[FONT_07_COUNT];
uint32_t font_07_sizes[FONT_07_COUNT];
uint8_t* font_08_resource[FONT_08_COUNT];
uint32_t font_08_sizes[FONT_08_COUNT];
uint8_t* font_09_resource[FONT_09_COUNT];
uint32_t font_09_sizes[FONT_09_COUNT];

uint8_t* keypad_resource[KEYPAD_COUNT];
uint32_t keypad_sizes[KEYPAD_COUNT];

uint32_t setAResource(const uint8_t *buf, uint32_t offset, uint8_t count, uint32_t resource_sizes[], uint8_t *resource_buf[]);

enum SCREEN_RESOURCES {img_screen_pharse_input_textarea, img_screen_recommend_bg, img_screen_recommend_bg_blank, img_screen_recommend_bg_more, img_screen_text_field_input_activated, img_screen_text_field_input_error, img_screen_font_01_blank_field_all_del, img_screen_confirmation_divider, img_screen_tui_button_divider, img_screen_word_bg, img_screen_word_bg_del, img_screen_word_blank, img_screen_btn_word_del, img_screen_confirm_text_field_input_activated, img_screen_confirm_text_field_input_complete, img_screen_confirm_text_field_input_error, img_screen_ic_enter, img_screen_ic_enter_0, img_screen_ic_enter_pressed, img_screen_ic_v};

#define RESOURCE_TYPE_COUNT 10
uint32_t resCount[RESOURCE_TYPE_COUNT] = {
        SCREEN_COUNT,
        KEYPAD_COUNT,
        FONT_01_COUNT,
        FONT_02_COUNT,
        FONT_03_COUNT,
        FONT_04_COUNT,
        FONT_07_COUNT,
        FONT_08_COUNT,
        FONT_09_COUNT
};
uint32_t *resSizes[RESOURCE_TYPE_COUNT] = {
        screen_sizes,
        keypad_sizes,
        font_01_sizes,
        font_02_sizes,
        font_03_sizes,
        font_04_sizes,
        font_07_sizes,
        font_08_sizes,
        font_09_sizes
};

uint8_t **resResources[RESOURCE_TYPE_COUNT]= {
        screen_resource,
        keypad_resource,
        font_01_resource,
        font_02_resource,
        font_03_resource,
        font_04_resource,
        font_07_resource,
        font_08_resource,
        font_09_resource
};

uint8_t* getScreenResource(uint32_t resourceId, uint32_t *resourceSize) {
	switch (resourceId) {
    case ID_RESOURCE_RESTORE_TEXT_INPUT_ACTIVATED:
        *resourceSize = screen_sizes[img_screen_text_field_input_activated];
        return screen_resource[img_screen_text_field_input_activated];
    case ID_RESOURCE_RESTORE_TEXT_INPUT_ERROR:
        *resourceSize = screen_sizes[img_screen_text_field_input_error];
        return screen_resource[img_screen_text_field_input_error];
    case ID_RESOURCE_RESTORE_TEXT_INPUT_CLEAR:
        *resourceSize = screen_sizes[img_screen_font_01_blank_field_all_del];
        return screen_resource[img_screen_font_01_blank_field_all_del];
    case ID_RESOURCE_RESTORE_PHARSE_TEXTAREA:
        *resourceSize = screen_sizes[img_screen_pharse_input_textarea];
        return screen_resource[img_screen_pharse_input_textarea];
    case ID_RESOURCE_RESTORE_RECOMMEND_BG:
        *resourceSize = screen_sizes[img_screen_recommend_bg];
        return screen_resource[img_screen_recommend_bg];
    case ID_RESOURCE_RESTORE_RECOMMEND_CLEAR:
        *resourceSize = screen_sizes[img_screen_recommend_bg_blank];
        return screen_resource[img_screen_recommend_bg_blank];
    case ID_RESOURCE_RESTORE_RECOMMEND_MORE:
        *resourceSize = screen_sizes[img_screen_recommend_bg_more];
        return screen_resource[img_screen_recommend_bg_more];
    case ID_RESOURCE_CONFIRM_DIVIDER:
        *resourceSize = screen_sizes[img_screen_confirmation_divider];
        return screen_resource[img_screen_confirmation_divider];
    case ID_RESOURCE_RESTORE_WORD_BG:
        *resourceSize = screen_sizes[img_screen_word_bg];
        return screen_resource[img_screen_word_bg];
    case ID_RESOURCE_RESTORE_WORD_FOCUS_BG:
        *resourceSize = screen_sizes[img_screen_word_bg_del];
        return screen_resource[img_screen_word_bg_del];
    case ID_RESOURCE_RESTORE_WORD_CLEAR:
        *resourceSize = screen_sizes[img_screen_word_blank];
        return screen_resource[img_screen_word_blank];
    case ID_RESOURCE_RESTORE_BUTTON_DELETE_WORD:
        *resourceSize = screen_sizes[img_screen_btn_word_del];
        return screen_resource[img_screen_btn_word_del];
    case ID_RESOURCE_BACKUP_QUIZ_TEXT_INPUT_ACTIVATED:
        *resourceSize = screen_sizes[img_screen_confirm_text_field_input_activated];
        return screen_resource[img_screen_confirm_text_field_input_activated];
    case ID_RESOURCE_BACKUP_QUIZ_TEXT_INPUT_COMPLETE:
        *resourceSize = screen_sizes[img_screen_confirm_text_field_input_complete];
        return screen_resource[img_screen_confirm_text_field_input_complete];
    case ID_RESOURCE_BACKUP_QUIZ_TEXT_INPUT_ERROR:
        *resourceSize = screen_sizes[img_screen_confirm_text_field_input_error];
        return screen_resource[img_screen_confirm_text_field_input_error];
    case ID_RESOURCE_BACKUP_QUIZ_BUTTON_ENTER_ENABLE:
        *resourceSize = screen_sizes[img_screen_ic_enter];
        return screen_resource[img_screen_ic_enter];
    case ID_RESOURCE_BACKUP_QUIZ_BUTTON_ENTER_PRESSED:
        *resourceSize = screen_sizes[img_screen_ic_enter_pressed];
        return screen_resource[img_screen_ic_enter_pressed];
    case ID_RESOURCE_BACKUP_QUIZ_BUTTON_ENTER_DEFAULT:
        *resourceSize = screen_sizes[img_screen_ic_enter_0];
        return screen_resource[img_screen_ic_enter_0];
    case ID_RESOURCE_BACKUP_QUIZ_BUTTON_ENTER_CHECKED:
        *resourceSize = screen_sizes[img_screen_ic_v];
        return screen_resource[img_screen_ic_v];

	default:
		TTY_LOG("Invalid Screen Resource ID : %d", resourceId);
		*resourceSize = 0;
		return NULL;
	}
}

EFontType getScreenFontType(uint32_t resourceId) {
	switch (resourceId) {
	case ID_FONT_TYPE_RESTORE_MNEMONIC_LIST:
		return FONT_TYPE_02;
	case ID_FONT_TYPE_RESTORE_MNEMONIC_INPUT:
		return FONT_TYPE_01;
	case ID_FONT_TYPE_RESTORE_MNEMONIC_RECOMMEND:
		return FONT_TYPE_02;
	case ID_FONT_TYPE_BACKUP_MNEMONIC_LIST:
		return FONT_TYPE_03;
	case ID_FONT_TYPE_CONFIRM_ADDRESS:
		return FONT_TYPE_02;
	case ID_FONT_TYPE_CONFIRM_AMOUNT:
		return FONT_TYPE_04;
	case ID_FONT_TYPE_CONFIRM_TOTAL:
		return FONT_TYPE_08;
	case ID_FONT_TYPE_CONFIRM_DATA:
		return FONT_TYPE_07;
	case ID_FONT_TYPE_CONFIRM_GAS:
		return FONT_TYPE_07;
	case ID_FONT_TYPE_BACKUP_MNEMONIC_PHRASE_NUMBER:
	    return FONT_TYPE_09;
	default:
		TTY_LOG("Invalid FontType ID : %d", resourceId);
		return FONT_TYPE_01;
	}
}

void setResources(const uint32_t idx, const uint8_t *buf) {
    if (idx == 0xFF) {
        TTY_LOG("free all current screen resources");
        for(int i=0; i<RESOURCE_TYPE_COUNT; i++) {
            for(int j=0; j<resCount[i]; j++) {
                if(resResources[i][j] != NULL) {
                    TZ_free(resResources[i][j]);
                    resResources[i][j] = NULL;
                }
            }
        }
        return;
    }
    //read resource size header
    TTY_LOG("set resource with index %d", idx);

    uint32_t total = *((uint32_t *)buf);
    uint32_t offset = 4;
    const uint8_t count = buf[offset++];

    if(resCount[idx] != count) // error
        TTY_LOG("setResources count error with idx %d : %d", idx, count);

    offset = setAResource(buf, offset, resCount[idx], resSizes[idx], resResources[idx]);

    if (total != offset-4) {
        TTY_LOG("error! : written bytes %d is not matched with header %d", offset-4, total);
    }
}

uint32_t setAResource(const uint8_t *buf, uint32_t offset, uint8_t count, uint32_t resource_sizes[], uint8_t *resource_buf[]) {
    for(int i=0; i < count; i++) {
        resource_sizes[i] = (buf[offset] << 8) + buf[offset + 1];
        offset += 2;

        resource_sizes[i] = (resource_sizes[i] << 16) + (buf[offset] << 8) + buf[offset + 1];
        offset += 2;

        if (resource_buf[i] != NULL) {
            TZ_free(resource_buf[i]);
        }
        resource_buf[i] = TZ_malloc(resource_sizes[i]);

        memcpy(resource_buf[i], buf+offset, resource_sizes[i]);
        offset += resource_sizes[i];
    }
    return offset;
}
