/*
 *****************************************************
 *
 *  SaVi by Robert Thurman (thurman@geom.umn.edu) and
 *          Patrick Worfolk (worfolk@alum.mit.edu).
 *
 *  Copyright (c) 1997 by The Geometry Center.
 *  This file is part of SaVi.  SaVi is free software;
 *  you can redistribute it and/or modify it only under
 *  the terms given in the file COPYRIGHT which you should
 *  have received along with this file.  SaVi may be
 *  obtained from:
 *  http://savi.sourceforge.net/
 *  http://www.geom.uiuc.edu/locate/SaVi
 *
 *****************************************************
 *
 * main.c
 *
 * $Id: main.c,v 1.29 2005/02/12 15:52:33 lloydwood Exp $
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

#include "utils.h"
#include "constants.h"
#include "coverage_vis.h"
#include "globals.h"
#include "sats.h"
#include "savi.h"
#include "tcl_utils.h"
#include "gv_utils.h"

static unsigned int check_env_vars(void);
static void decode_cmd_line(int argc, char *argv[]);

int
main(int argc, char *argv[])
{
  char buf[] = "main(update)";

  /* decode command line */
  decode_cmd_line(argc, argv);

  /* initialize geomview if started as a module */
  if (geomview_module) {
    if (!gv_stream_init_proc()) {
      error("could not open pipe to Geomview; savi is now running standalone.");
      geomview_module = FALSE;
    } else if (!gv_init()) {
      error("could not initialise Geomview (main: error in gv_init).");
      geomview_module = FALSE;
    } else {
      GV_BINARY_FORMAT_AVAILABLE = gv_init_proc();
    }
  }

  if (!check_env_vars()) {
    error("run the savi wrapper script in savi's directory to set locations.");
  }

  Tcl_FindExecutable(argv[0]);

  interp = Tcl_CreateInterp();

  /* initialize Tcl interface */
  if (!tcl_init(interp)) {
    error_and_exit("could not initialise Tcl (main: error in tcl_init).");
  }

  /* initialize Tk interface */
  if (!tk_init(interp)) {
    error_and_exit("could not initialise Tk (main: error in tk_init).");
  }

  /* load up a single satellite */
  if (!first_filename) {
      satellite_init();
  }
  /* initialise satellites */
  sats_init();

  /* and update interface */
  if (!tcl_script(buf)) {
    error_and_exit("is savi compiled correctly? "
		   "Edit savi startup scripts to set locations.");
  }

  /* loop until exit */
  while (sats_update() && tk_update());

  Tcl_DeleteInterp(interp);

  exit(0);
}

static unsigned int
check_env_vars(void)
{
  unsigned int all_env_found = TRUE;

  if (!getenv("SAVI")) {
    error("$SAVI was not set to location of savi directory containing launch script.");
    all_env_found = FALSE;
  }

  if (!getenv("TCL_LIBRARY")) {
    error("$TCL_LIBRARY was not set to location of directory containing Tcl.");
    all_env_found = FALSE;
  }

  if (!getenv("TK_LIBRARY")) {
    error("$TK_LIBRARY was not set to location of directory containing Tk.");
    all_env_found = FALSE;
  }

  return all_env_found;
}

static void
decode_cmd_line(int argc, char *argv[])
{
  unsigned int unknown_parameters = 0;
  unsigned int skipped_filenames = 0;
  unsigned int more_filenames = 0;
  unsigned int special_flags_done = 0;
  unsigned int give_help = 0;
  char * script_filename = NULL;
  FILE *script_file = NULL;
  int i;

  for (i = 1; i < argc; i++) {
    /* argv[0] gives name of binary, not wrapper script */
    if (strcmp(argv[i], "-geomview") == 0) {
      geomview_module = TRUE;
    } else if (strcmp(argv[i], "-debug") == 0) {
      debug = TRUE;
    } else if (strcmp(argv[i], "-help") == 0) {
      special_flags_done++;
      give_help = TRUE;
    } else if (strcmp(argv[i], "-large-map") == 0) {
      coverage_large_map = TRUE;
    } else if (strcmp(argv[i], "-dynamic-texture") == 0) {
      /* do nothing - on by default */
    } else if (strcmp(argv[i], "-dynamic-texture-with-map") == 0) {
      geomview_texture_with_map = TRUE;
    } else if ((strcmp(argv[i], "-no-logo") == 0) ||
	       (strcmp(argv[i], "-nologo") == 0)) {
      /* supporting older -nologo variant */
      geomview_logo = FALSE;
    } else if (strcmp(argv[i], "-no-X") == 0) {
      use_X = FALSE;
    } else if (strcmp(argv[i], "-version") == 0) {
      special_flags_done++;
      error(Version);
    } else if (strcmp(argv[i],"-map-view-middle") == 0) {
      if (++i < argc) {
	if (sscanf((char *) argv[i], "%i", &coverage_display_center_longitude) == 1) {
	  if ((coverage_display_center_longitude < -180) ||
	      (coverage_display_center_longitude > 180)) {
	    coverage_display_center_longitude = 0;
	    error("longitude given for middle of map view is invalid.");
          }
	} else {
	  error("format is -map-view-middle <longitude>");
	  i--;
	}
      }
    } else if (strncmp(argv[i],"-",1) == 0) {
      unknown_parameters++;
    } else if (!script_filename) {
      if (NULL == (script_file = fopen(argv[i], "r"))) {
        error("couldn't find file passed as parameter.");
        skipped_filenames++;
      } else {
        script_filename = argv[i];
        fclose(script_file);
      }
    } else if (!more_filenames) {
      error("already found specified file. Ignoring any additional filenames.");
      more_filenames++;
    }
  }

  if (unknown_parameters) {
    if (unknown_parameters == 1) {
      error ("Unknown flag passed to SaVi.");
    } else {
      error ("Multiple unknown flags passed to SaVi.");
    }
    give_help = 1;
  }

  if (give_help) {
    error("supported command-line usage includes: \n"
          "savi [-large-map] [-map-view-middle <longitude>] [-no-X] [-debug] [filename]\n"
	  "  when SaVi is run standalone. Additional flags:\n"
	  "savi [-geomview] [-dynamic-texture-with-map] [-no-logo]\n"
	  "  become available when SaVi is run from Geomview.\n"
          "savi -version provides version information.\n"
          "savi -help shows this help information.");
  }

  if (special_flags_done && (special_flags_done == argc - (1 - use_X) - 1)) {
    /*
     * exit only if only help was requested. Relies on use_X being 0/1.
     * argc is 2 for ./savi -help only
     */
    exit(0);
  }

  if (script_filename) {
    first_filename = script_filename;
    /*
     * Only display filename if multiple filenames given means ambiguity.
     */
    if (skipped_filenames || more_filenames) {
      error("loading specified file:");
      error(first_filename);
    }
  }

  if (!geomview_module) {
    error("For 3D visualization, run from within Geomview.");
    if (!geomview_logo) {
      error("logo control is for Geomview.");
      geomview_logo = TRUE;
    }
    if (geomview_texture_with_map) {
      error("dynamic texture mapping only under Geomview.");
      geomview_dynamic_texture_flag = FALSE;
      geomview_texture_with_map = FALSE;
    }
  }
}
