#include <exec/ports.h>
#include <exec/memory.h>
#include <exec/types.h>
#include <clib/macros.h>
#include <devices/timer.h>
#include <intuition/intuition.h>
#include <graphics/text.h>
#include <datatypes/pictureclass.h>
#include <dos/datetime.h>
#include <stdio.h>
#include <exec/io.h>
#include <devices/serial.h>


#define BSIZY   (dftm.BorderY)
#define BSIZX   (dftm.BorderX)
#define BSPC    (dftm.SpaceY)
#define YPOS(line)  ((ULONG)((yypos[line])+1+BSIZY))

#include "structs.h"

extern struct Library          *RetinaBase;
extern struct Library          *DataTypesBase;
extern struct tm_settings       dftm;
extern struct Window           *my_window;
extern struct Screen           *my_pub_screen;
extern struct TextFont         *my_text_font,
                               *my_clock_font_1,
                               *my_clock_font_2;
extern struct RastPort         *my_rastport,
                                my_rp,
                                my_rp_2;
extern ULONG                    gauge_x_pos,
                                gauge_y_pos_2,
                                gauge_x_size,
                                gauge_y_size,
                                info_x_size,
                                texty,
                                textdelta,
                                space,
                                space_x,
                                space_s;
extern ULONG                    bas_c_ram,
                                bas_f_ram,
                                act_c_ram,
                                act_f_ram,
                                all_c_ram,
                                all_f_ram,
                                all_r_ram,
                                bas_r_ram,
                                act_r_ram,
                                all_o_ram[32],
                                bas_o_ram[32],
                                act_o_ram[32],
                                bas_idle;
extern UWORD                    yypos[32];
extern UWORD                    xxpos[32];
extern struct BitMap           *my_bitmap;
extern struct BitMapHeader     *my_header;
extern char                    *LoadedVolList[64],
                               *LoadedVolList_1[64];

extern unsigned long idle,maximum;

display_info(char *format, UBYTE line, UBYTE indent)
{
    char    *printstr;
    WORD    where,spalte;

    spalte=line%dftm.colums;
    ClipBlit(&my_rp_2,(gauge_x_pos+gauge_x_size+BSIZX)*(line%dftm.colums)+BSIZX+1,(yypos[line/dftm.colums])+BSIZY+1,&my_rp,0,textdelta,info_x_size-1,gauge_y_size,0xc0);
    printstr=(char *)formatinfotext(format);
    SetAPen (&my_rp,dftm.back_col);
    SaveRectFill(&my_rp,0,textdelta,my_window->Width-(BSIZX<<1),gauge_y_size+textdelta);
    SetAPen (&my_rp,dftm.lowl_col);
    switch(indent)
    {
        case    0:
                where=(info_x_size>>1)-(TextLength(&my_rp,printstr,my_strlen(printstr))>>1);
                break;
        case    1:
                where=BSIZX+4L;
                break;
        case    2:
                where=(info_x_size-TextLength(&my_rp,printstr,my_strlen(printstr)));
                break;
    }
    Move(&my_rp,where,texty+textdelta);
    if(TextLength(&my_rp,printstr,my_strlen(printstr))<info_x_size) Text(&my_rp,printstr,my_strlen(printstr));
    ClipBlit(&my_rp,0,textdelta,my_rastport,(gauge_x_pos+gauge_x_size+BSIZX)*(line%dftm.colums)+BSIZX+1,(yypos[line/dftm.colums])+BSIZY+1,info_x_size-1,gauge_y_size,0xc0);
}

display_a_gauge(LONG siz_1, LONG siz_2)
{
    siz_2--;
    siz_1--;
    if(siz_2>0)SaveRectFill(&my_rp,0,textdelta,siz_2,gauge_y_size+1+textdelta);
    if(!dftm.NoBaseMem)
    {
        SetAPen(&my_rp,dftm.base_mem_col);
        if(siz_1>0)SaveRectFill(&my_rp,0,textdelta,siz_1,gauge_y_size+1+textdelta);
    }
    SetAPen(&my_rp,dftm.back_col);
    SaveRectFill(&my_rp,siz_2,textdelta,gauge_x_size-(siz_2+1),gauge_y_size+1+textdelta);
    if(dftm._3DGauge)
    {
        if(!dftm.NoBaseMem)
        {
            if(siz_1>0)draw_a_border(0,textdelta,siz_1,gauge_y_size-1+textdelta,2,1,&my_rp);
            if(((siz_1-siz_2)>1) || ((siz_2-siz_1)>1))draw_a_border(siz_1+1,textdelta,siz_2,gauge_y_size-1+textdelta,2,1,&my_rp);
        }
        else if(siz_2>0)draw_a_border(0,textdelta,siz_2,gauge_y_size-1+textdelta,2,1,&my_rp);
    }
}

