/*
 * w_base.c : main game window related routines
 *
 * Copyright (c) Yukihiko Aoki 1999
 * NetHack may be freely redistributed.  See license for details.
 *
 */

#include "hack.h"

#ifdef NH2K_EXTENDS

#include "win32api.h"
#include "w_main.h"
#include "res/resource.h"

/*
 * base window property
 */
typedef struct tagWINBASEPROP{
    int x;                              /* horizontal window position */
    int y;                              /* vertical window position */
    int cx;                             /* window width */
    int cy;                             /* window height */
}WINBASEPROP;

/*
 * local variables
 */
static WINBASEPROP property;

const static struct {
    int menu_id;
    char cmd;
}menu_cmd[] = {
    { IDM_OPTION,       'O' },
    { IDM_AUTOPICKUP,   '@' },
    { IDM_ORIGINAL,     '`' },
    { IDM_DISCOVER,     'X' },
    { IDM_SAVEGAME,     'S' },
    { IDM_QUITGAME,     'Q' },
    { IDM_OPEN,         'o' },
    { IDM_CLOSE,        'c' },
    { IDM_FORCE,        M('f') },
    { IDM_LOOT,         M('l') },
    { IDM_KICK,         C('d') },
    { IDM_SEARCH,       's' },
    { IDM_ENGRAVE,      'E' },
    { IDM_SIT,          M('s') },
    { IDM_INV_ALL,      'i' },
    { IDM_VERSION,      'v' },
    { IDM_SYMBOL,       '/' },
    { IDM_UP,           '<' },
    { IDM_DOWN,         '>' },
    { IDM_REST,         '.' },
    { IDM_APPLY,        'a' },
    { IDM_TAKEOFF_SELECT,'A' },
    { IDM_TAKEOFF_ARMOR,'T' },
    { IDM_TAKEOFF_ACC,  'R' },
    { IDM_REDO,         C('A') },
    { IDM_MONNAME,      'C' },
    { IDM_DROP,         'd' },
    { IDM_DROP_SELECT,  'D' },
    { IDM_EAT,          'e' },
    { IDM_ENGRAVE,      'E' },
/*
    { IDM_INV_GOLD,     '' } 
    { IDM_INV_UNPAID,   '' }
    { IDM_INV_USED,     '' }
*/
    { IDM_PAY,          'p' },
    { IDM_WEAR_RING,    'P' },
    { IDM_PREV,         C('p') },
    { IDM_QUAFF,        'q' },
    { IDM_READ,         'r' },
    { IDM_REDRAW,       C('r') },
    { IDM_THROW,        't' },
    { IDM_TELEPORT,     C('t') },
    { IDM_HISTORY,      'V' },
    { IDM_WEAR_WEAPON,   'w' },
    { IDM_TAKEOFF_WEAPON,'w' },
    { IDM_WEAR_ARMOR,   'W' },
    { IDM_SPELLLIST,    '+' },
    { IDM_ZAP,          'z' },
    { IDM_CASTSPELL,    'Z' },
    { IDM_FLOOR,        ';' },
    { IDM_PICKUP,       ',' },
    { IDM_AUTOPICKUP,   '@' },
    { IDM_CHECKTRAP,    '^' },
    { IDM_INV_WEAPON,   ')' },
    { IDM_INV_ARMOR,    '[' },
    { IDM_INV_RING,     '=' },
    { IDM_INV_AMULET,   '~' },
    { IDM_INV_TOOL,     '$' },
    { IDM_DISCOVERITEM, '\\' },
    { IDM_ADJUST,       M('a') },
    { IDM_CHAT,         M('c') },
    { IDM_DIP,          M('d') },
    { IDM_ENHANCE,      M('e') },
    { IDM_INVOKE,       M('i') },
    { IDM_JUMP,         M('j') },
    { IDM_MONSTER,      M('m') },
    { IDM_NAME,         M('n') },
    { IDM_OFFER,        M('o') },
    { IDM_PRAY,         M('p') },
    { IDM_RUB,          M('r') },
    { IDM_TURNUNDEAD,   M('t') },
    { IDM_UNTRAP,       M('u') },
    { IDM_COMPILEOPTION,M('v') },
    { IDM_WIPE,         M('w') },
    { IDM_NUMBER,       'n' },
    { IDM_HELP,         '?' },
    { 0, 0 }
};

/*
 * local functions
 */
