#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <intuition/intuitionbase.h>
#include <intuition/classusr.h>
#include <intuition/gadgetclass.h>
#include <intuition/cghooks.h>
#include <intuition/icclass.h>
#include <intuition/classes.h>
#include <intuition/sghooks.h>
#include <intuition/screens.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/datatypes.h>
#include <datatypes/pictureclass.h>
#include <libraries/SysInfo.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <graphics/gfxmacros.h>
#include <utility/tagitem.h>
#include <utility/hooks.h>
#include <string.h>
#include <clib/macros.h>
#include "gaugeclass.h"
#include "tinymeter.h"

extern struct Library *RetinaBase;

/* the only two globals */

extern ULONG    maximum,
		idle;

drawBackground(struct tm_sys_set *set,struct tm_data *data)
{
    struct RastPort *rp=data->win->RPort;
    UWORD  x,y;

    x=data->win->Width-1;
    y=data->win->Height-1;

    if(data->bg_bm)
    {
	BltBitMapRastPort(data->bg_bm,0,0,rp,0,0,x+1,y+1,0xc0);
    }
    else
    {
	SetAPen(rp,data->bg_color);
	RectFill(rp,0,0,x,y);
    }

    SetAPen(rp,data->bright_color);
    switch (set->bd_type)
    {
	case    bd_simple:
		RectFill(rp,0,0,x,0);
		RectFill(rp,0,0,0,y);
		RectFill(rp,x,0,x,y);
		RectFill(rp,0,y,x,y);
		break;
	case    bd_standard:
		RectFill(rp,0,0,x,0);
		RectFill(rp,0,0,0,y);
		SetAPen(rp,data->dark_color);
		RectFill(rp,x,1,x,y);
		RectFill(rp,1,y,x,y);
		break;
	case    bd_double:
		SetAPen(rp,data->dark_color);
		RectFill(rp,0,0,x,0);
		RectFill(rp,0,0,0,y);
		RectFill(rp,1,y-1,x-1,y-1);
		RectFill(rp,x-1,2,x-1,y-1);
		SetAPen(rp,data->bright_color);
		RectFill(rp,x,1,x,y);
		RectFill(rp,1,y,x,y);
		RectFill(rp,1,1,x-1,1);
		RectFill(rp,1,1,1,y-1);
		break;
    }
}

