#include "low_level_touch_ft6336u.h"
#include "board_config.h"
#include <cstdio>

LowLevelTouchFT6336U::LowLevelTouchFT6336U(int width, int height, bool swap_xy, 
                                           bool invert_x, bool invert_y)
    : screen_width(width)
    , screen_height(height)
    , swap_xy(swap_xy)
    , invert_x(invert_x)
    , invert_y(invert_y)
    , initialized(false)
{
}

LowLevelTouchFT6336U::~LowLevelTouchFT6336U() {
    // Cleanup if needed
}

bool LowLevelTouchFT6336U::init() {
    if (initialized) {
        return true;
    }
    
    // Build configuration from board_config.h
    ft6336u_config_t config = {
        .i2c = TOUCH_I2C_PORT,
        .gpio_sda = TOUCH_SDA_PIN,
        .gpio_scl = TOUCH_SCL_PIN,
        .gpio_rst = TOUCH_RST_PIN,
        .gpio_int = TOUCH_INT_PIN,
        .screen_width = (uint16_t)screen_width,
        .screen_height = (uint16_t)screen_height,
        .swap_xy = swap_xy,
        .invert_x = invert_x,
        .invert_y = invert_y
    };
    
    // Print the complete configuration for debugging
    printf("\n=== FT6336U Touch Configuration ===\n");
    printf("  I2C Port: %s\n", config.i2c == i2c0 ? "i2c0" : "i2c1");
    printf("  SDA Pin: %d\n", config.gpio_sda);
    printf("  SCL Pin: %d\n", config.gpio_scl);
    printf("  RST Pin: %d\n", config.gpio_rst);
    printf("  INT Pin: %d\n", config.gpio_int);
    printf("  Screen: %dx%d\n", config.screen_width, config.screen_height);
    printf("  Swap XY: %s\n", config.swap_xy ? "true" : "false");
    printf("  Invert X: %s\n", config.invert_x ? "true" : "false");
    printf("  Invert Y: %s\n", config.invert_y ? "true" : "false");
    printf("===================================\n\n");
    fflush(stdout);
    
    initialized = ft6336u_init(&config);
    
    if (initialized) {
        printf("Touch FT6336U initialized: Chip ID=0x%02X, FW Ver=0x%02X\n", 
               get_chip_id(), get_firmware_version());
    } else {
        printf("Touch FT6336U initialization failed!\n");
    }
    
    return initialized;
}

bool LowLevelTouchFT6336U::read_touch(TouchData* data) {
    if (!initialized || !data) {
        return false;
    }
    
    ft6336u_touch_data_t ft_data;
    if (!ft6336u_read_touch(&ft_data)) {
        return false;
    }
    
    // Convert from FT6336U format to our abstract format
    data->touch_count = ft_data.touch_count;
    data->gesture = ft_data.gesture;
    
    for (int i = 0; i < ft_data.touch_count && i < TOUCH_MAX_POINTS; i++) {
        data->points[i].x = ft_data.points[i].x;
        data->points[i].y = ft_data.points[i].y;
        data->points[i].event = ft_data.points[i].event;
        data->points[i].id = ft_data.points[i].id;
        data->points[i].pressure = ft_data.points[i].weight;
    }
    
    return true;
}

bool LowLevelTouchFT6336U::is_touched() {
    if (!initialized) {
        return false;
    }
    return ft6336u_is_touched();
}

uint8_t LowLevelTouchFT6336U::get_chip_id() {
    return ft6336u_get_chip_id();
}

uint8_t LowLevelTouchFT6336U::get_firmware_version() {
    return ft6336u_get_firmware_version();
}

void LowLevelTouchFT6336U::set_coordinate_transform(bool swap_xy, bool invert_x, bool invert_y) {
    this->swap_xy = swap_xy;
    this->invert_x = invert_x;
    this->invert_y = invert_y;
    
    // Note: This only updates internal state. To apply to the driver,
    // you would need to reinitialize with the new settings.
    printf("Touch coordinate transform updated (requires re-init to apply)\n");
}

void LowLevelTouchFT6336U::set_interrupt_callback(void (*callback)(unsigned int gpio, uint32_t events)) {
    ft6336u_set_interrupt_callback(callback);
}

bool LowLevelTouchFT6336U::test_communication() {
    return ft6336u_test_i2c();
}