static void FDECL(BaseWnd_OnGetMinMaxInfo,(HWND,LPMINMAXINFO));
static void FDECL(BaseWnd_OnSize,(HWND,UINT,int,int));
static void FDECL(BaseWnd_OnMove,(HWND,int,int));
static void FDECL(BaseWnd_OnDestroy,(HWND));
static void FDECL(BaseWnd_OnClose,(HWND));
static void FDECL(BaseWnd_OnCommand,(HWND,int,HWND,UINT));
static void FDECL(BaseWnd_defaultProperty,(void *));
static void FDECL(BaseWnd_OnPaletteChanged,(HWND,HWND));
static BOOL FDECL(BaseWnd_OnQueryNewPalette,(HWND));
static void FDECL(BaseWnd_OnInitMenuPopup, (HWND,HMENU,UINT,BOOL));

/***************************************************************************************
 * main game window procedure
 ***************************************************************************************/
LRESULT CALLBACK BaseWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch(Msg) {
        HANDLE_MSG(hWnd, WM_KEYDOWN,         NHWnd_OnKey);
        HANDLE_MSG(hWnd, WM_CHAR,            NHWnd_OnChar);
        HANDLE_MSG(hWnd, WM_SYSKEYDOWN,      NHWnd_OnSysKey);
        HANDLE_MSG(hWnd, WM_GETMINMAXINFO,   BaseWnd_OnGetMinMaxInfo);
        HANDLE_MSG(hWnd, WM_SIZE,            BaseWnd_OnSize);
        HANDLE_MSG(hWnd, WM_DESTROY,         BaseWnd_OnDestroy);
        HANDLE_MSG(hWnd, WM_CLOSE,           BaseWnd_OnClose);
        HANDLE_MSG(hWnd, WM_COMMAND,         BaseWnd_OnCommand);
        HANDLE_MSG(hWnd, WM_PALETTECHANGED,  BaseWnd_OnPaletteChanged);
        HANDLE_MSG(hWnd, WM_QUERYNEWPALETTE, BaseWnd_OnQueryNewPalette);
        HANDLE_MSG(hWnd, WM_MOVE,            BaseWnd_OnMove);
        HANDLE_MSG(hWnd, WM_INITMENUPOPUP,   BaseWnd_OnInitMenuPopup);
    default:
        return DefWindowProc(hWnd,Msg,wParam,lParam);
    }
}

/***************************************************************************************
 * create base window
 ***************************************************************************************/
HWND BaseWnd_create()
{
    HWND hwnd;

    hwnd = CreateWindowEx(
        0,                                  /* extra style          */
        "NHBASE",                           /* class name           */
        DEF_BASEWNDNAME,                    /* window name          */
        WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,/* window style         */
        0,                                  /* horizontal position  */
        0,                                  /* vertical position    */
        DEF_BASEMINWIDTH,                   /* width                */
        DEF_BASEMINHEIGHT,                  /* height               */
        NULL,                               /* parent window        */
        (HMENU)0,                           /* child-window id      */
        g_hInstance,                        /* instance handle      */
        (LPVOID)0);                         /* CREATESTRUCT         */

    /* restore window settings */
    if(NHWnd_loadProperty(
        "BaseWnd", &property, sizeof(WINBASEPROP), BaseWnd_defaultProperty)) {
        SetWindowPos(hwnd, NULL, 
            property.x, property.y, property.cx, property.cy,
            SWP_NOZORDER);
    }else {
        /* default window size and position */
        NHWnd_moveCenter(hwnd, GetDesktopWindow());
    }
    ShowWindow(hwnd, SW_SHOW);

    return hwnd;
}