allocGadgets(struct tm_sys_set *set, struct tm_data *data, Class *gclass)
{
    struct tm_gau_set *many;
    ULONG  i,max,cur,y_pos,j,tmp,voltype;
    
    for(i=0,many=data->list;i<data->num_of_gaug;i++)
    {
	voltype=0;
	switch (many->type)
	{
	    case    typ_all:
		    max=AvailMem(MEMF_TOTAL);
		    cur=AvailMem(0L);
		    break;
	    case    typ_chip:
		    max=AvailMem(MEMF_CHIP|MEMF_TOTAL);
		    cur=AvailMem(MEMF_CHIP);
		    break;
	    case    typ_fast:
		    max=AvailMem(MEMF_FAST|MEMF_TOTAL);
		    cur=AvailMem(MEMF_FAST);
		    break;
	    case    typ_largest_total:
		    max=AvailMem(MEMF_TOTAL);
		    cur=AvailMem(MEMF_LARGEST);
		    break;
	    case    typ_largest_chip:
		    max=AvailMem(MEMF_TOTAL|MEMF_CHIP);
		    cur=AvailMem(MEMF_LARGEST|MEMF_CHIP);
		    break;
	    case    typ_largest_fast:
		    max=AvailMem(MEMF_TOTAL|MEMF_FAST);
		    cur=AvailMem(MEMF_LARGEST|MEMF_FAST);
		    break;
	    case    typ_largest_retina:
		    if(RetinaBase)
		    {
			max=Retina_AvailMem(MEMF_TOTAL);
			cur=Retina_AvailMem(MEMF_LARGEST);
		    }
		    else
		    {
			max=0L;
			cur=GAU_err_notavail;
		    }
		    break;
	    case    typ_volume:
		    getVolsize(data,&many->expansion[0]);
		    max=data->volmax;
		    cur=data->volcur;
		    voltype=data->voltype;
		    break;
	    case    typ_idle:
		    switch (data->executive)
		    {
			case    idle_none:
				max=0L;
				cur=GAU_err_notavail;
				break;
			case    idle_executive:
				GetCpuUsage(data->si,&data->cpu);
				max=(data->cpu.used_cputime_lastsec_hz)<<8;
				cur=(data->cpu.used_cputime_lastsec_hz-data->cpu.used_cputime_lastsec)<<8;
				break;
			case    idle_own:
				max=maximum;
				cur=idle;
				break;
		    }
		    break;
	    case    typ_retina:
		    if(RetinaBase)
		    {
			max=Retina_AvailMem(MEMF_TOTAL);
			cur=Retina_AvailMem(0L);
		    }
		    else
		    {
			max=0L;
			cur=GAU_err_notavail;
		    }
		    break;
	    case    typ_clock_:
		    many->gauge_type=typ_clock;
		    break;
	    case    typ_image:
		    break;
	    case    typ_none:
		    data->gdg[i]=0L;
		    goto typ_none_1;
		    break;
	}

	tmp=i/set->colums;
	if(set->lay_falling)
	{
	    y_pos=set->win_border_y+(tmp*set->win_space_y);
	    for(j=(i-(tmp*set->colums));j<i;j+=set->colums) y_pos+=data->gauge_y_size_falling[j];
	}
	else
	{
	    y_pos= set->win_border_y+(tmp*set->win_space_y)+((data->gauge_y_size[tmp]-data->gauge_y_size_falling[i])>>1);
	    for(j=0;j<tmp;j++) y_pos+=data->gauge_y_size[j];
	}
	data->gdg[i]=(struct Gadget *)NewObject(gclass, NULL,
			GA_ID,          i,
			GA_Top,         y_pos,
			GA_Left,        set->win_border_x+((i)%set->colums)*data->gauge_x_size+((i)%set->colums)*set->win_space_x,
			GA_Width,       data->gauge_x_size,
			GA_Height,      data->gauge_y_size_falling[i],
			GAU_Type,       many->gauge_type,
			GAU_Current,    cur,
			GAU_Max,        max,
			GAU_Base,       cur,
			GAU_VolType,    voltype,
			GAU_Label,      many->label,
			GAU_TextFormat, many->format,
			GAU_TextFont,   data->Font[i],
			GAU_LabelPos,   data->labelpos,
			GAU_FmtIndent,  many->indent,

			GAU_3D,         many->sty_3d,
			GAU_Border,     many->sty_border,
			GAU_Background, many->sty_bg,
			GAU_ShadowLabel,many->sty_shadow,
			GAU_NoGauge,    many->sty_nogauge,
			GAU_NoFormat,   many->sty_noformat,
			GAU_NoBase,     many->sty_nobase,

			GAU_ColLabel,   &many->Colors[col_label],
			GAU_ColFormat,  &many->Colors[col_format],
			GAU_ColBase,    &many->Colors[col_base],
			GAU_ColCurrent, &many->Colors[col_current],
			GAU_ColNegative,&many->Colors[col_negative],
			GAU_ColBrightEdg,&many->Colors[col_bright],
			GAU_ColDarkEdg, &many->Colors[col_dark],
			GAU_ColBackground,&many->Colors[col_bg],

			TAG_DONE);
	if(!data->gdg[i]) show("Gadget creation failed!");
	else
	{
	    SetGadgetAttrs(data->gdg[i],data->win,NULL,TAG_DONE);
	    RefreshGList  (data->gdg[i],data->win,NULL,1);
	}
	typ_none_1:
	many=many->next;
    }
}

removeGadgets(struct tm_sys_set *set, struct tm_data *data)
{
    int i;

    for(i=0;i<data->num_of_gaug;i++)
	if(data->gdg[i])
	{
	    DisposeObject(data->gdg[i]);
	    data->gdg[i]=0L;
	}
}
