/********************************************************
               Intex-A ICATT File converter program.  
               Pat Carmichael, ARIM/NCAR, 6-25-04
               Written in GNU Emacs, GCC 3.3.1,
               Cygming special.
               For converting SAFS .jv files to .ict files
----------------------------------------------------------
    Versions:
               RC1:  Initial version, general functionality 
                     working, no date stamp, no R versioning.
               RC2:  Date stamp working, file name working,
                     program 100% functional for general use.
               RC3:  Testing of R# versioning system (to come)
               1.0:  Release
               1.1:  Fix bug
               1.2:  Fix revisioning system
               1.3:  Fix bug in revisioning system (change)
----------------------------------------------------------
    Stipulations on use:
               None, this program is released under the GNU Public liscense.
               No warranty, express or implied, or even of usability.
               You may include this program with any data set/etc,
               but you may NOT edit this header without explicit
               permission of Pat Carmichael.
----------------------------------------------------------
    Contact info:
               Pat Carmichael, ARIM/NCAR
               1800 Table Mesa Dr
               Boulder, CO, 80301
               lopoetve@ucar.edu, 303-497-1674.
*********************************************************/





#include<iostream>
#include<cstring>
#include<iomanip>
#include<fstream>
#include<cstdlib>
#include<time.h>

using namespace std;

//Program Variables
char test;
char *inputfile;
char *outputfile;
char *temp, *temp2;
ifstream ccin;
ofstream ccout;
char *input;
FILE *fp;
int linecount;
int generic;
int firsttime;

//File variables.  
char *date;
int data_interval;
float altitude, lat, lon;
char *geofile;
float freq, stime;
char *iname[2];
int inumber;
int tshift[2], wvloffset[2], cal_factor[2];
float gain65[2], gain76[2], gain87[2];
float tuv_albedo, tuv_O3, tuv_offset;
char *molecules[100];
float data[75][100000];
char *data_time;
int utctime[100000];
int missingdata = -9999;
int ulod = -7777;
int llod = -8888;
int scalefactor = 1;
string out;
int datalat[100000], datalong[100000], data_alt[100000];
float interval;
int rnum;
string rstring;
char *testvar;
int smode;

//constants
int BUFFERSIZE = 1000;
int LINESIZE = 950;

void bail();
void filechecks();
int parsetime(char *dtime);
string parsemonkey(char *thing);  //removes /n at end of string/
void printusage();  //prints usage when you mess up.  

