/*
 * w_text.c : Text display window related routines(NHW_TEXT)
 *
 * Copyright (c) Yukihiko Aoki 1999, 2005
 * NetHack may be freely redistributed.  See license for details.
 *
 */

#include "hack.h"

#ifdef NH2K_EXTENDS

#include "win32api.h"
#include "w_main.h"

/*
 * structure for single line
 */
typedef struct tagWINTEXTITEM{
    int    attr;
    char   *str;
    struct tagWINTEXTITEM *next;
}WINTEXTITEM;

/*
 * structure for text window
 */
typedef struct tagWINTEXTINFO{
    int         cur_show;
    int         scr_pos;
    int         numlines;
    int         maxlen;
    WINTEXTITEM *topitem;
    FONTINFO    *font;
}WINTEXTINFO;

extern FONTINFO menu_font;

/*
 * local functions
 */
static void FDECL(TextWnd_procCalcRect, (WINDESC *,RECT *,RECT *));
static void FDECL(TextWnd_procDestroy,  (WINDESC *));
static void FDECL(TextWnd_procDisplay,  (WINDESC *));
static void FDECL(TextWnd_procPutStr,   (WINDESC *,int,const char*));
static void FDECL(TextWnd_procDraw,     (WINDESC *,HDC));
static void FDECL(TextWnd_procClear,    (WINDESC *));

/***************************************************************************************
 * Window Procedure
 ***************************************************************************************/
LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg) {
        HANDLE_MSG(hwnd, WM_NCCREATE,   NHWnd_OnCreate);
        HANDLE_MSG(hwnd, WM_PAINT,      NHWnd_OnPaint);
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
}

/*-------------------------------------------------------------------------------------
 * 
 *-------------------------------------------------------------------------------------*/
static void TextWnd_procCalcRect(WINDESC *wd, RECT *rcParent, RECT *rcChild)
{
    WINTEXTINFO *wti = (WINTEXTINFO *)wd->pinfo;
    HDC hdc;
    int cx, cy;
    int width;

    hdc = GetDC(wd->hwnd);
    cx = Font_width(wti->font, hdc);
    cy = Font_height(wti->font, hdc);
    ReleaseDC(wd->hwnd, hdc);

    CopyRect(rcChild, rcParent);
    width = wti->maxlen * cx + 8;
    rcChild->top += 6;
    rcChild->bottom -= 6;
    rcChild->left += ((RCWIDTH(rcParent) - width) / 2);
    rcChild->right = rcChild->left + width;
}

/*-------------------------------------------------------------------------------------
 * Fill WINDESC structure
 *-------------------------------------------------------------------------------------*/
static void TextWnd_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          = "NHTEXT";
    wd->wname          = "";
    wd->hwnd           = NULL;
    wd->type           = type;
    wd->cur.x          = -1;
    wd->cur.y          = -1;
    wd->more           = FALSE;
    wd->pinfo          = pinfo;

    wd->procCalcRect   = TextWnd_procCalcRect;
    wd->procDestroy    = TextWnd_procDestroy;
    wd->procDisplay    = TextWnd_procDisplay;
    wd->procClear      = TextWnd_procClear;
    wd->procSetCursor  = NULL;
    wd->procPutStr     = TextWnd_procPutStr;
    wd->procDraw       = TextWnd_procDraw;
}

/***************************************************************************************
 * Initialize
 ***************************************************************************************/
BOOL TextWnd_init(WINDESC *wd, int type)
{
    WINTEXTINFO *wti;

    wti = (WINTEXTINFO*)calloc(1, sizeof(WINTEXTINFO));
    if(wti) {

        wti->font = &menu_font;
        wti->numlines = 0;
        wti->maxlen = 0;
        wti->topitem = NULL;
        TextWnd_setWindesc(wd, type, wti);

        return TRUE;
    }

    return FALSE;
}

/*-------------------------------------------------------------------------------------
 * destructor
 *-------------------------------------------------------------------------------------*/
static void TextWnd_procDestroy(WINDESC *wd)
{
    WINTEXTINFO *wti = (WINTEXTINFO *)wd->pinfo;

    if(wti) {
        TextWnd_procClear(wd);
        free(wti);
    }
}

/*-------------------------------------------------------------------------------------
 * display_nhwindow
 *-------------------------------------------------------------------------------------*/
