#include <SDL2/SDL.h>
#include <SDL2/SDL_net.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define TOP_BAR_HEIGHT 50
#define TITLE_BAR_HEIGHT 20
#define BUTTON_WIDTH 80
#define BUTTON_HEIGHT 30
#define SCROLL_SPEED 30
#define MAX_URL_LENGTH 2048
#define MAX_CONTENT_LINES 10000
#define MAX_LINE_LENGTH 4096

#define CHAR_WIDTH 6
#define CHAR_HEIGHT 8

typedef enum {
    STATE_BROWSER,
    STATE_OPTIONS
} AppState;

typedef struct {
    char url[MAX_URL_LENGTH];
    int cursor_pos;
    int active;
} UrlBar;

typedef enum {
    ELEM_NONE,
    ELEM_TEXT_INPUT,
    ELEM_BUTTON,
    ELEM_TEXTAREA
} FormElemType;

typedef struct {
    char *text;
    unsigned char *bold_mask;    // 1 = bold, 0 = normal
    unsigned char *italic_mask;  // 1 = italic, 0 = normal
    char **link_urls;            // URL for link text, NULL if not a link
    int length;
    int font_scale;  // 1 = normal, 2-3 = headings
    FormElemType form_elem;      // Type of form element on this line
    char *input_name;            // Name attribute for form inputs
    char *input_value;           // Current value of input
    int input_width;             // Width in characters
} Line;

typedef struct {
    Line *lines;
    int line_count;
    int scroll_y;
    int content_height;
} ContentView;

typedef struct {
    SDL_Window *window;
    SDL_Renderer *renderer;
    AppState state;
    UrlBar url_bar;
    ContentView content;
    char page_title[256];
    int running;
    int window_width;
    int window_height;
    SDL_Rect refresh_btn;
    SDL_Rect options_btn;
    SDL_Rect url_bar_rect;
    // Form state
    int focused_line;           // Which line has the focused input (-1 = none)
    int cursor_pos;             // Cursor position in focused input
} Browser;

