#include <exec/types.h>
#include <exec/libraries.h>
#include <exec/io.h>
#include <hardware/blit.h>
#include <graphics/gfx.h>
#include <graphics/rastport.h>
#include <graphics/text.h>
#include <libraries/diskfont.h>
#include <libraries/dos.h>
#include <devices/keymap.h>
#include <proto/exec.h>
#include <proto/diskfont.h>

#include "main.h"

struct chardef {
    WORD offset;
    WORD charbitwidth;
    };

struct Library *DiskfontBase,*GfxBase;

struct TextAttr fonts[FONTS] = {
 { (STRPTR)"ascii.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"supplemental.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"graphics.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"british.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"dutch.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"finnish.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"french.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"french_canadian.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"german.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"italian.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"norwegian.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"spanish.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"swedish.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"swiss.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"technical.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT },
 { (STRPTR)"display_controls.font",YSIZE,FS_NORMAL,FPF_DISKFONT|FPF_TALLDOT }
 };

openfonts(register struct console *con)
{
register USHORT cnt;
for (cnt = 0; cnt < FONTS; cnt++) con->font[cnt] = NULL;
if ((GfxBase = OpenLibrary("graphics.library",0)) != NULL) {
    if ((DiskfontBase = OpenLibrary("diskfont.library",0)) != NULL) {
        for (cnt = 0; cnt < FONTS; cnt++) {
            if ((con->font[cnt]=OpenDiskFont(&fonts[cnt])) == NULL) {
                closefonts(con);
                return(-1);
                }
            }
        SetFont(con->rp,con->font[DISPLAY_CONTROLS]);
        return(0);
        }
    CloseLibrary(GfxBase);
    }
return(-1);
}

closefonts(register struct console *con)
{
register USHORT cnt;
for (cnt = 0; cnt < FONTS; cnt++)
    if (con->font[cnt] != NULL) CloseFont(con->font[cnt]);
CloseLibrary(DiskfontBase);
CloseLibrary(GfxBase);
return(0);
}

setlset(register struct console *con,USHORT set)
{
register struct TextFont *sf,*df;
register UBYTE *scp,*dcp,cnt1;
register WORD smod,dmod;
register UBYTE cnt2;
register WORD *opt;

con->lset = set;
if (con->nstat & NATIONAL) cnt2 = con->mset[set];
else cnt2 = con->gset[set];
if (cnt2 == DISPLAY_CONTROLS) {
    con->tstat |= DCONTLO;
    cnt2 = ASCII;
    }
else con->tstat &= (MASK - DCONTLO);
sf = con->font[cnt2];
df = con->font[DISPLAY_CONTROLS];
cnt1 = sf->tf_HiChar - sf->tf_LoChar + 1;
smod = sf->tf_Modulo;
dmod = df->tf_Modulo;
while (cnt1--) {
    scp = (UBYTE *)sf->tf_CharData;
    opt = (WORD *)sf->tf_CharLoc;
    opt += cnt1 * 2;
    scp += *opt >> 3;
    dcp = (UBYTE *)df->tf_CharData;
    opt = (WORD *)df->tf_CharLoc;
    opt += (cnt1 + FIRSTLCHAR) * 2;
    dcp += *opt >> 3;
    cnt2 = YSIZE;
    do {
        *dcp = *scp;
        scp += smod;
        dcp += dmod;
        } while (--cnt2);
    }
return(0);
}

setrset(register struct console *con,USHORT set)
{
register struct TextFont *sf,*df;
register UBYTE *scp,*dcp,cnt1;
register WORD smod,dmod;
register UBYTE cnt2;
register WORD *opt;

con->rset = set;
if (con->nstat & NATIONAL) cnt2 = con->mset[set];
else cnt2 = con->gset[set];
if (cnt2 == DISPLAY_CONTROLS) {
    con->tstat |= DCONTHI;
    cnt2 = SUPPLEMENTAL;
    }
else con->tstat &= (MASK - DCONTHI);
sf = con->font[cnt2];
df = con->font[DISPLAY_CONTROLS];
cnt1 = sf->tf_HiChar - sf->tf_LoChar + 1;
smod = sf->tf_Modulo;
dmod = df->tf_Modulo;
while (cnt1--) {
    scp = (UBYTE *)sf->tf_CharData;
    opt = (WORD *)sf->tf_CharLoc;
    opt += cnt1 * 2;
    scp += *opt >> 3;
    dcp = (UBYTE *)df->tf_CharData;
    opt = (WORD *)df->tf_CharLoc;
    opt += (cnt1 + FIRSTRCHAR) * 2;
    dcp += *opt >> 3;
    cnt2 = YSIZE;
    do {
        *dcp = *scp;
        scp += smod;
        dcp += dmod;
        } while (--cnt2);
    }
return(0);
}

cset(char c)
{
switch (c) {
    case 'B': return(ASCII);
    case '<': return(SUPPLEMENTAL);
    case '0': return(GRAPHICS);
    case 'A': return(BRITISH);
    case '4': return(DUTCH);
    case '5':
    case 'C': return(FINNISH);
    case 'R': return(FRENCH);
    case 'Q': return(FRENCH_CANADIAN);
    case 'K': return(GERMAN);
    case 'Y': return(ITALIAN);
    case '6':
    case 'E': return(NORWEGIAN);
    case 'Z': return(SPANISH);
    case '7':
    case 'H': return(SWEDISH);
    case '=': return(SWISS);
    default: ;
    }
return(0);
}
