/****************************************************************************

				Basic.c

	This file defines the basic operations that are needed to print
	a set of structures. It is called from the Print module.

					Rick van Rein, October 30, 1990

****************************************************************************/



#include <functions.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <stdio.h>

#define abs(x) (((x) >= 0)? (x): (-(x)))


struct IntuitionBase *IntuitionBase;

extern struct Window *win;


#define INTUITEXT	0
#define BORDER		1
#define BORDERCOORDS	2
#define IMAGE		3
#define IMAGEDATA	4
#define GADGET		5
#define BOOLINFO	6
#define PROPINFO	7
#define STRINGINFO	8
#define STRINGBUF	9
#define STRINGUNDO	10
#define WINDOW		11
#define PROPBUF		12
#define MENU		13
#define MENUITEM	14
#define NEWSCREEN	15
#define COLORMAP	16
#define WINDOWARRAY	17
#define MENUARRAY	18


char *StructNames []=
 { "itx", "bor", "xy", "img", "pic", "gad", "bin", "pin", "sin", "str", "undo", "nwin", "pbuf", "men", "mit", "nscr", "cols", "swin", "smen" };

int ctr [19];

static FILE *file;



/***** Print a requester if the required file exists, and find out iff appending is wanted (=RetVal): */

static struct IntuiText negtv=
 {
   0,1,JAM1,
   7,3,
   NULL,
   (UBYTE *) "Cancel",
   NULL
 };

static struct IntuiText postv=
 {
   0,1,JAM1,
   7,3,
   NULL,
   (UBYTE *) "OverWrite",
   NULL
 };

static struct IntuiText line3=
 {
   0,1,JAM1,
   12,25,
   NULL,
   (UBYTE *) "Already exists.",
   NULL
 };

static struct IntuiText line2=
 {
   0,1,JAM1,
   12,15,
   NULL,
   NULL,		/* Filename filled in by program */
   &line3
 };

static struct IntuiText line1=
 {
   0,1,JAM1,
   12,5,
   NULL,
   (UBYTE *) "File",
   &line2
 };

static int AppendReq (fn)
   char *fn;
 {
   line2.IText=(UBYTE *) fn;
   return AutoRequest (win,&line1,&postv,&negtv,0L,0L,320L,72L);
 }



/***** Print a formatted text in the way printf does it; No more than 4 args are expected: */

void mprintf (fmt,arg1,arg2,arg3,arg4)
   char *fmt;
   long arg1,arg2,arg3,arg4;			/* Should be enough */
 {
   static char buf [300]="";
   int s=strlen (buf);
   int newline,tabulate;

   sprintf (&buf [s],fmt,arg1,arg2,arg3,arg4);
   while ((newline=FindChar (buf,'\n')) >= 0)
    {
      buf [newline]='\0';
      tabulate=FindChar (buf,'\t');
      if (tabulate>=0)
         buf [tabulate]='\0';
      fputs (buf,file);
      if (tabulate>=0)
       {
         if (tabulate>48)
	    fputs ("\n\t\t\t\t\t\t",file);
	 else
		/* How many tabs are needed?
		   We should end at x=48, so 6 tabs from left. If x is already >0, then we can
		   subtract one tab for every 8 characters. 7 is not enough! Round down!
		   So, the number of tabs is 6 - (reached_x >> 3). Note that reached_x is
		   already determined: It can be found in tabulate! */
            fputs (&"\t\t\t\t\t\t" [tabulate>>3],file);
	 fputs (&buf [tabulate+1],file);
       }
      fputc ('\n',file);
      strcpy (buf,&buf [newline+1]);		/* Overwrite old line; It's finished! */
    }
 }



/***** Open a file for output; TRUE is returned iff opening went OK: */

int OpenPrintFile (name)
   char *name;
 {
   int cont;
   struct Lock *lock;

   lock=Lock (name);		/* Test if it already is there */
   if (lock)
    {
      UnLock (lock);
      cont=AppendReq (name);	/* Ask if we want to OverWrite old file */
    }
   else
      cont=1;

   if (cont)
      file=fopen (name,"w");
   else
      file=NULL;

   if (!file)
      return 0;			/* It didn't work out as it should */
   else
    {
      mprintf ("/***** Intuition structures stolen by means of Steal 1.1 by Rick van Rein */\n\n\n"
		 "#include <intuition/intuition.h>\n"
		 "#include <graphics/view.h>\n\n"
		 "#define BLUE_0      0\n"
		 "#define WHITE_1     1\n"
		 "#define BLACK_2     2\n"
		 "#define ORANGE_3    3\n\n");

      return 1;			/* All went as it should */
    }
 }


/***** Close the PrintFile; Do not send a last '\n' to empty the mprintf-buffer; This must be OK! */

void ClosePrintFile ()
 {
   fclose (file);
 }



/***** Seek for a character in the goiven buffer; Return -1 if not found; Otherwise find-index: */

static int FindChar (buf,ch)
   char *buf;
   char ch;
 {
   int loc=0;
   while (buf [loc] && buf [loc] != ch)
      loc++;
   return ((buf [loc]==ch)? loc: -1);
 }


/***** Print a string in a C-readable format: */

void PrintStr (str)
   char *str;
 {
   mprintf ("\"");
   while (*str)
    {
      if (*str<' ')
         switch (*str)
	  {
	    case '\n':mprintf ("\\n");break;
	    case '\t':mprintf ("\\t");break;
	    default:  mprintf ("\%3o",*str);
	  }
      else
         if (*str!='\"')
            mprintf ("%c",*str);
	 else
	    mprintf ("\\\"");
      str++;
    }
   mprintf ("\"");
 }


/***** Print a Pen as if it was given in using several labels: */

void PrintPen (pen)
   int pen;
 {
   static char *penarr [4] = { "BLUE_0","WHITE_1","BLACK_2","ORANGE_3" };
   if (pen>=0 && pen<4)
      mprintf ("%s",penarr [pen]);
   else
      mprintf ("%d",pen);
 }


/***** Print all the Flags given in the first parameter.
       fields Gives an array with the fields that should be AND-ed with those flags one by one;
       The array ends in a 0L. If the result of the AND equals the value in matches at the same
       index, the entry in names, (at that same index again) will be printed: */

void PrintFlags (flags,fields,matches,names)
   long flags;
   long fields [],matches [];	/* Closed by 0L in fields */
   char *names [];
 {
   int found=0;

   while (*fields)
    {
      if ((flags & *fields)==*matches)
       {
         mprintf ("%s%s",found? " | ": "",*names);
	 found=1;
       }
      fields++;
      matches++;
      names++;
    }

   if (!found)
      mprintf ("0");
 }


/***** Print a DrawMode as if it was given in using several labels: */

static long DrawModeFld []=
 { JAM2, JAM2, COMPLEMENT, INVERSVID, 0L };

static long DrawMode []=
 { JAM2, JAM1, COMPLEMENT, INVERSVID };

static char *DrawModeNms []=
 { "JAM2", "JAM1", "COMPLEMENT", "INVERSVID" };


void PrintDrawMode (md)
   int md;
 {
   PrintFlags ((long) md,DrawModeFld,DrawMode,DrawModeNms);
 }