static const unsigned char font8x8_basic[128][8] = {
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},
    {0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},
    {0x0C, 0x3E, 0x03, 0x1E, 0x60, 0x3F, 0x0C, 0x00},
    {0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},
    {0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},
    {0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00},
    {0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00},
    {0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00},
    {0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06},
    {0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00},
    {0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00},
    {0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00},
    {0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00},
    {0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00},
    {0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00},
    {0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00},
    {0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00},
    {0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00},
    {0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00},
    {0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},
    {0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},
    {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},
    {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},
    {0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},
    {0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},
    {0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},
    {0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00},
    {0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},
    {0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},
    {0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},
    {0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},
    {0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},
    {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},
    {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},
    {0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},
    {0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},
    {0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},
    {0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},
    {0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},
    {0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},
    {0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},
    {0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},
    {0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},
    {0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},
    {0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},
    {0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},
    {0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},
    {0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},
    {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},
    {0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},
    {0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},
    {0x63, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x63, 0x00},
    {0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},
    {0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00},
    {0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00},
    {0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00},
    {0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00},
    {0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},
    {0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
    {0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00},
    {0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00},
    {0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00},
    {0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00},
    {0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00},
    {0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00},
    {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F},
    {0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00},
    {0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},
    {0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E},
    {0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00},
    {0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},
    {0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00},
    {0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00},
    {0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00},
    {0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F},
    {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78},
    {0x00, 0x00, 0x3B, 0x6E, 0x06, 0x06, 0x0F, 0x00},
    {0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00},
    {0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00},
    {0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00},
    {0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},
    {0x00, 0x00, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},
    {0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00},
    {0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F},
    {0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00},
    {0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00},
    {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},
    {0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},
    {0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
};

void fetch_url(const char *url, const char *method, char **response, size_t *response_size);

void init_content_view(ContentView *cv) {
    cv->lines = malloc(MAX_CONTENT_LINES * sizeof(Line));
    cv->line_count = 0;
    cv->scroll_y = 0;
    cv->content_height = 0;
}

void free_content_view(ContentView *cv) {
    for (int i = 0; i < cv->line_count; i++) {
        free(cv->lines[i].text);
        free(cv->lines[i].bold_mask);
        free(cv->lines[i].italic_mask);
        if (cv->lines[i].link_urls) {
            for (int j = 0; j < cv->lines[i].length; j++) {
                free(cv->lines[i].link_urls[j]);
            }
            free(cv->lines[i].link_urls);
        }
        free(cv->lines[i].input_name);
        free(cv->lines[i].input_value);
    }
    free(cv->lines);
}

void add_content_line(ContentView *cv, const char *line) {
    if (cv->line_count < MAX_CONTENT_LINES) {
        size_t len = strlen(line);
        cv->lines[cv->line_count].text = strdup(line);
        cv->lines[cv->line_count].bold_mask = calloc(len + 1, sizeof(unsigned char));
        cv->lines[cv->line_count].italic_mask = calloc(len + 1, sizeof(unsigned char));
        cv->lines[cv->line_count].link_urls = calloc(len + 1, sizeof(char*));
        cv->lines[cv->line_count].length = len;
        cv->lines[cv->line_count].font_scale = 1;
        cv->lines[cv->line_count].form_elem = ELEM_NONE;
        cv->lines[cv->line_count].input_name = NULL;
        cv->lines[cv->line_count].input_value = NULL;
        cv->lines[cv->line_count].input_width = 20;
        cv->line_count++;
    }
}

void load_sample_content(ContentView *cv) {
    free_content_view(cv);
    init_content_view(cv);

    add_content_line(cv, "Welcome to SDL Browser!");
    add_content_line(cv, "");
    add_content_line(cv, "This is a simple browser built with SDL2.");
    add_content_line(cv, "");
    add_content_line(cv, "Features:");
    add_content_line(cv, "- URL bar at the top");
    add_content_line(cv, "- Page title display above URL bar");
    add_content_line(cv, "- Refresh button");
    add_content_line(cv, "- Options button (top-right)");
    add_content_line(cv, "- Scrollable content area");
    add_content_line(cv, "- HTML parsing with <p>, <b>, and <title> support");
    add_content_line(cv, "");
    add_content_line(cv, "Enter a URL above to fetch content.");
    add_content_line(cv, "Or click Options for settings.");

    cv->content_height = cv->line_count * 20;
}

void update_layout(Browser *browser) {
    browser->refresh_btn.x = 10;
    browser->refresh_btn.y = 10 + TITLE_BAR_HEIGHT;
    browser->refresh_btn.w = BUTTON_WIDTH;
    browser->refresh_btn.h = BUTTON_HEIGHT;

    browser->options_btn.x = browser->window_width - BUTTON_WIDTH - 10;
    browser->options_btn.y = 10 + TITLE_BAR_HEIGHT;
    browser->options_btn.w = BUTTON_WIDTH;
    browser->options_btn.h = BUTTON_HEIGHT;

    browser->url_bar_rect.x = browser->refresh_btn.x + browser->refresh_btn.w + 10;
    browser->url_bar_rect.y = 10 + TITLE_BAR_HEIGHT;
    browser->url_bar_rect.w = browser->options_btn.x - browser->url_bar_rect.x - 10;
    browser->url_bar_rect.h = 30;
}

typedef struct {
    char host[256];
    char path[1024];
    int port;
    int is_https;
} ParsedURL;

int parse_url(const char *url, ParsedURL *parsed) {
    memset(parsed, 0, sizeof(ParsedURL));
    parsed->port = 80;
    
    const char *ptr = url;
    
    if (strncmp(ptr, "http://", 7) == 0) {
        ptr += 7;
        parsed->is_https = 0;
        parsed->port = 80;
    } else if (strncmp(ptr, "https://", 8) == 0) {
        ptr += 8;
        parsed->is_https = 1;
        parsed->port = 443;
        fprintf(stderr, "Warning: HTTPS not supported yet, using HTTP\n");
    } else {
        parsed->is_https = 0;
        parsed->port = 80;
    }
    
    // Find end of host (first / or ?)
    const char *path_start = strchr(ptr, '/');
    const char *query_start = strchr(ptr, '?');
    
    // Use whichever comes first
    const char *end_of_host = path_start;
    if (!end_of_host || (query_start && query_start < end_of_host)) {
        end_of_host = query_start;
    }
    
    if (end_of_host) {
        size_t host_len = end_of_host - ptr;
        if (host_len >= sizeof(parsed->host)) host_len = sizeof(parsed->host) - 1;
        strncpy(parsed->host, ptr, host_len);
        parsed->host[host_len] = '\0';
        // Ensure path starts with /
        if (*end_of_host == '?') {
            snprintf(parsed->path, sizeof(parsed->path), "/%s", end_of_host);
        } else {
            strncpy(parsed->path, end_of_host, sizeof(parsed->path) - 1);
            parsed->path[sizeof(parsed->path) - 1] = '\0';
        }
    } else {
        strncpy(parsed->host, ptr, sizeof(parsed->host) - 1);
        parsed->host[sizeof(parsed->host) - 1] = '\0';
        strcpy(parsed->path, "/");
    }
    
    // Extract port from host if present
    char *colon = strrchr(parsed->host, ':');
    if (colon) {
        *colon = '\0';
        parsed->port = atoi(colon + 1);
    }
    
    return 0;
}

void fetch_url(const char *url, const char *method, char **response, size_t *response_size) {
    printf("Fetching URL: %s (Method: %s)\n", url, method);
    
    ParsedURL parsed;
    if (parse_url(url, &parsed) != 0) {
        const char *error_msg = "Error: Failed to parse URL\n";
        *response_size = strlen(error_msg) + 1;
        *response = malloc(*response_size);
        strcpy(*response, error_msg);
        return;
    }
    
    printf("Connecting to %s:%d%s\n", parsed.host, parsed.port, parsed.path);
    
    IPaddress ip;
    if (SDLNet_ResolveHost(&ip, parsed.host, parsed.port) < 0) {
        char error_msg[512];
        snprintf(error_msg, sizeof(error_msg), "Error: Could not resolve host '%s': %s\n", parsed.host, SDLNet_GetError());
        *response_size = strlen(error_msg) + 1;
        *response = malloc(*response_size);
        strcpy(*response, error_msg);
        return;
    }
    
    TCPsocket socket = SDLNet_TCP_Open(&ip);
    if (!socket) {
        char error_msg[512];
        snprintf(error_msg, sizeof(error_msg), "Error: Could not connect to '%s:%d': %s\n", parsed.host, parsed.port, SDLNet_GetError());
        *response_size = strlen(error_msg) + 1;
        *response = malloc(*response_size);
        strcpy(*response, error_msg);
        return;
    }
    
    char request[4096];
    snprintf(request, sizeof(request),
        "%s %s HTTP/1.1\r\n"
        "Host: %s\r\n"
        "User-Agent: SDLBrowser/0.0\r\n"
        "Accept: */*\r\n"
        "Connection: close\r\n"
        "\r\n",
        method, parsed.path, parsed.host);
    
    if (SDLNet_TCP_Send(socket, request, strlen(request)) < (int)strlen(request)) {
        char error_msg[512];
        snprintf(error_msg, sizeof(error_msg), "Error: Failed to send request: %s\n", SDLNet_GetError());
        SDLNet_TCP_Close(socket);
        *response_size = strlen(error_msg) + 1;
        *response = malloc(*response_size);
        strcpy(*response, error_msg);
        return;
    }
    
    size_t buffer_size = 8192;
    *response = malloc(buffer_size);
    *response_size = 0;
    
    char recv_buffer[1024];
    int recv_len;
    while ((recv_len = SDLNet_TCP_Recv(socket, recv_buffer, sizeof(recv_buffer) - 1)) > 0) {
        if (*response_size + recv_len >= buffer_size) {
            buffer_size *= 2;
            *response = realloc(*response, buffer_size);
        }
        memcpy(*response + *response_size, recv_buffer, recv_len);
        *response_size += recv_len;
    }
    
    SDLNet_TCP_Close(socket);
    
    if (*response_size + 1 >= buffer_size) {
        buffer_size = *response_size + 1;
        *response = realloc(*response, buffer_size);
    }
    (*response)[*response_size] = '\0';
    
    printf("Received %zu bytes\n", *response_size);
}

void draw_char(SDL_Renderer *renderer, char c, int x, int y, SDL_Color color) {
    unsigned char ch = (unsigned char)c;
    if (ch > 127) ch = '?';
    
    for (int row = 0; row < 8; row++) {
        for (int col = 0; col < 6; col++) {
            if (font8x8_basic[ch][row] & (1 << col)) {
                SDL_Rect pixel = {
                    x + col,
                    y + row,
                    1,
                    1
                };
                SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
                SDL_RenderFillRect(renderer, &pixel);
            }
        }
    }
}

void render_text(Browser *browser, const char *text, int x, int y, SDL_Color color) {
    for (size_t i = 0; i < strlen(text); i++) {
        draw_char(browser->renderer, text[i], x + i * CHAR_WIDTH, y, color);
    }
}

int text_width(const char *text) {
    return strlen(text) * CHAR_WIDTH;
}

void render_button(Browser *browser, SDL_Rect *rect, const char *label, int hovered) {
    SDL_Color bg_color = hovered ? (SDL_Color){100, 100, 100, 255} : (SDL_Color){70, 70, 70, 255};
    SDL_SetRenderDrawColor(browser->renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
    SDL_RenderFillRect(browser->renderer, rect);
    
    SDL_SetRenderDrawColor(browser->renderer, 150, 150, 150, 255);
    SDL_RenderDrawRect(browser->renderer, rect);
    
    SDL_Color text_color = {255, 255, 255, 255};
    int text_w = text_width(label);
    int text_x = rect->x + (rect->w - text_w) / 2;
    int text_y = rect->y + (rect->h - CHAR_HEIGHT) / 2;
    
    render_text(browser, label, text_x, text_y, text_color);
}

void render_url_bar(Browser *browser) {
    SDL_Color bg_color = browser->url_bar.active ? (SDL_Color){50, 50, 50, 255} : (SDL_Color){40, 40, 40, 255};
    SDL_SetRenderDrawColor(browser->renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
    SDL_RenderFillRect(browser->renderer, &browser->url_bar_rect);
    
    SDL_SetRenderDrawColor(browser->renderer, 100, 100, 100, 255);
    SDL_RenderDrawRect(browser->renderer, &browser->url_bar_rect);
    
    SDL_Color text_color = {255, 255, 255, 255};
    
    char display_url[MAX_URL_LENGTH];
    if (strlen(browser->url_bar.url) == 0 && !browser->url_bar.active) {
        strcpy(display_url, "Enter URL...");
        text_color = (SDL_Color){150, 150, 150, 255};
    } else {
        strcpy(display_url, browser->url_bar.url);
    }
    
    render_text(browser, display_url, browser->url_bar_rect.x + 10, 
                browser->url_bar_rect.y + (browser->url_bar_rect.h - CHAR_HEIGHT) / 2, text_color);
}

void draw_scaled_char(SDL_Renderer *renderer, char c, int x, int y, SDL_Color color, int scale, int is_italic) {
    unsigned char ch = (unsigned char)c;
    if (ch > 127) ch = '?';

    for (int row = 0; row < 8; row++) {
        for (int col = 0; col < 6; col++) {
            if (font8x8_basic[ch][row] & (1 << col)) {
                // Calculate italic offset (slant to the right)
                int italic_offset = is_italic ? (row * scale) / 3 : 0;
                // Draw scaled pixel (scale x scale rectangle)
                SDL_Rect pixel = {
                    x + col * scale + italic_offset,
                    y + row * scale,
                    scale,
                    scale
                };
                SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
                SDL_RenderFillRect(renderer, &pixel);
            }
        }
    }
}

void render_line(Browser *browser, Line *line, int x, int y, SDL_Color color, int line_index, int is_focused) {
    int x_pos = x;
    int scale = line->font_scale > 0 ? line->font_scale : 1;
    int letter_spacing = 1;
    int char_width = CHAR_WIDTH * scale + letter_spacing;
    int line_height = 8 * scale;
    
    // Handle form elements specially
    if (line->form_elem == ELEM_TEXT_INPUT || line->form_elem == ELEM_TEXTAREA) {
        // Draw input box background
        int input_width = line->input_width * char_width + 10;
        int input_height = line_height + 8;
        
        SDL_Rect input_box = {x_pos, y - 2, input_width, input_height};
        
        // White background for input
        SDL_SetRenderDrawColor(browser->renderer, 255, 255, 255, 255);
        SDL_RenderFillRect(browser->renderer, &input_box);
        
        // Border - blue if focused, gray if not
        if (is_focused) {
            SDL_SetRenderDrawColor(browser->renderer, 0, 100, 255, 255);
        } else {
            SDL_SetRenderDrawColor(browser->renderer, 150, 150, 150, 255);
        }
        SDL_RenderDrawRect(browser->renderer, &input_box);
        
        // Draw input value text
        if (line->input_value && line->input_value[0]) {
            int text_x = x_pos + 5;
            int text_y = y + 2;
            for (int i = 0; line->input_value[i] && i < line->input_width; i++) {
                SDL_Color text_color = {0, 0, 0, 255};
                draw_scaled_char(browser->renderer, line->input_value[i], text_x, text_y, text_color, scale, 0);
                text_x += char_width;
            }
        }
        
        // Draw cursor if focused
        if (is_focused) {
            int cursor_x = x_pos + 5 + (browser->cursor_pos * char_width);
            SDL_SetRenderDrawColor(browser->renderer, 0, 0, 0, 255);
            SDL_RenderDrawLine(browser->renderer, cursor_x, y + 2, cursor_x, y + line_height);
        }
        return;
    }
    
    if (line->form_elem == ELEM_BUTTON) {
        // Draw button
        int button_width = line->input_width * char_width;
        int button_height = line_height + 8;
        
        SDL_Rect button = {x_pos, y - 2, button_width, button_height};
        
        // Button background
        SDL_SetRenderDrawColor(browser->renderer, 220, 220, 220, 255);
        SDL_RenderFillRect(browser->renderer, &button);
        
        // Button border
        SDL_SetRenderDrawColor(browser->renderer, 100, 100, 100, 255);
        SDL_RenderDrawRect(browser->renderer, &button);
        
        // Button text (centered)
        int text_width = line->length * char_width;
        int text_x = x_pos + (button_width - text_width) / 2;
        int text_y = y + 2;
        
        for (int i = 0; i < line->length; i++) {
            draw_scaled_char(browser->renderer, line->text[i], text_x, text_y, color, scale, 0);
            text_x += char_width;
        }
        return;
    }

    // Regular text rendering
    int in_link = 0;
    int link_start_x = x;
    int link_end_x = x;
    char current_link_url[1024] = {0};

    for (int i = 0; i < line->length; i++) {
        int is_bold = line->bold_mask && line->bold_mask[i];
        int is_italic = line->italic_mask && line->italic_mask[i];
        int is_link = line->link_urls && line->link_urls[i] != NULL;
        
        SDL_Color char_color = is_link ? (SDL_Color){0, 0, 255, 255} : color;
        
        if (is_bold && is_italic) {
            draw_scaled_char(browser->renderer, line->text[i], x_pos, y, char_color, scale, is_italic);
            draw_scaled_char(browser->renderer, line->text[i], x_pos + scale, y, char_color, scale, is_italic);
        } else if (is_bold) {
            draw_scaled_char(browser->renderer, line->text[i], x_pos, y, char_color, scale, 0);
            draw_scaled_char(browser->renderer, line->text[i], x_pos + scale, y, char_color, scale, 0);
        } else if (is_italic) {
            draw_scaled_char(browser->renderer, line->text[i], x_pos, y, char_color, scale, 1);
        } else {
            draw_scaled_char(browser->renderer, line->text[i], x_pos, y, char_color, scale, 0);
        }
        
        if (is_link) {
            if (!in_link) {
                in_link = 1;
                link_start_x = x_pos;
                strncpy(current_link_url, line->link_urls[i], sizeof(current_link_url) - 1);
            }
            link_end_x = x_pos + char_width;
        } else if (in_link) {
            in_link = 0;
            SDL_SetRenderDrawColor(browser->renderer, 0, 0, 255, 255);
            SDL_RenderDrawLine(browser->renderer, link_start_x, y + line_height - 1, link_end_x, y + line_height - 1);
        }
        
        x_pos += char_width;
    }
    
    if (in_link) {
        SDL_SetRenderDrawColor(browser->renderer, 0, 0, 255, 255);
        SDL_RenderDrawLine(browser->renderer, link_start_x, y + line_height - 1, link_end_x, y + line_height - 1);
    }
}

void render_content(Browser *browser) {
    int content_top = TOP_BAR_HEIGHT + TITLE_BAR_HEIGHT;
    SDL_Rect content_rect = {0, content_top, browser->window_width, browser->window_height - content_top};

    SDL_RenderSetClipRect(browser->renderer, &content_rect);

    // White background for HTML content (per HTML standard)
    SDL_SetRenderDrawColor(browser->renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(browser->renderer, &content_rect);

    // Black text for HTML content
    SDL_Color text_color = {0, 0, 0, 255};
    int base_line_height = 12;
    int y_offset = content_top - browser->content.scroll_y;
    int current_y = y_offset;

    for (int i = 0; i < browser->content.line_count; i++) {
        int scale = browser->content.lines[i].font_scale > 0 ? browser->content.lines[i].font_scale : 1;
        int line_height = base_line_height * scale;

        if (current_y + line_height > content_top && current_y < browser->window_height) {
            int is_focused = (i == browser->focused_line);
            render_line(browser, &browser->content.lines[i], 20, current_y, text_color, i, is_focused);
        }
        current_y += line_height;
    }

    SDL_RenderSetClipRect(browser->renderer, NULL);
}

void render_scrollbar(Browser *browser) {
    int content_top = TOP_BAR_HEIGHT + TITLE_BAR_HEIGHT;
    int visible_height = browser->window_height - content_top;
    int total_height = browser->content.line_count * 12;

    if (total_height > visible_height) {
        float scroll_ratio = (float)browser->content.scroll_y / (total_height - visible_height);
        int scrollbar_height = (visible_height * visible_height) / total_height;
        if (scrollbar_height < 30) scrollbar_height = 30;

        int scrollbar_y = content_top + scroll_ratio * (visible_height - scrollbar_height);

        SDL_Rect scrollbar = {browser->window_width - 12, scrollbar_y, 10, scrollbar_height};
        SDL_SetRenderDrawColor(browser->renderer, 100, 100, 100, 200);
        SDL_RenderFillRect(browser->renderer, &scrollbar);
    }
}

void render_options(Browser *browser) {
    SDL_SetRenderDrawColor(browser->renderer, 40, 40, 40, 255);
    SDL_Rect options_rect = {0, 0, browser->window_width, browser->window_height};
    SDL_RenderFillRect(browser->renderer, &options_rect);

    SDL_Color title_color = {255, 255, 255, 255};
    SDL_Color text_color = {200, 200, 200, 255};

    const char *title = "Options";
    const char *msg = "Options will be added later";

    render_text(browser, title, browser->window_width / 2 - text_width(title) / 2, 100, title_color);
    render_text(browser, msg, browser->window_width / 2 - text_width(msg) / 2, 200, text_color);

    SDL_Rect back_btn = {browser->window_width / 2 - 60, 300, 120, 40};
    render_button(browser, &back_btn, "Back", 0);
}

void render(Browser *browser) {
    SDL_SetRenderDrawColor(browser->renderer, 30, 30, 30, 255);
    SDL_RenderClear(browser->renderer);

    if (browser->state == STATE_BROWSER) {
        // Title bar (at very top)
        SDL_SetRenderDrawColor(browser->renderer, 60, 60, 60, 255);
        SDL_Rect title_bar = {0, 0, browser->window_width, TITLE_BAR_HEIGHT};
        SDL_RenderFillRect(browser->renderer, &title_bar);

        // Draw title text
        if (strlen(browser->page_title) > 0) {
            SDL_Color title_color = {255, 255, 255, 255};
            render_text(browser, browser->page_title, 10, 6, title_color);
        }

        // Top bar with controls (below title bar)
        SDL_SetRenderDrawColor(browser->renderer, 50, 50, 50, 255);
        SDL_Rect top_bar = {0, TITLE_BAR_HEIGHT, browser->window_width, TOP_BAR_HEIGHT};
        SDL_RenderFillRect(browser->renderer, &top_bar);

        render_url_bar(browser);
        render_button(browser, &browser->refresh_btn, "Refresh", 0);
        render_button(browser, &browser->options_btn, "Options", 0);

        render_content(browser);
        render_scrollbar(browser);
    } else {
        render_options(browser);
    }

    SDL_RenderPresent(browser->renderer);
}

void display_response_in_browser(Browser *browser, char *response);

int get_line_at_position(Browser *browser, int x, int y) {
    int content_top = TOP_BAR_HEIGHT + TITLE_BAR_HEIGHT;
    
    if (y < content_top) return -1;
    
    int y_offset = y - content_top + browser->content.scroll_y;
    int current_y = 0;
    
    for (int i = 0; i < browser->content.line_count; i++) {
        int scale = browser->content.lines[i].font_scale > 0 ? browser->content.lines[i].font_scale : 1;
        int line_height = 12 * scale;
        
        if (y_offset >= current_y && y_offset < current_y + line_height) {
            return i;
        }
        current_y += line_height;
    }
    
    return -1;
}

char* get_link_at_position(Browser *browser, int x, int y) {
    int clicked_line = get_line_at_position(browser, x, y);
    if (clicked_line < 0) return NULL;
    
    // Calculate which character was clicked
    Line *line = &browser->content.lines[clicked_line];
    int char_x = 20;  // Left margin
    int scale = line->font_scale > 0 ? line->font_scale : 1;
    int char_width = CHAR_WIDTH * scale + 1;  // +1 for letter spacing
    
    for (int i = 0; i < line->length; i++) {
        if (x >= char_x && x < char_x + char_width) {
            // Check if this character has a link
            if (line->link_urls && line->link_urls[i]) {
                return line->link_urls[i];
            }
            return NULL;
        }
        char_x += char_width;
    }
    
    return NULL;
}

void submit_form(Browser *browser);

void handle_mouse_click(Browser *browser, int x, int y) {
    if (browser->state == STATE_OPTIONS) {
        SDL_Rect back_btn = {browser->window_width / 2 - 60, 300, 120, 40};
        if (x >= back_btn.x && x <= back_btn.x + back_btn.w &&
            y >= back_btn.y && y <= back_btn.y + back_btn.h) {
            browser->state = STATE_BROWSER;
        }
        return;
    }
    
    // Check if clicked on form element
    int clicked_line = get_line_at_position(browser, x, y);
    if (clicked_line >= 0 && clicked_line < browser->content.line_count) {
        Line *line = &browser->content.lines[clicked_line];
        
        if (line->form_elem == ELEM_TEXT_INPUT || line->form_elem == ELEM_TEXTAREA) {
            // Focus the input
            browser->focused_line = clicked_line;
            browser->cursor_pos = line->input_value ? strlen(line->input_value) : 0;
            browser->url_bar.active = 0;
            printf("Input focused: %s\n", line->input_name ? line->input_name : "unnamed");
            return;
        } else if (line->form_elem == ELEM_BUTTON) {
            // Submit form
            printf("Button clicked: %s\n", line->text);
            submit_form(browser);
            return;
        }
    }
    
    // Check if clicked on a link
    char *link_url = get_link_at_position(browser, x, y);
    if (link_url) {
        printf("Link clicked: %s\n", link_url);
        strncpy(browser->url_bar.url, link_url, sizeof(browser->url_bar.url) - 1);
        browser->url_bar.url[sizeof(browser->url_bar.url) - 1] = '\0';
        browser->url_bar.active = 0;
        browser->focused_line = -1;
        char *response = NULL;
        size_t response_size = 0;
        fetch_url(browser->url_bar.url, "GET", &response, &response_size);
        if (response) {
            display_response_in_browser(browser, response);
            free(response);
        }
        return;
    }
    
    // Unfocus input if clicked elsewhere
    if (clicked_line < 0 || browser->content.lines[clicked_line].form_elem == ELEM_NONE) {
        browser->focused_line = -1;
    }
    
    if (x >= browser->url_bar_rect.x && x <= browser->url_bar_rect.x + browser->url_bar_rect.w &&
        y >= browser->url_bar_rect.y && y <= browser->url_bar_rect.y + browser->url_bar_rect.h) {
        browser->url_bar.active = 1;
    } else {
        browser->url_bar.active = 0;
    }
    
    if (x >= browser->refresh_btn.x && x <= browser->refresh_btn.x + browser->refresh_btn.w &&
        y >= browser->refresh_btn.y && y <= browser->refresh_btn.y + browser->refresh_btn.h) {
        printf("Refreshing: %s\n", browser->url_bar.url);
        char *response = NULL;
        size_t response_size = 0;
        fetch_url(browser->url_bar.url, "GET", &response, &response_size);
        if (response) {
            display_response_in_browser(browser, response);
            free(response);
        }
    }
    
    if (x >= browser->options_btn.x && x <= browser->options_btn.x + browser->options_btn.w &&
        y >= browser->options_btn.y && y <= browser->options_btn.y + browser->options_btn.h) {
        browser->state = STATE_OPTIONS;
    }
}

int is_hex_digit(char c) {
    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}

size_t parse_hex(const char *str) {
    size_t val = 0;
    while (is_hex_digit(*str)) {
        val *= 16;
        if (*str >= '0' && *str <= '9') val += *str - '0';
        else if (*str >= 'a' && *str <= 'f') val += *str - 'a' + 10;
        else if (*str >= 'A' && *str <= 'F') val += *str - 'A' + 10;
        str++;
    }
    return val;
}

int is_chunked_response(const char *response) {
    const char *transfer_encoding = strstr(response, "Transfer-Encoding:");
    if (!transfer_encoding) transfer_encoding = strstr(response, "transfer-encoding:");
    if (transfer_encoding) {
        const char *chunked = strstr(transfer_encoding, "chunked");
        if (chunked) {
            const char *end_of_header = strstr(transfer_encoding, "\r\n");
            if (end_of_header && chunked < end_of_header) return 1;
        }
    }
    return 0;
}

char *dechunk_body(const char *body, size_t body_len, size_t *out_len) {
    char *result = malloc(body_len + 1);
    char *out = result;
    const char *in = body;
    const char *end = body + body_len;
    
    while (in < end) {
        // Skip any leading whitespace/newlines
        while (in < end && (*in == '\r' || *in == '\n')) in++;
        if (in >= end) break;
        
        // Parse chunk size (hex)
        const char *size_start = in;
        while (in < end && is_hex_digit(*in)) in++;
        
        // Skip chunk extensions
        while (in < end && *in != '\r' && *in != '\n') in++;
        
        // Skip CRLF after chunk size
        if (in < end && *in == '\r') in++;
        if (in < end && *in == '\n') in++;
        
        size_t chunk_size = parse_hex(size_start);
        if (chunk_size == 0) break; // Last chunk
        
        // Copy chunk data
        if (in + chunk_size <= end) {
            memcpy(out, in, chunk_size);
            out += chunk_size;
            in += chunk_size;
        } else {
            break;
        }
        
        // Skip CRLF after chunk data
        if (in < end && *in == '\r') in++;
        if (in < end && *in == '\n') in++;
    }
    
    *out_len = out - result;
    result[*out_len] = '\0';
    return result;
}

typedef enum {
    TAG_UNKNOWN = 0,
    TAG_P, TAG_TITLE, TAG_SCRIPT, TAG_STYLE,
    TAG_BOLD, TAG_ITALIC, TAG_H1, TAG_H2, TAG_H3, TAG_H4, TAG_H5, TAG_H6, TAG_LINK,
    TAG_FORM, TAG_INPUT, TAG_TEXTAREA, TAG_BUTTON, TAG_SELECT, TAG_OPTION, TAG_LABEL
} TagType;

// Efficient tag lookup using hash table approach
// Simple hash: sum of first 2 chars (case insensitive) + length
static const struct { const char *name; TagType type; } tag_table[] = {
    {"p", TAG_P}, {"title", TAG_TITLE}, {"script", TAG_SCRIPT}, {"style", TAG_STYLE},
    {"b", TAG_BOLD}, {"strong", TAG_BOLD}, {"i", TAG_ITALIC}, {"em", TAG_ITALIC},
    {"h1", TAG_H1}, {"h2", TAG_H2}, {"h3", TAG_H3}, {"h4", TAG_H4}, {"h5", TAG_H5}, {"h6", TAG_H6},
    {"a", TAG_LINK},
    {"form", TAG_FORM}, {"input", TAG_INPUT}, {"textarea", TAG_TEXTAREA}, {"button", TAG_BUTTON},
    {"select", TAG_SELECT}, {"option", TAG_OPTION}, {"label", TAG_LABEL},
    {NULL, TAG_UNKNOWN}
};

// Case-insensitive string compare
int tag_strcmp(const char *a, const char *b) {
    while (*b && (*a == *b || *a == (*b ^ 32))) {  // Check both cases
        a++; b++;
    }
    return *b == '\0' && (*a == '\0' || *a == ' ' || *a == '>');
}

TagType get_tag_type(const char *tag) {
    for (int i = 0; tag_table[i].name; i++) {
        if (tag_strcmp(tag, tag_table[i].name)) {
            return tag_table[i].type;
        }
    }
    return TAG_UNKNOWN;
}

int is_block_tag(TagType type) {
    return type == TAG_P || type == TAG_TITLE || 
           (type >= TAG_H1 && type <= TAG_H6) ||
           type == TAG_FORM || type == TAG_TEXTAREA ||
           type == TAG_UNKNOWN;
}

void flush_current_line(ContentView *cv, char *line_buffer, unsigned char *bold_buffer, unsigned char *italic_buffer, char **link_url_buffer, int *line_pos, int font_scale) {
    if (*line_pos > 0) {
        line_buffer[*line_pos] = '\0';
        if (cv->line_count < MAX_CONTENT_LINES) {
            cv->lines[cv->line_count].text = strdup(line_buffer);
            cv->lines[cv->line_count].bold_mask = malloc(*line_pos + 1);
            cv->lines[cv->line_count].italic_mask = malloc(*line_pos + 1);
            cv->lines[cv->line_count].link_urls = calloc(*line_pos + 1, sizeof(char*));
            memcpy(cv->lines[cv->line_count].bold_mask, bold_buffer, *line_pos);
            memcpy(cv->lines[cv->line_count].italic_mask, italic_buffer, *line_pos);
            // Copy link URLs and free temporary ones
            for (int i = 0; i < *line_pos; i++) {
                if (link_url_buffer[i]) {
                    cv->lines[cv->line_count].link_urls[i] = strdup(link_url_buffer[i]);
                    free(link_url_buffer[i]);  // Free temporary
                    link_url_buffer[i] = NULL;
                }
            }
            cv->lines[cv->line_count].length = *line_pos;
            cv->lines[cv->line_count].font_scale = font_scale;
            // Initialize form element fields
            cv->lines[cv->line_count].form_elem = ELEM_NONE;
            cv->lines[cv->line_count].input_name = NULL;
            cv->lines[cv->line_count].input_value = NULL;
            cv->lines[cv->line_count].input_width = 20;
            cv->line_count++;
        }
        *line_pos = 0;
    }
}

void add_char_to_line(char *line_buffer, unsigned char *bold_buffer, unsigned char *italic_buffer, char **link_url_buffer, int *line_pos, char c, int is_bold, int is_italic, const char *link_url) {
    if (*line_pos < MAX_LINE_LENGTH - 1) {
        line_buffer[*line_pos] = c;
        bold_buffer[*line_pos] = is_bold;
        italic_buffer[*line_pos] = is_italic;
        if (link_url) {
            link_url_buffer[*line_pos] = strdup(link_url);
        } else {
            link_url_buffer[*line_pos] = NULL;
        }
        (*line_pos)++;
    }
}

int get_total_content_height(ContentView *cv);

void parse_html(Browser *browser, const char *html);

void resolve_url(const char *base_url, const char *href, char *resolved, size_t resolved_size) {
    if (!href || !resolved || resolved_size == 0) return;
    
    // Absolute URL (has scheme)
    if (strncmp(href, "http://", 7) == 0 || strncmp(href, "https://", 8) == 0) {
        strncpy(resolved, href, resolved_size - 1);
        resolved[resolved_size - 1] = '\0';
        return;
    }
    
    // Protocol-relative URL (//example.com/path)
    if (strncmp(href, "//", 2) == 0) {
        // Extract scheme from base_url
        const char *scheme_end = strstr(base_url, "://");
        if (scheme_end) {
            int scheme_len = scheme_end - base_url;
            snprintf(resolved, resolved_size, "%.*s:%s", scheme_len, base_url, href);
        } else {
            strncpy(resolved, href, resolved_size - 1);
            resolved[resolved_size - 1] = '\0';
        }
        return;
    }
    
    // Root-relative URL (/path)
    if (href[0] == '/') {
        // Extract scheme and host from base_url
        const char *scheme_end = strstr(base_url, "://");
        if (scheme_end) {
            const char *host_start = scheme_end + 3;
            // Find end of host (first / or ?)
            const char *path_start = NULL;
            for (const char *p = host_start; *p; p++) {
                if (*p == '/' || *p == '?') {
                    path_start = p;
                    break;
                }
            }
            if (path_start) {
                int base_len = path_start - base_url;
                if (base_len < (int)resolved_size - 1) {
                    memcpy(resolved, base_url, base_len);
                    resolved[base_len] = '\0';
                    strncat(resolved, href, resolved_size - base_len - 1);
                }
            } else {
                strncpy(resolved, base_url, resolved_size - 1);
                resolved[resolved_size - 1] = '\0';
                strncat(resolved, href, resolved_size - strlen(resolved) - 1);
            }
        } else {
            strncpy(resolved, base_url, resolved_size - 1);
            resolved[resolved_size - 1] = '\0';
            strncat(resolved, href, resolved_size - strlen(resolved) - 1);
        }
        return;
    }
    
    // Relative URL (./path, ../path, or just path)
    // Find the last '/' in base_url (before query string or fragment)
    char base_copy[2048];
    strncpy(base_copy, base_url, sizeof(base_copy) - 1);
    base_copy[sizeof(base_copy) - 1] = '\0';
    
    // Remove query string and fragment
    char *query = strchr(base_copy, '?');
    if (query) *query = '\0';
    char *fragment = strchr(base_copy, '#');
    if (fragment) *fragment = '\0';
    
    // Find the directory part
    char *last_slash = strrchr(base_copy, '/');
    if (last_slash) {
        // Check if base_url ends with a filename or just a directory
        // If the last component has a dot, it's likely a file
        char *last_component = last_slash + 1;
        if (strchr(last_component, '.')) {
            // It's a file, use the directory
            *last_slash = '\0';
        }
        // If no dot, it's a directory, keep the trailing slash
    }
    
    // Handle ../ (parent directory)
    const char *rel_path = href;
    while (strncmp(rel_path, "../", 3) == 0) {
        rel_path += 3;
        // Go up one directory
        last_slash = strrchr(base_copy, '/');
        if (last_slash) {
            // Find the previous slash
            *last_slash = '\0';
            char *prev_slash = strrchr(base_copy, '/');
            if (prev_slash) {
                *(prev_slash + 1) = '\0';
            } else {
                // No more parent directories
                base_copy[0] = '\0';
            }
        }
    }
    
    // Handle ./ (current directory)
    while (strncmp(rel_path, "./", 2) == 0) {
        rel_path += 2;
    }
    
    // Build final URL
    size_t base_len = strlen(base_copy);
    if (base_len > 0 && base_copy[base_len - 1] != '/') {
        strncat(base_copy, "/", sizeof(base_copy) - base_len - 1);
    }
    
    snprintf(resolved, resolved_size, "%s%s", base_copy, rel_path);
}

void extract_attr(const char *tag_start, int tag_len, const char *attr_name, char *value, size_t value_size) {
    value[0] = '\0';
    int attr_len = strlen(attr_name);
    
    const char *p = tag_start;
    const char *end = tag_start + tag_len;
    
    while (p < end - attr_len - 1) {
        if (strncasecmp(p, attr_name, attr_len) == 0 && p[attr_len] == '=') {
            p += attr_len + 1;
            // Skip whitespace
            while (p < end && (*p == ' ' || *p == '\t')) p++;
            
            if (p < end && (*p == '"' || *p == '\'')) {
                char quote = *p++;
                const char *value_start = p;
                
                while (p < end && *p != quote) p++;
                
                int len = p - value_start;
                if (len > 0 && len < (int)value_size) {
                    memcpy(value, value_start, len);
                    value[len] = '\0';
                }
            }
            return;
        }
        p++;
    }
}

// Wrapper for backward compatibility
void extract_href(const char *tag_start, int tag_len, char *href, size_t href_size) {
    extract_attr(tag_start, tag_len, "href", href, href_size);
}

void parse_html(Browser *browser, const char *html) {
    free_content_view(&browser->content);
    init_content_view(&browser->content);

    // Clear page title
    browser->page_title[0] = '\0';

    char current_line[MAX_LINE_LENGTH] = {0};
    unsigned char bold_mask[MAX_LINE_LENGTH] = {0};
    unsigned char italic_mask[MAX_LINE_LENGTH] = {0};
    char *link_url_buffer[MAX_LINE_LENGTH] = {0};
    char current_link_url[1024] = {0};
    int line_pos = 0;
    int in_block = 0;
    int skip_content = 0;
    int in_bold = 0;
    int in_italic = 0;
    int font_scale = 1;

    const char *p = html;

    while (*p) {
        if (*p == '<') {
            // Parse tag
            const char *tag_start = p + 1;
            const char *tag_end = p;

            while (*tag_end && *tag_end != '>') tag_end++;
            if (*tag_end == '>') {
                int tag_len = tag_end - tag_start;
                char tag[64] = {0};

                // Copy tag name (up to space or >)
                int name_len = 0;
                while (name_len < tag_len && name_len < 63 &&
                       tag_start[name_len] != ' ' && tag_start[name_len] != '>') {
                    tag[name_len] = tag_start[name_len];
                    name_len++;
                }
                tag[name_len] = '\0';

                int is_closing = (tag[0] == '/');
                const char *tag_name = is_closing ? tag + 1 : tag;
                TagType tag_type = get_tag_type(tag_name);

                if (skip_content) {
                    if (is_closing && (tag_type == TAG_SCRIPT || tag_type == TAG_STYLE || tag_type == TAG_TITLE)) {
                        skip_content = 0;
                    }
                    p = tag_end + 1;
                    continue;
                }

                // Skip title tag content entirely (it's handled separately above)
                if (tag_type == TAG_TITLE) {
                    skip_content = 1;
                    p = tag_end + 1;
                    continue;
                }

                // Handle link tags <a href="...">
                if (tag_type == TAG_LINK) {
                    if (is_closing) {
                        current_link_url[0] = '\0';
                    } else {
                        // Extract href attribute
                        char href[1024] = {0};
                        extract_href(tag_start, tag_len, href, sizeof(href));
                        if (href[0]) {
                            // Resolve relative URL
                            resolve_url(browser->url_bar.url, href, current_link_url, sizeof(current_link_url));
                        }
                    }
                    p = tag_end + 1;
                    continue;
                }

                // Handle bold tags
                if (tag_type == TAG_BOLD) {
                    if (is_closing) {
                        in_bold = 0;
                    } else {
                        in_bold = 1;
                    }
                    p = tag_end + 1;
                    continue;
                }

                // Handle italic tags (i and em)
                if (tag_type == TAG_ITALIC) {
                    if (is_closing) {
                        in_italic = 0;
                    } else {
                        in_italic = 1;
                    }
                    p = tag_end + 1;
                    continue;
                }

                // Handle heading tags h1-h6 with different sizes
                if (tag_type >= TAG_H1 && tag_type <= TAG_H6) {
                    int heading_scale;
                    switch (tag_type) {
                        case TAG_H1: heading_scale = 3; break;  // 3x
                        case TAG_H2: heading_scale = 2; break;  // 2x
                        case TAG_H3: heading_scale = 2; break;  // 2x
                        case TAG_H4: heading_scale = 2; break;  // 2x
                        case TAG_H5: heading_scale = 1; break;  // 1x (normal size)
                        case TAG_H6: heading_scale = 1; break;  // 1x (normal size)
                        default: heading_scale = 2;
                    }
                    
                    if (is_closing) {
                        in_bold = 0;
                        font_scale = 1;
                        // Add blank line after heading
                        if (line_pos > 0) {
                            flush_current_line(&browser->content, current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, heading_scale);
                        }
                        add_content_line(&browser->content, "");
                    } else {
                        // Add blank line before heading
                        if (line_pos > 0) {
                            flush_current_line(&browser->content, current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, font_scale);
                        }
                        add_content_line(&browser->content, "");
                        in_bold = 1;
                        font_scale = heading_scale;
                    }
                    p = tag_end + 1;
                    continue;
                }

                // Handle form elements
                if (tag_type >= TAG_FORM && tag_type <= TAG_LABEL) {
                    if (is_closing) {
                        // Flush current line on closing
                        if (line_pos > 0) {
                            flush_current_line(&browser->content, current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, font_scale);
                        }
                        if (tag_type == TAG_FORM || tag_type == TAG_TEXTAREA) {
                            add_content_line(&browser->content, "");
                        }
                    } else {
                        // Opening tag - flush current line
                        if (line_pos > 0) {
                            flush_current_line(&browser->content, current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, font_scale);
                        }
                        
                        // Create actual form elements
                        if (tag_type == TAG_INPUT) {
                            char input_name[256] = {0};
                            char input_type[64] = {0};
                            char input_value[256] = {0};
                            extract_attr(tag_start, tag_len, "name", input_name, sizeof(input_name));
                            extract_attr(tag_start, tag_len, "type", input_type, sizeof(input_type));
                            extract_attr(tag_start, tag_len, "value", input_value, sizeof(input_value));
                            
                            // Check if this is a submit button
                            if (strcasecmp(input_type, "submit") == 0) {
                                // Treat submit input like a button
                                char button_text[256] = {0};
                                if (input_value[0]) {
                                    strcpy(button_text, input_value);
                                } else {
                                    strcpy(button_text, "Submit");
                                }
                                
                                if (browser->content.line_count < MAX_CONTENT_LINES) {
                                    Line *line = &browser->content.lines[browser->content.line_count];
                                    line->text = strdup(button_text);
                                    line->bold_mask = calloc(strlen(button_text) + 1, sizeof(unsigned char));
                                    line->italic_mask = calloc(strlen(button_text) + 1, sizeof(unsigned char));
                                    line->link_urls = calloc(strlen(button_text) + 1, sizeof(char*));
                                    line->length = strlen(button_text);
                                    line->font_scale = 1;
                                    line->form_elem = ELEM_BUTTON;
                                    line->input_name = NULL;
                                    line->input_value = NULL;
                                    line->input_width = strlen(button_text) + 4;
                                    browser->content.line_count++;
                                }
                            } else {
                                // Create text input line
                                if (browser->content.line_count < MAX_CONTENT_LINES) {
                                    Line *line = &browser->content.lines[browser->content.line_count];
                                    line->text = strdup("");
                                    line->bold_mask = calloc(1, sizeof(unsigned char));
                                    line->italic_mask = calloc(1, sizeof(unsigned char));
                                    line->link_urls = calloc(1, sizeof(char*));
                                    line->length = 0;
                                    line->font_scale = 1;
                                    line->form_elem = ELEM_TEXT_INPUT;
                                    line->input_name = strdup(input_name);
                                    line->input_value = strdup(input_value);
                                    line->input_width = 30;
                                    browser->content.line_count++;
                                }
                            }
                        } else if (tag_type == TAG_BUTTON) {
                            char button_text[256] = {0};
                            extract_attr(tag_start, tag_len, "value", button_text, sizeof(button_text));
                            if (!button_text[0]) {
                                extract_attr(tag_start, tag_len, "name", button_text, sizeof(button_text));
                            }
                            if (!button_text[0]) {
                                strcpy(button_text, "Submit");
                            }
                            
                            if (browser->content.line_count < MAX_CONTENT_LINES) {
                                Line *line = &browser->content.lines[browser->content.line_count];
                                line->text = strdup(button_text);
                                line->bold_mask = calloc(strlen(button_text) + 1, sizeof(unsigned char));
                                line->italic_mask = calloc(strlen(button_text) + 1, sizeof(unsigned char));
                                line->link_urls = calloc(strlen(button_text) + 1, sizeof(char*));
                                line->length = strlen(button_text);
                                line->font_scale = 1;
                                line->form_elem = ELEM_BUTTON;
                                line->input_name = NULL;
                                line->input_value = NULL;
                                line->input_width = strlen(button_text) + 4;
                                browser->content.line_count++;
                            }
                        } else if (tag_type == TAG_TEXTAREA) {
                            char textarea_name[256] = {0};
                            extract_attr(tag_start, tag_len, "name", textarea_name, sizeof(textarea_name));
                            
                            if (browser->content.line_count < MAX_CONTENT_LINES) {
                                Line *line = &browser->content.lines[browser->content.line_count];
                                line->text = strdup("");
                                line->bold_mask = calloc(1, sizeof(unsigned char));
                                line->italic_mask = calloc(1, sizeof(unsigned char));
                                line->link_urls = calloc(1, sizeof(char*));
                                line->length = 0;
                                line->font_scale = 1;
                                line->form_elem = ELEM_TEXTAREA;
                                line->input_name = strdup(textarea_name);
                                line->input_value = strdup("");
                                line->input_width = 40;
                                browser->content.line_count++;
                            }
                            add_content_line(&browser->content, "");
                        } else if (tag_type == TAG_FORM) {
                            add_content_line(&browser->content, "--- Form ---");
                        } else if (tag_type == TAG_LABEL) {
                            // Labels will be handled as regular text
                        }
                    }
                    p = tag_end + 1;
                    continue;
                }

                // Flush current line if we have content and entering a block
                if (is_block_tag(tag_type) && !is_closing) {
                    if (line_pos > 0) {
                        flush_current_line(&browser->content, current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, font_scale);
                    }
                    if (in_block) {
                        add_content_line(&browser->content, "");
                    }
                    in_block = 1;

                    if (tag_type == TAG_SCRIPT || tag_type == TAG_STYLE) {
                        skip_content = 1;
                    }
                } else if (is_block_tag(tag_type) && is_closing) {
                    if (line_pos > 0) {
                        flush_current_line(&browser->content, current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, font_scale);
                    }
                    add_content_line(&browser->content, "");
                    in_block = 0;
                }

                // Handle title tag - store in page_title instead of content
                if (tag_type == TAG_TITLE && !is_closing) {
                    // Collect title content
                    p = tag_end + 1;
                    char title_buf[256] = {0};
                    int title_pos = 0;

                    while (*p && !(p[0] == '<' && p[1] == '/' &&
                           strncasecmp(p+2, "title", 5) == 0)) {
                        if (title_pos < 255) {
                            title_buf[title_pos++] = *p;
                        }
                        p++;
                    }
                    title_buf[title_pos] = '\0';

                    // Trim whitespace
                    char *start = title_buf;
                    while (*start && (*start == ' ' || *start == '\t' ||
                           *start == '\n' || *start == '\r')) start++;
                    char *end = title_buf + strlen(title_buf) - 1;
                    while (end > start && (*end == ' ' || *end == '\t' ||
                           *end == '\n' || *end == '\r')) {
                        *end = '\0';
                        end--;
                    }

                    strncpy(browser->page_title, start, sizeof(browser->page_title) - 1);
                    browser->page_title[sizeof(browser->page_title) - 1] = '\0';

                    // Skip past </title> (8 chars: < / t i t l e >)
                    if (*p == '<') {
                        p += 8;
                    }
                    continue;
                }

                p = tag_end + 1;
                continue;
            }
        }

        if (!skip_content) {
            // Add character to current line
            if (*p == '\n' || *p == '\r') {
                // Ignore newlines inside blocks, flush otherwise
                if (!in_block && line_pos > 0) {
                    flush_current_line(&browser->content, current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, font_scale);
                }
            } else if (*p == ' ' || *p == '\t') {
                // Collapse whitespace
                if (line_pos > 0 && current_line[line_pos-1] != ' ') {
                    add_char_to_line(current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, ' ', in_bold, in_italic, current_link_url[0] ? current_link_url : NULL);
                }
            } else {
                add_char_to_line(current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, *p, in_bold, in_italic, current_link_url[0] ? current_link_url : NULL);
            }
        }

        p++;
    }

    // Flush remaining content
    if (line_pos > 0) {
        flush_current_line(&browser->content, current_line, bold_mask, italic_mask, link_url_buffer, &line_pos, font_scale);
    }

    browser->content.scroll_y = 0;
    browser->content.content_height = get_total_content_height(&browser->content);
}

void display_response_in_browser(Browser *browser, char *response) {
    free_content_view(&browser->content);
    init_content_view(&browser->content);
    
    char *body = strstr(response, "\r\n\r\n");
    if (!body) {
        body = strstr(response, "\n\n");
    }
    
    if (body) {
        body += 4;
        
        char *content_to_display = body;
        char *dechunked = NULL;
        
        if (is_chunked_response(response)) {
            size_t dechunked_len;
            dechunked = dechunk_body(body, strlen(body), &dechunked_len);
            content_to_display = dechunked;
        }
        
        // Check if content looks like HTML
        if (strstr(content_to_display, "<") != NULL) {
            parse_html(browser, content_to_display);
        } else {
            // Plain text - display as before
            char *content_copy = strdup(content_to_display);
            char *line = strtok(content_copy, "\n");
            while (line && browser->content.line_count < MAX_CONTENT_LINES) {
                size_t len = strlen(line);
                while (len > 0 && (line[len-1] == '\r' || line[len-1] == '\n')) {
                    line[len-1] = '\0';
                    len--;
                }
                add_content_line(&browser->content, line);
                line = strtok(NULL, "\n");
            }
            free(content_copy);
        }
        
        if (dechunked) free(dechunked);
    } else {
        add_content_line(&browser->content, response);
    }
    
    browser->content.scroll_y = 0;
    browser->content.content_height = browser->content.line_count * 12;
}

void handle_text_input(Browser *browser, const char *text) {
    if (browser->url_bar.active && strlen(browser->url_bar.url) + strlen(text) < MAX_URL_LENGTH - 1) {
        strcat(browser->url_bar.url, text);
        return;
    }
    
    // Handle form input
    if (browser->focused_line >= 0 && browser->focused_line < browser->content.line_count) {
        Line *line = &browser->content.lines[browser->focused_line];
        if ((line->form_elem == ELEM_TEXT_INPUT || line->form_elem == ELEM_TEXTAREA) && 
            line->input_value) {
            int val_len = strlen(line->input_value);
            int text_len = strlen(text);
            if (val_len + text_len < line->input_width - 1) {
                // Insert at cursor position
                memmove(line->input_value + browser->cursor_pos + text_len,
                        line->input_value + browser->cursor_pos,
                        val_len - browser->cursor_pos + 1);
                memcpy(line->input_value + browser->cursor_pos, text, text_len);
                browser->cursor_pos += text_len;
            }
        }
    }
}

void handle_key_press(Browser *browser, SDL_Keycode key) {
    if (browser->url_bar.active) {
        if (key == SDLK_BACKSPACE && strlen(browser->url_bar.url) > 0) {
            browser->url_bar.url[strlen(browser->url_bar.url) - 1] = '\0';
        } else if (key == SDLK_RETURN) {
            printf("Navigating to: %s\n", browser->url_bar.url);
            browser->url_bar.active = 0;
            char *response = NULL;
            size_t response_size = 0;
            fetch_url(browser->url_bar.url, "GET", &response, &response_size);
            if (response) {
                display_response_in_browser(browser, response);
                free(response);
            }
        }
        return;
    }
    
    // Handle form input keys
    if (browser->focused_line >= 0 && browser->focused_line < browser->content.line_count) {
        Line *line = &browser->content.lines[browser->focused_line];
        if ((line->form_elem == ELEM_TEXT_INPUT || line->form_elem == ELEM_TEXTAREA) && 
            line->input_value) {
            int val_len = strlen(line->input_value);
            
            if (key == SDLK_BACKSPACE && browser->cursor_pos > 0) {
                // Delete character before cursor
                memmove(line->input_value + browser->cursor_pos - 1,
                        line->input_value + browser->cursor_pos,
                        val_len - browser->cursor_pos + 1);
                browser->cursor_pos--;
            } else if (key == SDLK_DELETE && browser->cursor_pos < val_len) {
                // Delete character at cursor
                memmove(line->input_value + browser->cursor_pos,
                        line->input_value + browser->cursor_pos + 1,
                        val_len - browser->cursor_pos);
            } else if (key == SDLK_LEFT && browser->cursor_pos > 0) {
                browser->cursor_pos--;
            } else if (key == SDLK_RIGHT && browser->cursor_pos < val_len) {
                browser->cursor_pos++;
            } else if (key == SDLK_HOME) {
                browser->cursor_pos = 0;
            } else if (key == SDLK_END) {
                browser->cursor_pos = val_len;
            } else if (key == SDLK_RETURN && line->form_elem == ELEM_TEXTAREA) {
                // New line in textarea (simplified - just add space)
                if (val_len < line->input_width - 1) {
                    memmove(line->input_value + browser->cursor_pos + 1,
                            line->input_value + browser->cursor_pos,
                            val_len - browser->cursor_pos + 1);
                    line->input_value[browser->cursor_pos] = ' ';
                    browser->cursor_pos++;
                }
            }
        }
    }
}

void submit_form(Browser *browser) {
    // Build form data from all inputs
    char form_data[4096] = {0};
    int form_data_len = 0;
    
    for (int i = 0; i < browser->content.line_count; i++) {
        Line *line = &browser->content.lines[i];
        if ((line->form_elem == ELEM_TEXT_INPUT || line->form_elem == ELEM_TEXTAREA) &&
            line->input_name && line->input_value) {
            
            // URL encode the value (simplified)
            if (form_data_len > 0) {
                strcat(form_data + form_data_len, "&");
                form_data_len++;
            }
            
            // Add name=value (simplified - no actual URL encoding)
            int name_len = strlen(line->input_name);
            int val_len = strlen(line->input_value);
            
            snprintf(form_data + form_data_len, sizeof(form_data) - form_data_len,
                     "%s=%s", line->input_name, line->input_value);
            form_data_len += name_len + 1 + val_len;
        }
    }
    
    printf("Form submission: %s\n", form_data);
    
    // Navigate to current URL with form data as query string
    char new_url[MAX_URL_LENGTH];
    strncpy(new_url, browser->url_bar.url, sizeof(new_url) - 1);
    new_url[sizeof(new_url) - 1] = '\0';
    
    // Check if URL already has query parameters
    char *query_start = strchr(new_url, '?');
    if (query_start) {
        // Replace existing query
        *query_start = '\0';
    }
    
    // Append form data as query string
    strncat(new_url, "?", sizeof(new_url) - strlen(new_url) - 1);
    strncat(new_url, form_data, sizeof(new_url) - strlen(new_url) - 1);
    
    // Update URL bar and navigate
    strncpy(browser->url_bar.url, new_url, sizeof(browser->url_bar.url) - 1);
    browser->url_bar.url[sizeof(browser->url_bar.url) - 1] = '\0';
    browser->url_bar.active = 0;
    browser->focused_line = -1;
    
    printf("Navigating to: %s\n", new_url);
    
    // Fetch the new URL
    char *response = NULL;
    size_t response_size = 0;
    fetch_url(browser->url_bar.url, "GET", &response, &response_size);
    if (response) {
        display_response_in_browser(browser, response);
        free(response);
    }
}

int get_total_content_height(ContentView *cv) {
    int total = 0;
    for (int i = 0; i < cv->line_count; i++) {
        int scale = cv->lines[i].font_scale > 0 ? cv->lines[i].font_scale : 1;
        total += 12 * scale;
    }
    return total;
}

void handle_scroll(Browser *browser, int y) {
    if (browser->state == STATE_BROWSER) {
        browser->content.scroll_y -= y * SCROLL_SPEED;
        int content_top = TOP_BAR_HEIGHT + TITLE_BAR_HEIGHT;
        int total_height = get_total_content_height(&browser->content);
        int max_scroll = total_height - (browser->window_height - content_top);
        if (browser->content.scroll_y < 0) browser->content.scroll_y = 0;
        if (browser->content.scroll_y > max_scroll) browser->content.scroll_y = max_scroll;
        if (max_scroll < 0) browser->content.scroll_y = 0;
    }
}

int main(int argc, char *argv[]) {
    (void)argc;
    (void)argv;
    
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "SDL init failed: %s\n", SDL_GetError());
        return 1;
    }
    
    if (SDLNet_Init() < 0) {
        fprintf(stderr, "SDLNet init failed: %s\n", SDLNet_GetError());
        SDL_Quit();
        return 1;
    }
    
    Browser browser = {0};
    browser.window = SDL_CreateWindow("SDL Browser",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        WINDOW_WIDTH, WINDOW_HEIGHT,
        SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
    
    if (!browser.window) {
        fprintf(stderr, "Window creation failed: %s\n", SDL_GetError());
        SDL_Quit();
        return 1;
    }
    
    browser.renderer = SDL_CreateRenderer(browser.window, -1, SDL_RENDERER_ACCELERATED);
    if (!browser.renderer) {
        fprintf(stderr, "Renderer creation failed: %s\n", SDL_GetError());
        SDL_DestroyWindow(browser.window);
        SDL_Quit();
        return 1;
    }
    
    browser.running = 1;
    browser.state = STATE_BROWSER;
    browser.url_bar.url[0] = '\0';
    browser.url_bar.cursor_pos = 0;
    browser.url_bar.active = 0;
    browser.focused_line = -1;  // No input focused initially
    browser.cursor_pos = 0;
    browser.window_width = WINDOW_WIDTH;
    browser.window_height = WINDOW_HEIGHT;

    update_layout(&browser);

    init_content_view(&browser.content);
    load_sample_content(&browser.content);
    
    SDL_StartTextInput();
    
    SDL_Event event;
    while (browser.running) {
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_QUIT:
                    browser.running = 0;
                    break;
                    
                case SDL_MOUSEBUTTONDOWN:
                    if (event.button.button == SDL_BUTTON_LEFT) {
                        handle_mouse_click(&browser, event.button.x, event.button.y);
                    }
                    break;
                    
                case SDL_TEXTINPUT:
                    handle_text_input(&browser, event.text.text);
                    break;
                    
                case SDL_KEYDOWN:
                    handle_key_press(&browser, event.key.keysym.sym);
                    break;
                    
                case SDL_MOUSEWHEEL:
                    handle_scroll(&browser, event.wheel.y);
                    break;
                    
                case SDL_WINDOWEVENT:
                    if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
                        browser.window_width = event.window.data1;
                        browser.window_height = event.window.data2;
                        update_layout(&browser);
                    }
                    break;
            }
        }
        
        render(&browser);
        SDL_Delay(16);
    }
    
    SDL_StopTextInput();
    
    free_content_view(&browser.content);
    SDL_DestroyRenderer(browser.renderer);
    SDL_DestroyWindow(browser.window);
    SDLNet_Quit();
    SDL_Quit();

    return 0;
}
