/*
File: LCDVIEW.C

Methods for Class: cpview  (Superclass: win).

Main client window
*/

#include <lcdtest.g>
#include <hwim.g>
#include <gate.g>
#include <hwim.h>
#include <olib.h>
#include <fonts.h>
#include <p_file.h>
#include <lcdview.g>
#include <lcdtest.rsg>

#define FONT_DEF        FONT_ID_MONO_8x8
#define CHARBUFFSIZE    64

GLREF_D PR_GATE     *DatGate;
GLREF_D WSERV_SPEC  *wserv_channel;
GLREF_D PR_LCDVIEW   *DatApp3;   /* Main Client Window   */

LOCAL_C VOID lSetDisplayInfo(LCD_DISP_INFO * pLinfo)
    {
    G_FONT_INFO finfo;

        gFontInfo(pLinfo->textfont,G_STY_MONO,&finfo);
        pLinfo->numwidth = finfo.numeric_width;
        pLinfo->textheight = finfo.height;
        pLinfo->textascent = finfo.ascent;
        pLinfo->lineheight = finfo.height + 2;
        pLinfo->lineascent = finfo.ascent + 2;
        pLinfo->scrlines = wserv_channel->conn.info.pixels.y
                                                        /pLinfo->lineheight;
        pLinfo->scrwidth = wserv_channel->conn.info.pixels.x;
    }

LOCAL_C VOID lSetGCTemp(UWORD fid, UWORD style)
/* Sets font and style    */
    {
    G_GC g_gc;

    g_gc.font = fid;
    g_gc.style = (BYTE)style;
    gSetGC(WS_TEMPORARY_GC,G_GC_MASK_FONT|G_GC_MASK_STYLE,&g_gc);
    }

LOCAL_C VOID lFillCharBuff(PR_LCDVIEW *const self, TEXT *pTxt, INT size)
    {
    INT jj;

    for(jj = 0; jj < size; ++jj, ++pTxt)
        {
        *pTxt = self->lcdview.letter;
        ++self->lcdview.letter;
        if(self->lcdview.letter > 'Z')
            self->lcdview.letter = 'A';
        }
    }

LOCAL_C VOID lDrawPatternHHH(PR_LCDVIEW *const self)
    {
    P_RECT rect0;
    P_RECT rect1;
    TEXT xBuff[CHARBUFFSIZE];
    INT row;
    INT chars;
    UINT width;

    p_bfil(&xBuff[0],sizeof(xBuff),'H');

    /* Set font and style    */
    lSetGCTemp(self->lcdview.dinfo.textfont,G_STY_MONO);
    rect1 = rect0 = *((P_RECT*)&self->lcdview.extent);
    gClrRect(&rect1,G_TRMODE_CLR);
    width = self->lcdview.dinfo.scrwidth;
    chars = gTextCount(self->lcdview.dinfo.textfont,G_STY_MONO,
                                    &xBuff[0],sizeof(xBuff),&width);

    rect0.tl.y = 25;
    ++rect0.tl.x;
    --rect0.br.x;
    for(row = 0; row < 5; ++row)
        {
        rect0.br.y = rect0.tl.y + self->lcdview.dinfo.lineheight;
        gPrintBoxText(&rect0,self->lcdview.dinfo.lineascent,
                        G_TEXT_ALIGN_LEFT,0,&xBuff[0],chars);
        rect0.tl.y += 10;
        }

    gDrawBox(&rect1);
    }

LOCAL_C VOID lDrawPatternOnOff(PR_LCDVIEW *const self)
    {   /* Alternate pixels On/Off  */
    gFillPattern((P_RECT*)&self->lcdview.extent,
                                    WS_BITMAP_GREY,G_TRMODE_REPL);
    }

LOCAL_C VOID lDrawPatternON(PR_LCDVIEW *const self)
    {   /* All pixels ON    */
    gClrRect((P_RECT*)&self->lcdview.extent,G_TRMODE_SET);
    }

LOCAL_C VOID lDrawPatternOFF(PR_LCDVIEW *const self)
    {   /* All pixels OFF    */
    gClrRect((P_RECT*)&self->lcdview.extent,G_TRMODE_CLR);
    }

LOCAL_C VOID lDrawPatternGrey(PR_LCDVIEW *const self)
    {
    INT row;
    P_RECT rect0;
    G_GC g_gc;

    gClrRect((P_RECT*)&self->lcdview.extent,G_TRMODE_CLR);
    g_gc.flags = G_GC_FLAG_GREY_PLANE;
    gSetGC(WS_TEMPORARY_GC,G_GC_MASK_GREY,&g_gc);
    rect0 = *((P_RECT*)&self->lcdview.extent);
    rect0.tl.y = self->lcdview.offset % (self->lcdview.dinfo.lineheight+1);
    for(row = 0; row < self->lcdview.dinfo.scrlines; ++row)
        {
        rect0.br.y = rect0.tl.y + self->lcdview.dinfo.lineheight;
        gClrRect(&rect0,row%2? G_TRMODE_SET: G_TRMODE_CLR);
        rect0.tl.y += self->lcdview.dinfo.lineheight;
        }
    gClrRect(&rect0,G_TRMODE_CLR);
    g_gc.flags = 0;
    gSetGC(WS_TEMPORARY_GC,G_GC_MASK_GREY,&g_gc);
    }

