/*  Source Control
$RCS

$version 0.2

$date Wed Jun 17 14:19:36 1992

$changes :

Revision 0.2	Jim Wed Jun 17 14:19:36 1992
Now adds fortunes to the END of the linked list!

Revision 0.1	Jim Fri May 31 11:40:06 1991
Now makes icons

Revision 0.0	Jim Mon Sep 10 19:22:19 1990
Added to RCS

*/

#include <exec/types.h>
#include <exec/tasks.h>
#include <libraries/dosextens.h>
#include <workbench/workbench.h>
#include <proto/all.h>

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

#define MAXSIZE 5000
char *Version="[33mMakefort[31m Version 0.3, written by Jim Finnis.\n";

extern int writeshort(BPTR,int);
extern int writelong(BPTR,long);
extern int writestring(BPTR,char *);
extern void savehuffman(BPTR);
extern void genhuffman(void);
extern void freehuffman(void);
extern void clearhuffman(void);
extern void addtohuffman(char *);
extern char *compress(char *);

char *infile="fortunes.dat";
char *outfile="fortunes";

/* data from file dataicon.brush.me2 */
USHORT IconImageData[]={
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0xfff,	0x8000,	0x0,	0x1,	0xf000,	0x7c00,	0x0,
0xe,	0x0,	0x380,	0x0,	0x30,	0x1f0,	0x60,	0x0,
0xc0,	0x318,	0x18,	0x0,	0x300,	0x30,	0x6,	0x0,
0x400,	0x60,	0x1,	0x0,	0x800,	0x60,	0x0,	0x8000,
0x1000,	0x0,	0x0,	0x4000,	0x1000,	0x60,	0x0,	0x4000,
0x2000,	0x0,	0x0,	0x2000,	0x2000,	0x7010,	0x0,	0x2000,
0x2000,	0x4998,	0xc000,	0x2000,	0x2000,	0x4850,	0x2000,	0x2000,
0x2000,	0x4bd1,	0xe000,	0x2000,	0x1000,	0x71d0,	0xe000,	0x4000,
0x1000,	0x0,	0x0,	0x4000,	0x800,	0x60,	0x0,	0x8000,
0x400,	0x1fd0,	0x1e01,	0x0,	0x303,	0xf01d,	0xedf6,	0x0,
0xfe,	0xf,	0x18,	0x0,	0x30,	0x0,	0x60,	0x0,
0xe,	0x0,	0x380,	0x0,	0x1,	0xf000,	0x7c00,	0x0,
0x0,	0xfff,	0x8000,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x20,	0x0,	0x0,
0x0,	0xfe0,	0x1200,	0x0,	0x1,	0xfff0,	0xffe0,	0x0,
0xf,	0xffff,	0xff80,	0x0,	0x1,	0xffff,	0xfc00,	0x0,
0x0,	0xfff,	0x8000,	0x0,	0x0,	0x0,	0x0,	0x0,
0x0,	0x0,	0x0,	0x0,	0x0,	0x0,	0x0
};
/* end of data from file dataicon.brush.me2 */

struct Image IconImage=
{0,0,53,29,0x0002,&IconImageData[0],0x0003,0,NULL};


UBYTE *ttypes[]=
{
	"FILETYPE=Fortunes",
	NULL
};

char deftoolname[]="fortune";

struct DiskObject ProjIcon=
{
	WB_DISKMAGIC,WB_DISKVERSION,
	{
		NULL,0,0,53,29,GADGIMAGE|GADGHBOX,GADGIMMEDIATE|RELVERIFY,
		BOOLGADGET,(APTR)&IconImage,NULL,NULL,NULL,NULL,0,NULL
	},
	WBPROJECT,
	deftoolname,
	ttypes,
	NO_ICON_POSITION,
	NO_ICON_POSITION,
	NULL,NULL,6000
};

struct FortList
{
	char *data;
	unsigned long pos;
	struct FortList *next;
};

struct FortList *Head=NULL,*Tail=NULL;
long number=0;

