/*
 * w_stat.c : Status window related routines(NHW_STATUS)
 *
 * 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"
#include "w_dibtile.h"

/*
 * Display mode
 */
#define STAT_MODE_ORIGINAL      (0x00)
#define STAT_MODE_ADVANCED      (0x01)

/*
 * Status window property
 */
typedef struct tagWINSTATPROP {
    unsigned char mode;
    unsigned char show_top;
    unsigned char show_detail;
    unsigned char show_bar;
}WINSTATPROP;

/*
 * Status item
 */
typedef struct tagSTATITEM {
    char *name;                         /* Name */
    int value;                          /* Current value */
    int max;                            /* Max value (if exist) */
}STATITEM;

/*
 * Status window data
 */
typedef struct tagWINSTATINFO {
    char bot[2][BUFSZ];                 /* Original status line */
    char cname[BUFSZ];                  /* Advanced(?) status line */
    STATITEM hp;                        /* Hit point (current/max) */
    STATITEM pow;                       /* Magic power (current/max) */
    HWND icon_wnd;                      /* Icon window */
    HWND side_wnd;                      /* Side status window */
    OFFSCREEN   *ofb;                   /* Offscreen for icon_wnd */
    FONTINFO    font;                   /* Font */
    WINSTATPROP property;               /* Property */
    BOOL init_flg;
}WINSTATINFO;

/*
 * External variables
 */
extern const char *hu_stat[];
extern const char *enc_stat[];
extern int g_childid;

/*
 * Local functions
 */
static void FDECL(StatWnd_setWindesc, (WINDESC *,int,void *));
static void FDECL(StatWnd_procCalcRect, (WINDESC *,RECT *,RECT *));
static void FDECL(StatWnd_procDestroy, (WINDESC *));
static void FDECL(StatWnd_procSetCursor, (WINDESC *,int,int));
static void FDECL(StatWnd_procPutStr, (WINDESC *,int,const char *));
static void FDECL(StatWnd_procDraw, (WINDESC *wd, HDC hdc));
static BOOL FDECL(StatWnd_OnCreate, (HWND, LPCREATESTRUCT));
static void FDECL(StatWnd_defaultProperty, (void *));
static int  FDECL(_drawGold, (int,int,OFFSCREEN *,TILELIST *));
static void FDECL(_drawIcons, (WINDESC *, HDC));
static void FDECL(_drawAbility, (WINDESC *, HDC));
static void FDECL(_updateSubWnd, (HWND, WINSTATINFO *));
static void FDECL(_drawBar, (HDC,FONTINFO*,RECT*,STATITEM*,COLORREF));

/***************************************************************************************/
/* Initialize
/***************************************************************************************/
BOOL StatWnd_init(WINDESC *wd, int type)
{
	WINSTATINFO *wsi;

	wsi = (WINSTATINFO*)NEWMEMORY(sizeof(WINSTATINFO));
	if(wsi) {
        /* Load window settings */
        NHWnd_loadProperty(
            "StatWnd", &wsi->property, sizeof(WINSTATPROP), StatWnd_defaultProperty);

        /* Load font settings */
        Font_load(&wsi->font, g_propFile, "StatWnd");

        /* create offscreen for bottom_wnd */
        wsi->ofb = Offscreen_create(
            STB_GOLD_WIDTH * g_resource->gld_bmp->numtiles +
            STB_HUN_WIDTH +
            STB_ENC_WIDTH +
            STB_STAT_WIDTH * g_resource->stt_bmp->numtiles,
            STB_HEIGHT, g_resource->gld_bmp->hpal);
        Offscreen_clear(wsi->ofb);

        StatWnd_setWindesc(wd, type, (void*)wsi);

		return TRUE;
	}
	return FALSE;
}

/*-------------------------------------------------------------------------------------
 * Fill WINDESC structure
 *-------------------------------------------------------------------------------------*/
