
/*
	Dec 6, 2004: added capability to re-enter bad filenames
	when running interactively. Changed open_input_ff and
	open_output_ff in calfunc02.cpp
	Version is 041206.
*/

/*
	June 19, 2004; changed units to nT as in cal02_a, 04-05-25..
	Also changed Time units in cal_mag.h to Counts, for Adrian.
	Version is 040619.
*/

/* Jan 19, 2004; made changes in calfunc02.cpp and calfunc02.h */
/* Joyce Wolf, Dec. 7, 2003
   Changes:
   (1) Linked with EPOCH=1958 TIME_IGPP and FF_IGPP (12/4/03).
   (2) Replaced byte-swapping procedures by call to FFSwapRecords.
   (3) Column descriptors are copied with ff_hget and ff_hput.


/* Joyce Wolf, June 5, 2001
   CAL02 is a modified version of CAL01. 
	Interactive input parameters are the same as in CAL01.
	CAL02 should be linked with calfunc02.obj instead of 
		CalFunc01.obj.
  Changes:
  (1) Fixed bugs with CDATE and FIRST TIME and LAST TIME in
		output flatfile header file.
  (2) If a data time is later than the StopTime of the last
		record in the Calibration File, data will continue
		to be calibrated using the values from the last
		calibration record, and a warning will be added to
		the output flatfile header file.  CAL01 looped forever.
  (3) If read or write errors occur on the flatfile data files,
		error messages are now written to the report file 
		before the program exits.
  (4) The field CoordID, bits 7-0 of the status word VHMStatus
		or FGMStatus. is now set to hex 03 if the data point
		was calibrated. CAL01 left this field unchanged.
  (5) The field CalibID, bits 15-8 of the status word VHMStatus
		or FGMStatus, is now set to the calibration record
		number mod 256. CAL01 set this field to hex 40.
*/
#include <fstream.h>
#include <iostream.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <time.h>

extern "C" {
#ifndef FF_IGPP
#include "..\ff_user\time_igpp.h"
#include "..\ff_user\ff_igpp.h"
#endif
}
// Add ..\ff_user\ff_igpp_mod.obj to cal02 project files
// also ..\ff_user\time_igpp_mod2.obj

#ifndef CAL_MAG
#include "cal_mag.h"
#endif

#ifndef CALFUNC02
#include "calfunc02.h"
#endif


#define READ_OK  1
#define WRITE_OK 1 

