#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/muimaster.h>
#include <libraries/mui.h>
#include <utility/hooks.h>
#include <sys/dir.h>
#include <gl/outputhandler.h>

#include <mui/readargsgroup_mcc.h>

#define PROGNAME "Mesa Output Preferences"

extern struct WBStartup *_WBenchMsg;

struct Library *MUIMasterBase;
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}

char defaulthandler[100]="dl1";
int localdefault=0;
char *selectedhandler=0;

long __stack=8192;

struct { char *qname; long local,global,params,list;} args={0,0,0,0,0};

Object *app,*win,*li_quant=0,*gr_qprefs=0,*space,
	*txt_info=0,*but_default=0,*but_dellocal,*prefobj=0,
	*gr_buttons,*gr_all,*realprefsobject=0;

long get1(Object *o,ULONG par)
{
ULONG out=0;
GetAttr(par,(void*)o,&out);
return out;
}

Object *myButton(char *label,int id)
{
Object *o=SimpleButton(label);
DoMethod(o,MUIM_Notify,MUIA_Pressed,0,
	MUIV_Notify_Application,2,MUIM_Application_ReturnID,id);
return o;
}

char *handlerprefsenv(char *handler)
{
static char t[100];
sprintf(t,"AmigaMesaRTL/%s.prefs",handler);
return t;
}

char *defaulthandlerenv(void)
{
static char t[]="AmigaMesaRTL/OutputHandler";
return t;
}

int vartypewaslocal=0;
char *mygetvar(char *envname)
{
static char t[1000];
int ok;
vartypewaslocal=0;
if ((ok=GetVar(envname,t,1000,GVF_LOCAL_ONLY))>=0)
	{
	vartypewaslocal=1;
	return t;
	}
if ((ok=GetVar(envname,t,1000,0))>=0) return t;
return 0;
}

long __saveds __asm qlistDispFunc(register __a0 struct Hook *h,
	register __a2 char **out,register __a1 char *name)
{
if (name) {out[1]=name; 
			out[0]=stricmp(name,defaulthandler)?"":(localdefault?"L\033I[6:30]":"\033I[6:30]");}
return 0;
}
struct Hook qlistDispHook = { { NULL,NULL },(ULONG(*)())qlistDispFunc,NULL,NULL };

long __saveds __asm setdefaultFunc(register __a0 struct Hook *h,
	register __a2 int dummy1,register __a1 int dummy2)
{
if (selectedhandler) 
	{
	strcpy(defaulthandler,selectedhandler);
	if (li_quant) DoMethod(li_quant,MUIM_List_Redraw,MUIV_List_Redraw_All);
	}
}
struct Hook setdefaultHook = { { NULL,NULL },(ULONG(*)())setdefaultFunc,NULL,NULL };

void showparams(char* name)
{
char t[100];
struct Library *outputhandlerBase;
if (!name) name="";
realprefsobject=0;
if (gr_qprefs)
	{
	DoMethod(gr_qprefs,MUIM_Group_InitChange);
	if (prefobj) 
		{
		DoMethod(gr_qprefs,OM_REMMEMBER,prefobj);
		MUI_DisposeObject(prefobj);
		}
	}
prefobj=0;
sprintf(t,"outputhandlers/%s",name);
if (outputhandlerBase=OpenLibrary(t,2))
	{
	char *params=mygetvar(handlerprefsenv(name));
	selectedhandler=name;
	if (gr_qprefs)
		{
		SetAttrs(txt_info,MUIA_Text_Contents,outputhandlerBase->lib_IdString,0);
		if (GetOutputHandlerAttr(OH_ParameterQuery,&name))
			{
			prefobj=ScrollgroupObject,GroupFrameT(vartypewaslocal?"Local Parameters":"Parameters"),
				MUIA_Weight,1000,
				MUIA_Scrollgroup_FreeHoriz,0,
				MUIA_Scrollgroup_Contents,VirtgroupObject,
				Child,realprefsobject=ReadargsgroupObject,
					MUIA_Readargsgroup_Key,name,
					MUIA_Readargsgroup_Args,params,
					End,
					End,
				End;
			DoMethod(realprefsobject,OM_ADDMEMBER,HVSpace);		
			}
		else	
			{
			prefobj=TextObject,
				MUIA_Text_Contents,"\033cThis handler\ndoesn't support\nParameterQuery",
				MUIA_Text_SetMin,0,
				End;
			}
		SetAttrs(but_default,MUIA_Disabled,0,0);
		}
	CloseLibrary(outputhandlerBase);
	}
else 
	{
	if (gr_qprefs)
		{
		SetAttrs(txt_info,MUIA_Text_Contents,"Not a valid handler",0);
		SetAttrs(but_default,MUIA_Disabled,1,0);
		}
	selectedhandler=0;
	}
if (gr_qprefs)
	{
	if (prefobj) 
		{
		DoMethod(gr_qprefs,OM_ADDMEMBER,prefobj);		
		DoMethod(gr_qprefs,MUIM_Group_Sort,prefobj,space,0);
		}
	DoMethod(gr_qprefs,MUIM_Group_ExitChange);
	}
}

