/* CC.c */

/* Cachebits zeile 189 ff */

#include "sc:source/cc/cc-INCLUDES.h"

/* Version | Revisionscontrol */

#define	VERSION		1
#define	REVISION	20
#define	DATE		"__Date__"
#define	VERS		"CacheControl 1.20"
#define	VSTRING		"CacheControl 1.20 ("__DATE__")\n\r"
#define	VERSTAG		"\0$VER: CacheControl 1.20 ("__DATE__")"

void GetSysLevel(void);
void OpenLibs(void);
void OpenGUI(void);
void CloseAll(void);
void LoadPrefs(char *name);
void SavePrefs(char *name);

/* Externs */

extern struct ExecBase 		*SysBase;

/* Globals */

UBYTE VersTag[]=VERSTAG;		/* Versionsstring */
struct IntuitionBase	*IntuitionBase=0l;
struct GfxBase	 		*GfxBase=0l;
struct Library 			*UtilityBase=0l,*DiskfontBase=0l;
struct Screen			*scr=0l;
struct Window			*win=0l;
struct Gadget			*GList=0l;
struct TextAttr 		*sysfont=0l;
ULONG oldbits,cachebits,cachemask;
UWORD syslevel;

struct TagItem wintags[]={
	WA_Left,				50,
	WA_Top,					20,
	WA_InnerWidth,			200,
	WA_InnerHeight,			70,
	WA_IDCMP,				IDCMP_CLOSEWINDOW|IDCMP_VANILLAKEY|BUTTONIDCMP,
	WA_Flags,				WFLG_SMART_REFRESH|WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_GIMMEZEROZERO|WFLG_RMBTRAP,
	WA_Title,				(ULONG *)"CacheControl V1.20",
	WA_ScreenTitle,			(ULONG *)"CacheControl V1.20 (C) 1995 by ENSONIC of TRINOMIC",
	WA_CustomScreen,		0l,
	WA_Gadgets,				0l,
	WA_PubScreenName,		0l,
	WA_PubScreenFallBack,	TRUE,
	TAG_DONE
};

UBYTE *DCLabels[]={"DCache Off","DCache On",0l };
UBYTE *DBLabels[]={"DBurst Off","DBurst On",0l };
UBYTE *ICLabels[]={"ICache Off","ICache On",0l };
UBYTE *IBLabels[]={"IBurst Off","IBurst On",0l };
UBYTE *CBLabels[]={"CopyBack Off","CopyBack On",0l };

Prefs_Hdr		prefs_hdr;
Data_ICache		d_i;
Data_DCache		d_d;
Data_CpyBck		d_c;

void GetSysLevel(void)
{
	UWORD level;

	syslevel=0;
	level=SysBase->AttnFlags;
	if(level&(1L<<1)) syslevel=1;
	if(level&(1L<<2)) syslevel=2;
	if(level&(1L<<3)) syslevel=3;
	if(!syslevel) exit(1);
}

void OpenLibs(void)
{
	if(!(IntuitionBase=OpenLibrary("intuition.library",37))) CloseAll();
	if(!(GfxBase=OpenLibrary("graphics.library",37))) CloseAll();
	if(!(UtilityBase=OpenLibrary("utility.library",37))) CloseAll();
}

