#include "cp.h"
#include "spr.h"

UBYTE     *version_string     = "$VER: cP 4.3 (31.7.94)";

long      __oslibversion      = 37;     /* requires KickStart 37 */
long      __BackGroundIO      = 1;
long      __stack             = 6000L;   /* stack size doesn't seem to work for cli proc??? */
char     *__procname          = "cPlot"; /* process name */

extern BPTR _Backstdout;      /* keep stdout till we get past startup */

struct List         *SetList       = NULL;
struct RDArgs       *cli_args      = NULL;
struct RDArgs       *env_args      = NULL;
struct TextFont     *fontPtr       = NULL;
struct TextAttr     CPFont         = { (STRPTR)"topaz.font", 8, 0x00, 0x00 };
struct TextAttr     *cPFont        = NULL;
struct AnchorPath   *anchorpath;

AREXXCONTEXT	RexxStuff;

/* Set Defaults */

BOOL grid    = FALSE;     /* No Grid */
BOOL LOGX    = FALSE;     /* Lin X */
BOOL LOGY    = FALSE;     /* Lin Y */
BOOL sym     = FALSE;     /* No Symbols */
BOOL DEFS    = FALSE;     /* Don't make cP */
BOOL MONO    = FALSE;     /* color default */
BOOL CPANEL  = TRUE;      /* control panel on */
BOOL NOFNAME = FALSE;     /* usually put filename boxes on screen */
BOOL BEHIND  = FALSE;     /* usually open screen to front */
BOOL RealTime = FALSE;    /* May not be time sampled data */

LONG Disp;

UBYTE *path;        /* extern pointer to Path */
UBYTE Path[255];    /* Path String same as path but not external */

UBYTE *fName;		/* extern pointer to fontname */
UBYTE fontName[64]; /* im too lazy to allocate dynamically */

UBYTE *MyName;		/* extern pointer to name of process screen and rexxport */
UBYTE Name[64];

UBYTE *XLAB=NULL;
UBYTE xlabel[64];
UBYTE *YLAB=NULL;
UBYTE ylabel[64];
UBYTE *TITLE=NULL;
UBYTE title[128];


LONG points    = 1000000; /* should be enough max per set */
LONG thin      = 1;	/* dont depopulate */

WORD lastcolor = 15;     /* 16 colors default palette */
WORD depth     = 4;


UBYTE **files=NULL;           /* pointer to pointer to FILES/M */

UBYTE RexxName[64];

#define ENVSIZE 1024     /* max char length for envvar */

UBYTE *template = "FILES=WILD/M,LX=LOGX/S,LY=LOGY/S,GRID/S,SYM/S,ID=DISPLAYID/N/K,FONT/K,FS=SIZE/N/K,LORES/S,HIRES/S,LACE/S,SETDEF/S,W=WIDTH/N/K,H=HEIGHT/N/K,P=POINTS/N/K,T=THIN/N/K,D=DEPTH/N/K,MONO/S,CPANEL/S,NOFN=NOFNBOXES/S,OB=OPENBEHIND/S,MYNAME/K,XLAB/K,YLAB/K,TITLE/K,REALTIME/S,SD=DIGITS/N/K";

LONG cli_array[ 27 ] = { 0L, 0L, 0L, 0L, 0L ,0L ,0L ,0L ,0L ,0L ,0L ,0L ,0L ,0L ,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L};
LONG env_array[ 27 ] = { 0L, 0L, 0L, 0L, 0L ,0L ,0L ,0L ,0L ,0L ,0L ,0L ,0L ,0L ,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L};

extern void exit(int);   /* from stdlib.h */

/* Use the same function to process command line and envvar */