void ReadFortunes(fn)
char *fn;
{
	FILE *a;
	char c,oc,buf[MAXSIZE];
	struct FortList *new;
	int bad=0,i=0,n=0,len;

	printf(Version);
	a=fopen(fn,"r");
	if(a==NULL)
	{
		printf("File not found\n"); exit(200);
	}

	clearhuffman();
	printf("Reading...\n");
	for(;;)
	{
		for(;;)
		{
			c=getc(a);
			if(feof(a))break;
			if(c=='%')
			{
				oc=getc(a);
				if(oc!='%')
				{
					buf[i++]=c; buf[i++]=oc;
				}
				else
				{
					while(!feof(a)&&(getc(a)!='\n'));
					break;
				}
			}
			else
			{
				if(c=='\t')
				{
					buf[i++]=' ';
					buf[i++]=' ';
					buf[i++]=' ';
					buf[i++]=' ';
					buf[i++]=' ';
				}
				else
				{
					buf[i++]=c;
				}
			}

			if(i>=MAXSIZE-1)
			{
				bad=1;
				break;
			}

		}
		if(bad)
		{
			printf("Fortune too big.\n");
			fclose(a);
			exit(0);
		}
		printf("%d Read %d chars.  \r",n++,i);
		buf[i]=NULL; i=0;
		addtohuffman(buf);

		new=(struct FortList *)malloc(sizeof(struct FortList));
		if(new==NULL)
		{
			printf("Unable to allocate node\n");
			exit(200);
		}

		if(!(len=strlen(buf)))
		{
			printf("Zero length string found - please correct.\n");
			exit(200);
		}
		new->data=(char *)malloc(len+1);
		if(new->data==NULL)
		{
			printf("Unable to allocate string\n");
			exit(200);
		}
		strcpy(new->data,buf);
		new->next=NULL;
		if(!Head)Head=new;
		if(Tail)Tail->next=new;
		Tail=new;
		number++;

		if(feof(a))break;
	}
}

struct Library *IconBase=NULL;

BOOL MakeIcon(UBYTE *name,char **newtooltypes,char *newdeftool)
{
        struct DiskObject *dobj;
        char *olddeftool;
        char **oldtooltypes;
        BOOL success=0;

        if(!(IconBase=OpenLibrary("icon.library",0L)))
        	return(FALSE);

        if(dobj=GetDiskObject(name))
        {
                oldtooltypes=dobj->do_ToolTypes;
                olddeftool=dobj->do_DefaultTool;
                dobj->do_ToolTypes=newtooltypes;
                dobj->do_DefaultTool=newdeftool;
                success=PutDiskObject(name,dobj);
                dobj->do_ToolTypes=oldtooltypes;
                dobj->do_DefaultTool=olddeftool;
                FreeDiskObject(dobj);
        }
        if(!success)
                success=PutDiskObject(name,&ProjIcon);
	if(IconBase)CloseLibrary(IconBase);
        return(success);
}

int CheckStack(void)
{
	LONG stacksize;
	struct Process *myproc;

	if(!(myproc=(struct Process *)FindTask(NULL)))
	{
		printf("Oh dear, I don't know who I am...\n");
		exit(4000);
	}

	stacksize=((struct CommandLineInterface *)
		((myproc->pr_CLI)<<2))->cli_DefaultStack<<2;

	return(stacksize<30000L ? 1 : 0);
}


void main(int argc,char *argv[])
{
	BPTR out;
	unsigned long pos=0;
	char *inpf=infile,*outf=outfile;
	struct FortList *p;
	int n;

	if(CheckStack())
	{
printf("You have insufficient stack in this CLI. Correct this by using the\n");
printf("command 'stack 40000' and then trying again.\n");
		exit(100);
	}

	if(argc>1)
	{
		inpf=argv[1];
		if(argc>2)
			outf=argv[2];
	}

	/* First, read the fortunes and build the table */

	ReadFortunes(inpf);
printf("all read!!\n");fflush(stdout);
	genhuffman();
printf("huffman genned!!\n");fflush(stdout);
	freehuffman();
printf("huffman freed!!\n");fflush(stdout);

	out=Open(outf,MODE_OLDFILE);
	if(out==NULL)
	{
		printf("Unable to open file\n");
		exit(200);
	}
printf("file opened!!\n");fflush(stdout);

	/* Write out the huffman table */

	savehuffman(out);
printf("huffman saved!!\n");fflush(stdout);

	/* Write how many fortunes there are */

	writelong(out,number);

	/* Start position for fortunes */

	pos=4*(number+1)+20*16;

	/* Now go through the FortList, writing the jump table and setting
	up the positions */

	printf("Writing jump table\n");
	for(p=Head;p!=NULL;p=p->next)
	{
		writelong(out,pos);
		p->pos=pos;
		pos+=strlen(compress(p->data))+1;
	}
printf("JT writted!!\n");fflush(stdout);

	/* The fortunes are written out */

	for(n=0,p=Head;p!=NULL;p=p->next)
	{
		char *t;
		printf("%d Writing...  \r",n++);
		t=compress(p->data);
		Write(out,t,strlen(t)+1);
	}
	Close(out);

	printf("%ld fortunes done.\n",number);
	if(!(MakeIcon(outf,ttypes,deftoolname)))
		printf("unable to write icon!\n");
}

