/******************************************************************************
* Copyright 1996-2013 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All Rights Reserved.
******************************************************************************/

using System;
using System.Runtime.InteropServices;
using CDF;

public class Qst2cTT2000 : CDFAPIs {

unsafe public static void Main() {
void* id = (void*) 0;
/******************************************************************************
* Display title.
******************************************************************************/

Console.WriteLine("Testing C# interface for CDF_TT2000 ...");

int status;
int varnum;
int variance = VARY;
int[] dimSizes = new int[1] {0}, dimVary = new int[1] {VARY};
int[] indices = new int[1] {0}, counts = new int[1] {1}, intervals = new int[1] {1};

long[] tt2000 = new long[8], mm = new long[8];
double year1=2008, month1=12, day1=31, hour1=23, minute1=59, second1=57, 
       msec1=100, usec1=200, nsec1=300;
double year=2008, month=12, day=31, hour=23, minute=59, second=57, 
       msec=100, usec=200, nsec=300;
double yearOut, monthOut, dayOut, hourOut, minuteOut, secondOut, msecOut, 
       usecOut, nsecOut;
long   yearlOut, monthlOut, daylOut, hourlOut, minutelOut, secondlOut, mseclOut, 
       useclOut, nseclOut;
int  ix;
string tt2000String;

long[,] int8 = new long[3,2];
long[,] int8o = new long[3,2];
long nn;

/******************************************************************************
* Create CDF.
******************************************************************************/
try {     
  status = CDFcreate ("TEST", 0, dimSizes, IBMPC_ENCODING, ROW_MAJOR, &id);
} catch (CDFException ex) {
  status = ex.CDFgetCurrentStatus();
  if (status < CDF_OK) {
    if (status == CDF_EXISTS) { 
      status = CDFopen ("TEST", &id);
      if (status < CDF_OK) QuitCDF ("1.0", status);

      status = CDFdeleteCDF (id);
      if (status < CDF_OK) QuitCDF ("1.1", status);
      status = CDFcreate ("TEST", 0, dimSizes, IBMPC_ENCODING, ROW_MAJOR, &id);
      if (status < CDF_OK) QuitCDF ("6.0", status);
    }
  }
}
/******************************************************************************
* Create variables.
******************************************************************************/
try {
status = CDFcreatezVar(id, "myTT2000", CDF_TIME_TT2000, 1,
		       0, dimSizes, variance, dimVary, &varnum);
if (status < CDF_OK) QuitCDF ("7.0", status);

dimSizes[0] = 2;

status = CDFcreatezVar(id, "myINT8", CDF_INT8, 1,
                       1, dimSizes, variance, dimVary, &varnum);
if (status < CDF_OK) QuitCDF ("7.1", status);

/******************************************************************************
* PUT to variables.
******************************************************************************/

tt2000[0] = computeTT2000(year, month, day, hour, minute, second,
                          msec, usec, nsec);
if (tt2000[0] == ILLEGAL_TT2000_VALUE) QuitCDF ("9.0", TT2000_TIME_ERROR);
for (ix = 1; ix < 8; ++ix) 
  tt2000[ix] = tt2000[0] + (long) ix*1000000000;

varnum = CDFgetVarNum (id, "myTT2000");
fixed(void* ptt2000 = tt2000) {
  status = CDFhyperPutzVarData (id, varnum, 0, 8, 1, indices, counts,
  			        intervals, ptt2000);
}
if (status < CDF_OK) QuitCDF ("10.0", status);

/******************************************************************************
* HyperGET from variables.
******************************************************************************/
fixed (void* pmm = mm) {
  status = CDFhyperGetzVarData (id, varnum, 0, 8, 1, indices, counts,
		                intervals, pmm);
}
if (status < CDF_OK) QuitCDF ("11.0", status);

for (ix= 0; ix < 8; ix++) {
  TT2000breakdown (mm[ix], &yearOut, &monthOut, &dayOut,
                   &hourOut, &minuteOut, &secondOut, &msecOut,
                   &usecOut, &nsecOut);
  TT2000breakdown (mm[ix], &yearlOut, &monthlOut, &daylOut,
                   &hourlOut, &minutelOut, &secondlOut, &mseclOut,
                   &useclOut, &nseclOut);
   if (year != yearOut) QuitCDF("11.1", status);
   if (month != monthOut) QuitCDF("11.2", status);
   if (day != dayOut) QuitCDF("11.3", status);
   if (hour != hourOut) QuitCDF("11.4", status);
   if (minute != minuteOut) QuitCDF("11.5", status);
   if (second != secondOut) QuitCDF("11.6", status);
   if (msec != msecOut) QuitCDF("11.7", status);
   if (usec != usecOut) QuitCDF("11.8", status);
   if (nsec != nsecOut) QuitCDF("11.9", status);
   if ((long)year != yearlOut) QuitCDF("11.1a", status);
   if ((long)month != monthlOut) QuitCDF("11.2a", status);
   if ((long)day != daylOut) QuitCDF("11.3a", status);
   if ((long)hour != hourlOut) QuitCDF("11.4a", status);
   if ((long)minute != minutelOut) QuitCDF("11.5a", status);
   if ((long)second != secondlOut) QuitCDF("11.6a", status);
   if ((long)msec != mseclOut) QuitCDF("11.7a", status);
   if ((long)usec != useclOut) QuitCDF("11.8a", status);
   if ((long)nsec != nseclOut) QuitCDF("11.9a", status);
   ++second;
   if (second > 60) {
     year = 2009;     
     month = 1; 
     day = 1;
     hour = 0;
     minute = 0;
     second = 0;
   }
}

varnum = CDFgetVarNum (id, "myINT8");
nn = 88888888888L;
for (ix = 0; ix < 3; ++ix) {
  int8[ix,0] = nn;
  int8[ix,1] = -nn;
  ++nn;
}

counts[0] = 2;
fixed(void* pint8 =int8) {
  status = CDFhyperPutzVarData (id, varnum, 0, 3, 1, indices, counts,
  		  	        intervals, pint8);
}
if (status < CDF_OK) QuitCDF ("12.0", status);

fixed(void* pint8o = int8o) {
  status = CDFhyperGetzVarData (id, varnum, 0, 3, 1, indices, counts,
		                intervals, pint8o);
}
if (status < CDF_OK) QuitCDF ("13.0", status);

nn = 88888888888L;
for (ix = 0; ix < 3; ++ix) {
  if (int8o[ix,0] != nn) QuitCDF ("14.0", status);;
  if (int8o[ix,1] != -nn) QuitCDF ("14.1", status);; 
  ++nn; 
}                         

/******************************************************************************
* Close CDF.
******************************************************************************/

status = CDFcloseCDF (id);
if (status < CDF_OK) QuitCDF ("26.2", status);

/******************************************************************************
* Re-open the CDF.
******************************************************************************/

status = CDFopen ("TEST", &id);

if (status < CDF_OK) QuitCDF ("30.1", status);
varnum = CDFvarNum (id, "myTT2000");
if (varnum < CDF_OK) QuitCDF ("31.1", status);
/******************************************************************************
* HyperGET from variables.
******************************************************************************/
fixed (void* pmm = mm) {
  status = CDFhyperGetzVarData (id, varnum, 0, 8, 1, indices, counts,
			        intervals, pmm);
}
if (status < CDF_OK) QuitCDF ("32.1", status);

for (ix= 0; ix < 8; ix++) {
//  TT2000breakdown (mm[ix], &yearOut, &monthOut, &dayOut,
//                   &hourOut, &minuteOut, &secondOut, &msecOut,
//                   &usecOut, &nsecOut);
//  encodeTT2000 (mm[ix], out tt2000String, 3);
  TT2000breakdown (mm[ix], out yearOut, out monthOut, out dayOut,
                   out hourOut, out minuteOut, out secondOut, out msecOut,
                   out usecOut, out nsecOut);
  encodeTT2000 (mm[ix], out tt2000String, 3);
  Console.WriteLine ("TT2000: "+mm[ix]+" -> "+tt2000String);
   if (year1 != yearOut) QuitCDF("33.1", status);
   if (month1 != monthOut) QuitCDF("33.2", status);
   if (day1 != dayOut) QuitCDF("33.3", status);
   if (hour1 != hourOut) QuitCDF("33.4", status);
   if (minute1 != minuteOut) QuitCDF("33.5", status);
   if (second1 != secondOut) QuitCDF("33.6", status);
   if (msec1 != msecOut) QuitCDF("33.7", status);
   if (usec1 != usecOut) QuitCDF("33.8", status);
   if (nsec1 != nsecOut) QuitCDF("33.9", status);
   ++second1;
   if (second1 > 60) {
     year1 += 1;     
     month1 = 1; 
     day1 = 1;
     hour1 = 0;
     minute1 = 0;
     second1 = 0;
   }
}

/******************************************************************************
* Close CDF.
******************************************************************************/

status = CDFcloseCDF (id);
if (status < CDF_OK) QuitCDF ("26.2", status);


/******************************************************************************
* Test for invalid time.
******************************************************************************/

String dummy;
encodeTT2000(DUMMY_TT2000_VALUE, out dummy);
Console.WriteLine(""+DUMMY_TT2000_VALUE+": is "+dummy);
long att2000 = parseTT2000("9999-12-31T23:59:59.999999999");
Console.WriteLine("9999-12-31T23:59:59.999999999 is: "+att2000);


} catch (CDFException ex) {
  Console.WriteLine("Error: "+ex);
}

}


/******************************************************************************
* QuitCDF.
******************************************************************************/

unsafe static void QuitCDF (string where, int status)
{
  Console.WriteLine("Aborting at "+where);
  string text;
  if (status < CDF_OK) {
    CDFgetStatusText (status, out text);
    Console.WriteLine ("Error..."+text);
  }
}

}