void arg_array_Parse( LONG *arg_array )
{
LONG *ptr;

     if ( arg_array[ 0 ] ) files = ( UBYTE ** ) arg_array[ 0 ];

     if ( arg_array[ 1 ] ) LOGX = TRUE;
     if ( arg_array[ 2 ] ) LOGY = TRUE;

     if ( arg_array[ 3 ] )
       {
          if ( grid ) grid = FALSE;
          else        grid = TRUE;
       }
     if ( arg_array[ 4 ] )
       {
          if ( sym ) sym = FALSE;
          else       sym = TRUE;
       }

     if ( arg_array[ 5 ] )
       {
          ptr = (LONG *)arg_array[ 5 ];
          Disp = *ptr;
       }

     if ( arg_array[ 6 ] )
       {
          strcpy( fName, (UBYTE *)arg_array[ 6 ]);
          strcat( fName, ".font");
          cPFont->ta_Name = (STRPTR)fName;
       }

     if ( arg_array[ 7 ] )
       {
          ptr = (LONG *)arg_array[ 7 ];
          cPFont->ta_YSize = (UWORD) *ptr;
       }

     if ( arg_array[ 8 ] )  Disp  = LORES_KEY;
     if ( arg_array[ 9 ] )  Disp  = HIRES_KEY;
     if ( arg_array[ 10 ] ) Disp |= LORESLACE_KEY;
     if ( arg_array[ 11 ] ) DEFS  = TRUE;

     if ( arg_array[ 12 ] )
       {
          ptr = (LONG *)arg_array[ 12 ];
          SWIDTH = *ptr;
       }

     if ( arg_array[ 13 ] )
       {
          ptr = (LONG *)arg_array[ 13 ];
          SHEIGHT = *ptr;
       }
     if ( arg_array[ 14 ] )
       {
          ptr = (LONG *)arg_array[ 14 ];
          points = *ptr;
       }
     if ( arg_array[ 15 ] )
       {
          ptr = (LONG *)arg_array[ 15 ];
          thin = *ptr;
          if (thin <= 0) thin = 1;
       }
     if ( arg_array[ 16 ] )
       {
          ptr = (LONG *)arg_array[ 16 ];
          depth = (WORD)*ptr;

          if (depth <= 1 )
            {
               depth = 1;
               lastcolor = 1;
               MONO = TRUE;
            }
          if (depth == 2) lastcolor = 3;
          if (depth == 3) lastcolor = 7;
          if (depth >= 4)
            {
               depth = 4;
               lastcolor = 15;
            }
       }
     if ( arg_array[ 17 ] )
       {
          MONO  = TRUE;
          depth = 1;
          lastcolor = 1;
       }
     if ( arg_array[ 18 ] )
       {
          if ( CPANEL ) CPANEL = FALSE;
          else          CPANEL = TRUE;
       }
     if ( arg_array[ 19 ] )
       {
          if ( NOFNAME ) NOFNAME = FALSE;
          else           NOFNAME = TRUE;
       }
     if ( arg_array[ 20 ] )
       {
          if ( BEHIND ) BEHIND = FALSE;
          else          BEHIND = TRUE;
       }
     if ( arg_array[ 21 ] )
       {
          strcpy( Name, (UBYTE *)arg_array[ 21 ]);
       }
     if ( arg_array[ 22 ] )
       {
          strcpy( xlabel, (UBYTE *)arg_array[ 22 ]);
       }
     if ( arg_array[ 23 ] )
       {
          strcpy( ylabel, (UBYTE *)arg_array[ 23 ]);
       }
     if ( arg_array[ 24 ] )
       {
          strcpy( title, (UBYTE *)arg_array[ 24 ]);
       }
     if ( arg_array[ 25 ] )
       {
          if ( RealTime ) RealTime = FALSE;
          else            RealTime = TRUE;
       }
     if ( arg_array[ 26 ] )
       {
          ptr = (LONG *)arg_array[ 26 ];
          precision = *ptr - 1;
       }

}


/* Clean up and die duh */

void Death( int v )
{
    if ( delwinWnd )     ClosedelwinWindow();

    if ( PlotWindowWnd ) ClosePlotWindowWindow();

    if ( Scr )           CloseDownScreen();

    if ( fontPtr )       CloseFont( fontPtr );

    FreeARexx(RexxStuff);

    FreeAllSets();

    if ( cli_args )      FreeArgs( cli_args );
    if ( anchorpath )    FreeVec( anchorpath );


    exit( v );
}