static void StatWnd_setWindesc(WINDESC *wd, int type, void *pinfo)
{
	wd->exstyle        = 0;
	wd->style          = WS_CHILD|WS_CLIPSIBLINGS;
	wd->can_show       = TRUE;
	wd->create_at_init = TRUE;
    wd->draw_memory    = TRUE;
	wd->cname          = "NHSTAT";
	wd->wname          = NULL;
    wd->hwnd           = NULL;
	wd->type           = type;
	wd->cur.x          = -1;
	wd->cur.y          = -1;
	wd->more           = FALSE;
    wd->pinfo          = pinfo;

    wd->procCalcRect   = StatWnd_procCalcRect;
	wd->procDisplay    = NHWnd_display;
	wd->procPutStr     = StatWnd_procPutStr;
	wd->procDestroy    = StatWnd_procDestroy;
	wd->procClear      = NULL;
	wd->procSetCursor  = StatWnd_procSetCursor;
    wd->procDraw       = StatWnd_procDraw;
}

/***************************************************************************************/
/* status window procedure
/***************************************************************************************/
LRESULT CALLBACK StatWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch(Msg) {
        HANDLE_MSG(hWnd, WM_NCCREATE,   NHWnd_OnCreate);
        HANDLE_MSG(hWnd, WM_ERASEBKGND, NHWnd_OnEraseBkgnd);
        HANDLE_MSG(hWnd, WM_PAINT,      NHWnd_OnPaint);
        HANDLE_MSG(hWnd, WM_CREATE,     StatWnd_OnCreate);
    default:
        return DefWindowProc(hWnd,Msg,wParam,lParam);
    }
}

/*-------------------------------------------------------------------------------------
 * WM_CREATE
 *-------------------------------------------------------------------------------------*/
static BOOL StatWnd_OnCreate(HWND hwnd, LPCREATESTRUCT lpCS)
{
    WINDESC     *wd = GETWINDESC(hwnd);
    WINSTATINFO *wsi = (WINSTATINFO *)wd->pinfo;

    /* Create sub windows */
    wsi->icon_wnd = CreateWindowEx(
		0,"NHSUBSTAT","",WS_CHILD|WS_CLIPSIBLINGS,0,0,CW_USEDEFAULT,CW_USEDEFAULT,
        g_baseHwnd,(HMENU)2000,g_hInstance,(LPVOID)wsi);
    wsi->side_wnd = CreateWindowEx(
		0,"NHSUBSTAT","",WS_CHILD|WS_CLIPSIBLINGS,0,0,CW_USEDEFAULT,CW_USEDEFAULT,
        g_baseHwnd,(HMENU)2001,g_hInstance,(LPVOID)wsi);

    /* Show windows */
    if(wsi->property.mode == STAT_MODE_ADVANCED) {
        ShowWindow(wsi->icon_wnd, SW_SHOW);
        if(wsi->property.show_detail) {
            ShowWindow(wsi->side_wnd, SW_SHOW);
        }
    }

    return TRUE;
}

/*-------------------------------------------------------------------------------------
 * Update main status window
 *-------------------------------------------------------------------------------------*/
static void StatWnd_procDraw(WINDESC *wd, HDC hdc)
{
	WINSTATINFO *wsi = (WINSTATINFO*)wd->pinfo;
	RECT		rc;
	HFONT		oldFont;
    int         height;
    char        buf[BUFSZ];

    /* Fill background */
    GetClientRect(wd->hwnd, &rc);
    NHWnd_drawWall(hdc, &rc);
    rc.left += 6;
    rc.right -= 6;

    if(!wsi->init_flg) {
        return;
    }

    /* Device context settings */
    oldFont = SelectObject(hdc, wsi->font.font_handle);

    height = Font_height(&wsi->font, hdc);
    if(wsi->property.mode == STAT_MODE_ORIGINAL) {
        rc.top += 3;

        /* First line */
	    rc.bottom = rc.top + height;
        NHWnd_drawShadeText(hdc, &rc, wsi->bot[0], colormap[CLR_WHITE], 0);

        /* Second line */
	    rc.top = rc.bottom;
	    rc.bottom = rc.top + height;
        NHWnd_drawShadeText(hdc, &rc, wsi->bot[1], colormap[CLR_WHITE], 0);

    } else {

        /* Top line */
        rc.top += 3;
        rc.bottom = rc.top + height;
	    NHWnd_drawShadeText(hdc, &rc, wsi->cname, colormap[CLR_WHITE], 0);

        sprintf(buf, "%s地下%d階", 
            jtrns_obj('d', dungeons[u.uz.dnum].dname), dunlev(&u.uz));
	    NHWnd_drawShadeText(hdc, &rc, buf, colormap[CLR_WHITE], DT_RIGHT);

        if(wsi->property.show_bar == FLAG_ON) {
            rc.bottom += 3;

            /* Middle line */
	        rc.top = rc.bottom;
	        rc.bottom = rc.top + height;
            _drawBar(hdc, &wsi->font, &rc, &wsi->hp, colormap[CLR_BRIGHT_CYAN]);

            /* Bottom line */
	        rc.top = rc.bottom;
	        rc.bottom = rc.top + height;
            _drawBar(hdc, &wsi->font, &rc, &wsi->pow, colormap[CLR_BRIGHT_GREEN]);
        }

    }

    /* Restore settings */
    SelectObject(hdc, oldFont);
}

