/********************/
/* File icon_data.c */
/********************/

/* Function: Configuration Load and Save using ToolTypes... */

#include <ctype.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/execbase.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <libraries/commodities.h>
#include <libraries/gadtools.h>
#include <workbench/startup.h>
#include <workbench/icon.h>
#include <workbench/workbench.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <dos/rdargs.h>

#include <clib/commodities_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/icon_protos.h>
#include <clib/intuition_protos.h>
#include <clib/macros.h>

#include "/includes/tom_gadget.h"
#include "/includes/struct.h"

#include <string.h>
#include <stdlib.h>


char	buffer_effet[20];

#define VOID_INTERRUPT void __interrupt __saveds
#define REGARGS        __regargs
#define VOID_STDARGS   void __stdargs
#define SIZE_VECT	100

UWORD PutChar[2] = {0x16C0,0x4E75};

extern	UBYTE	flg_debug;

/* dirty hack to avoid assembler part :-)

   16C0: move.b d0,(a3)+
   4E75: rts
*/

VOID_STDARGS SPrintF(char *Buffer,char *FormatString,...)

{
 RawDoFmt (FormatString,(APTR)((LONG *)&FormatString+1L),
           (void *)PutChar,Buffer);
}

/*
VOID_STDARGS printf(char *FormatString,...)

{
  char Buffer[256];

  RawDoFmt (FormatString,(APTR)((LONG *)&FormatString+1L),
           (void *)PutChar,Buffer);
    
}
*/

char	buffer_conv[256];

/*

   "icon.library" Stuff

*/

char	*convert_string(char	*p_c)
{
	char	*p_dest=buffer_conv;

	while(*p_c!=0){
		if(*p_c!='_'){
			*p_dest++=toupper(*p_c);
		}
		*p_c++;
	}
	*p_dest=0;
	return(buffer_conv);
}
char REGARGS *YesNo(LONG Flag)
{
	return Flag?"YES":"NO";
}

char REGARGS 
*ToolTypeString(struct DiskObject *DiskObject,char *ID,
                             char *Default)

{
	char *String;
	char	*ret;

	ret=Default;
	if (DiskObject!=NULL){
		if (String=FindToolType(DiskObject->do_ToolTypes,ID)){
			ret=String;
		}
	}
	return	ret;
}

LONG REGARGS
ToolTypeBoolean(struct DiskObject *DiskObject,char *ID,LONG Default)

{
	LONG	ret;
	char	*p_tool;
	ret=Default;
	p_tool=ToolTypeString(DiskObject,ID,"");
	if(p_tool!=NULL){
		if(stricmp(p_tool,YesNo(FALSE))==0){
			ret=FALSE;
		}else{
			ret=TRUE;
		}
	}
	return ret;
}

LONG REGARGS
ToolTypeLong(struct DiskObject *DiskObject,char *ID,LONG Default,
				LONG Min,LONG Max)
{
 char *String;
 LONG ret;

 ret=Default;
 if (DiskObject!=NULL){
	 if (String=FindToolType(DiskObject->do_ToolTypes,ID)){
		LONG Value;
		Value=atol(String);
		if ((Value>=Min)&&(Value<=Max)){
			ret=Value;
		}
	}
  }
  return(ret);
}

/******************************************************* find_next() ****/

/*******************************************/
/* Find the next occurence of a given char */
/* in a given string.			   */
/*******************************************/

char	*find_next(char *pc,char val)
{
	while((*pc!=0)&&(*pc!=val)){
		pc++;
	}
	if(*pc!=0){
		pc++;
	}
	return( pc );
}

/************************************************************ ahtoi() */

/**************************************/
/* Convert an ascII string containing */
/* an hexadecimal value in an integer */
/**************************************/

ULONG	ahtoi(char	*pc)
{
	char	c;
	ULONG	val;
	val=0;
	while(*pc==' ')pc++;
	while(isxdigit(*pc)){
		c=*pc++;
		if(c>='a'){
			c=c-('a'-'9')+1;
		}else if(c>='A'){
			c=c-('A'-'9')+1;
		}
		val=val*16+c-'0';
	}
	return (val);
}