displayline(LONG siz, LONG bas, LONG all, UBYTE line, char *format, UBYTE indent)
{
    LONG   siz_1,siz_2,siz_3,spalte;
    spalte=line%dftm.colums;
    ClipBlit(&my_rp_2,xxpos[spalte],yypos[line/dftm.colums]+BSIZY+1,&my_rp,0,textdelta,gauge_x_size-1,gauge_y_size,0xc0);
    if(all>0)
    {
        siz_1=p2s(bas,all,gauge_x_size); siz_2=p2s(siz,all,gauge_x_size);
        if(((siz) < (bas)) || (dftm.NoBaseMem )) SetAPen(&my_rp,dftm.add_mem_col);
        else
        {
            siz_3=siz_1; siz_1=siz_2; siz_2=siz_3;
            SetAPen(&my_rp,dftm.miss_mem_col);
        }
        if(!dftm.NoGauges)
        {
            if(!dftm.NoBaseMem) display_a_gauge(siz_1,siz_2);
            else
            {
                SetAPen(&my_rp,dftm.add_mem_col);
                display_a_gauge(0,siz_2);
            }
        }
        if(dftm.DisplayNums)
        {
            WORD where;
            char *printstr;

            printstr=(char *)formattext(siz,bas,all,format);

            switch(indent)
            {
                case    0:
                        where=(gauge_x_size>>1)-(TextLength(&my_rp,printstr,my_strlen(printstr))>>1);
                        break;
                case    1:
                        where=4L;
                        break;
                case    2:
                        where=gauge_x_size-TextLength(&my_rp,printstr,my_strlen(printstr))-4L;
                        break;
            }

            SetAPen(&my_rp,dftm.lowl_col); Move(&my_rp,where,texty+textdelta);
            if(TextLength(&my_rp,printstr,my_strlen(printstr))<gauge_x_size)
            {
                Move(&my_rp,where,texty+textdelta);
                Text(&my_rp,printstr,my_strlen(printstr));
            }
        }
    }
    ClipBlit(&my_rp,0,textdelta,my_rastport,xxpos[spalte],yypos[line/dftm.colums]+BSIZY+1,gauge_x_size-1,gauge_y_size,0xc0);
}

/*
#define MAX_SERS 8

extern struct IOExtSer *SerialIO[MAX_SERS];
extern BOOL   device_present[MAX_SERS];

displaycarrier(UBYTE line)
{
    ULONG   spalte;
    int     k;
    for(k=0;k<MAX_SERS;k++)
    if(device_present[k])
    {
        spalte=line%dftm.colums;
        ClipBlit(&my_rp_2,xxpos[spalte],yypos[line/dftm.colums]+BSIZY,&my_rp,0,textdelta,gauge_x_size,gauge_y_size+2,0xc0);
        SerialIO[k]->IOSer.io_Command  = SDCMD_QUERY;
        if (!DoIO((struct IORequest *)SerialIO[k]))
        {            
            if ((SerialIO[k]->io_Status&32))
            {
                draw_a_border(gauge_x_size/3,textdelta,(gauge_x_size/3)<<1,textdelta+gauge_y_size+1,1,2,&my_rp);
            }
            else
            {
                draw_a_border(gauge_x_size/3,textdelta,(gauge_x_size/3)<<1,textdelta+gauge_y_size+1,2,1,&my_rp);
                SetAPen(&my_rp,dftm.miss_mem_col);
                RectFill(&my_rp,gauge_x_size/3+1,textdelta+1,((gauge_x_size/3)<<1),textdelta+gauge_y_size);
            }
        }
        ClipBlit(&my_rp,0,textdelta,my_rastport,xxpos[spalte],yypos[line/dftm.colums]+BSIZY,gauge_x_size,gauge_y_size+2,0xc0);
    }
}
*/

