
/*
 * Copyright (C) Igor Sysoev
 */


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <nginx.h>


static ngx_thread_value_t __stdcall ngx_worker_thread_cycle(void *data);
static void ngx_process_tray(ngx_cycle_t *cycle);
static long __stdcall ngx_window_procedure(HWND window, u_int message,
    u_int wparam, long lparam);

#if 0
ngx_pid_t     ngx_new_binary;

sig_atomic_t  ngx_reap;
sig_atomic_t  ngx_timer;

#endif

ngx_uint_t    ngx_process;
ngx_pid_t     ngx_pid;
ngx_uint_t    ngx_threaded;
ngx_uint_t    ngx_inherited;


sig_atomic_t  ngx_terminate;
sig_atomic_t  ngx_quit;
ngx_uint_t    ngx_exiting;

#if 0

sig_atomic_t  ngx_noaccept;
sig_atomic_t  ngx_reconfigure;
sig_atomic_t  ngx_reopen;
sig_atomic_t  ngx_change_binary;

#endif


static HMENU  ngx_menu;


void
ngx_master_process_cycle(ngx_cycle_t *cycle)
{
    ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "master mode is not supported");

    exit(2);
}


void
ngx_single_process_cycle(ngx_cycle_t *cycle)
{
    ngx_int_t         i;
    ngx_err_t         err;
    ngx_tid_t         tid;
    ngx_core_conf_t  *ccf;

    ngx_init_temp_number();

    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->init_process) {
            if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
                /* fatal */
                exit(2);
            }
        }
    }

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle)
        != NGX_OK)
    {
        /* fatal */
        exit(2);
    }

    err = ngx_thread_key_create(&ngx_core_tls_key);
    if (err != 0) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
                      ngx_thread_key_create_n " failed");
        /* fatal */
        exit(2);
    }

    if (ngx_create_thread(&tid, ngx_worker_thread_cycle, NULL, cycle->log)
        != 0)
    {
        /* fatal */
        exit(2);
    }

    ngx_process_tray(cycle);
}


static ngx_thread_value_t __stdcall
ngx_worker_thread_cycle(void *data)
{
    ngx_cycle_t  *cycle;

    cycle = (ngx_cycle_t *) ngx_cycle;

    while (!ngx_quit) {
        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");

        ngx_process_events_and_timers(cycle);
    }

    return 0;
}


static void
ngx_process_tray(ngx_cycle_t *cycle)
{
    int        rc;
    MSG        message;
    HWND       window;
    HMENU      menu;
    HICON      icon, tray;
    WNDCLASS   wc;
    HINSTANCE  instance;

    instance = GetModuleHandle(NULL);

    icon = LoadIcon(instance, "nginx");
    if (icon == NULL) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                      "LoadIcon(\"nginx\") failed");
        /* fatal */
        exit(2);
    }

    tray = LoadIcon(instance, "tray");
    if (icon == NULL) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                      "LoadIcon(\"tray\") failed");
        /* fatal */
        exit(2);
    }

    menu = LoadMenu(instance, "nginx");
    if (menu == NULL) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                      "LoadMenu() failed");
        /* fatal */
        exit(2);
    }

    ngx_menu = GetSubMenu(menu, 0);
    if (ngx_menu == NULL) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                      "GetSubMenu() failed");
        /* fatal */
        exit(2);
    }


    wc.style = CS_HREDRAW|CS_VREDRAW;
    wc.lpfnWndProc = ngx_window_procedure;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = instance;
    wc.hIcon = icon;
    wc.hCursor = NULL;
    wc.hbrBackground = NULL;
    wc.lpszMenuName =  NULL;
    wc.lpszClassName = "nginx";

    if (RegisterClass(&wc) == 0) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                      "RegisterClass() failed");
        /* fatal */
        exit(2);
    }

    window = CreateWindow("nginx", "nginx", WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, instance, NULL);

    if (window == NULL) {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                      "CreateWindow() failed");
        /* fatal */
        exit(2);
    }


    if (ngx_system_tray_icon(window, NIM_ADD, tray, (u_char *) " nginx")
        != NGX_OK)
    {
        ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                      "Shell_NotifyIcon(NIM_ADD) failed");
        /* fatal */
        exit(2);
    }

    for ( ;; ) {
        rc = GetMessage(&message, NULL, 0, 0);

        if (rc == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "GetMessage() failed");
            continue;
        }

        if (rc == 0) {
            exit(0);
        }

        TranslateMessage(&message);
        DispatchMessage(&message);
    }
}


static long __stdcall
ngx_window_procedure(HWND window, u_int message, u_int wparam, long lparam)
{
    POINT  mouse;

    switch (message) {

    case NGX_WM_TRAY:
        if (lparam == WM_RBUTTONDOWN) {
            if (GetCursorPos(&mouse) == 0) {
                ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
                              "GetCursorPos() failed");
                return 0;
            }

            if (SetForegroundWindow(window) == 0) {
                ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
                              "SetForegroundWindow() failed");
                return 0;
            }

            if (TrackPopupMenu(ngx_menu, TPM_RIGHTBUTTON,
                               mouse.x, mouse.y, 0, window, NULL)
                == 0)
            {
                ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
                              "TrackPopupMenu() failed");
                return 0;
            }
        }

        return 0;

    case WM_COMMAND:
        if (wparam == NGX_WM_ABOUT) {
            ngx_message_box("nginx", MB_OK, 0,
                            NGINX_VER CRLF "(C) 2002-2009 Igor Sysoev");
            return 0;
        }

        if (wparam == NGX_WM_EXIT) {
            if (ngx_system_tray_icon(window, NIM_DELETE, NULL, NULL)
                != NGX_OK)
            {
                ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
                              "Shell_NotifyIcon(NIM_DELETE) failed");
            }
        }

        PostQuitMessage(0);

        return 0;

    default:
        return DefWindowProc(window, message, wparam, lparam);
    }
}