/*-------------------------------------------------------------------------------------
 * Caluculate window size
 *-------------------------------------------------------------------------------------*/
static void StatWnd_procCalcRect(WINDESC *wd, RECT *rcParent, RECT *rcChild)
{
	WINSTATINFO *wsi = (WINSTATINFO*)wd->pinfo;
    int height ,width;
    HDC hdc; /* for font size */

    /* Check main window height */
    hdc = GetDC(wd->hwnd);
    width = Font_width(&wsi->font, hdc);
    height = Font_height(&wsi->font, hdc);
    ReleaseDC(wd->hwnd, hdc);

    if(wsi->property.mode == STAT_MODE_ORIGINAL) {
        height = height * 2;
    }else if(wsi->property.show_bar) {
        height = height * 3 + 3;
    }
    height += 6;

    /* For icon window */
    if(wsi->property.mode == STAT_MODE_ADVANCED) {
        MoveWindow(wsi->icon_wnd, 
            rcParent->left,
            rcParent->bottom - STB_HEIGHT,
            rcParent->right - rcParent->left,
            STB_HEIGHT, TRUE);
        rcParent->bottom -= STB_HEIGHT;
    }

    /* For main window */
    CopyRect(rcChild, rcParent);
    if(wsi->property.show_top) {
        rcChild->bottom = rcChild->top + height;
        rcParent->top += height;
    } else {
        rcChild->top = rcChild->bottom - height;
        rcParent->bottom -= height;
    }

    /* For side window */
    if(wsi->property.mode == STAT_MODE_ADVANCED
        && wsi->property.show_detail) {
        MoveWindow(wsi->side_wnd,
            rcParent->left,
            rcParent->top,
            width * 11 + 12,
            rcParent->bottom - rcParent->top, TRUE);
        rcParent->left += width * 11 + 12;
    }
}

/*-------------------------------------------------------------------------------------
 * this function will called after bot()
 *-------------------------------------------------------------------------------------*/
