/* IconStuff.c **************************************************************
*
*	IconStuff -----	Programmfragment, das die für die Umwandlung
*			der Icon-Strukturen nötigen Routinen enthält.
*			Grob gesagt wird ein Image in Quellcode konvertiert
*			und anschließend mit der DiskObject-Struktur
*			verbunden, aber seht selbst...
*
*****************************************************************************
*
*	Autor...
*
*	Olaf Barthel & ED Electronic Design Hannover
*	Brabeckstraße 35
*	D-3000 Hannover 71
*
*	Bundesrepublik Deutschland
*
****************************************************************************/
#include <intuition/intuition.h>
#include <workbench/workbench.h>
#include <stdio.h>

	/* Image2C(IconImage,ImageName,ArrayName,ImageFile):

		Erzeugt aus einem Image, ein paar Variablennamen
		und einem Zeiger auf eine offene Datei 'C'-Quellcode,
		aus dem sich ohne weiteres ein Image rekonstruieren
		läßt. */

void
Image2C(IconImage,ImageName,ArrayName,ImageFile)
struct Image *IconImage;
char *ImageName,*ArrayName;
FILE *ImageFile;
{
	register short i,j,k,end;	/* Schleifenzähler, Schleifenende. */
	char Mod[10];			/* Puffer für Hexadezimal-Zahlen. */
	USHORT *ImageData;		/* Zeiger auf Bilddaten. */

		/* Anzahl der zu übertragenden USHORTs errechnen. */

	end = ((IconImage -> Width + 15) >> 4) * IconImage -> Height;

		/* Die erste Zeile schreiben... */

	fprintf(ImageFile,"USHORT %s[%d] =\n{",ArrayName,end * IconImage -> Depth);

		/* Zeiger auf Bilddaten initialisieren. */

	ImageData = IconImage -> ImageData;

		/* I einer großen Schleife die Bilddaten ausgeben. */

	for(k = 0 ; k < IconImage -> Depth ; k++)
	{
			/* Damit wir wissen wo wir sind, BitPlane angeben. */

		fprintf(ImageFile,"\n\t/* Plane %d */\n",k);

		for(i = 0 ; i < end ; i++)
		{
			if(!(i % 8))
				fprintf(ImageFile,"\n\t");

				/* Bitmap wird in Zahl verwandelt.
				   Wem diese Methode komisch vorkommt,
				   lese sich in K&R's "Programmieren in C"
				   noch einmal das Kapitel über Pointer
				   und Arrays durch. */

			sprintf(Mod,"%04x",*ImageData);

				/* Großbuchstaben erzeugen. */

			for(j = 0 ; j < 4 ; j++)
				Mod[j] = toupper(Mod[j]);

			fprintf(ImageFile,"0x%s",Mod);

			if(i != end - 1)
				fprintf(ImageFile,",");

				/* Bilddatenzeiger erhöhen. */

			ImageData++;
		}

			/* War dies schon die letzte Bitplane? */

		if(k != IconImage -> Depth - 1)
			fprintf(ImageFile,",\n");
	}

		/* Array abschließen. */

	fprintf(ImageFile,"\n};\n\n");

		/* Image-Struktur erzeugen. */

	fprintf(ImageFile,"struct Image %s =\n{\n",ImageName);

	fprintf(ImageFile,"\t0,0,\n");
	fprintf(ImageFile,"\t%d,%d,%d,\n",IconImage -> Width,IconImage -> Height,IconImage -> Depth);
	fprintf(ImageFile,"\t(USHORT *)&%s[0],\n",ArrayName);

		/* In welche Planes soll geschrieben werden? */

	sprintf(Mod,"%02x",(1 << IconImage -> Depth) - 1);

	for(j = 0 ; j < 2 ; j++)
		Mod[j] = toupper(Mod[j]);

	fprintf(ImageFile,"\t0x%s,0x00,\n",Mod);
	fprintf(ImageFile,"\t(struct Image *)NULL\n");

	fprintf(ImageFile,"};\n\n");
}

	/* Image2Icon(IconImage,Image1Name,Image2Name,IconName,IconType,ImageFile):

		Zaubert aus einem Image, ein paar Variablennamen und einem
		Zeiger auf eine offene Datei eine Icon-Struktur, aus der
		sich ein Icon erzeugen läßt. */