LOCAL_C VOID lDrawPatternChars(PR_LCDVIEW *const self)
    {
    P_RECT rect0;
    TEXT xBuff[CHARBUFFSIZE];
    INT row;
    INT chars;
    UINT width;

    /* Set font and style    */
    lSetGCTemp(self->lcdview.dinfo.textfont,G_STY_MONO);
    p_bcpy(&rect0,&self->lcdview.extent,sizeof(rect0));
    gClrRect(&rect0,G_TRMODE_CLR);
    for(row = 0; row < self->lcdview.dinfo.scrlines; ++row)
        {
        rect0.br.y = rect0.tl.y + self->lcdview.dinfo.lineheight;
        lFillCharBuff(self,&xBuff[0],sizeof(xBuff));
        width = self->lcdview.dinfo.scrwidth;
        chars = gTextCount(self->lcdview.dinfo.textfont,G_STY_MONO,
                                    &xBuff[0],sizeof(xBuff),&width);
        self->lcdview.letter = xBuff[chars];
        gPrintBoxText(&rect0,self->lcdview.dinfo.lineascent,
                        G_TEXT_ALIGN_LEFT,0,&xBuff[0],chars);
        rect0.tl.y += self->lcdview.dinfo.lineheight;
        }
    }

LOCAL_C VOID SetPattern(PR_LCDVIEW *const self, VOID(*func)(PR_LCDVIEW *))
    {
    self->lcdview.funct = (VOID(*)(VOID*))func;
    }

#pragma METHOD_CALL

METHOD VOID lcdview_wn_init(PR_LCDVIEW *const self)
    {
    W_WINDATA wd;

    wd.background = W_WIN_BACK_CLR|W_WIN_BACK_GREY_CLR;
    wd.flags = 0;
    wd.extent.tl.x = wd.extent.tl.y = 0;
    wd.extent.width = wserv_channel->conn.info.pixels.x;
    wd.extent.height = wserv_channel->conn.info.pixels.y;
    self->lcdview.extent = wd.extent;
    p_send5(self,O_WN_CONNECT,NULL_D,W_WIN_ALL_FLAGS|W_WIN_EXTENT|W_WIN_BACKGROUND,&wd);
    wStatusWindow(W_STATUS_WINDOW_OFF);
    wsSetList(W_STATUS_WINDOW_ICON,NULL_D,0);

    self->lcdview.letter = 'A';
    self->lcdview.dinfo.textfont = FONT_DEF;
    lSetDisplayInfo(&self->lcdview.dinfo);
    SetPattern(self,lDrawPatternHHH);
    }

METHOD VOID lcdview_wn_draw(PR_LCDVIEW *const self)
    {
    (*self->lcdview.funct)(self);
    if(self->lcdview.status & LCD_STAT_INVERSE)
            gInvObloid(&self->lcdview.extent);
    }

METHOD INT lcdview_wn_key(PR_LCDVIEW *const self,UINT key,UINT mod)
    {
    switch(key)
        {
        case '0':
            gCreateTempGC0(self->win.id);
            gInvObloid(&self->lcdview.extent);
            self->lcdview.status ^= LCD_STAT_INVERSE;
            gFreeTempGC();
            return WN_KEY_NO_CHANGE;
        case '1':
            SetPattern(self,lDrawPatternHHH);
            break; /* to WN_DODRAW  */
        case '2':
            SetPattern(self,lDrawPatternOnOff);
            break; /* to WN_DODRAW  */
        case '3':
            SetPattern(self,lDrawPatternON);
            break; /* to WN_DODRAW  */
        case '4':
            SetPattern(self,lDrawPatternOFF);
            break; /* to WN_DODRAW  */
        case '5':
            SetPattern(self,lDrawPatternGrey);
            break; /* to WN_DODRAW  */
        case '6':
            SetPattern(self,lDrawPatternChars);
            break; /* to WN_DODRAW  */
        case W_KEY_UP:
            ++self->lcdview.offset;
            break; /* to WN_DODRAW  */
        case W_KEY_DOWN:
            --self->lcdview.offset;
            break; /* to WN_DODRAW  */
        case W_KEY_HOME:
            self->lcdview.offset = 0;
            break; /* to WN_DODRAW  */
        case W_KEY_END:
            self->lcdview.offset = self->lcdview.dinfo.lineheight;
            break; /* to WN_DODRAW  */
        default:
            return WN_KEY_NO_CHANGE;
        }   /* End switch() */
    p_send2(self,O_WN_DODRAW);
    return WN_KEY_NO_CHANGE;
    }
