#include "lcd_touch.h"
#include "lcd_2inch.h"
#include "lcd_gui.h"
#include <Wire.h>

tp_dev_t tp_dev;

#define CST816_ADDR 0x15

#define SCREEN_W    320
#define SCREEN_H    240

#define MENU_W      80  

#define BTN_H       34 
#define GAP         4   // Button gap
#define BTN_START_X 5
#define BTN_W       (MENU_W - 10) 

// Total height 240px. Button Y positions:
#define Y_BTN1      5   // Clear
#define Y_BTN2      44  // Red
#define Y_BTN3      83  // Green
#define Y_BTN4      122 // Blue
#define Y_BTN5      161 // Black
#define Y_BTN6      200 // YELLOW


// I2C driver section
void CST816_Write_Reg(uint8_t reg, uint8_t data) {
    Wire.beginTransmission(CST816_ADDR);
    Wire.write(reg);
    Wire.write(data);
    Wire.endTransmission();
}

uint8_t CST816_Read_Reg(uint8_t reg) {
    Wire.beginTransmission(CST816_ADDR);
    Wire.write(reg);
    Wire.endTransmission(false);
    Wire.requestFrom((uint8_t)CST816_ADDR, (uint8_t)1);
    return Wire.read();
}

void TP_Init(void)
{
    tp_dev.paint_color = BLACK; 
    
    pinMode(TP_RST, OUTPUT);
    pinMode(TP_INT, INPUT_PULLUP);

    digitalWrite(TP_RST, HIGH); delay(50);
    digitalWrite(TP_RST, LOW);  delay(10);
    digitalWrite(TP_RST, HIGH); delay(50);

    Wire.begin(TP_SDA, TP_SCL);
}

void TP_Scan(uint8_t mode)
{
    uint8_t touch_data[7];
    Wire.beginTransmission(CST816_ADDR);
    Wire.write(0x01); 
    Wire.endTransmission(false);
    
    if (Wire.requestFrom((uint8_t)CST816_ADDR, (uint8_t)6) == 6) {
        for (int i = 0; i < 6; i++) touch_data[i] = Wire.read();
        
        if (touch_data[1] > 0) {
            uint16_t raw_x = ((touch_data[2] & 0x0F) << 8) | touch_data[3];
            uint16_t raw_y = ((touch_data[4] & 0x0F) << 8) | touch_data[5];

            tp_dev.x[0] = raw_y;
            tp_dev.y[0] = raw_x; 
            
            tp_dev.statu = TP_PRESS_DOWN;
        } else {
            tp_dev.statu = 0;
        }
    } else {
        tp_dev.statu = 0;
    }
}

void Load_Draw_Board(void)
{
    // Clear background
    LCD_Clear(WHITE);

    // [1] CLEAR
    Gui_fill_color(BTN_START_X, Y_BTN1, BTN_START_X+BTN_W, Y_BTN1+BTN_H, BLUE);
    Gui_draw_str(BTN_START_X+18, Y_BTN1+10, "CLR", &Font16, RED, BLUE);

    // [2] RED
    Gui_fill_color(BTN_START_X, Y_BTN2, BTN_START_X+BTN_W, Y_BTN2+BTN_H, RED);

    // [3] GREEN
    Gui_fill_color(BTN_START_X, Y_BTN3, BTN_START_X+BTN_W, Y_BTN3+BTN_H, GREEN);

    // [4] BLUE
    Gui_fill_color(BTN_START_X, Y_BTN4, BTN_START_X+BTN_W, Y_BTN4+BTN_H, BLUE);

    // [5] BLACK
    Gui_fill_color(BTN_START_X, Y_BTN5, BTN_START_X+BTN_W, Y_BTN5+BTN_H, BLACK);

    // [6] YELLOW
    Gui_fill_color(BTN_START_X, Y_BTN6, BTN_START_X+BTN_W, Y_BTN6+BTN_H, YELLOW);

    // Separator line
    Gui_draw_line(MENU_W, 0, MENU_W, SCREEN_H, BLACK, 1, SOLID);
}

void TP_Test(void)
{
    TP_Scan(0);

    if (tp_dev.statu & TP_PRESS_DOWN)
    {
        uint16_t x = tp_dev.x[0];
        uint16_t y = tp_dev.y[0];


        if (x < MENU_W)
        {
            delay(150); 

             if (y > Y_BTN1 && y < Y_BTN1+BTN_H) { // [CLEAR]
                Serial.println("Action: Clear");
                Gui_fill_color(MENU_W+1, 0, SCREEN_W-1, SCREEN_H-1, WHITE);
            }
            else if (y > Y_BTN2 && y < Y_BTN2+BTN_H) { // [RED]
                Serial.println("Color: RED");
                tp_dev.paint_color = RED;
            }
            else if (y > Y_BTN3 && y < Y_BTN3+BTN_H) { // [GREEN]
                Serial.println("Color: GREEN");
                tp_dev.paint_color = GREEN;
            }
            else if (y > Y_BTN4 && y < Y_BTN4+BTN_H) { // [BLUE]
                Serial.println("Color: BLUE");
                tp_dev.paint_color = BLUE;
            }
            else if (y > Y_BTN5 && y < Y_BTN5+BTN_H) { // [BLACK]
                Serial.println("Color: BLACK");
                tp_dev.paint_color = BLACK;
            }
            else if (y > Y_BTN6 && y < Y_BTN6+BTN_H) { // [YELLOW]
                Serial.println("Color: YELLOW");
                tp_dev.paint_color = YELLOW;
            }
        }

        else 
        {
            // Draw a point in the drawing area
            Gui_draw_point(x, y, tp_dev.paint_color, 4);
        }
    }
}