get_avail_ram_and_display(ULONG new_bas, UBYTE numofvols)
{
    UBYTE   actline=0;
    if((act_c_ram!=AvailMem(MEMF_CHIP))||(act_f_ram!=AvailMem(MEMF_FAST))||(new_bas!=0))
    {
        act_c_ram=AvailMem(MEMF_CHIP);
        act_f_ram=AvailMem(MEMF_FAST);

        if(RetinaBase) act_r_ram=Retina_AvailMem(0L);
        else act_r_ram=0L;

        if((numofvols>0)&(new_bas>0))getvolsizes(0);

        if(new_bas==1)
        {
            bas_c_ram=act_c_ram; bas_f_ram=act_f_ram;bas_r_ram=act_r_ram;
            getvolsizes(1);
        }
        SetDrMd(&my_rp,JAM1);
        SetFont(&my_rp,my_text_font);

        if(dftm.DisplayAll)     displayline(act_c_ram+act_f_ram,bas_c_ram+bas_f_ram,all_c_ram+all_f_ram,actline++,&dftm.TextFormat[0],dftm.MemIndent);
        if(dftm.DisplayChip)    displayline(act_c_ram,bas_c_ram,all_c_ram,actline++,&dftm.TextFormat[0],dftm.MemIndent);
        if(dftm.DisplayFast)    displayline(act_f_ram,bas_f_ram,all_f_ram,actline++,&dftm.TextFormat[0],dftm.MemIndent);
        if(dftm.DisplayRetina)  displayline(act_r_ram,bas_r_ram,all_r_ram,actline++,&dftm.TextFormat[0],dftm.MemIndent);
        if((numofvols>0)&(new_bas>1))
        {
            int k;
            for(k=0;k<numofvols;k++) displayline(act_o_ram[k],bas_o_ram[k],all_o_ram[k],actline++,&dftm.VolumeTextFormat[0],dftm.VolIndent);
        }
        else actline+=numofvols;

        if(dftm.DisplayInfo_1) display_info(dftm.InfoTextFormat_1,actline++,dftm.InfIndent);
        if(dftm.DisplayInfo_2) display_info(dftm.InfoTextFormat_2,actline++,dftm.InfIndent);
/*        if(dftm.DisplayCarrier) displaycarrier(actline++);*/
    }
    else
    {
        SetDrMd(&my_rp,JAM1);
        SetFont(&my_rp,my_text_font);

        if(dftm.DisplayAll)     actline++;
        if(dftm.DisplayChip)    actline++;
        if(dftm.DisplayFast)    actline++;
        if(dftm.DisplayRetina)  actline++;
        actline+=numofvols;
        if(dftm.DisplayInfo_1)  actline++;
        if(dftm.DisplayInfo_2)  actline++;
    }
    if(new_bas==1)bas_idle=0; if(bas_idle<idle)bas_idle=idle;if(dftm.DisplayIdle) displayline(idle,bas_idle,maximum,actline++,&dftm.IdleFormat[0],dftm.IdleIndent);
}

make_add(UBYTE line)
{
    draw_a_border( (gauge_x_pos+gauge_x_size+BSIZX)*(line%dftm.colums)+BSIZX, yypos[line/dftm.colums]+BSIZY, (gauge_x_pos+gauge_x_size+BSIZX)*(line%dftm.colums)+BSIZX+info_x_size, yypos[line/dftm.colums]+1+BSIZY+gauge_y_size , 1 , 2 , my_rastport );
}

dummy_proc(UBYTE actline, char *text)
{
    WORD spalte;
    WORD x_pos;
    spalte=actline%dftm.colums;
    x_pos=((BSIZX+gauge_x_pos+gauge_x_size)*spalte)+gauge_x_pos;
    if(dftm.GaugesBorder)draw_a_border(x_pos,YPOS(actline/dftm.colums)-1,x_pos+gauge_x_size,YPOS(actline/dftm.colums)+gauge_y_size,1,2,my_rastport);
    if(dftm.ShadowText)
    {
        SetAPen(my_rastport,1);
        Move(my_rastport,((gauge_x_pos+gauge_x_size+BSIZX)*spalte)+BSIZX,YPOS(actline/dftm.colums)+texty+1);
        Text(my_rastport,text,my_strlen(text));
        SetAPen(my_rastport,2);
        Move(my_rastport,((gauge_x_pos+gauge_x_size+BSIZX)*spalte)+BSIZX-1,YPOS(actline/dftm.colums)+texty);
        Text(my_rastport,text,my_strlen(text));
    }
    else
    {
        SetAPen(my_rastport,dftm.text_col);
        Move(my_rastport,((gauge_x_pos+gauge_x_size+BSIZX)*spalte)+BSIZX-1,YPOS(actline/dftm.colums)+texty);
        Text(my_rastport,text,my_strlen(text));
    }

}