void OpenGUI(void)
{
	WORD winx,winy,fonty,gwidth,cgwi;
	struct NewGadget ng;
	struct Gadget *g;
	APTR VisualInfo=0l;
	struct RastPort *rp;

	oldbits=CacheControl(0l,0l);
	d_i.cache=d_i.burst=d_d.cache=d_d.burst=d_c.cpybck=0;
	if(oldbits&(1L<< 0)) d_i.cache=1;
	if(oldbits&(1L<< 4)) d_i.burst=1;
	if(oldbits&(1L<< 8)) d_d.cache=1;
	if(oldbits&(1L<<12)) d_d.burst=1;
	if(oldbits&(1L<<31)) d_c.cpybck=1;

	if(!(scr=LockPubScreen(0l))) CloseAll();
	sysfont=scr->Font;
	rp=&scr->RastPort;
	fonty=max(11,(sysfont->ta_YSize+4));
	winy=((syslevel+1)*fonty)+10;
	gwidth=TextLength(rp,CBLabels[0],strlen(CBLabels[0]))+30;
	cgwi=(gwidth<<1)/3-1;
	winx=gwidth+gwidth+10;

	if(!(VisualInfo=GetVisualInfo(scr,TAG_DONE))) CloseAll();

	if(!(g=CreateContext(&GList))) CloseAll();

	ng.ng_LeftEdge		=4;
	ng.ng_TopEdge		=6+syslevel*(fonty+1);
	ng.ng_Width			=cgwi;
	ng.ng_Height		=fonty;
	ng.ng_GadgetText	="Save";
	ng.ng_TextAttr		=sysfont;
	ng.ng_GadgetID		=0;
	ng.ng_Flags			=PLACETEXT_IN;
	ng.ng_VisualInfo	=VisualInfo;
	g=CreateGadget(BUTTON_KIND,g,&ng,TAG_DONE);

	ng.ng_LeftEdge		=5+(cgwi+1);
	ng.ng_GadgetText	="Use";
	ng.ng_GadgetID		=1;
	g=CreateGadget(BUTTON_KIND,g,&ng,TAG_DONE);

	ng.ng_LeftEdge		=7+(cgwi+1)+(cgwi+1);
	ng.ng_GadgetText	="Cancel";
	ng.ng_GadgetID		=2;
	g=CreateGadget(BUTTON_KIND,g,&ng,TAG_DONE);

	if(syslevel>0)
	{
		ng.ng_LeftEdge		=4;
		ng.ng_TopEdge		=2;
		ng.ng_Width			=gwidth;
		ng.ng_GadgetText	="";
		ng.ng_GadgetID		=10;
		ng.ng_Flags			=PLACETEXT_LEFT;
		g=CreateGadget(CYCLE_KIND,g,&ng,GTCY_Labels,&ICLabels,GTCY_Active,d_i.cache,TAG_DONE);

		ng.ng_LeftEdge		=gwidth+6;
		ng.ng_GadgetID		=11;
		g=CreateGadget(CYCLE_KIND,g,&ng,GTCY_Labels,&IBLabels,GTCY_Active,d_i.burst,TAG_DONE);
	}
	if(syslevel>1)
	{
		ng.ng_LeftEdge		=4;
		ng.ng_TopEdge		=2+(fonty+1);
		ng.ng_GadgetID		=12;
		g=CreateGadget(CYCLE_KIND,g,&ng,GTCY_Labels,&DCLabels,GTCY_Active,d_d.cache,TAG_DONE);

		ng.ng_LeftEdge		=gwidth+6;
		ng.ng_GadgetID		=13;
		g=CreateGadget(CYCLE_KIND,g,&ng,GTCY_Labels,&DBLabels,GTCY_Active,d_d.burst,TAG_DONE);
	}
	if(syslevel>2)
	{
		ng.ng_LeftEdge		=4;
		ng.ng_TopEdge		=2+(fonty+1)+(fonty+1);
		ng.ng_GadgetID		=14;
		g=CreateGadget(CYCLE_KIND,g,&ng,GTCY_Labels,&CBLabels,GTCY_Active,d_c.cpybck,TAG_DONE);
	}

	wintags[2].ti_Data=winx;
	wintags[3].ti_Data=winy;
	wintags[8].ti_Data=scr;
	wintags[9].ti_Data=GList;
	if(!(win=OpenWindowTagList(0l,wintags))) CloseAll();

	UnlockPubScreen(0l,scr);
}

void CloseAll(void)
{
	if(win)				CloseWindow(win);
	if(UtilityBase)		CloseLibrary(UtilityBase);
	if(GfxBase)			CloseLibrary(GfxBase);
	if(IntuitionBase)	CloseLibrary(IntuitionBase);
	exit(1);
}

void LoadPrefs(char *name)
{
	FILE *prefs;
	ULONG subtyp,len;

	if(prefs=fopen(name,"rb"))
	{
		if(!fread(&prefs_hdr,8,1,prefs)) { fclose(prefs);return; }
		if(prefs_hdr.id!=PREF_FORM) { fclose(prefs);return; }
		len=prefs_hdr.len;
		if(!fread(&subtyp,4,1,prefs)) { fclose(prefs);return; }
		if(subtyp!=PREF_PREF) { fclose(prefs);return; }

		while(len>0)
		{
			if(!fread(&prefs_hdr,8,1,prefs)) { fclose(prefs);return; }
			len-=8;
			switch(prefs_hdr.id)
			{
				case PREF_ICAC:
					if(!fread(&d_i,sizeof(d_i),1,prefs)) { fclose(prefs);return; }
					break;
				case PREF_DCAC:
					if(!fread(&d_d,sizeof(d_d),1,prefs)) { fclose(prefs);return; }
					break;
				case PREF_CBCK:
					if(!fread(&d_c,sizeof(d_c),1,prefs)) { fclose(prefs);return; }
					break;
				default:
					fseek(prefs,prefs_hdr.len,1);
					break;
			}
			len-=prefs_hdr.len;
			if(prefs_hdr.len&1) { len--;fseek(prefs,1L,1); }
		}
		fclose(prefs);
	}
}