static void StatWnd_procPutStr(WINDESC *wd, int attr, const char *str)
{
    WINSTATINFO *wsi = (WINSTATINFO *)wd->pinfo;
    char buf[BUFSZ];
    int tmp1, tmp2;
    BOOL need_redraw = FALSE;

    wsi->init_flg = TRUE;

    if(str && strcmp(wsi->bot[wd->cur.y], str) != 0) {
        strcpy(wsi->bot[wd->cur.y], str);
        need_redraw = TRUE;
    }
    
    /* set new hit point */
    tmp1 = Upolyd ? u.mh : u.uhp;
    tmp2 = Upolyd ? u.mhmax : u.uhpmax;
    if(wsi->hp.value != tmp1 || wsi->hp.max != tmp2) {
        wsi->hp.name = "体力:";
        wsi->hp.value = tmp1;
        wsi->hp.max = tmp2;
    }
    /* set new power */
    if(wsi->pow.value != u.uen || wsi->pow.max != u.uenmax) {
        wsi->pow.name = "魔力:";
        wsi->pow.value = u.uen;
        wsi->pow.max = u.uenmax;
    }
    /* set player name */
    sprintf(buf, "%s-%s %s %s%u",
        plname, 
        Upolyd ? jtrns_mon(mons[u.umonnum].mname, flags.female)
            : rank_of(u.ulevel, u.role, flags.female),
        align_str(u.ualign.type),
        Upolyd ? "HD:" : "Lev:",
        Upolyd ? mons[u.umonnum].mlevel : u.ulevel);
    if(flags.showexp) {
        sprintf(&buf[strlen(buf)], "/%-1ld", u.uexp);
    }
    if(!wsi->property.show_bar) {
        sprintf(&buf[strlen(buf)], " %s%d(%d) %s%d(%d)",
            wsi->hp.name, wsi->hp.value, wsi->hp.max,
            wsi->pow.name, wsi->pow.value, wsi->pow.max);
    }

    /* check player name */
    if(strcmp(buf, wsi->cname) != 0) {
        strcpy(wsi->cname, buf);
    }

    if(need_redraw) {
        InvalidateRect(wd->hwnd, NULL, FALSE);
        _updateSubWnd(wsi->icon_wnd, wsi);
        if(wsi->property.show_detail) {
            _updateSubWnd(wsi->side_wnd, wsi);
        }
    }
}

/*--------------------------------------------------------------------------------------
 * Destroy window
 *-------------------------------------------------------------------------------------*/
static void StatWnd_procDestroy(WINDESC* wd)
{
    WINSTATINFO *wsi = (WINSTATINFO *)wd->pinfo;

    if(wsi) {
        if(wsi->ofb) {
            Offscreen_free(wsi->ofb);
        }
        if(wsi->icon_wnd) {
            DestroyWindow(wsi->icon_wnd);
        }
        if(wsi->side_wnd) {
            DestroyWindow(wsi->side_wnd);
        }
        DELMEMORY(wsi);
    }
}

/*-------------------------------------------------------------------------------------
 * Set Cursor position
 *-------------------------------------------------------------------------------------*/
static void StatWnd_procSetCursor(WINDESC *wd, int col, int row)
{
    wd->cur.x = col;
    wd->cur.y = row;
}

/*-------------------------------------------------------------------------------------
 * Draw bar graph
 *-------------------------------------------------------------------------------------*/
static void _drawBar(
    HDC hdc, FONTINFO *font, RECT *rc, STATITEM *item, COLORREF color)
{
    char        buf[BUFSZ];
	RECT		rcDraw;
	COLORREF	showColor;
    HBRUSH      oldBrs;
    HPEN        oldPen;
    HFONT       oldFont;
    int         cur;

    /* Device context settings */
    oldFont = SelectObject(hdc, font->font_handle);
    oldBrs = SelectObject(hdc, GetStockObject(WHITE_BRUSH));
	oldPen = SelectObject(hdc, GetStockObject(WHITE_PEN));

    /* Draw title */
    CopyRect(&rcDraw, rc);
    rcDraw.right = rcDraw.left + Font_width(font, hdc) * 15;
	NHWnd_drawShadeText(hdc, &rcDraw, item->name, colormap[CLR_WHITE], 0);

    /* Draw values */
    cur = (item->value >= 0) ? item->value : 0;
    showColor = (item->max / 5 > item->value) ? colormap[CLR_RED] : 
        (item->max / 3 > item->value) ? colormap[CLR_YELLOW] : color;
    sprintf(buf, "%d(%d)", cur, item->max);
	NHWnd_drawShadeText(hdc, &rcDraw, buf, showColor, DT_RIGHT);

	/* Fill frame */
    CopyRect(&rcDraw, rc);
    rcDraw.left = rcDraw.left + Font_width(font, hdc) * 16;
	RoundRect(hdc, 
        rcDraw.left,
        rcDraw.top + 2,
        rcDraw.left + item->max + 6,
        rcDraw.bottom - 2, 5, 5);

    /* Fill max value box */
    if(item->max > 0) {
        CopyRect(&rcDraw, rc);
        rcDraw.left   += Font_width(font, hdc) * 16 + 2;
        rcDraw.top    += 3;
        rcDraw.right  = rcDraw.left + item->max + 2;
        rcDraw.bottom -= 3;
    	SetBkColor(hdc, colormap[CLR_BLACK]);
	    ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, NULL);
    }

    /* Fill current value box */
    if(cur > 0) {
        CopyRect(&rcDraw, rc);
        rcDraw.left   += Font_width(font, hdc) * 16 + 3;
        rcDraw.top    += 4;
        rcDraw.right  = rcDraw.left + cur;
        rcDraw.bottom -= 4;
	    SetBkColor(hdc, showColor);
	    ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, NULL);
    }

    /* Restore settings */
	SelectObject(hdc, oldBrs);
	SelectObject(hdc, oldPen);
    SelectObject(hdc, oldFont);
}
/*-------------------------------------------------------------------------------------
 * Draw gold count to offscreen buffer
 *-------------------------------------------------------------------------------------*/
