/***************************************************************************
 *		  Copyright (C) 1994  Charles P. Peterson                  *
 *	     4007 Enchanted Sun, San Antonio, Texas 78244-1254             *
 *              Email: Charles_P_Peterson@fcircus.sat.tx.us                *
 *                                                                         *
 *		  This is free software with NO WARRANTY.                  *
 *			  See below for details.                           *
 *		      Support is available for a fee.                      *
 ***************************************************************************
 *
 * Program:     gfft--General FFT analysis
 * File:        gfft.c
 * Purpose:     main() function--get args and/or commands
 * Author:      Charles Peterson (CPP)
 * History:     27-May-1993 CPP; Created.
 *              6-July-1994 CPP (0.74); allow simultaneous MORE sessions
 *              21-July-1994 CPP (1.02); remove "delete failed..." msgs
 */

/*
 *  Copyright (C) 1994  Charles P. Peterson
 *  4007 Enchanted Sun, San Antonio, TX 78244-1254
 *  Email: Charles_P_Peterson@fcircus.sat.tx.us
 *
 *  Please refer to the README file included in this distribution
 *  concerning low-cost support and update services available from the
 *  author, as well as encouragement to make suggestions, bug reports,
 *  usage reports, enhancement requests, donations, equipment loans, and
 *  ports to different systems.  If the README files is unavailable, Email
 *  or send a SASE to the author (address above).  A limited amount of free
 *  help may also be available by Email or mail (SASE required).  If
 *  address has changed, try finding the most recent distribution.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  The
 *  GNU General Public License should be in a file named 'COPYING'.
 *  Do not contact the Free Software Foundation for any other information
 *  about this program; contact the author instead.
 *
 */

#include <stdlib.h>    /* exit(), system() */
#include <stdio.h>     /* printf()   */
#include <dos.h>       /* _CXBRK */
#include <math.h>      /* _CXFERR */
#include <string.h>

#define DEFINE_HERE
#include "gfft.h"
#undef DEFINE_HERE
#include "settings.h"

extern Name_Info_St Gfft_Command[];  /* GFFT commands */

char *StartupPathList[] = STARTUP_PATH_LIST;  /* From Xdef.h where X is sys */

static void cleanup (void);
static void delete_temp_files (void);

void main (int argc, char *argv[])
{

    CATCH_ERROR  /* This is the ultimate safety net */
    {

	startup_cli_file ();

/**************************************************************************\
 * Workbench Mode                                                         *
\**************************************************************************/

#ifdef AMIGA

	if (argc < 1)
	{
	    CommandMode = WORKBENCH_MODE;
	    Plot = ANY_PLOT;
	    workbench_main ();  /* Failures gabort() directly */
	    quit (NullString);  /* Successful exit */
	}

#endif

/**************************************************************************\
 * CLI-Batch Mode                                                         *
\**************************************************************************/

	if (argc > 1)
	{
        /*
         * This is a non-interactive (i.e. batch) session
         * qabort on error (indicated by longjmp).
         */
	    CommandMode = BATCH_MODE;
	    Plot = NO_PLOT;
	    CATCH_ERROR
	    {
		batch_command (argc, argv);
		quit (NullString);
	    }
	    ON_ERROR
	    {
		gabort (EXIT_FAILURE);
	    }
	    END_CATCH_ERROR;

	} /* End of batch session handling */

/**************************************************************************\
 * CLI-Interactive Mode (gets called from here)                           *
\**************************************************************************/

	Plot = ANY_PLOT;
	banner_message (NullString);
	cli_interactive_loop (TRUE);

/* Shouldn't get here; quit() or gabort() are called somewhere to exit */
    }

#ifdef _DEBUG
    ON_ERROR
    {
    /*
     * WARNING!  Do not put any code (or calls) here which could possibly
     * raise an error.  If it does, the 'ultimate' safety net will be
     * leaky, and a system crash could result!
     */
	fprintf (stderr,"\nWarning.  Error caught by safety net.\n");
    }
#endif /* ifdef _DEBUG */

    END_CATCH_ERROR;  /* End of the ultimate safety net. */

/* Shouldn't get here; quit() or gabort() are called somewhere to exit */

}


