/* Agent Tcl
   Bob Gray
   2 October 1995
  
   This file implements the Agent_AppInit procedure and "main".
 
   Copyright (c) 1995, Robert S. Gray Dartmouth College

   See the file "agent.terms" for information on usage and redistribution
   of this file and for a DISCLAIMER OF ALL WARRANTIES.
*/

#include "tcl.h"
#include "tk.h"
#include "agentId.h"
#include "agentTcl.h"
#include "agentTk.h"
#include "blobTcl.h"
#include "restrictTcl.h"
#include "tcpipTcl.h"

/*
 * The following variable is a special hack that is needed in order for
 * Sun shared libraries to be used for Tcl.  Feel free to DELETE this variable
 * eif you are not running on a Sun.
 */

extern "C" {
  int matherr();
}

int *tclDummyMathPtr = (int *) matherr;

/*
 * The following variable is a special hack that we seem to need for certain
 * RedHat Linux/gcc combinations.  Under these combinations, if this variable
 * is not here, a reference to the "environ" variable is not included in the 
 * static executable, and the "environ" variable is not correctly initialized
 * to point to the user's environment.
 */

char **tclDummyEnviron = environ;

/* AgentTk_AppInit

   Purpose: Initialize an Agent Tk interpreter

     Input: interp = the current interpreter
		     (Tcl_Interp *)

    Output: The procedure returns TCL_OK on successful initializatio and
            TCL_ERROR otherwise.
*/

int AgentTk_AppInit (Tcl_Interp *interp)
{
    Tcl_Interp *masterInterp;    /* master interpreter */

	/*
	 * Assertions on the parameters.
	 */

    assert (interp != NULL);

	/* 
         * See if we have a master interpreter.  If we do, then we are a 
         * slave interpreter and must perform safe initialization rather 
         * than normal initialization.					
   	 */

    masterInterp = Tcl_GetMaster (interp);

	/* 
	 * An "unsafe" slave interpreter is an error. 
	 */

    if (masterInterp != NULL) {
	if (!Tcl_IsSafe(interp)) {
	    Tcl_SetResult (interp, "slave interpreter is not \"safe\"", TCL_STATIC);    
	    return TCL_ERROR;
	}
    }

	/*
	 * Intialize the Tcl core.  
	 */

    if (masterInterp != NULL) {

	if (Tcl_SafeInit(interp, masterInterp) != TCL_OK) {
	    return TCL_ERROR;
	}

    } else {

	if (Tcl_Init(interp) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

	/* agents -- use default version information if necessary */

#ifndef LANGUAGE_NAME
#define LANGUAGE_NAME "STATE-TK"
#endif

    Version version (LANGUAGE_NAME, TK_MAJOR_VERSION, TK_MINOR_VERSION, Version::e_PRODUCTION);

    if (Agent_Init (interp, version) != TCL_OK) { 
	return TCL_ERROR;
    }

	/* tk agents */

    if (AgentTk_Init (interp) != TCL_OK) {
	return TCL_ERROR;
    }

	/* restrictions */

    if (Restrict_Init(interp) != TCL_OK) {
	return TCL_ERROR;
    }

	/* TCP/IP */

    if (Tcpip_Init (interp) != TCL_OK) {
	return TCL_ERROR;
    }

	/* blobs */

    if (Blob_Init (interp) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Call the init procedures for included packages.  Each call should
     * look like this:
     *
     * if (Mod_Init(interp) == TCL_ERROR) {
     *     return TCL_ERROR;
     * }
     *
     * where "Mod" is the name of the module.
     */

    /*
     * Call Tcl_CreateCommand for application-specific commands, if
     * they weren't already created by the init procedures called above.
     */

    /*
     * Specify a user-specific startup file to invoke if the application
     * is run interactively.  Typically the startup file is "~/.apprc"
     * where "app" is the name of the application.  If these two lines are
     * deleted then no user-specific startup file will be run under any 
     * conditions.
     */

  Tcl_SetVar (interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY);
  Tcl_GlueVar (interp, "tcl_rcFileName", TCL_GLOBAL_ONLY); 
  return TCL_OK;
}

/* main */

int main (int argc, char **argv)
{
  AgentTk_Main (argc, argv, AgentTk_AppInit);
  return 0;    /* should never get here -- prevents compiler warning */		
}