void	get_gadg(struct	tom_gadget	*p_g,struct DiskObject *DiskObject)
{
	char	buffer[SIZE_VECT];
	char	**p_tab,*p_temp;
	int	i,flg_found;
	int	word1,byte1,byte2;
	struct	TextAttr *p_attr;

	convert_string(p_g->GadgetText);
	printd(":%s   ",buffer_conv);
	switch(p_g->type_gadg){
			case BUTTON:
				p_g->value=ToolTypeBoolean(DiskObject,buffer_conv,FALSE);
				break;
			case CHECKBOX:
				p_g->value=ToolTypeBoolean(DiskObject,buffer_conv,p_g->value);
				printd("get_gadg:checkbox:%d\n",p_g->value);
				break;
			case MX:
			case CYCLE:
				(void)strcpy(buffer,ToolTypeString(DiskObject,buffer_conv,"Bof"));
				p_tab=(char **)p_g->p_data;
				i=0;
				flg_found=FALSE;
				while((*p_tab!=NULL)&&(flg_found==FALSE)){
					if(strcmp(*p_tab,buffer)==0){
						printd("Type found,%s=%d\n",*p_tab,i);
						flg_found=TRUE;
					}else{
						p_tab++;
						i++;
					}
				}
				if(flg_found==FALSE){
					i=0;
				}
				printd("mx ou cycle:string:%d\n",i);
				p_g->value=i;
				break;
			case SLIDER:
				p_g->value=ToolTypeLong(DiskObject,buffer_conv,p_g->value,p_g->d1,p_g->d2);
				if(p_g->p_data!=0)(*(int *)p_g->p_data=p_g->value);
				printd("slider:%d\n",p_g->value);
				break;
			case STRING:
			case DATA_STRING:
				(void)strcpy(p_g->p_data,ToolTypeString(DiskObject,buffer_conv,p_g->p_data));
				printd("string:%s\n",p_g->p_data);
				break;
			case	LISTVIEW:

				/* Vu qu'a ce niveau on n'a pas encore la liste */
				/* des effets,on sauve le nom du buffer tempo.	*/

				strcpy(buffer_effet,ToolTypeString(DiskObject,buffer_conv,"Bof"));
				printd("listview:%s\n",buffer_effet);
				break;
			case	OWN_GADGET:
				p_g->value=ToolTypeLong(DiskObject,buffer_conv,0L,-10000,10000);
				break;

			case SCREEN:
				strcpy(buffer_effet,ToolTypeString(DiskObject,buffer_conv,""));
				printd("screen:%s\n",buffer_effet);
				p_temp=buffer_effet;
				p_g->d1=atoi(p_temp);
				p_temp=find_next(p_temp,'x');
				p_g->d2=atoi(p_temp);
				p_temp=find_next(p_temp,'x');
				p_g->d3=atoi(p_temp);
				p_temp=find_next(p_temp,'=');
				p_g->p_data=(char *)ahtoi(p_temp);
				p_temp=find_next(p_temp,'=');
				p_g->value=atoi(p_temp);

				printd ("Resultat:%ld x %ld x %ld ID=%lx OVSCAN=%ld",
					p_g->d1,
					p_g->d2,
					p_g->d3,
					(ULONG)p_g->p_data,
					p_g->value);
				break;
			case FONT:
				strcpy(buffer_effet,ToolTypeString(DiskObject,buffer_conv,"Topaz.font 8 0 0"));
				printd("font:%s\n",buffer_effet);
				p_attr=(struct TextAttr *)p_g->p_data;
				p_temp=find_next(buffer_effet,' ');
				if(*p_temp!=0)*(p_temp-1)=0;
				strcpy(p_attr->ta_Name,buffer_effet);
				sscanf(p_temp,"%d %d %d",
						&word1,&byte1,&byte2);

				p_attr->ta_YSize=word1;
				p_attr->ta_Style=byte1;
				p_attr->ta_Flags=byte2;

				printd ("Resultat:%s  size %ld Style %ld flags:%ld",
					p_attr->ta_Name,word1,byte1,byte2);
				break;
	}
}

void
LoadConfig(char *Name,struct	tom_gadget *p_gadg)

{
	struct DiskObject *DiskObject;
	int	i;

	if (Name){
		DiskObject=GetDiskObject(Name);
		if(DiskObject!=0){
			i=0;
			while(p_gadg[i].type_gadg!=END_LISTE){
				get_gadg(&p_gadg[i],DiskObject);
				i++;
			}
			FreeDiskObject (DiskObject);
		}
	}
}