/*-------------------------------------------------------------------------------------
 * 
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_handleCommand(int id)
{
    int i;

    for(i = 0; menu_cmd[i].menu_id != 0; i++) {
        if(menu_cmd[i].menu_id == id) {
            Key_put(menu_cmd[i].cmd);
            break;
        }
    }
}

/*-------------------------------------------------------------------------------------
 * WM_COMMAND
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
    switch(id) {
    case IDM_CONFIGMAP:
        MapWnd_cmdProperty(WIN_MAP);
        break;
    case IDM_CONFIGMESSAGE:
        MesgWnd_cmdProperty(WIN_MESSAGE);
        break;
    case IDM_CONFIGSTATUS:
        StatWnd_cmdProperty(WIN_STATUS);
        break;
    case IDM_CONFIGMENU:
        MenuWnd_cmdProperty();
        break;
    case IDM_CONFIGSYS:
        break;
    case IDM_COPYMAPTEXT:
        MapWnd_copyText(WIN_MAP);
        break;
    case IDM_COPYMESSAGE:
        MesgWnd_copyText(WIN_MESSAGE);
        break;
    default:
        BaseWnd_handleCommand(id);
        break;
    }
}

/*-------------------------------------------------------------------------------------
 * WM_GETMINMAXINFO
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_OnGetMinMaxInfo(HWND hwnd, LPMINMAXINFO lpMinMaxInfo)
{
    lpMinMaxInfo->ptMinTrackSize.x = DEF_BASEMINWIDTH;
    lpMinMaxInfo->ptMinTrackSize.y = DEF_BASEMINHEIGHT;
}

/*-------------------------------------------------------------------------------------
 * WM_MOVE
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_OnMove(HWND hwnd, int x, int y)
{
    DWORD style, exstyle;
    RECT rc;

    GetClientRect(hwnd, &rc);
    OffsetRect(&rc, x, y);
    style = GetWindowLong(hwnd, GWL_STYLE);
    exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
    AdjustWindowRectEx(&rc, style, TRUE, exstyle);
    property.x = rc.left;
    property.y = rc.top;
    NHWnd_saveProperty("BaseWnd", &property, sizeof(WINBASEPROP));
}

/*-------------------------------------------------------------------------------------
 * WM_SIZE
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_OnSize(HWND hwnd, UINT state, int cx, int cy)
{
    DWORD style, exstyle;
    RECT rc;

    if(state != SIZE_MINIMIZED) {
        GetClientRect(hwnd, &rc);
        style = GetWindowLong(hwnd, GWL_STYLE);
        exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
        AdjustWindowRectEx(&rc, style, TRUE, exstyle);
        property.cx = rc.right - rc.left;
        property.cy = rc.bottom - rc.top;
        NHWnd_saveProperty("BaseWnd", &property, sizeof(WINBASEPROP));
        NHWnd_newLayout();
    }
}

/*-------------------------------------------------------------------------------------
 * WM_DETROY
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_OnDestroy(HWND hwnd)
{
    /* finish */
    PostQuitMessage(0);
    exit(EXIT_SUCCESS);
}

/*-------------------------------------------------------------------------------------
 * WM_CLOSE
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_OnClose(HWND hwnd)
{
    if(Key_getStatus() == KEYSTAT_WAITCOMMAND) {
        Key_put('Q');
    }else {
        /* warning */
    }
}

/*-------------------------------------------------------------------------------------
 * WM_PALETTECHANGED
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_OnPaletteChanged(HWND hwnd, HWND hwndPaletteChange)
{
    if(hwndPaletteChange != hwnd) {
        BaseWnd_OnQueryNewPalette(hwnd);
    }
}

/*-------------------------------------------------------------------------------------
 * WM_QUERYNEWPALETTE
 *-------------------------------------------------------------------------------------*/
static BOOL BaseWnd_OnQueryNewPalette(HWND hwnd)
{
    HDC hdc;
    HPALETTE newPal, oldPal;

    newPal = disp_procs.getPalette();
    hdc = GetDC(hwnd);
    oldPal = SelectPalette(hdc, newPal, FALSE);
    RealizePalette(hdc);
    SelectPalette(hdc, oldPal, FALSE);
    ReleaseDC(hwnd, hdc);
    InvalidateRect(hwnd, NULL, FALSE);

    return TRUE;
}

/*-------------------------------------------------------------------------------------
 * WM_INITMENUPOPUP
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_OnInitMenuPopup(HWND hwnd, HMENU hMenu, UINT item, BOOL fSystemMenu)
{
    UINT enable;
    int  i, count;

    if(!fSystemMenu) {
        count = GetMenuItemCount(hMenu);
        enable = (Key_getStatus() == KEYSTAT_WAITCOMMAND) ? MF_ENABLED : MF_GRAYED;
        for(i = 0; i < count; i++) {
            EnableMenuItem(hMenu, i, enable|MF_BYPOSITION);
        }
    }
}

/*-------------------------------------------------------------------------------------
 * Set default property
 *-------------------------------------------------------------------------------------*/
static void BaseWnd_defaultProperty(void *param)
{
    WINBASEPROP *property = (WINBASEPROP *)param;

    property->x  = 0;
    property->y  = 0;
    property->cx = DEF_BASEMINWIDTH;
    property->cy = DEF_BASEMINHEIGHT;
}


#endif /* NH2K_EXTENDS */
