#ifndef kclient_hxx_included
#define kclient_hxx_included
/*========================================================================
    Copyright (c) 1995, Trustees of Columbia University 
    in the City of New York.  All rights reserved.
-----------------------------------------------------------------------

    File.......: kclient.hxx
    Author.....: Thomas Wu (thomaswu@columbia.edu)
    Created....: December 27, 1995

    Description: base class for main window's client area.
        Used by terminal, command and clientserver.

========================================================================*/

extern "C" {
#include "ckcdeb.h"
#include "ckocon.h"
}

#include "kwin.hxx"
#include "kscroll.hxx"
#include "ksoftfont.hxx"

/* MAXNUMCOL is also defined in ckocon.h */
#if (defined(_MSC_VER) && _MSC_VER > 1400) || defined(__GNUC__)
const int MAXNUMCOL = 512;
#else
const int MAXNUMCOL = 256;
#endif
struct _K_CLIENT_PAINT;
struct _K_WORK_STORE;

class IKTerm;
class KFont;
class KClient : public KWin
{
public:
    KClient( K_GLOBAL*, BYTE );
    ~KClient();

    void getCreateInfo( K_CREATEINFO* info );
    void createWin( KWin* par );
    void size( int width, int height );
    Bool message( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );

    void setDimensions( Bool sizeparent );
    void setFont( KFont* );
    void fontChanged();
    void clearPaintRgn();
    void setInterSpacing( KFont* );

    Bool getMaxpDim( int& rw, int& rh );
    KFont* getFont() { return font; }
    HDC hdc() { return _hdc; }
    HDC hdcScreen() { return _hdcScreen; }
    int margin() { return _margin; }

    void writeMe();
    Bool paint();
    void endSizing( Bool doAnyway = FALSE );

    // scrollbar callbacks
    long vertScroll( long );
    long horzScroll( long );

    BYTE getClientID() { return clientID; }
    long msgret() { return _msgret; }

    void checkBlink();
    void getDrawInfo();
    void smoothScroll();
    void drawDisabledState( int w, int h );

    void getEndSize( int& w, int& h );
    void calculateSize( int& w, int& h );

    void syncSize(void);

    KScroll* getVertSB(void) { return vert; }
    KScroll* getHorzSB(void) { return horz; }

    void stopTimer();
    void startTimer();

    bool smoothScrolling();

    BOOL renderToEmfFile(int vnum, char* filename);
#ifdef CK_SAVE_TO_IMAGE
    BOOL renderToBmpFile(int vnum, char* filename);
#ifdef CK_HAVE_GDIPLUS
    BOOL renderToPngFile(int vnum, char* filename);
    BOOL renderToGifFile(int vnum, char* filename);
    BOOL saveFontBuffer(int buffer_number, const char* filename,
        const wchar_t *format);
#endif /* CK_HAVE_GDIPLUS */
#endif /* CK_SAVE_TO_IMAGE */

private:    // this section is for performance
    uchar* workTemp;
    size_t workTempSize;

    ushort* textBuffer;
    cell_video_attr_t* attrBuffer;
    vt_char_attr_t* effectBuffer;
    ushort* lineAttr;
    vt_cell_attr_t* cellAttrBuffer;
    _K_WORK_STORE* kws;

    cell_video_attr_t prevAttr;
    vt_char_attr_t prevEffect;
    vt_cell_attr_t prevCellAttr;
    COLORREF textColor;

    int wc;
    int vscrollpos;
    int hscrollpos;

    void ToggleCursor(HDC, LPRECT);

    static void SetWorkStoreRect(RECT* rect, _K_WORK_STORE* kws, KFont *font,
        int terminalCellsWide, int terminalCellsHigh, int margin);
    static void drawRuledLines(
        HDC hdc, HPEN pen, int cells, KFont* font, RECT rect,
        BOOL rlTop, BOOL rlBottom, BOOL rlLeft, BOOL rlRight);
    static BOOL renderToDc(HDC hdc, KFont *font, int vnum, int margin=0, bool blinkOn=TRUE);
    HBITMAP renderToBitmap(int vnum, DWORD **outPixels);
#ifdef CK_HAVE_GDIPLUS
    BOOL renderToImageFile(int vnum, char* filename, const wchar_t* format);
    BOOL saveBitmap(HBITMAP hbmp, const char* filename, const wchar_t *format);
#endif /* CK_HAVE_GDIPLUS */

    static size_t allocateClientPaintBuffers(
        struct _K_CLIENT_PAINT* clientPaint,
        long maxcells,
        uchar** workTempOut);

    bool getSmoothScrollDrawInfo();
    int smoothScrollOffset(int lineHeight) const;

    CRITICAL_SECTION csDraw;

    IKTerm* ikterm;
    BYTE clientID;
    _K_CLIENT_PAINT* clientPaint;
    _K_WORK_STORE* workStore;
    Bool  ws_blinking;
    Bool  cursor_displayed;

    HDC _hdc;
    HDC _hdcScreen;
    HDC _hdcScratch;
    HDC _hdcSScrollBlinkOn;
    HDC _hdcSScrollBlinkOff;
    HBITMAP compatBitmap;
    HBITMAP scratchBitmap;
    HBITMAP scrollBlinkOnBitmap;
    HBITMAP scrollBlinkOffBitmap;
    HRGN hrgnPaint;
    HBRUSH disabledBrush;
    HBRUSH bgBrush;
    HPEN ruledLinePen;
    cell_video_attr_t normalAttr;
    bool screenNormal;
    DWORD savebgcolor;
    int interSpace[MAXNUMCOL];

    Bool _inFocus;
    RECT cursorRect;
    int cursorCount;
    int maxCursorCount;
    int blinkInterval;

#if defined(_MSC_VER) && _MSC_VER < 1300
    UINT timerID;
#else
    UINT_PTR timerID;
#endif
    KFont* font;

    KScroll* vert;
    KScroll* horz;

    int saveTermHeight;
    int saveTermWidth;
    double saveLineSpacing;
    int saveHorzIsV;

    /* So that we can tell when the size has been changed and the vterm, etc,
     * needs updating */
    int previousHeight;
    int previousWidth;

    int maxpHeight;     // max parent window height
    int maxpWidth;      // max parent window width
    int maxHeight;      // max client window height
    int maxWidth;       // max client window width

    int _margin;        // margin around the display area (bottom & right)

    int _xoffset;       // x and y offsets used by scrolling
    int _yoffset;

    Bool processKey;
    long _msgret;

    KSoftFont softFont;

    double smoothScrollProgress;
    long smoothScrollTime;

    // If a smooth scroll event is currently being rendered smoothly.
    // During mark mode, a popup, or if a different vscreen is being
    // displayed then the vscreen is rendered normally but the smooth
    // smooth scroll progress is still calculated.
    bool smoothScrollRendering;
};

#endif
