#include <stdio.h>
#include <time.h>
#include <math.h>
#include "astro.h"
#include "ppm.h"
#include "size.h"

typedef struct
{
  double x, y, z;
}
Vec;

#define DOT(a,b) (((a.x)*(b.x))+ ((a.y)*(b.y))+ ((a.z)*(b.z)))

getsun (Vec * v, int i)
{
  time_t cctime;
  struct tm ctim;
  double jt;
  double sunra, sundec, sunrv, sunlong, subslong;
  double gt;
  double vlat, vlon, valt;

  time (&cctime);
  cctime += i;
  ctim = *gmtime (&cctime);
  jt = jtime (&ctim);
  sunpos (jt, FALSE, &sunra, &sundec, &sunrv, &sunlong);
  gt = gmst (jt);

  subslong = (gt * 15) - sunra;
  if (subslong > 180)
    {
      subslong = -(360 - subslong);
    }
  else if (subslong < -180)
    {
      subslong += 360;
    }


  vlat = dtr (sundec);
  vlon = dtr (subslong);
  valt = sunrv * SunSMAX - EarthRad;

  v->x = cos (vlat) * cos (-vlon);
  v->y = cos (vlat) * sin (-vlon);
  v->z = sin (vlat);

}


int
main (argc, argv)
     int argc;
     char *argv[];
{
  FILE *ifp, *afp = NULL;
  int argn;
  char *usage = "fish";

  pixel **ipixels, **dpixels, **opixels;
  pixval r, g, b, dr, dg, db, maxval;

#define DARKEN(r,g,b,w) r-=(((r)*w)/255), g-=(((g)*w)/255), b-=(((b)*w)/255)
#define SLEW(r,g,b,e,f,h,w) r=((r*(255-w))+(w*e))/255, g=((g*(255-w))+(w*f))/255, b=((b*(255-w))+(w*h))/255


  Vec sun, me;


  int x, y;
  int w, h;

  ppm_init (&argc, argv);

  argn = 1;

  while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0')
    {
      pm_usage (usage);
      ++argn;
    }

  ifp = pm_openr (argv[1]);
  ipixels = ppm_readppm (ifp, &w, &h, &maxval);
  pm_close (ifp);

  ifp = pm_openr (argv[2]);
  dpixels = ppm_readppm (ifp, &w, &h, &maxval);
  pm_close (ifp);

  opixels = ppm_allocarray (OWIDTH, OHEIGHT);
  maxval = 255;

  {
    int q = (int) (60.0 * atof (argv[3]));

    getsun (&sun, q);
  }

  for (y = 0; y < OHEIGHT; ++y)
    {
      double lat =
        (M_PI / 2.0) * ((double) ((OHEIGHT / 2) - y)) /
        ((double) (OHEIGHT / 2));

      double clat;

      clat = cos (lat);
      me.z = sin (lat);

      for (x = 0; x < OWIDTH; ++x)
        {
          double lon = M_PI *
            ((double) (x - (OWIDTH / 2))) / ((double) (OWIDTH / 2));

          double dot;
          me.x = cos (lon) * clat;
          me.y = sin (lon) * clat;

          dot = DOT (sun, me);

          r = PPM_GETR (ipixels[y][x]);
          g = PPM_GETG (ipixels[y][x]);
          b = PPM_GETB (ipixels[y][x]);

          dr = PPM_GETR (dpixels[y][x]);
          dg = PPM_GETG (dpixels[y][x]);
          db = PPM_GETB (dpixels[y][x]);

          if (dot < 0)
            {
              int idot = (int) (255.0 * tanh (-10.0 * dot));
              if (idot > 255)
                idot = 255;
              if (idot < 0)
                idot = 0;
              SLEW (r, g, b, dr, dg, db, idot);
            }

          PPM_ASSIGN (opixels[y][x], r, g, b);

        }
    }


  ppm_writeppm (stdout, opixels, OWIDTH, OHEIGHT, maxval, 0);
  pm_close (stdout);
  exit (0);
}