/**************************************************************************\
 * CLI-Interactive Mode (implemented here)                                *
\**************************************************************************/

void cli_interactive_loop (BOOLEAN started_from_cli)
{
    int previous_command_mode = CommandMode;

    CommandMode = INTERACTIVE_MODE;
    while (started_from_cli || CommandMode == INTERACTIVE_MODE)
    {
	prompt_command ();  /* Might gabort() from here on EOF */
	CATCH_ERROR
	{
	    invoke_method (Command, Gfft_Command);
	}
	END_CATCH_ERROR;  /* We don't break loop on error here */
    }
    CommandMode = previous_command_mode;
}


void startup_cli_file ()
{
    int previous_command_mode = CommandMode;
    FILE * startup_file_ptr = NULL;

    CommandMode = BATCH_MODE;

    if ( startup_file_ptr = gopen (StartupPathList, ".gfft", "r"))
    {
	char *next_command = Command;

	while (next_command)
	{
	    next_command = fgets (Command, COMMAND_BUFFER_SIZE, 
				  startup_file_ptr);
	    if (next_command)
	    {
		int length = strlen (Command);
		
		if (length == 0) continue;
		if (Command[length-1] == '\n')
		{
		    Command[length-1] = '\0';
		    if (length == 1) continue;
		}
		if (Command[0] == ';' || Command[0] == '#' ||
		    Command[0] == '!')
		{
		    continue;
		}
		CATCH_ERROR
		{
		    invoke_method (Command, Gfft_Command);
		}
		ON_ERROR
		{
		    error_message (STARTUP_FILE_ERROR);
		    gabort (EXIT_FAILURE);
		}
		END_CATCH_ERROR;
	    }
	}
	fclose (startup_file_ptr);
    }
    CommandMode = previous_command_mode;
}


/**************************************************************************\
 * Termination Handlers                                                   *
\**************************************************************************/

/*
 * The system function exit() should not be called directly except
 * by quit() and gabort(), which follow.
 */


char *quit (char *arguments)
{
    cleanup ();
    exit (EXIT_SUCCESS);
    return arguments;    /* This is a dummy to make compiler happy */
}

void gabort (int status)
{
    cleanup ();
    exit (status);
}

static void cleanup (void)
{
    delete_temp_files ();
#ifdef AMIGA
    close_amiga_stuff ();
#endif
}

static void delete_temp_files (void)  /* rework when adding other systems */
{
    char buffer[COMMAND_BUFFER_SIZE];

    if (Plot && CommandMode == BATCH_MODE)
    {
	error_message (CANT_CLEANUP_BATCH_PLOT);
	return;
    }

    sprintf (buffer, 
	     "run >nil: delete >nil: %s QUIET\n", DATA_FILE_WILDCARD);
    system (buffer);

    sprintf (buffer, 
	     "run >nil: delete >nil: %s QUIET\n", MESSAGE_FILE_WILDCARD);
    system (buffer);

    sprintf (buffer, 
	     "run >nil: delete >nil: %s QUIET\n", COMMAND_FILE_WILDCARD);
    system (buffer);

    remove (GNUPLOT_COMMAND_FILE_NAME);
}

/*
 * Well, C= says to disable SAS interrupt handler
 * though they don't say why...
 * So, I'm doing it, reluctantly...
 */

void __regargs _CXBRK(void) { return; }  /* Disable SAS interrupt handlr */
    
/*
 * This was part of an attempt to intercept the divide by zero error
 * so the damned requester doesn't come up.
 * Unfortunately, FFP library doesn't follow ANSI C,
 * so this didn't work.
 * I'd have to write processor dependent assy code to intercept the error.
 */

#if FALSE
void _CXFERR (int code)
{
    _FPERR = code;
    return;
}
#endif