draw_borders_and_background()
{
    UBYTE   c_1=2,c_2=1;

    ClipBlit(&my_rp_2,0,0,my_rastport,0,0,my_window->Width,my_window->Height,0xc0);

    if((dftm.back_pic==1)&&(DataTypesBase))
    {
        if(my_bitmap)
        {
            CopyTiledBitMap(my_bitmap,my_header->bmh_Width,my_header->bmh_Height,my_rastport);
            CopyTiledBitMap(my_bitmap,my_header->bmh_Width,my_header->bmh_Height,&my_rp_2);
        }
        else
        {
            SetAPen(my_rastport,dftm.all_back_col);
            SaveRectFill(my_rastport,0,0,my_window->Width,my_window->Height);
            SetAPen(&my_rp_2,dftm.all_back_col);
            SaveRectFill(&my_rp_2,0,0,my_window->Width,my_window->Height);
        }
    }
    else
        if((dftm.back_pic==2))
        {
            WORD oldx,oldy,oldx1,oldy1;
            oldx=my_window->Width;
            oldy=my_window->Height;
            oldx1=my_window->LeftEdge;
            oldy1=my_window->TopEdge;
            WaitBlit();
            RemoveGList(my_window,my_window->FirstGadget,-1);
            CloseWindow(my_window);
            BltBitMapRastPort(my_pub_screen->RastPort.BitMap,oldx1,oldy1,&my_rp_2,0,0,oldx,oldy,0xc0);
            WaitBlit();
            open_new_window(oldx1,oldy1,oldx,oldy);
            get_min_size();
            ClipBlit(&my_rp_2,0,0,my_rastport,0,0,my_window->Width,my_window->Height,0xc0);
            WaitBlit();
        }
        else
        {
            SetAPen(my_rastport,dftm.all_back_col);
            SaveRectFill(my_rastport,0,0,my_window->Width,my_window->Height);
            SetAPen(&my_rp_2,dftm.all_back_col);
            SaveRectFill(&my_rp_2,0,0,my_window->Width,my_window->Height);
        }

    SetAPen(my_rastport,1);
    if(dftm.border_double!=2)
    {
        if(dftm.border_double)
        {
            c_1=1;c_2=2;
            draw_a_border(1,1,my_window->Width-2,my_window->Height-2,2,1,my_rastport);
        }
        draw_a_border(0,0,my_window->Width-1,my_window->Height-1,c_1,c_2,my_rastport);
    }
    c_2=0;
    c_1=0;
    if(dftm.DisplayAll)         dummy_proc(c_2++,&dftm.AllText[0]);
    if(dftm.DisplayChip)        dummy_proc(c_2++,&dftm.ChipText[0]);
    if(dftm.DisplayFast)        dummy_proc(c_2++,&dftm.FastText[0]);
    if(dftm.DisplayRetina)      dummy_proc(c_2++,&dftm.RetinaText[0]);
    while(LoadedVolList[c_1]!=0)dummy_proc(c_2++,LoadedVolList[c_1++]);
    if(dftm.DisplayInfo_1&&dftm.GaugesBorder) make_add(c_2++);
    if(dftm.DisplayInfo_2&&dftm.GaugesBorder) make_add(c_2++);
    if(dftm.DisplayIdle  )      dummy_proc(c_2++,&dftm.IdleText[0]);
}

BOOL on_off;