__saveds ULONG __asm selectquantfun(register __a0 struct Hook *h, register __a2 Object *obj,register __a1 long *par)
{
char *entry;
DoMethod(li_quant,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&entry);
showparams(entry);
}

struct Hook selectquanthook
 = { {0,0},(ULONG(*)())selectquantfun, NULL, NULL };

void readhandlerlist()
{
DIR *dfd;
struct dirent *dptr;

if (dfd=opendir("LIBS:outputhandlers"))
	{
	while (dptr=readdir(dfd))
		DoMethod(li_quant,MUIM_List_InsertSingle,dptr->d_name,MUIV_List_Insert_Sorted);
	closedir(dfd);
	}
}

void selecthandler(char *name)
{
char *entry;
int i;
if (li_quant)
	{
	for (i=0;;i++)
		{
		DoMethod(li_quant,MUIM_List_GetEntry,i,&entry);
			if (!entry) { i=0; break;}
		if (!stricmp(entry,name)) break;
		}
	SetAttrs(li_quant,MUIA_List_Active,i,0);
	}
else showparams(name);
}

void restart(void)
{
char *defqname=mygetvar(defaulthandlerenv());
if (defqname) strcpy(defaulthandler,defqname);
localdefault=vartypewaslocal;
selecthandler(args.qname?args.qname:defaulthandler);
if (li_quant) DoMethod(li_quant,MUIM_List_Redraw,MUIV_List_Redraw_All);
}


Object *createwin(void)
{
Object *w;
w=WindowObject,
	MUIA_Window_Title, PROGNAME,
	MUIA_Window_ID   , 'WIN1',
	WindowContents,VGroup,
		Child,gr_all=HGroup,End,
		Child,gr_buttons=HGroup,End,
		End,
	End;

if (!args.params)
	{
	DoMethod(gr_all,OM_ADDMEMBER,ListviewObject,
		MUIA_Weight,40,
		MUIA_Listview_List,
			li_quant=ListObject,InputListFrame,
			MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
			MUIA_List_DestructHook,MUIV_List_DestructHook_String,
			MUIA_List_DisplayHook,&qlistDispHook,
			MUIA_List_Format,",",
			End,
		End);
	}
if (!args.list)
	{
	DoMethod(gr_all,OM_ADDMEMBER,VGroup,
				Child,txt_info=TextObject,TextFrame,
					MUIA_Text_SetMin,0,
					MUIA_Background,MUII_TextBack,
					MUIA_Weight,300,
					End,
				Child,HGroup,
					Child,but_default=SimpleButton("Mark as default"),
					Child,HVSpace,
					Child,but_dellocal=myButton("Delete local",100),
					End,
				Child,gr_qprefs=VGroup,
					Child,space=HVSpace,
					End,
				End);
	}

if (!args.local) 
	{
	DoMethod(gr_buttons,OM_ADDMEMBER,myButton("Save",10));
	DoMethod(gr_buttons,OM_ADDMEMBER,HVSpace);
	DoMethod(gr_buttons,OM_ADDMEMBER,myButton("Use",20));
	}
if (!args.global) 
	DoMethod(gr_buttons,OM_ADDMEMBER,myButton("Use local",30));
DoMethod(gr_buttons,OM_ADDMEMBER,HVSpace);
DoMethod(gr_buttons,OM_ADDMEMBER,myButton("Cancel",MUIV_Application_ReturnID_Quit));

if (li_quant)
	{
	readhandlerlist();
	DoMethod(li_quant,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,
		w,2,MUIM_CallHook,&selectquanthook);
	if (!but_default)
		DoMethod(li_quant,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,
			w,2,MUIM_CallHook,&setdefaultHook);
	SetAttrs(li_quant,MUIA_List_Active,0,0);
	}

if (but_default)
	{
	DoMethod(but_default,MUIM_Notify,MUIA_Pressed,0,
		w,2,MUIM_CallHook,&setdefaultHook);
	}

restart();
return w;
}