void
Image2Icon(IconImage,Image1Name,Image2Name,IconName,IconType,ImageFile)
struct Image *IconImage;
char *Image1Name,*Image2Name,*IconName;
UBYTE IconType;
FILE *ImageFile;
{
	static char *WB_Types[7] =
	{
		"WBDISK",	/* Diskettenicon */
		"WBDRAWER",	/* Schubladenicon */
		"WBTOOL",	/* Programmicon */
		"WBPROJECT",	/* Dateiicon */
		"WBGARBAGE",	/* Trashcanicon */
		"WBDEVICE",	/* Geräticon (PRT: o.Ä.) !LÄUFT NOCH NICHT! */
		"WBKICK"	/* Kickstarticon !ÜBERFLÜSSIG! */
	};

		/* Falls das Icon eine Art von Verzeichnis (Diskette, etc.)
		   darstellt, benötigen wir eine Zusatzstruktur, die sich
		   um die Darstellung und Größe des zu öffnenden Fensters
		   kümmert. Diese Struktur enthält eine NewWindow-Struktur,
		   deren Werte wir setzen müssen. */

	if(IconType == WBDISK || IconType == WBDRAWER || IconType == WBGARBAGE)
	{
		fprintf(ImageFile,"struct DrawerData %sDrawer =\n{\n",IconName);
		fprintf(ImageFile,"\t50,50,\n");		/* Position */
		fprintf(ImageFile,"\t400,100,\n");		/* Ausmaße */
		fprintf(ImageFile,"\t-1,-1,\n");		/* Zeichenstifte */
		fprintf(ImageFile,"\tNULL,\n");			/* IDCMPFlags */
		fprintf(ImageFile,"\t0x0240027F,\n");		/* Magische Zahl, erkläre ich später */
		fprintf(ImageFile,"\t(struct Gadget *)NULL,\n");/* Gagdgets */
		fprintf(ImageFile,"\t(struct Image *)NULL,\n");	/* CheckMark */
		fprintf(ImageFile,"\t(UBYTE *)NULL,\n");	/* Titel */
		fprintf(ImageFile,"\t(struct Screen *)NULL,\n");/* Screen */
		fprintf(ImageFile,"\t(struct BitMap *)NULL,\n");/* CustomBitMap */
		fprintf(ImageFile,"\t90,40,\n");		/* Minimale Größe */
		fprintf(ImageFile,"\t-1,-1,\n");		/* Maximale Größe (= 65535) */
		fprintf(ImageFile,"\tWBENCHSCREEN,\n\n");	/* Hier erscheint das Fenster */

		fprintf(ImageFile,"\t0,\n");			/* Stellung der Rollbalken */
		fprintf(ImageFile,"\t0\n};\n\n");
	}

		/* Nachtrag zu der "Magischen Zahl": Diese Zahl setzt sich aus etwa
		   zehn Flags zusammen (so z.B. WINDOWDRAG, REPORTMOUSE, etc.).
		   Da ich die Zeile allerdings nicht vollpfropfen wollte, habe
		   ich mich des absoluten Wertes bedient. */

		/* Hier folgt die eigentliche DiskObject-Struktur. */

	fprintf(ImageFile,"struct DiskObject %s =\n{\n",IconName);
	fprintf(ImageFile,"\tWB_DISKMAGIC,\n");			/* Identifikation = Icon */
	fprintf(ImageFile,"\tWB_DISKVERSION,\n\n");		/* Wird von der Icon.Library gesetzt. */

		/* Jede DiskObject-Struktur enthält eine Gadget-Struktur. */

	fprintf(ImageFile,"\t(struct Gadget *)NULL,\n");
	fprintf(ImageFile,"\t0,0,\n");
	fprintf(ImageFile,"\t%d,%d,\n",IconImage -> Width,IconImage -> Height);

		/* Falls ein zweites Image gewünscht wird, passen wir
		   die Struktur entsprechend an. */

	if(Image2Name)
		fprintf(ImageFile,"\tGADGIMAGE | GADGHIMAGE,\n");
	else
		fprintf(ImageFile,"\tGADGIMAGE | GADGBACKFILL, /* Könnte auch GADGHCOMP sein. */\n");

	fprintf(ImageFile,"\tRELVERIFY | GADGIMMEDIATE,\n");
	fprintf(ImageFile,"\tBOOLGADGET,\n");
	fprintf(ImageFile,"\t(APTR)&%s,\n",Image1Name);

		/* Ein weiteres Mal: Image anpassen. */

	if(Image2Name)
		fprintf(ImageFile,"\t(APTR)&%s,\n",Image2Name);
	else
		fprintf(ImageFile,"\t(APTR)NULL,\n");

	fprintf(ImageFile,"\t(struct IntuiText *)NULL,\n");
	fprintf(ImageFile,"\tNULL,\n");
	fprintf(ImageFile,"\t(APTR)NULL,\n");
	fprintf(ImageFile,"\tNULL,\n");
	fprintf(ImageFile,"\t(APTR)NULL,\n\n");

	fprintf(ImageFile,"\t%s,\n",WB_Types[IconType - 1]);
	fprintf(ImageFile,"\t(char *)NULL, /* DefaultTool */\n");
	fprintf(ImageFile,"\t(char **)NULL, /* ToolTypes */\n");
	fprintf(ImageFile,"\tNO_ICON_POSITION,\n");
	fprintf(ImageFile,"\tNO_ICON_POSITION,\n");

		/* Die DrawerData-Struktur wird gegebenenfalls
		   angebunden. */

	if(IconType == WBDISK || IconType == WBDRAWER || IconType == WBGARBAGE)
		fprintf(ImageFile,"\t(struct DrawerData *)&%sDrawer,\n",IconName);
	else
		fprintf(ImageFile,"\t(struct DrawerData *)NULL,\n");

	fprintf(ImageFile,"\t(char *)NULL, /* ToolWindow */\n");
	fprintf(ImageFile,"\t0 /* StackSize */\n};\n\n");

		/* Mit diesem Makro wird das Icon gespeichert. */

	fprintf(ImageFile,"#define SaveMyIcon(Destination) PutDiskObject(Destination,&MyIcon)\n");
}