DisplayCLOCK(struct DateTime *dtt, UBYTE lastline)
{
    char                     extstr[64],len=8;
    ULONG                    where,pitty;
    struct DateStamp        *ptr_ds;

    if(dftm.DisplayDIGITAL|dftm.DisplayDATE)
    {
        if((dftm.ClockFormat & 1)==0)len=5;
        if((dftm.ClockFormat & 2)==2)len+=3;
        SetAPen(&my_rp,dftm.text_col);
        SetDrMd(&my_rp,JAM1);
        pitty=MAX(my_clock_font_1->tf_YSize,my_clock_font_2->tf_YSize);
    }
    switch((dftm.ClockIndent & 15))
    {
        case    0:
                where=((my_window->Width>>1) - (dftm.DisplayDIGITAL ? ((my_clock_font_1->tf_XSize*len)>>1) : 0) - ((dftm.DisplayDATE ? (my_clock_font_2->tf_XSize*9) : 0)>>1) );
                break;
        case    1:
                where=BSIZX;
                break;
        case    2:
                where=my_window->Width-(dftm.DisplayDIGITAL ? (my_clock_font_1->tf_XSize*len):0)-BSIZX - (dftm.DisplayDATE ? (my_clock_font_2->tf_XSize*9) : 0) ;
                break;
    }
    if(dftm.DisplayDIGITAL)
    {
        char text[21];        
        ptr_ds=&dtt->dat_Stamp;
        if((dftm.ClockFormat&2)==0)
        {
            strcpy((char *)&text,on_off ? (char *)"%02ld:%02ld:%02ld" : (char *)"%02ld %02ld %02ld");
            sprintf_exec(&extstr[0], &text ,(ptr_ds->ds_Minute/60),ptr_ds->ds_Minute%60,ptr_ds->ds_Tick/50);
        }
        else
        {
            ULONG dummy_1;
            BOOL  dummy_2=FALSE;
            dummy_1=(ptr_ds->ds_Minute/60);
            if(dummy_1>12) {dummy_1-=12;dummy_2=TRUE;}
            if (len==8)
            {
                strcpy((char *)&text,on_off ? (char *)"%2ld:%02ld %s" : (char *)"%2ld %02ld %s");
                sprintf_exec(&extstr[0], &text,dummy_1,ptr_ds->ds_Minute%60,dummy_2 ? "PM" : "AM" );
            }
            else
            {
                strcpy((char *)&text,on_off ? (char *)"%2ld:%02ld:%02ld %s" : (char *)"%2ld %02ld %02ld %s");
                sprintf_exec(&extstr[0], &text,dummy_1,ptr_ds->ds_Minute%60,ptr_ds->ds_Tick/50,dummy_2 ? "PM" : "AM" );
            }

        }
        SetFont(&my_rp,my_clock_font_1);
        ClipBlit(&my_rp_2,where,( dftm.ClockIndent & 16 ? BSIZY : YPOS(lastline)),&my_rp,0,textdelta,(my_clock_font_1->tf_XSize*len),pitty+1,0xc0);
        if(dftm.ShadowText)
        {
            SetAPen(&my_rp,1);
            Move(&my_rp,1,pitty+textdelta);
            Text(&my_rp,extstr,my_strlen(extstr));
            SetAPen(&my_rp,2);
            Move(&my_rp,0,pitty+textdelta-1);
            Text(&my_rp,extstr,my_strlen(extstr));
        }
        else
        {
            SetAPen(&my_rp,dftm.text_col);
            Move(&my_rp,0,pitty+textdelta-1);
            Text(&my_rp,extstr,my_strlen(extstr));
        }
        ClipBlit(&my_rp,0,textdelta,my_rastport,where, ( dftm.ClockIndent & 16 ? BSIZY : YPOS(lastline)) ,my_clock_font_1->tf_XSize*len,pitty+1,0xc0);
    }
    if(dftm.DisplayDATE)
    {
        dtt->dat_Format=dftm.DateFormat ? FORMAT_USA : FORMAT_CDN;
        dtt->dat_Flags=0;
        dtt->dat_StrDate=&extstr[0];
        dtt->dat_StrDay=0L;
        dtt->dat_StrTime=0L;
        if(DateToStr(dtt))
        {
            SetFont(&my_rp,my_clock_font_2);
            ClipBlit(&my_rp_2,where+(dftm.DisplayDIGITAL ? my_clock_font_1->tf_XSize*len : 0)+my_clock_font_2->tf_XSize,( dftm.ClockIndent & 16 ? BSIZY : YPOS(lastline)),&my_rp,0,textdelta,(my_clock_font_2->tf_XSize*8),pitty+1,0xc0);
            if(dftm.ShadowText)
            {
                SetAPen(&my_rp,1);
                Move(&my_rp,1,pitty+textdelta);
                Text(&my_rp,extstr,my_strlen(extstr));
                SetAPen(&my_rp,2);
                Move(&my_rp,0,pitty+textdelta-1);
                Text(&my_rp,extstr,my_strlen(extstr));
            }
            else
            {
                SetAPen(&my_rp,dftm.text_col);
                Move(&my_rp,1,pitty+textdelta);
                Text(&my_rp,extstr,my_strlen(extstr));
            }
            ClipBlit(&my_rp,0,textdelta,my_rastport,where+(dftm.DisplayDIGITAL ? (my_clock_font_1->tf_XSize*len) : 0)+my_clock_font_2->tf_XSize,( dftm.ClockIndent & 16 ? BSIZY : YPOS(lastline)),my_clock_font_2->tf_XSize*8,pitty+1,0xc0);
        }
    }
}