void deletelocal(void)
{
DeleteVar(defaulthandlerenv(),GVF_LOCAL_ONLY);
if (selectedhandler)
	DeleteVar(handlerprefsenv(selectedhandler),GVF_LOCAL_ONLY);
}

void assertdir(char *name)
{
BPTR lock;
struct FileInfoBlock fib;
if (lock=Lock(name,ACCESS_READ))
	{
	if (Examine(lock,&fib))
		{
		UnLock(lock);
		if (fib.fib_DirEntryType>0) return;
		}
	else UnLock(lock);
	DeleteFile(name);
	}
UnLock(CreateDir(name));
}

////////////////////      MAIN      ///////////////////////

int main(void)
{
ULONG sigs = 0;
long id;
struct RDArgs *rda;
if (_WBenchMsg) args.global=1;
else
 {
 if (!(rda = ReadArgs("HANDLER,LOCAL/S,GLOBAL/S,PARAMS/S,LIST/S",(LONG *)&args,NULL)))
	{
	PrintFault(IoErr(),NULL);
	return 10;
	}
 }
//if (args.qname) showparams(args.qname);

if (args.local&&args.global) {puts("LOCAL & GLOBAL?!\n"); args.local=args.global=0;}
if (args.params&&args.list) {puts("PARAMS & LIST?!\n"); args.list=args.params=0;}

assertdir("ENV:AmigaMesaRTL");
assertdir("ENVARC:AmigaMesaRTL");

MUIMasterBase=OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN);
if (MUIMasterBase) 
{
app = ApplicationObject,
		MUIA_Application_Title      , PROGNAME,
		MUIA_Application_Version    , "$VER: " PROGNAME " 1.01 (13.09.98)",
		MUIA_Application_Copyright  , "©1998, Szymon Ulatowski",
		MUIA_Application_Author     , "Szymon Ulatowski",
		MUIA_Application_Description, "Adjust Ouput Settings for MesaRTL",
		MUIA_Application_Base       , "MESAOUTPUTPREFS",
	End;

if (app&&(win=createwin()))
	{
		DoMethod(app,OM_ADDMEMBER,win);

		DoMethod(win,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
			app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

		SetAttrs(win,MUIA_Window_Open,TRUE,0);	

		while (1)
			{
			switch(id=DoMethod(app,MUIM_Application_NewInput,&sigs))
				{
				case MUIV_Application_ReturnID_Quit: goto quit;
				case 100: // delete local
					deletelocal();
					restart();
					break;
				case 10: //save
				case 20: //use
				case 30: //use l
					{
					long type;
					if (id==30) //local
						type=GVF_LOCAL_ONLY;
					else
						{
						type=GVF_GLOBAL_ONLY;
						if (id==10) type|=GVF_SAVE_VAR;
						deletelocal();
						}
					SetVar(defaulthandlerenv(),defaulthandler,strlen(defaulthandler),type);
					if (realprefsobject)
						{
						char *args=get1(realprefsobject,MUIA_Readargsgroup_Args);
						SetVar(handlerprefsenv(selectedhandler),args,strlen(args),type);
						}
					goto quit;
					}
					break;
				}
			if (sigs)
				{
				sigs = Wait(sigs | SIGBREAKF_CTRL_C);
				if (sigs & SIGBREAKF_CTRL_C) break;
				}
			}
			quit:

		MUI_DisposeObject(app);
	}
else puts("MUI can't create application!\n");
CloseLibrary(MUIMasterBase);
}
else puts("Can't open muimaster.library!");
FreeArgs(rda);
return 0;
}
