/*
 * thread_demo.c — eduwin_thread 线程模块演示
 *
 * 展示功能：
 *   1. thread_run() — 创建多个线程
 *   2. execute_on_main() — 线程安全更新 UI
 *   3. eduwin_mutex_*() — 互斥锁保护共享数据
 *
 * 编译：build.bat
 */

#define _CRT_SECURE_NO_WARNINGS
#include "eduwin.h"

/* ── 控件 ── */
static HWND g_win;
static HWND g_log;
static HWND g_status;
static HWND g_btn_start, g_btn_status, g_btn_clear;

/* ── 日志辅助 ── */
static void llog(const WCHAR *s)
{
    const WCHAR *cur = get_text(g_log);
    if (!cur) cur = L"";
    int clen = (int)wcslen(cur);
    int slen = (int)wcslen(s);
    WCHAR *buf = (WCHAR*)malloc((clen + slen + 3) * sizeof(WCHAR));
    if (!buf) return;
    wcscpy(buf, cur);
    wcscat(buf, s);
    wcscat(buf, L"\r\n");
    set_text(g_log, buf);
    free(buf);
}

/* ── 共享计数器（用互斥锁保护） ── */
static int g_counter = 0;
static mutex_t *g_mutex = NULL;

/* ── 回调：更新日志和状态（在主线程执行） ── */
static void update_log(void *msg)
{
    llog((const WCHAR*)msg);
    free(msg);
}

static void update_status(void *msg)
{
    statusbar_set_text(g_status, (const WCHAR*)msg);
    free(msg);
}

/* ── 线程 1：计数器递增 ── */
static void thread_counter(void *arg)
{
    (void)arg;
    for (int i = 0; i < 10; i++)
    {
        thread_sleep(300);  /* 模拟工作 */

        /* 加锁保护共享数据 */
        mutex_lock(g_mutex);
        g_counter++;
        int val = g_counter;
        mutex_unlock(g_mutex);

        /* 线程安全更新 UI */
        WCHAR buf[128];
        swprintf(buf, 128, L"计数器线程: 第 %d 次递增 → 当前值 %d", i + 1, val);
        execute_on_main(g_win, update_log, _wcsdup(buf));

        WCHAR sbuf[64];
        swprintf(sbuf, 64, L"计数器: %d", val);
        execute_on_main(g_win, update_status, _wcsdup(sbuf));
    }
    execute_on_main(g_win, update_log, _wcsdup(L"计数器线程: 已完成"));
}

/* ── 线程 2：模拟耗时任务 ── */
static void thread_worker(void *arg)
{
    (void)arg;
    const WCHAR *steps[] = {
        L"工作线程: 正在加载数据...",
        L"工作线程: 数据处理中 (25%%)",
        L"工作线程: 数据处理中 (50%%)",
        L"工作线程: 数据处理中 (75%%)",
        L"工作线程: 处理完成！",
    };

    for (int i = 0; i < 5; i++)
    {
        thread_sleep(500);
        execute_on_main(g_win, update_log, _wcsdup(steps[i]));

        WCHAR sbuf[64];
        swprintf(sbuf, 64, L"工作中... %d/5", i + 1);
        execute_on_main(g_win, update_status, _wcsdup(sbuf));
    }
    execute_on_main(g_win, update_log, _wcsdup(L"工作线程: 已结束"));
}

/* ── 线程 3：定时心跳 ── */
static void thread_heartbeat(void *arg)
{
    (void)arg;
    for (int i = 0; i < 8; i++)
    {
        thread_sleep(400);
        WCHAR buf[64];
        swprintf(buf, 64, L"♥ 心跳 %d/8", i + 1);
        execute_on_main(g_win, update_log, _wcsdup(buf));
    }
    execute_on_main(g_win, update_log, _wcsdup(L"心跳线程: 已结束"));
}

/* ── 完成后显示最终状态 ── */
static int g_threads_done = 0;
static mutex_t *g_done_mutex = NULL;

static void on_thread_done(void *arg)
{
    (void)arg;
    mutex_lock(g_done_mutex);
    g_threads_done++;
    if (g_threads_done >= 3)
    {
        llog(L"═══ 所有线程已结束 ═══");
        statusbar_set_text(g_status, L"所有任务完成");
        set_enable(g_btn_start, 1);  /* 重新启用开始按钮 */
        g_threads_done = 0;
    }
    mutex_unlock(g_done_mutex);
}

/* ── 线程包装：执行完调 on_thread_done ── */
static void thread_runner1(void *arg) { thread_counter(arg);  execute_on_main(g_win, on_thread_done, NULL); }
static void thread_runner2(void *arg) { thread_worker(arg);   execute_on_main(g_win, on_thread_done, NULL); }
static void thread_runner3(void *arg) { thread_heartbeat(arg); execute_on_main(g_win, on_thread_done, NULL); }

/* ── 按钮回调：启动 3 个线程 ── */
static void on_start(void *data)
{
    (void)data;
    set_enable(g_btn_start, 0);    /* 防止重复点击 */
    llog(L"═══ 启动 3 个并发线程 ═══");
    g_counter = 0;

    thread_run(thread_runner1, NULL);
    thread_run(thread_runner2, NULL);
    thread_run(thread_runner3, NULL);
}

static void on_clear(void *data)
{
    (void)data;
    set_text(g_log, L"");
    statusbar_set_text(g_status, L"已清空");
}

/* ── 入口 ── */
int main(void)
{
    if (init_app() != 0)
    {
        alert(L"错误", L"Eduwin 初始化失败");
        return 1;
    }

    /* 初始化线程模块 */
    if (thread_init() != 0)
    {
        alert(L"错误", L"线程模块初始化失败");
        return 1;
    }

    /* 创建互斥锁 */
    g_mutex      = mutex_create();
    g_done_mutex = mutex_create();

    g_win = create_window(L"线程模块演示 (eduwin_thread)", 620, 440);
    if (!g_win)
    {
        alert(L"错误", L"创建窗口失败");
        mutex_free(g_mutex);
        mutex_free(g_done_mutex);
        thread_cleanup();
        return 1;
    }

    int m = 8;
    int cw = 620 - 2 * m;

    /* 日志区 */
    g_log = create_textarea(g_win, L"", m, m, cw, 280);
    set_readonly(g_log, 1);

    /* 按钮 */
    g_btn_start = create_button(g_win, L"启动 3 个线程", m,        m + 290, 130, 32);
    g_btn_clear = create_button(g_win, L"清空日志",      m + 140,  m + 290, 100, 32);

    on_button_click(g_btn_start, on_start, NULL);
    on_button_click(g_btn_clear, on_clear, NULL);

    /* 状态栏 */
    g_status = create_statusbar(g_win);
    statusbar_set_text(g_status, L"就绪 — 点击「启动 3 个线程」");

    show_window(g_win);

    /* 启动说明 */
    llog(L"═════ Thread Demo ═════");
    llog(L"eduwin_thread 线程模块演示");
    llog(L"点击按钮启动 3 个并发线程：");
    llog(L"  · 计数器线程 — 每 300ms 递增一次（用互斥锁保护）");
    llog(L"  · 工作线程   — 模拟耗时任务（5 步进度）");
    llog(L"  · 心跳线程   — 每 400ms 输出一次");
    llog(L"所有 UI 更新通过 execute_on_main() 安全投递");
    llog(L"");

    run_app();

    mutex_free(g_mutex);
    mutex_free(g_done_mutex);
    thread_cleanup();
    return 0;
}
