/******************************************************************************
    Xplanet 0.43 - render an image of the earth into an X window
    Copyright (C) 1999 Hari Nair <hari@alumni.caltech.edu>

    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

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

#include <iostream.h>

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "auxfiles.h"
#include "image.h"
#include "options.h"
#include "planet.h"
#include "text.h"
#include "util.h"

double sunlon, sunlat, sundist; 

extern void sunpos (double &sunlon, double &sunlat, double &sundist, 
		    double T);
extern void moonpos (double &moonlon, double &moonlat, double &moondist,
		     double T);
extern void doAnimate (int argc, char **argv);

int 
main (int argc, char **argv)
{ 
  process_args (argc, argv);

  double T = jcentury (opts.time.tv_sec);
  sunpos (sunlon, sunlat, sundist, T);
  double eps = compute_obliquity (T);

  double alpha, delta;    // Solar right ascension & declination

  if (opts.body == 0)    // Earth
    {
      compute_ra_dec (sunlon, sunlat, alpha, delta, eps);
      //  set sunlon and sunlat to subsolar longitude/latitude
      sunlon = TWO_PI * (alpha - gmst (T, opts.time.tv_sec)) / 24;
      sunlat = delta;

      if (opts.localtime <= 24)
	{
	  double currgmt = (gmtime (&opts.time.tv_sec)->tm_hour 
			    + gmtime (&opts.time.tv_sec)->tm_min/60.
			    + gmtime (&opts.time.tv_sec)->tm_sec/3600.);
	  opts.obslon = (opts.localtime - currgmt) * M_PI / 12;
	  if (opts.obslon < 0 || opts.obslon > TWO_PI) {
	    opts.obslon = fmod (opts.obslon, TWO_PI);
	    if (opts.obslon < 0) opts.obslon += TWO_PI;
	  }
	}
    }
  else 
    {
      planet planet (T, opts.body);
      if (opts.body == 3)
	{
	  planet.helio.lon = sunlon + M_PI;
	  planet.helio.lat = sunlat;
	  planet.helio.dist = sundist;
	}
      else
	planet.calc_helio ();

      coordinates subsolar = planet.calc_coordinates (planet.helio, eps);
      sunlon = subsolar.lon;
      sunlat = subsolar.lat;

      if (flipped) opts.obslon *= -1;  

      if (opts.position == EARTHSIDE)
	{
	  if (opts.body == 3)
	    moonpos (planet.geo.lon, planet.geo.lat, planet.geo.dist, T);
	  else
	    planet.calc_geo ();

	  coordinates subearth = planet.calc_coordinates (planet.geo, eps);
	  opts.rotate += subearth.dist;       // position angle of north pole 
	  opts.obslon = subearth.lon;   
	  opts.obslon -= subearth.alpha;      // correction for light_time
	  opts.obslat = subearth.lat;
	}

      if (opts.localtime <= 24)
	{
	  opts.obslon = sunlon + opts.localtime * M_PI / 12 - M_PI;
	  if (fabs(opts.obslon) > TWO_PI)
	    opts.obslon = fmod (opts.obslon, TWO_PI);
	  if (opts.obslon < 0) opts.obslon += TWO_PI;
	}
    }

  if (opts.position == SUNREL) 
    {
      /* 
	 if either dellon or dellat is 999 user has explicitly set 
	 lon or lat
      */
      if (opts.dellon != 999) 
	{
	  opts.obslon = sunlon + opts.dellon;
	  if (fabs(opts.obslon) > TWO_PI) 
	    opts.obslon = fmod (opts.obslon, TWO_PI);
	  if (opts.obslon < 0) opts.obslon += TWO_PI;
	}
      if (opts.dellat != 999) 
	{
	  opts.obslat = sunlat + opts.dellat;
	  while(opts.obslat < -M_PI_2) opts.obslat =  -M_PI - opts.obslat;
	  while(opts.obslat > M_PI_2) opts.obslat = M_PI - opts.obslat;
	}
    }
  else if (opts.position == DAYSIDE) 
    {
      opts.obslon = sunlon;
      opts.obslat = sunlat;
    }
  else if (opts.position == NIGHTSIDE) 
    {
      opts.obslon = sunlon + M_PI;
      opts.obslat = -sunlat;
    }
  else if (opts.position == MOONSIDE)
    {
      double moonlon, moonlat, moondist;
      double moonalpha, moondelta;
      moonpos (moonlon, moonlat, moondist, T);
      compute_ra_dec (moonlon, moonlat, moonalpha, moondelta, eps);
      opts.obslon = TWO_PI * (moonalpha - gmst(T, opts.time.tv_sec)) / 24;
      opts.obslat = moondelta;
    }

  init_display ();
  read_image ();
  create_merc ();
  
  if (opts.display == ANIMATE) 
    doAnimate (argc, argv);
  else 
    {
      if (opts.mode == ORTHOGRAPHIC) create_ortho ();
      render_image ();
    }

  exit (EXIT_SUCCESS);
}  