static int _drawGold(int val, int offset, OFFSCREEN *ofb, TILELIST *list)
{
    TILEDATA *tile;
    int pos;
    
    pos = offset;
    if((val / 10) > 0) {
        pos = _drawGold(val / 10, offset, ofb, list);
    }
    tile = &list->tiles[val %10];
    Offscreen_blt(ofb, pos, 0, tile->cx, tile->cy, tile, 0, 0, BLTMODE_MASK);

    return pos + list->width;
}

/*-------------------------------------------------------------------------------------
 * Update sub status window 
 *-------------------------------------------------------------------------------------*/
static void _drawIcons(WINDESC *wd, HDC hdc)
{
    WINSTATINFO *wsi = (WINSTATINFO *)wd->pinfo;
    int  i;
    int offset, x;
    BOOL ills[6];
    HDC dcMem;
    HBITMAP oldBmp;
    RECT rc;

    GetClientRect(wsi->icon_wnd, &rc);
    if((rc.right - rc.left) > wsi->ofb->info->biWidth) {
        rc.left -= wsi->ofb->info->biWidth;
        FillRect(hdc, &rc, GetStockObject(BLACK_BRUSH));
    }

    if(!wsi->init_flg) {
        return;
    }

    /* Check illness status */
    ills[0] = (Confusion);
    ills[1] = (Sick && (u.usick_type & SICK_VOMITABLE));
    ills[2] = (Sick && (u.usick_type & SICK_NONVOMITABLE));
    ills[3] = (Blind);
    ills[4] = (Stunned);
    ills[5] = (Hallucination);

    x = 6;
    Offscreen_clear(wsi->ofb);

    /* Print gold symbol */
    offset = STB_GOLD_WIDTH;
    Offscreen_blt(wsi->ofb, x, 0, g_resource->gld_bmp->width, g_resource->gld_bmp->height,
        &g_resource->gld_bmp->tiles[10], 0, 0, BLTMODE_MASK);
    x += offset;
    Offscreen_blt(wsi->ofb, x, 0, g_resource->gld_bmp->width, g_resource->gld_bmp->height,
        &g_resource->gld_bmp->tiles[11], 0, 0, BLTMODE_MASK);
    x += offset;

    /* Print gold value */
    x = _drawGold(u.ugold, x, wsi->ofb, g_resource->gld_bmp);

    x += 6;
    /* Print hunger status */
    Offscreen_blt(wsi->ofb, x, 0, g_resource->hun_bmp->width, g_resource->hun_bmp->height,
        &g_resource->hun_bmp->tiles[u.uhs], 0, 0, BLTMODE_MASK);
    x += STB_HUN_WIDTH;

    /* Print encumbered status */
    Offscreen_blt(wsi->ofb, x, 0, g_resource->enc_bmp->width, g_resource->enc_bmp->height,
        &g_resource->enc_bmp->tiles[near_capacity()], 0, 0, BLTMODE_MASK);
    x += STB_ENC_WIDTH;

    /* Print special status */
    offset = STB_STAT_WIDTH;
    for(i = 0; i < g_resource->stt_bmp->numtiles; i++) {
        if(ills[i]) {
            x += offset;
            Offscreen_blt(wsi->ofb, x, 0, g_resource->stt_bmp->width, g_resource->stt_bmp->height,
                &g_resource->stt_bmp->tiles[i], 0, 0, BLTMODE_MASK);
        }
    }

    dcMem = CreateCompatibleDC(hdc);
    oldBmp = SelectObject(dcMem, wsi->ofb->hbmp);
    BitBlt(hdc,0,0,wsi->ofb->info->biWidth, wsi->ofb->info->biHeight,dcMem,0,0,SRCCOPY);
    SelectObject(dcMem, oldBmp);
    DeleteDC(dcMem);
}