int main(int argc, char *argv[])
{
  inputfile = (char *)calloc(BUFFERSIZE, sizeof(char));
  outputfile = (char *)calloc(BUFFERSIZE, sizeof(char));
  input = (char *)calloc(LINESIZE, sizeof(char));
  date = (char *)calloc(LINESIZE, sizeof(char));
  geofile = (char *)calloc(LINESIZE, sizeof(char));
  iname[0] = (char *)calloc(LINESIZE, sizeof(char));
  iname[1] = (char *)calloc(LINESIZE, sizeof(char));
  //iname2 = (char *)calloc(LINESIZE, sizeof(char));
  data_time = (char *)calloc(50, sizeof(char));

  if (argc < 3 || argc > 3) //this shouldn't be called
    {
      printusage();
      /*
      cout<<"Please enter input filename"<<endl;
      cout<<": ";
      cin>>inputfile;
      //Parse out the name of the file and add the appropriate section here.
      temp = (char *)calloc(BUFFERSIZE, sizeof(char));
      strcpy(outputfile, inputfile);
      //outputfile = strtok(temp, ".");
      strtok(outputfile, ".");
      strcat(outputfile, ".ict");
      cout<<outputfile<<endl;
      */
    }
  else //specified at start
    {
      testvar = argv[2];
      if (strcmp(testvar, "a")==0)
	{
	  cout<<"Preliminary Data"<<endl;
	  rnum = 0;
	  smode = 1;
	}
      else
	{
	  rnum = atoi(argv[2]);
	  smode = 0;
	}
      inputfile = argv[1];
      temp = (char *)calloc(BUFFERSIZE, sizeof(char));
      temp2 = (char *)calloc(BUFFERSIZE, sizeof(char));
      strcpy(temp, inputfile);
      strtok(temp, "_");  //now temp has date string only
      strcpy(temp2, "20");
      strcat(temp2, temp);

      cout<<"Date of original data: "<<temp2<<endl;
      strcpy(outputfile, "SAFS-jv_DC8_");
      strcat(outputfile, temp2);
      strcat(outputfile, "_R");
      strcat(outputfile, argv[2]);
      strcat(outputfile, ".ict");
      cout<<"Output file name: "<<outputfile<<endl;
      cout<<"Revision number: "<<rnum<<endl;
     
    }

  filechecks();  //CHECK ME SOME FILES!

  //THIS IS THE MAIN FILE INPUT LOOP.  THIS READS IN THE FILE INFORMATION, PROCESSES IT, AND THEN SPITS IT BACK OUT.  
  int headerlines; //total lines in header
  int variablecount;  //molecules and other stuff
  int commentcount;
  int totalcount;
  int moleculecount;  //number of molecules ONLY

  fp = fopen(inputfile, "r");
  fgets(input, 1900, fp);
  strtok(input, " ");
  cout<<"Lines in header: "<<input<<endl;
  headerlines = atoi(input);
  fgets(input, 1900, fp);
  strtok(input, " ");
  cout<<"Number of variables: "<<input<<endl;
  variablecount = atoi(input);
  fgets(input, 1900, fp);
  strtok(input, " ");
  cout<<"Number of comment lines: "<<input<<endl;
  commentcount = atoi(input);
  totalcount = commentcount + variablecount; //needed for the final file only

  moleculecount = variablecount - 3;
  for (int i = 0; i < variablecount; i++)
    fgets(input, 1900, fp);

  //char *temp;
  //Now we are to the comment lines.  These have a very specific order and purpose.  

  fgets(input, 1900, fp);  //project directory
  fgets(input, 1900, fp);  //Mission directory.
  
  fgets(input, 1900, fp);  //date
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  strcpy(date,temp);
  //Date now set.
  
  fgets(input, 1900, fp);  //start hour
  fgets(input, 1900, fp);  //total hours
  fgets(input, 1900, fp);  //mode
  
  fgets(input, 1900, fp);  //Altitude. 
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  altitude = atof(temp);

  fgets(input, 1900, fp);  //Latitude
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  lat = atof(temp);

  fgets(input, 1900, fp);  //Longitude
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  lon = atof(temp);

  fgets(input, 1900, fp);  //geofile
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  strcpy(geofile, temp);

  fgets(input, 1900, fp);  //freq
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  freq = atoi(temp);

  fgets(input, 1900, fp);  //scan time
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  stime = atoi(temp);

  fgets(input, 1900, fp);  //number of instruments.  
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  inumber = atoi(temp);

  for (int n = 0; n < inumber; n ++)
    {

      fgets(input, 1900, fp);  //instrument name
      temp = strtok(input, "=");
      temp = strtok(NULL, "\0");
      strcpy(iname[n], temp);
      strcat(iname[n], "\0");

      fgets(input, 1900, fp);  //time shift
      temp = strtok(input, "=");
      temp = strtok(NULL, "\0");
      tshift[n] = atoi(temp);

      fgets(input, 1900, fp);  //wavelegnth offset
      temp = strtok(input, "=");
      temp = strtok(NULL, "\0");
      wvloffset[n] = atoi(temp);

      fgets(input, 1900, fp);  //cal factor
      temp = strtok(input, "=");
      temp = strtok(NULL, "\0");
      cal_factor[n] = atoi(temp);
      
      fgets(input, 1900, fp);  //correction flags

      fgets(input, 1900, fp);  //gain65
      temp = strtok(input, "=");
      temp = strtok(NULL, "\0");
      gain65[n] = atof(temp);
      
      fgets(input, 1900, fp);  //gain76
      temp = strtok(input, "=");
      temp = strtok(NULL, "\0");
      gain76[n] = atof(temp);
      
      fgets(input, 1900, fp);  //gain87
      temp = strtok(input, "=");
      temp = strtok(NULL, "\0");
      gain87[n] = atof(temp);
    

      fgets(input, 1900, fp);  //compute new sensitivity
      fgets(input, 1900, fp);  //cal file
      fgets(input, 1900, fp);  //" "
      fgets(input, 1900, fp);  //" "
      fgets(input, 1900, fp);  //" "
      fgets(input, 1900, fp);  //" "
      fgets(input, 1900, fp);  //" "

    }//End of 2 instrument loop

  fgets(input, 1900, fp);  //tuv albedo
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  tuv_albedo = atof(temp);

  fgets(input, 1900, fp);  //tuv O3
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  tuv_O3 = atof(temp);

  fgets(input, 1900, fp);  //tuv offset
  temp = strtok(input, "=");
  temp = strtok(NULL, "\0");
  tuv_offset = atof(temp);

  

  //INPUT comment line.  Parse for variable names.
  fgets(input, 1900, fp);
  temp = strtok(input, " ");  //date
  temp = strtok(NULL, " ");  //time
  temp = strtok(NULL, " ");  //sza
  //Now we're to the variable names.  At this point, we should be able to parse them out.
  

  //Parse in the molecule names from the final comment line.
  for (int i = 0; i < moleculecount; i++)
    {
      temp = strtok(NULL, " ");
      cout<<"Molecule "<<i+1<<" "<<temp<<endl;
      molecules[i] = (char *)calloc(LINESIZE, sizeof(char));
      strcpy(molecules[i], temp);
    }


  linecount = 0;

  //start doing the lines of data.
  do 
    {
      fgets(input, 1900, fp);
      if(feof(fp))
	break;
      temp = strtok(input, " ");  //separate out the date
      temp = strtok(NULL, " ");  //separate time
      strcpy(data_time, temp);  //copy time over.
      temp = strtok(NULL, " ");  //separate sza
      

      for(int i = 0; i < moleculecount; i++)
	{
	  temp = strtok(NULL, " ");  
	  data[i][linecount] = atof(temp);
	  
	}//Parse the data for that time.  
      utctime[linecount] = parsetime(data_time);  //parsetime uses strtok, RUN IT LAST
      if (linecount == 0)
	{
	  firsttime = utctime[linecount];
	}
      else
	{
	  if (utctime[linecount] < firsttime)
	    {
	      utctime[linecount] += 86400;
	    }
	}
      linecount ++;
    }while(!feof(fp));
  //ENDING STUFF HERE
  cout<<"bye"<<endl;

  
  ////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////


  //All data has been read in and stored at this point.  Now it's time to start writing the final output file.  File is already open, stream loaded via ccout.

  ccout.open(outputfile);
  int specialcount;
  specialcount = 12 + moleculecount + (2) + (1 + 1) + (1 + 18 + rnum);
  //Base number of lines + number of molecules + stop and mid time + (1 + special counter) + (1 + normal)
  ccout<<specialcount<<" 1001"<<endl;
  ccout<<"Shetter, Rick"<<endl;
  ccout<<"ARIM/NCAR"<<endl;

  string inames, inames2;
  inames = iname[0];
  inames.erase(4);
  inames.erase(0,1);  //formatting output
  ccout<<"Photolysis Frequencies calculated from NCAR Scanning Actinic Flux Spectroradiometers."<<endl;

  ccout<<"NASA INTEX-NA MISSION 2004"<<endl;
  ccout<<"1 1"<<endl;
  
  string d1;
  char *d2;
  d1 = temp2;
  ccout<<d1[0]<<d1[1]<<d1[2]<<d1[3]<<" "<<d1[4]<<d1[5]<<" "<<d1[6]<<d1[7]<<" ";

  d2 = (char *)calloc(100, sizeof(char));
  time_t current_timestamp = time(NULL);
  struct tm current_time;
  localtime_r(&current_timestamp, &current_time);
  strftime(d2, 100, "%Y %m %d", &current_time);
  ccout<<d2<<endl;
  
  

  interval = freq + stime;
  ccout<<"0"<<endl;
  ccout<<"UTC Time in seconds"<<endl;
  int finalcount = moleculecount + 2;
  ccout<<finalcount<<endl;  //
  for(int i = 0; i < finalcount; i++)
    ccout<<scalefactor<<" ";
  ccout<<endl;

  for(int i = 0; i < finalcount; i++)
    ccout<<missingdata<<" ";
  ccout<<endl;

  ccout<<"stop_time"<<endl;
  ccout<<"mid_time";
  for(int i = 0; i < moleculecount; i++)
    {
      ccout<<endl;
      ccout<<molecules[i];
    }
  ccout<<"1"<<endl;  //this is the number of special comment lines.  Any notable changes will have to be hand entered. 
  //ccout<<"Geofile with lat/long/pressure: "<<geofile;//<<endl; 
  ccout<<"This is preliminary data, for final data release date, contact the PI"<<endl;
  ccout<<18 + rnum<<endl;  //number of normal comments.  this is hard coded.



  //THIS IS THE NORMAL COMMENTING SECTOR.  THESE MUST BE HERE
  ccout<<"PI_CONTACT_INFO: "<<"303-497-1480, 1850 Table Mesa Dr, Boulder, CO, 80305, shetter@ucar.edu"<<endl;
  ccout<<"PLATFORM: "<<"NASA DRYDEN DC-8"<<endl;
  ccout<<"LOCATION: "<<"Lat/long/etc is in NAV_dc8_"<<d1[0]<<d1[1]<<d1[2]<<d1[3]<<d1[4]<<d1[5]<<d1[6]<<d1[7]<<"_ra.ict"<<endl;
  out = parsemonkey(geofile);
  ccout<<"ASSOCIATED_DATA: "<<"See project file for this flight"<<endl;
  ccout<<"INSTRUMENT_INFO: "<<"Scanning actinic flux spectroradiometer with PMT detector"<<endl;
  ccout<<"DATA_INFO: "<<"This file is preliminary"<<endl;
  ccout<<"UNCERTAINTY: "<<"N/A"<<endl;
  ccout<<"ULOD_FLAG: "<<ulod<<endl;
  ccout<<"ULOD_VALUE: "<<"N/A"<<endl;
  ccout<<"LLOD_FLAG: "<<llod<<endl;
  ccout<<"LLOD_VALUE: "<<"N/A"<<endl;
  ccout<<"DM_CONTACT_INFO: "<<"a.a.acknan@larc.nasa.gov"<<endl;
  ccout<<"PROJECT_INFO: "<<"arim.ucar.edu"<<endl;
  ccout<<"STIPULATIONS_ON_USE: "<<"Use of this data requires PRIOR OK from the PI"<<endl;
  ccout<<"OTHER_COMMENTS: "<<"None"<<endl;
  if (smode == 0)
    {
      ccout<<"REVISION: "<<"R"<<rnum<<endl; 
      ccout<<"R0: NONE"<<endl;
    }
  if (smode == 1)
    {
      ccout<<"REVISION: "<<"Ra"<<endl;
      ccout<<"Ra: NONE"<<endl;
    }
  if (rnum > 0)
    {
      for (int i = 1; i <= rnum; i++)
	{
	  cout<<"Please enter comments for revision R"<<i<<endl;
	  cout<<": ";
	  getline(cin, rstring);
	  ccout<<"R"<<i<<": "<<rstring<<endl;
	}
    } 


  int counter = 1;
  ccout<<"UTC_TIME";
  ccout<<" stop_time mid_time";
  //Dump molecule and variable names here.  
  for (int i = 0; i < moleculecount; i++)
    {
      if (i == moleculecount - 4)
	ccout<<" "<<parsemonkey(molecules[i]);
      else
	ccout<<" "<<molecules[i];
    }

  
  //Data loop.  This dumps out the data section of the files.  
  do 
    {
    restart:
      if(counter > 1 && utctime[counter - 1] == utctime[counter])
	{
	  counter++;  //fix for duplicate time sigs
	  goto restart;
	}
      ccout<<utctime[counter];
      ccout<<" "<<utctime[counter] + stime - .5;
      ccout<<" "<<utctime[counter] + stime/2;
      
      for(int i = 0; i < variablecount - 3; i++)
	{  
	  ccout<<" "<<data[i][counter];
	}//Parse the data for that time.
      ccout<<endl;
      counter++;

    }while(counter < linecount);  //to the end of the file listing

  //This is the ending section.  Closes all files, etc and exits the program.  
  fclose(fp);
  ccin.close();
  ccout.close();
  return EXIT_SUCCESS;
}

void bail()
{
  ccout.close();
  ccin.close();
  exit(1);
}

void filechecks()
{
  ccin.open(outputfile);
  if (!ccin.fail())
    {
      cout<<"Output file exists.  Overwriting not enabled."<<endl;
      bail();
    }
  ccin.close();
  if (fopen(inputfile, "r") == NULL)
    {
      cout<<"Input file does NOT exist.  Exiting"<<endl;
      bail();
   } 
}

int parsetime(char *dtime)
{
  char *working;
  int rtime;
  working = strtok(dtime, ":");
  rtime = atoi(working) * 3600;
  working = strtok(NULL, ":");
  rtime = rtime + atoi(working) * 60;
  working = strtok(NULL, "\0");
  rtime = rtime + atoi(working);
  return rtime;  //atoi(dtime);
}

string parsemonkey(char *thing)
{
  string t;
  int point;
  point = strlen(thing) - 2;
  t = thing;
  t.erase(point);
  return t;
}

void printusage()
{
  cout<<"Usage: ";
  cout<<"converter INPUTFILE #"<<endl;
  cout<<"Where INPUTFILE is the .jv file, and # is the revision number you would like to have for this data file"<<endl;
  bail();
}