void SavePrefs(char *name)
{
	FILE *prefs;
	ULONG subtyp;

	if(prefs=fopen(name,"wb"))
	{
		prefs_hdr.id=PREF_FORM;
		prefs_hdr.len=34;
		if(!fwrite(&prefs_hdr,8,1,prefs)) { fclose(prefs);return; }
		subtyp=PREF_PREF;
		if(!fwrite(&subtyp,4,1,prefs)) { fclose(prefs);return; }

		prefs_hdr.len=2;
		prefs_hdr.id=PREF_ICAC;
		if(!fwrite(&prefs_hdr,8,1,prefs)) { fclose(prefs);return; }
		if(!fwrite(&d_i,sizeof(d_i),1,prefs)) { fclose(prefs);return; }

		prefs_hdr.id=PREF_DCAC;
		if(!fwrite(&prefs_hdr,8,1,prefs)) { fclose(prefs);return; }
		if(!fwrite(&d_d,sizeof(d_d),1,prefs)) { fclose(prefs);return; }

		prefs_hdr.id=PREF_CBCK;
		if(!fwrite(&prefs_hdr,8,1,prefs)) { fclose(prefs);return; }
		if(!fwrite(&d_c,sizeof(d_c),1,prefs)) { fclose(prefs);return; }

		fclose(prefs);
	}
}

void main(int argc,char *argv[])
{
	struct IntuiMessage *imsg;
	ULONG iclass;
	APTR iadr;
	USHORT icode;
	UBYTE quit=0;
	UBYTE mode=0;

	if(argc==2 && !stricmp(argv[1],"SET")) mode=1;
	GetSysLevel();
	OpenLibs();

	if(mode)
	{
		LoadPrefs("ENV:cc.prefs");
		cachebits=cachemask=0L;

		if(syslevel>0)
		{
			cachemask|=(1L|(1L<<4));
			if(d_i.cache) cachebits|=1L;
			if(d_i.burst) cachebits|=(1L<<4);
		}

		if(syslevel>1)
		{
			cachemask|=((1L<<8)|(1L<<12));
			if(d_d.cache) cachebits|=(1L<<8);
			if(d_d.burst) cachebits|=(1L<<12);
		}

		if(syslevel>2)
		{
			cachemask|=(1L<<31);
			if(d_c.cpybck) cachebits|=(1L<<31);
		}
		CacheControl(cachebits,cachemask);
	}
	else
	{
		OpenGUI();
		while(!quit)
		{
			WaitPort(win->UserPort);
			while(imsg=GT_GetIMsg(win->UserPort))
			{
				iclass	=imsg->Class;
				iadr	=imsg->IAddress;
				icode	=imsg->Code;
				GT_ReplyIMsg(imsg);
				switch(iclass)
				{
					case IDCMP_GADGETUP:
						switch((int)(((struct Gadget *)iadr)->GadgetID))
						{
							case 0:			/* Save */
								SavePrefs("ENVARC:cc.prefs");
								SavePrefs("ENV:cc.prefs");
								quit=1;
								break;
							case 1:			/* Use */
								SavePrefs("ENV:cc.prefs");
								quit=1;
								break;
							case 2:			/* Cancel */
								quit=1;
								break;

							case 10:		/* ICache On/Off */
								if(icode) cachebits=cachemask=1L;
								else { cachebits=0;cachemask=1L; }
								CacheControl(cachebits,cachemask);
								break;
							case 11:		/* IBurst On/Off */
								if(icode) cachebits=cachemask=(1L<<4);
								else { cachebits=0;cachemask=(1L<<4); }
								CacheControl(cachebits,cachemask);
								break;
							case 12:		/* DCache On/Off */
								if(icode) cachebits=cachemask=(1L<<8);
								else { cachebits=0;cachemask=(1L<<8); }
								CacheControl(cachebits,cachemask);
								break;
							case 13:		/* DBurst On/Off */
								if(icode) cachebits=cachemask=(1L<<12);
								else { cachebits=0;cachemask=(1L<<12); }
								CacheControl(cachebits,cachemask);
								break;
							case 14:		/* CopyBack On/Off */
								if(icode) cachebits=cachemask=(1L<<31);
								else { cachebits=0;cachemask=(1L<<31); }
								CacheControl(cachebits,cachemask);
								break;
						}
						break;
					case IDCMP_CLOSEWINDOW:
						quit=1;break;
				}
			}
		}
	}
	CloseAll();
}