/*-------------------------------------------------------------------------------------
 * Draw sub status window 
 *-------------------------------------------------------------------------------------*/
static void _drawAbility(WINDESC *wd, HDC hdc)
{
    WINSTATINFO *wsi = (WINSTATINFO *)wd->pinfo;
    char   buf[BUFSZ];
    char   str[20];
    RECT   rc;
    int    value;
    int    height, width;
    HFONT  oldFont;

    GetClientRect(wd->hwnd, &rc);
    NHWnd_drawWall(hdc, &rc);

    if(!wsi->init_flg) {
        return;
    }

    oldFont = SelectObject(hdc, wsi->font.font_handle);
    width = Font_width(&wsi->font, hdc);
    height = Font_height(&wsi->font, hdc);

    value = ACURR(A_STR);
	if(value > 18) {
        if(value > 118) {
			sprintf(str, "%2d", value - 100);
        } else if(value < 118) {
			sprintf(str, "18/%02d", value - 18);
        } else {
			sprintf(str,"18/**");
        }
    } else {
		sprintf(str, "%-1d", value);
	}
    rc.left += 6;
    rc.right -= 6;
    sprintf(buf, "\n強さ:\n早さ:\n耐久:\n知力:\n賢さ:\n魅力:\n\n装備:");
#ifdef SCORE_ON_BOTL
    if(flags.showscore) {
        strcat(buf, "\n\n点:");
    }
#endif
    if(flags.time) {
        strcat(buf, "\n\n歩:");
    }
    NHWnd_drawShadeText(hdc, &rc, buf, colormap[CLR_WHITE], 0);

    sprintf(buf, "\n%s\n%d\n%d\n%d\n%d\n%d\n\n%d",
        str, ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA), u.uac);
#ifdef SCORE_ON_BOTL
    if(flags.showscore) {
        sprintf(str, "\n\n%ld", botl_score());
        strcat(buf, str);
    }
#endif
    if(flags.time) {
        sprintf(str, "\n\n%d", moves);
        strcat(buf, str);
    }
    NHWnd_drawShadeText(hdc, &rc, buf, colormap[CLR_GRAY], DT_RIGHT);

    SelectObject(hdc, oldFont);
}

/*-------------------------------------------------------------------------------------
 * Update sub status window 
 *-------------------------------------------------------------------------------------*/
static void _updateSubWnd(HWND hwnd, WINSTATINFO *wsi)
{
    WINDESC wd;

    wd.hwnd = hwnd;
    wd.procDraw = (hwnd == wsi->side_wnd ? _drawAbility : _drawIcons);
    wd.pinfo = wsi;
    wd.more = FALSE;
    NHWnd_display(&wd);
}

/*-------------------------------------------------------------------------------------
 * status dialog window procedure
 *-------------------------------------------------------------------------------------*/