extern EPOCH epoch58 = Y1958; 
////////////////////////////////////////////////////////////////////////////

	void main ()  {


/* No, not OldStyle.; want to write EPOCH=Y1958 
	extern int ff_oldstyle;
	FFOldStyle();
*/

//Variable declarations
	int ncopied = 0;
	int swap_in; //non-zero to swap bytes on input flatfile
	int swap_out; // non-zero to swap bytes on output file
	double time_first, time_last;
	int irange;
	int lastrange = -1;
	int sensor;
	char csensor[2][4] = {"FGM", "VHM"};
	char cswap[2][4] = {"OFF", "ON "};
	char atime[32]; //Storage for time string
	MAGDATA data_rec;
	int tryagain = _isatty(_fileno(stdin));
		/* tryagain = 1 if stdin is device, 0 if file */
	int ntries = 0; /* No. of times report filename entered */

//Report file
	FILE *rpt = NULL;  
	char report_name[256];
	char def_report[256] = "";  //default

//Input Flatfile
	FF_ID *idin;
	char in_name[256];
//	char def_input[256] = "";  //default

//Output Flatfile
	FF_ID *idout;
	char out_name[256];
	char def_output[256] = "";

//Flat File Name pointer and Calibration instance
	FF_ID *Cal_id = NULL;
	VHM_CAL cal_rec;
	VHM_CAL *pcal_rec;
	pcal_rec = &cal_rec;

//Get filenames and input parameters

	cout << "Cal02 Ver 041206" << endl << endl;


	cout << endl << "Input FlatFile:" << endl;
	cout << "Enter full flatfile name: ";
	cin.getline (in_name, 255);
	idin = open_input_ff (in_name);
	if (idin == NULL && tryagain) {
		cout << "Could not open Input " << in_name << endl << "Exit" << endl;
		exit(1);
	}


	cout << endl << "Enter 0 if input is FGM, 1 if VHM: ";
	cin >> sensor;

	cout << endl << "Enter 1 to SWAP BYTES on INPUT flatfile, 0 not to swap: ";
	cin >> swap_in;

	cout << endl << "Output FlatFile,";
	strcpy (def_output, in_name);
	strcat (def_output, "_C");
	cout << "Default is "<< def_output << endl;
	cout << "Enter full flatfile name: ";
	cin.get(); // Necessary to clear buffer between numeric and string entries
	cin.getline (out_name, 255);
	if (strlen(out_name) == 0)  
		strcpy (out_name, def_output);

	cout << endl << "Enter 1 to SWAP BYTES on OUTPUT flatfile, 0 not to swap: ";
	cin >> swap_out;

	cout << endl;
	strcpy (def_report, out_name);
	strcat (def_report, "_Rpt.txt");
	cout << "Default Report File: " << def_report << endl;
	cout << "Enter Report filename: ";
	cin.get(); // Necessary to clear buffer between numeric and string entries
	cin.getline (report_name, 255);
	if (strlen(report_name) == 0)  
		strcpy (report_name, def_report);
	rpt = fopen(report_name, "w");
	while (rpt == NULL && tryagain && ntries < 7)  {
		cout << "Cannot open " << report_name << endl;
		cout << " Enter 1 to try again or 0 to exit: ";
		cin  >> tryagain;
		if (tryagain)  {
			cout << "Enter Report filename: ";
			cin.get();
			cin.getline(report_name, 255);
			rpt = fopen(report_name, "w");
			ntries ++;
		} /* end if */
	} /* end while */
	if (rpt != NULL){
		cout << "Opened Report File " << report_name << endl;
		fprintf (rpt, "CAL02 ver041206 Report\n\n");}
	else {
		cout << "Could not open " << report_name << endl;
		exit(1);
	}

//Start
	if (idin == NULL) {
		cout << "Could not open Input " << in_name << endl << "Exit" << endl;
		fprintf (rpt, "Could not open Input %s\nExit", in_name);
		exit(1);
	}
	
	printf("\nOpened Input Flatfile %s\n", in_name); 
	fprintf (rpt, "Opened Input Flatfile: %s \n", in_name);
	fprintf (rpt, "Sensor: %s \n", csensor[sensor]);
	fprintf (rpt, "Input Byte Swapping is %s \n\n", cswap[swap_in]);
	
	int ncols = get_ncols (idin);
	int recl = get_recl(idin);
	cout << "NCOLS " << ncols << "  RECL " << recl << endl;
	idout = open_output_ff (out_name, ncols, recl);
	if (idout == NULL) {
		cout << "Could not open Output " << out_name << endl << "Exit" << endl;
		fprintf(rpt, "Could not open Output %s\nExit", out_name);
		exit(1);
	}
	fprintf (rpt, "Opened Output Flatfile %s  \n", out_name);
	fprintf (rpt, "Output Byte Swapping is %s \n\n", cswap[swap_out]);

	ncopied = copy_col_desc (idin, idout);
	if (ncopied != ncols)
		cout << "Error, " << ncopied << "Col Desc's copied\n";

	int nrecs = get_nrows (idin);
	int nwrit = 0;
	int notcal = 0;
	int ncal = 0;

//Loop
	int check_in =0;
	int check_out = 0;
	for (int n=1; n<= nrecs; n++)  {
		check_in = get_magdata (idin, &data_rec, swap_in);
		if (check_in != READ_OK)  {
			fprintf (rpt,"ERROR on input data file at Rec %d\nExit.", n);
			printf ("ERROR on input data file at Rec %d\nExit.", n);
			exit(1);
		}
		irange = get_range (&data_rec, sensor);
		if (is_valid(&data_rec, sensor)){
			Cal_id = calibrate (Cal_id, pcal_rec, &data_rec, irange);
			if (Cal_id == NULL) {
				fprintf(rpt, "Could not open Calibration File\nExit ");
				printf ("Could not open Calibration File\nExit ");
				exit(1);
			}
			ncal++;
			if (ncal == 1) fprintf(rpt, "Calibration File = %s \n\n",
				Cal_id->ffd->name);
		}
		else {
			notcal++;
		}
		if (nwrit == 0)   time_first = data_rec.time;
		time_last = data_rec.time;
		check_out = put_magdata (idout, &data_rec, swap_out);
		if (check_out != WRITE_OK)  {
			fprintf (rpt,"ERROR on Output data file at Rec %d\nExit.", nwrit);
			printf ("ERROR on Output data file at Rec %d\nExit.", nwrit);
			exit(1);
		}
//	numflushed = flushall();
		nwrit++;
		if (irange != lastrange) 
			fprintf(rpt, "Rec %8d,  Range %8d \n", nwrit, irange);
		lastrange = irange;
	}

//Finish
	fprintf(rpt, "Rec %8d,  Range %8d \n", nwrit, irange);
	cout << "Data Recs Written = " << nwrit << endl;
	fprintf(rpt, "\nData Recs Written = %d \n", nwrit);
	fprintf(rpt, "Data Recs Calibrated = %d \n", ncal);
	cout << "Invalid Data Recs Not Calibrated = " << notcal << endl;
	fprintf(rpt, "Invalid Data Recs Not Calibrated = %d \n", notcal);

	copy_info_abs (idin, idout, time_first, time_last);

	char comment[72] = "#########";
	for (n=0; n<8; n++) {
		if (n==1) strcpy (comment, "Calibration: Cal02 v041206");
		if (n==2) {
			strcpy (comment, "Input Flatfile = ");
			strcat (comment, in_name);
		}
		if (n==3) {
			strcpy (comment, "Sensor = ");
			strcat (comment, csensor[sensor]);
		}
		if (n==4) {
			strcpy (comment, "Calibration Source File = ");
			strcat (comment, Cal_id->ffd->name);
		}
		if (n==5) {
			strcpy (comment, "Output Byte Swapping was ");
			strcat (comment, cswap[swap_out]);
		}
		if (n==6) {
			sprintf (comment, "Number of records not calibrated = %d", notcal);
				}
		if (n==7) 
			strcpy (comment, "Output Times are left unchanged");

		if (ff_cput(idout->ffh, &comment[0]) < 0)  {
		cout << "Error from ff_cput on Output flatfile.\nExit.\n"; 
		exit(1);}
	}
//Warn if data time is later than calibration stop time
	if (time_last > pcal_rec->dStopTime)  {
		t_con_c (pcal_rec->dStopTime, atime);
		sprintf (comment,
			"WARNING: Calibration Stop Time = %s", atime);
		if (ff_cput(idout->ffh, &comment[0]) < 0)  
			cout << "Error from ff_cput on Output flatfile.\nExit.\n";
		fprintf (rpt, "WARNING: Calibration Stop Time = %s", atime);
	}


	ff_close (idin);
	ff_close (idout);
	cout << "Flatfiles Closed" << endl;
	fprintf(rpt, "\nFlatfiles Closed \n");
	fprintf(rpt, "End of CAL02 Report.\n");

	cout << "Press Enter to Exit";
	cin.getline (in_name,255);

	
	}  // End main 