char	*add_gadg(struct	tom_gadget	*p_g,char	*vect)
{
	UBYTE	**p_tab;
	int	num,i;
	struct	Node	*node;
	struct	TextAttr *p_attr;

	convert_string(p_g->GadgetText);
	printd("add_gadg:%s..",buffer_conv);
	switch(p_g->type_gadg){
			case BUTTON:
				*vect=0;
				break;
			case CHECKBOX:
				SPrintF (vect,"%s=%s",buffer_conv,YesNo(p_g->value));
				printd("Checkbox:%d ",p_g->value);
				break;
			case MX:
			case CYCLE:
				p_tab=(UBYTE **)p_g->p_data;
				SPrintF (vect,"%s=%s",buffer_conv,p_tab[p_g->value]);
				printd("Add gadg,MX ou cycle,resultat:%s ",p_tab[p_g->value]);
				break;
			case	LISTVIEW:
				num=p_g->value;
				node=((struct List *)(p_g->p_data))->lh_Head;
				for(i=0;i<p_g->value;i++){
					if(node->ln_Succ!=NULL){
						node=node->ln_Succ;
					}
				}
				SPrintF (vect,"%s=%s",buffer_conv,node->ln_Name);
				printd("listvue,value:%d ",p_g->value);
				break;
			case	OWN_GADGET:
				SPrintF (vect,"%s=%d",buffer_conv,p_g->value);
				break;
			case SLIDER:
				SPrintF (vect,"%s=%ld",buffer_conv,p_g->value);
				printd("Slider,value:%d ",p_g->value);
				break;
			case STRING:
			case DATA_STRING:
				SPrintF (vect,"%s=%s",buffer_conv,p_g->p_data);
				printd("String,value:%s ",p_g->p_data);
				break;
			case SCREEN:
				SPrintF (vect,"%s=%ld x %ld x %ld ID=%lx OVSCAN=%ld",
					buffer_conv,
					p_g->d1,
					p_g->d2,
					p_g->d3,
					(ULONG)p_g->p_data,
					p_g->value);
				printd("Screen,value:%s ",vect);
				break;
			case FONT:
				p_attr=(struct TextAttr *)p_g->p_data;
				SPrintF (vect,"%s=%s %ld %ld %ld",
					buffer_conv,
					p_attr->ta_Name,
					(ULONG)p_attr->ta_YSize,
					(ULONG)p_attr->ta_Style,
					(ULONG)p_attr->ta_Flags);
				printd("Font,value:%s ",vect);
				break;
			default:
				break;
	}
	printd("\n");
	return(vect);
}

void SaveConfig(char *Name,struct tom_gadget *p_gadg)
{
	int	i,num,mem,mem2;
	struct DiskObject *DiskObject;
	ULONG Index;
	char **NewToolTypes,**NextEntry,**OldToolTypes;

	printd("Save config:%s\n",Name);

	/* GetDiskObjectNew() is a 2.0 function	*/
#ifndef	WB_13
	if ((DiskObject=GetDiskObjectNew(Name))!=NULL){
#endif
#ifdef	WB_13
	if ((DiskObject=GetDiskObject(Name))!=NULL){
#endif
		Index=0L;
		OldToolTypes=DiskObject->do_ToolTypes;
		while (OldToolTypes[Index]) Index++;
		num=0;
		while(p_gadg[num].type_gadg!=END_LISTE){
				num++;
		}
		Index+=num+1;
		printd("index=%d\n",Index);

		mem2=Index*4L+num*SIZE_VECT;
		if ((NewToolTypes=(char **)AllocMem(mem2,
                                     MEMF_PUBLIC|MEMF_CLEAR))==NULL){
			FreeDiskObject (DiskObject);
			return;
		}
		NextEntry=NewToolTypes;

		i=0;
		while(p_gadg[i].type_gadg!=END_LISTE){
				if(i==0){
					*NextEntry++=add_gadg(&p_gadg[i],(char *)&NewToolTypes[Index]);
				}else{
					*NextEntry++=add_gadg(&p_gadg[i],NewToolTypes[i-1]+SIZE_VECT);
				}
				i++;
		}

		Index=0L;
		while (OldToolTypes[Index]){
			char *Ptr,*Asgn;

			mem=strlen(OldToolTypes[Index])+1L;
			if (Ptr=(char *)AllocMem(mem,0L)){
				if (Asgn=strchr(strcpy(Ptr,OldToolTypes[Index]),'=')){
					*Asgn='\0';
				}
				if (FindToolType(NewToolTypes,Ptr)==NULL){
						*NextEntry++=OldToolTypes[Index];
				}
				FreeMem ((APTR)Ptr,mem);
			}
			Index++;
#ifndef WB_13
		}
#endif

		DiskObject->do_ToolTypes=NewToolTypes;
		if (!PutDiskObject(Name,DiskObject)){
/*
			 DisplayBeep (BlankerWindow->WScreen);
*/
		}
		DiskObject->do_ToolTypes=OldToolTypes;
#ifdef WB_13
		}
#endif

		FreeMem ((APTR)NewToolTypes,mem2);
		FreeDiskObject (DiskObject);
	}
}