LRESULT CALLBACK SubStatProc(HWND hwnd, UINT mesg, UINT wParam, LONG lParam)
{
    switch(mesg) {
    case WM_CREATE:
        SetWindowLong(hwnd, GWL_USERDATA, (LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
        return 0;
    case WM_PAINT:
        ValidateRect(hwnd, NULL);
        _updateSubWnd(hwnd, (WINSTATINFO *)GetWindowLong(hwnd, GWL_USERDATA));
        return 0;
    case WM_ERASEBKGND:
        return TRUE;
    default:
        return DefWindowProc(hwnd,mesg,wParam,lParam);
    }
}

/*-------------------------------------------------------------------------------------
 * load settings from ini file 
 *-------------------------------------------------------------------------------------*/
static void StatWnd_defaultProperty(void *param)
{
    WINSTATPROP *property = (WINSTATPROP *)param;

    property->mode = STAT_MODE_ORIGINAL;
    property->show_top = FLAG_OFF;
    property->show_bar = FLAG_ON;
    property->show_detail = FLAG_ON;
}

/*-------------------------------------------------------------------------------------
 * Status window property dialog procedure
 *-------------------------------------------------------------------------------------*/
static BOOL CALLBACK StatPropProc(HWND hDlg, UINT mesg, UINT wParam, LONG lParam)
{
    static WINSTATPROP property;
    static FONTINFO    font;
    static WINSTATINFO *wsi;

    switch (mesg) {
    case WM_INITDIALOG:

        /* Set initial values */
        wsi = (WINSTATINFO *)lParam;
        CopyMemory(&property, &wsi->property, sizeof(WINSTATPROP));
        CopyMemory(&font, &wsi->font, sizeof(FONTINFO));
        CheckRadioButton(hDlg, RADIO_TOP, RADIO_BOTTOM, (property.show_top ? RADIO_TOP : RADIO_BOTTOM));
        CheckRadioButton(hDlg, RADIO_ORIGINAL, RADIO_ADVANCED, (property.mode == STAT_MODE_ORIGINAL ?
            RADIO_ORIGINAL : RADIO_ADVANCED));
        CheckDlgButton(hDlg, CHECK_DETAIL, (property.show_detail ? BST_CHECKED : BST_UNCHECKED));
        CheckDlgButton(hDlg, CHECK_BAR, (property.show_bar ? BST_CHECKED : BST_UNCHECKED));
        EnableWindow(GetDlgItem(hDlg, CHECK_DETAIL), (property.mode == STAT_MODE_ADVANCED));
        EnableWindow(GetDlgItem(hDlg, CHECK_BAR), (property.mode == STAT_MODE_ADVANCED));
        SendDlgItemMessage(hDlg, STATIC_FONT, WM_SETFONT, (WPARAM)font.font_handle, 0);
        break;

    case WM_CTLCOLORSTATIC:

        /* Set sample font color */
        if((HWND)lParam == GetDlgItem(hDlg, STATIC_FONT)) {
            SetTextColor((HDC)wParam, font.font_color);
            SetBkMode((HDC)wParam, TRANSPARENT);
            return (BOOL)GetStockObject(BLACK_BRUSH);
        } else {
            return DefWindowProc(hDlg, mesg, wParam, lParam);
        }
        break;

    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:

            /* Save settings */
            property.mode = IsDlgButtonChecked(hDlg, RADIO_ORIGINAL) == BST_CHECKED 
                ? STAT_MODE_ORIGINAL : STAT_MODE_ADVANCED;
            property.show_top = IsDlgButtonChecked(hDlg, RADIO_TOP) == BST_CHECKED 
                ? FLAG_ON : FLAG_OFF;
            property.show_detail = IsDlgButtonChecked(hDlg, CHECK_DETAIL) == BST_CHECKED 
                ? FLAG_ON : FLAG_OFF;
            property.show_bar = IsDlgButtonChecked(hDlg, CHECK_BAR) == BST_CHECKED
                ? FLAG_ON : FLAG_OFF;
            CopyMemory(&wsi->property, &property, sizeof(WINSTATPROP));
            CopyMemory(&wsi->font, &font, sizeof(FONTINFO));
            EndDialog(hDlg, 1);
            break;

        case IDCANCEL:

            /* Dialog canceled */
            Font_delete(&font);
            Font_create(&wsi->font);
            EndDialog(hDlg, 0);
            break;

        case BUTTON_FONT:

            /* Show font dialog */
            Font_select(hDlg, &font, TRUE, FALSE, TRUE);
            SendDlgItemMessage(
                hDlg, STATIC_FONT, WM_SETFONT, (WPARAM)font.font_handle, MAKELPARAM(TRUE, 0));
            break;

        case BUTTON_RESET:

            /* Restore previous values */
            CopyMemory(&property, &wsi->property, sizeof(WINSTATPROP));

            Font_delete(&font);
            CopyMemory(&font, &wsi->font, sizeof(FONTINFO));
            Font_create(&font);
            CheckRadioButton(hDlg, RADIO_TOP, RADIO_BOTTOM, (property.show_top ? RADIO_TOP : RADIO_BOTTOM));
            CheckRadioButton(hDlg, RADIO_ORIGINAL, RADIO_ADVANCED, (property.mode == STAT_MODE_ORIGINAL ?
                RADIO_ORIGINAL : RADIO_ADVANCED));
            CheckDlgButton(hDlg, CHECK_DETAIL, (property.show_detail ? BST_CHECKED : BST_UNCHECKED));
            CheckDlgButton(hDlg, CHECK_BAR, (property.show_bar ? BST_CHECKED : BST_UNCHECKED));
            EnableWindow(GetDlgItem(hDlg, CHECK_DETAIL), (property.mode == STAT_MODE_ADVANCED));
            EnableWindow(GetDlgItem(hDlg, CHECK_BAR), (property.mode == STAT_MODE_ADVANCED));
            SendDlgItemMessage(
                hDlg, STATIC_FONT, WM_SETFONT, (WPARAM)font.font_handle, MAKELPARAM(TRUE, 0));
            break;

        case RADIO_ADVANCED:
        case RADIO_ORIGINAL:

            EnableWindow(GetDlgItem(hDlg, CHECK_DETAIL), IsDlgButtonChecked(hDlg, RADIO_ADVANCED));
            EnableWindow(GetDlgItem(hDlg, CHECK_BAR), IsDlgButtonChecked(hDlg, RADIO_ADVANCED));
            break;

        default:
            break;
        }
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

/***************************************************************************************
 * Display property dialog
 ***************************************************************************************/
void StatWnd_cmdProperty(WINDESC *wd)
{
	WINSTATINFO *wsi;
    
    if(!NHWnd_isValid(wd)) {
        return;
    }
    
    wsi = (WINSTATINFO *)wd->pinfo;

    /* Property dialog open */
    if(DialogBoxParam(g_hInstance, "STAT_PROP", g_baseHwnd, StatPropProc, (LPARAM)wsi)) {

        /* "OK" button pressed */
        NHWnd_saveProperty("StatWnd", &wsi->property, sizeof(WINSTATPROP));
        Font_save(&wsi->font, g_propFile, "StatWnd");
        NHWnd_newLayout();
        StatWnd_procPutStr(wd,0,NULL);
        InvalidateRect(wd->hwnd, NULL, FALSE);
        if(wsi->property.mode == STAT_MODE_ADVANCED) {
            ShowWindow(wsi->icon_wnd, SW_SHOW); 
            if(wsi->property.show_detail) {
                ShowWindow(wsi->side_wnd, SW_SHOW); 
            }else {
                ShowWindow(wsi->side_wnd, SW_HIDE); 
            }
        }else {
            ShowWindow(wsi->icon_wnd, SW_HIDE);
            ShowWindow(wsi->side_wnd, SW_HIDE);
        }
        _updateSubWnd(wsi->icon_wnd, wsi);
        _updateSubWnd(wsi->side_wnd, wsi);
    }
}

/***************************************************************************************
 * Move Icon window to bottom
 * (I don't like this implement!)
 ***************************************************************************************/
void StatWnd_moveIconWindow(WINDESC *wd, RECT *rc)
{
	WINSTATINFO *wsi;
    
    if(!NHWnd_isValid(wd)) {
        return;
    }
    
    wsi = (WINSTATINFO *)wd->pinfo;

    if(wsi->property.mode == STAT_MODE_ADVANCED) {
        MoveWindow(wsi->icon_wnd, rc->left, rc->bottom - STB_HEIGHT,
            rc->right - rc->left, STB_HEIGHT, FALSE);
        rc->top -= STB_HEIGHT;
        rc->bottom -= STB_HEIGHT;
    }
}

#endif /* NH2K_EXTENDS */