void main(int argc, char **argv)
{
ULONG sigs;
ULONG rexxsigs;
LONG  mres;
struct List slist;
LONG j = 0;
BPTR lock;
LONG len;
UBYTE fault[300];
UBYTE *environ;
LONG alive;
struct Screen *WB_Screen;


     slist.lh_Head = (struct Node *) &slist.lh_Tail;
     slist.lh_Tail = 0;
     slist.lh_TailPred = (struct Node *) &slist.lh_Head;
     slist.lh_Type = NT_DATA;

     SetList   = &slist;

     cPFont    = &CPFont;
     fName     = &fontName[0];
     path      = (STRPTR)Path;
     MyName    = (STRPTR)Name;
	XLAB      = (STRPTR)xlabel;
	YLAB      = (STRPTR)ylabel;
	TITLE     = (STRPTR)title;

	strcpy(MyName,&version_string[5]);

     if ( argc == 2 && Stricmp(argv[1],"?")==0)  /* give help and exit */
       {
          if ( _Backstdout )
            {
            	FPuts(_Backstdout, template);
               FPutC ( _Backstdout, '\n');
               Close( _Backstdout);
            }
          Death ( 1 );
	  }       


	/* Clone Workbench DisplayID default to hires lace if we fail */
	
	WB_Screen = LockPubScreen("Workbench");
	if (WB_Screen!=NULL)
	  {
	  	Disp = GetVPModeID(&WB_Screen->ViewPort);
	  	if (Disp==INVALID_ID) Disp = HIRESLACE_KEY;    /* Hires Lace Default */
	  }
	

     /* Parse envvar CPCONFIG */

     if (( environ = AllocVec( ENVSIZE, MEMF_CLEAR )))
       {
          len = GetVar( "CPCONFIG", environ, ENVSIZE, NULL );
          if ( len > 0 )
            {
               environ[len]   = '\n';
               environ[++len] = '\0';

               if ((env_args = (struct RDArgs *)AllocDosObject(DOS_RDARGS, TAG_DONE)))
                 {
                    env_args->RDA_Source.CS_Buffer = environ;
                    env_args->RDA_Source.CS_Length = len;
                    env_args->RDA_Source.CS_CurChr = 0L;

	               memset(env_array,0,sizeof(env_array));

                    if( ReadArgs( template, (LONG *)&env_array[ 0 ], env_args ))
                         arg_array_Parse( &env_array[ 0 ] );

                    FreeArgs( env_args );
                    FreeDosObject(DOS_RDARGS, env_args);
                 }
            }
          FreeVec( environ );
       }

     /* Read command line with ReadArgs */

     memset(cli_array,0,sizeof(cli_array));

     if ( ! ( cli_args = ReadArgs( template, &cli_array[ 0 ], 0L )))
       {
          if ( _Backstdout )
            {
            	if ( Fault(IoErr(), "ERROR", fault, 300)) FPuts(_Backstdout, fault);
               FPutC ( _Backstdout, '\n');
               Close( _Backstdout);
            }
          Death ( 1 );
       }

     arg_array_Parse( &cli_array[ 0 ] );


	if (argc==0) AddNewSet(); /* program was run from workbench */

 

     if ( ! (fontPtr = OpencPFont()))
       {
            if ( _Backstdout) Close( _Backstdout);
            Death(10);
       }

     if ( OpenGTXScreen())
       {
            if ( _Backstdout) Close( _Backstdout);
            Death(10);
       }

     if ( OpenGTXWindow( OpenPlotWindowWindow ))
       {
            if ( _Backstdout) Close( _Backstdout);
            Death(10);
       }


/* load files from Wild pattern */

     SetPointer( PlotWindowWnd, WAITPointer, WAITHEIGHT, WAITWIDTH, WAITXOFF , WAITYOFF);  /* set wait pointer image */

	anchorpath = (struct AnchorPath *) AllocVec(sizeof(struct AnchorPath)+255,MEMF_CLEAR);
     anchorpath->ap_Strlen = 255;

     while ( files && files[ j ]  && anchorpath )
       {
          if ( ! Stricmp(files[ j ], "*")) files[ j ] = "#?";
          
          mres = MatchFirst( files[ j ], anchorpath );

          if ( mres == NULL )
            {
            	if (anchorpath->ap_Info.fib_DirEntryType < 0)
            	  {
               	lock = CurrentDir( anchorpath->ap_Current-> an_Lock );
	               AddSet( anchorpath->ap_Info.fib_FileName );
          	     CurrentDir( lock );
			  }
               while ( MatchNext( anchorpath ) == NULL )
                 {
	            	if (anchorpath->ap_Info.fib_DirEntryType < 0)
     	       	  {
          	          lock = CurrentDir( anchorpath->ap_Current-> an_Lock );
               	     AddSet( anchorpath->ap_Info.fib_FileName );
     	               CurrentDir( lock );
          	       }
			  }
            }
          else
            {
               if ( _Backstdout)
                 {
				if ( Fault(IoErr(), files[ j ], fault, 300)) FPuts(_Backstdout, fault);
                    FPutC ( _Backstdout, '\n');
                    Close( _Backstdout);
                 }
               MatchEnd( anchorpath );
               Death ( 5 );
            }

          MatchEnd( anchorpath );
          j++;
       }


     if ( _Backstdout) Close( _Backstdout);  /* close output so we detache from shell */

     DrawView( TRUE );   /* draw everything */

	/*
	 * Note that SimpleRexx is set up such that you do not
	 * need to check for an error to initialize your REXX port
	 * This is so application could run without REXX...
	 */

	if (Stricmp(MyName,&version_string[5])==0) strcpy (RexxName,"CPLOT_REXX");
	else strcpy(RexxName,MyName);

	RexxStuff=InitARexx(RexxName,NULL);

	rexxsigs = ARexxSignal(RexxStuff);

/* loop to monitor window events and rexx port and watch for break */

     do
       {
	     SetPointer( PlotWindowWnd, SAIPointer, SAIHEIGHT, SAIWIDTH, SAIXOFF , SAIYOFF);    /* Set SAIC pointer image */

          sigs = Wait ( rexxsigs | SIGBREAKF_CTRL_C | 1L<<PlotWindowWnd->UserPort->mp_SigBit );

	     SetPointer( PlotWindowWnd, WAITPointer, WAITHEIGHT, WAITWIDTH, WAITXOFF , WAITYOFF);    /* Set wait pointer image */

          SetWindowTitles( PlotWindowWnd, MyName, MyName );

		if (sigs & 1L<<PlotWindowWnd->UserPort->mp_SigBit) alive = HandlePlotWindowIDCMP();
          else if (sigs & rexxsigs ) alive = HandleARexxMes();
          else if (sigs & SIGBREAKF_CTRL_C ) alive = 0;
          
          if      (alive == 10) NewDepth(1);
          else if (alive == 20) NewDepth(2);
          else if (alive == 30) NewDepth(3);
          else if (alive == 40) NewDepth(4);
       }
     while ( alive );

     SetPointer( PlotWindowWnd, BOOMPointer, BOOMHEIGHT, BOOMWIDTH, BOOMXOFF , BOOMYOFF);    /* Set nuke pointer image */

     Death(0); /* normal exit */
}