static void TextWnd_procDisplay(WINDESC *wd)
{
    /* hide other windows */
    NHWnd_show((WINDESC *)WIN_MAP, FALSE);
    NHWnd_show((WINDESC *)WIN_STATUS, FALSE);
    NHWnd_show((WINDESC *)WIN_MESSAGE, FALSE);
    NHWnd_newLayout();
}

/*-------------------------------------------------------------------------------------
 * putstr
 *-------------------------------------------------------------------------------------*/
static void TextWnd_procPutStr(WINDESC *wd, int attr, const char *str)
{
    WINTEXTINFO *wti = (WINTEXTINFO *)wd->pinfo;
    WINTEXTITEM *newitem, *tmpitem;

    /* create new line */
    newitem = (WINTEXTITEM *)calloc(1, sizeof(WINTEXTITEM));
    newitem->attr = attr;
    newitem->str = (char *)calloc(strlen(str)+1, sizeof(char));
    strcpy(newitem->str, str);
    newitem->next = NULL;

    /* add last chain of link list */
    if (wti->topitem) {
        tmpitem = wti->topitem;
        while (tmpitem->next) {
            tmpitem= tmpitem->next;
        }
        tmpitem->next = newitem;
    } else {
        wti->topitem = newitem;
    }

    wti->numlines++;
    wti->maxlen = max(wti->maxlen, strlen(str));
}

/*-------------------------------------------------------------------------------------
 * clear_nhwindow
 *-------------------------------------------------------------------------------------*/
static void TextWnd_procClear(WINDESC *wd)
{
    WINTEXTINFO *wti = (WINTEXTINFO *)wd->pinfo;
    WINTEXTITEM *tmpitem, *delitem;

    if (wti) {
        delitem = wti->topitem;
        while (delitem) {
            tmpitem = delitem->next;
            free(delitem->str);
            free(delitem);
            delitem = tmpitem;
        }
        wti->topitem = NULL;
        wti->numlines = 0;
    }
}

/*-------------------------------------------------------------------------------------
 * Draw
 *-------------------------------------------------------------------------------------*/
static void TextWnd_procDraw(WINDESC *wd, HDC hdc)
{
    WINTEXTINFO *wti = (WINTEXTINFO *)wd->pinfo;
    WINTEXTITEM *tmp;
    COLORREF oldFg;
    int oldMode;
    HBITMAP oldBmp;
    HFONT   oldFont;
    HDC dcMem;
    RECT rc;
    int height = 20;

    GetClientRect(wd->hwnd, &rc);
    FillRect(hdc, &rc, GetStockObject(BLACK_BRUSH));
    oldFg = SetTextColor(hdc, colormap[CLR_BLACK]);
    oldMode = SetBkMode(hdc, TRANSPARENT);

    /* draw static line */
    dcMem = CreateCompatibleDC(hdc);
    oldBmp = SelectObject(dcMem, g_resource->btn_bmp);

    /* search */
    BitBlt(hdc, 0, 0, 43, 22, dcMem, 0, 44, SRCCOPY);

    /* close */
    BitBlt(hdc, rc.right - 64, 0, 64, 22, dcMem, 0, 66, SRCCOPY);

    /* previous */
    BitBlt(hdc, 0, rc.bottom - 22, 43, 22, dcMem,  0, 0, SRCCOPY);

    /* next */
    BitBlt(hdc, rc.right - 43, rc.bottom - 22, 43, 22, dcMem, 0, 22, SRCCOPY);

    SelectObject(dcMem, oldBmp);
    DeleteDC(dcMem);

    oldFont = SelectObject(hdc, wti->font->font_handle);

    rc.top += 22;
    rc.left += 2;
    rc.right -= 2;
    rc.bottom -= 22;
    FillRect(hdc, &rc, GetStockObject(GRAY_BRUSH));

    rc.top += 2;
    rc.left += 2;
    rc.right -= 2;
    rc.bottom -= 2;
    FillRect(hdc, &rc, GetStockObject(LTGRAY_BRUSH));

    rc.top += 22;
    rc.bottom = rc.top + height;
    tmp = wti->topitem;
    while(tmp) {
        DrawText(hdc, tmp->str, -1, &rc, DT_SINGLELINE|DT_EXPANDTABS|DT_LEFT);
        tmp = tmp->next;
        rc.top = rc.bottom;
        rc.bottom = rc.top + height;
    }

    SelectObject(hdc, oldFont);

    SetTextColor(hdc, oldFg);
    SetBkMode(hdc, oldMode);

}

#endif /* NH2K_EXTENDS */
