/********************************************************************
 * COPYRIGHT:
 * Copyright (c) 1996-2008, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

/* Test CalendarAstronomer for C++ */

#include "unicode/utypes.h"
#include "string.h"
#include "unicode/locid.h"

#if !UCONFIG_NO_FORMATTING

#include "astro.h"
#include "astrotst.h"
#include "gregoimp.h" // for Math
#include "unicode/simpletz.h"


static const double DAY_MS = 24.*60.*60.*1000.;

#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break

AstroTest::AstroTest(): astro(NULL), gc(NULL) {
}

void AstroTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    if (exec) logln("TestSuite AstroTest");
    switch (index) {
      // CASE(0,FooTest);
      CASE(0,TestSolarLongitude);
      CASE(1,TestLunarPosition);
      CASE(2,TestCoordinates);
      CASE(3,TestCoverage);
      CASE(4,TestSunriseTimes);
      CASE(5,TestBasics);
      CASE(6,TestMoonAge);
    default: name = ""; break;
    }
}

#undef CASE

#define ASSERT_OK(x)   if(U_FAILURE(x)) { errln("%s:%d: %s\n", __FILE__, __LINE__, u_errorName(x)); return; }


void AstroTest::initAstro(UErrorCode &status) {
  if(U_FAILURE(status)) return;

  if((astro != NULL) || (gc != NULL)) {
    errln("Err: initAstro() called twice!");
    closeAstro(status);
    if(U_SUCCESS(status)) {
      status = U_INTERNAL_PROGRAM_ERROR;
    }
  }

  if(U_FAILURE(status)) return;

  astro = new CalendarAstronomer();
  gc = Calendar::createInstance(TimeZone::getGMT()->clone(), status);
}

void AstroTest::closeAstro(UErrorCode &/*status*/) {
  if(astro != NULL) {
    delete astro;
    astro = NULL;
  }
  if(gc != NULL) {
    delete gc;
    gc = NULL;
  }
}

void AstroTest::TestSolarLongitude(void) {
  UErrorCode status = U_ZERO_ERROR;
  initAstro(status);
  ASSERT_OK(status);

  struct {
    int32_t d[5]; double f ;
  } tests[] = {
    { { 1980, 7, 27, 0, 00 },  124.114347 },
    { { 1988, 7, 27, 00, 00 },  124.187732 }
  };

  logln("");
  for (uint32_t i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
    gc->clear();
    gc->set(tests[i].d[0], tests[i].d[1]-1, tests[i].d[2], tests[i].d[3], tests[i].d[4]);

    astro->setDate(gc->getTime(status));

    double longitude = astro->getSunLongitude();
    //longitude = 0;
    CalendarAstronomer::Equatorial result;
    astro->getSunPosition(result);
    logln((UnicodeString)"Sun position is " + result.toString() + (UnicodeString)";  " /* + result.toHmsString()*/ + " Sun longitude is " + longitude );
  }
  closeAstro(status);
  ASSERT_OK(status);
}



void AstroTest::TestLunarPosition(void) {
  UErrorCode status = U_ZERO_ERROR;
  initAstro(status);
  ASSERT_OK(status);

  static const double tests[][7] = {
    { 1979, 2, 26, 16, 00,  0, 0 }
  };
  logln("");

  for (int32_t i = 0; i < (int32_t)(sizeof(tests)/sizeof(tests[0])); i++) {
    gc->clear();
    gc->set((int32_t)tests[i][0], (int32_t)tests[i][1]-1, (int32_t)tests[i][2], (int32_t)tests[i][3], (int32_t)tests[i][4]);
    astro->setDate(gc->getTime(status));

    const CalendarAstronomer::Equatorial& result = astro->getMoonPosition();
    logln((UnicodeString)"Moon position is " + result.toString() + (UnicodeString)";  " /* + result->toHmsString()*/);
  }

  closeAstro(status);
  ASSERT_OK(status);
}



void AstroTest::TestCoordinates(void) {
  UErrorCode status = U_ZERO_ERROR;
  initAstro(status);
  ASSERT_OK(status);

  CalendarAstronomer::Equatorial result;
  astro->eclipticToEquatorial(result, 139.686111 * CalendarAstronomer::PI / 180.0, 4.875278* CalendarAstronomer::PI / 180.0);
  logln((UnicodeString)"result is " + result.toString() + (UnicodeString)";  " /* + result.toHmsString()*/ );
  closeAstro(status);
  ASSERT_OK(status);
}



void AstroTest::TestCoverage(void) {
  UErrorCode status = U_ZERO_ERROR;
  initAstro(status);
  ASSERT_OK(status);
  GregorianCalendar *cal = new GregorianCalendar(1958, UCAL_AUGUST, 15,status);
  UDate then = cal->getTime(status);
  CalendarAstronomer *myastro = new CalendarAstronomer(then);
  ASSERT_OK(status);

  //Latitude:  34 degrees 05' North
  //Longitude:  118 degrees 22' West
  double laLat = 34 + 5./60, laLong = 360 - (118 + 22./60);
  CalendarAstronomer *myastro2 = new CalendarAstronomer(laLong, laLat);

  double eclLat = laLat * CalendarAstronomer::PI / 360;
  double eclLong = laLong * CalendarAstronomer::PI / 360;

  CalendarAstronomer::Ecliptic ecl(eclLat, eclLong);
  CalendarAstronomer::Equatorial eq;
  CalendarAstronomer::Horizon hor;

  logln("ecliptic: " + ecl.toString());
  CalendarAstronomer *myastro3 = new CalendarAstronomer();
  myastro3->setJulianDay((4713 + 2000) * 365.25);

  CalendarAstronomer *astronomers[] = {
    myastro, myastro2, myastro3, myastro2 // check cache
  };

  for (uint32_t i = 0; i < sizeof(astronomers)/sizeof(astronomers[0]); ++i) {
    CalendarAstronomer *anAstro = astronomers[i];

    //logln("astro: " + astro);
    logln((UnicodeString)"   date: " + anAstro->getTime());
    logln((UnicodeString)"   cent: " + anAstro->getJulianCentury());
    logln((UnicodeString)"   gw sidereal: " + anAstro->getGreenwichSidereal());
    logln((UnicodeString)"   loc sidereal: " + anAstro->getLocalSidereal());
    logln((UnicodeString)"   equ ecl: " + (anAstro->eclipticToEquatorial(eq,ecl)).toString());
    logln((UnicodeString)"   equ long: " + (anAstro->eclipticToEquatorial(eq, eclLong)).toString());
    logln((UnicodeString)"   horiz: " + (anAstro->eclipticToHorizon(hor, eclLong)).toString());
    logln((UnicodeString)"   sunrise: " + (anAstro->getSunRiseSet(TRUE)));
    logln((UnicodeString)"   sunset: " + (anAstro->getSunRiseSet(FALSE)));
    logln((UnicodeString)"   moon phase: " + anAstro->getMoonPhase());
    logln((UnicodeString)"   moonrise: " + (anAstro->getMoonRiseSet(TRUE)));
    logln((UnicodeString)"   moonset: " + (anAstro->getMoonRiseSet(FALSE)));
    logln((UnicodeString)"   prev summer solstice: " + (anAstro->getSunTime(CalendarAstronomer::SUMMER_SOLSTICE(), FALSE)));
    logln((UnicodeString)"   next summer solstice: " + (anAstro->getSunTime(CalendarAstronomer::SUMMER_SOLSTICE(), TRUE)));
    logln((UnicodeString)"   prev full moon: " + (anAstro->getMoonTime(CalendarAstronomer::FULL_MOON(), FALSE)));
    logln((UnicodeString)"   next full moon: " + (anAstro->getMoonTime(CalendarAstronomer::FULL_MOON(), TRUE)));
  }

  delete myastro2;
  delete myastro3;
  delete myastro;
  delete cal;

  closeAstro(status);
  ASSERT_OK(status);
}



void AstroTest::TestSunriseTimes(void) {
  UErrorCode status = U_ZERO_ERROR;
  initAstro(status);
  ASSERT_OK(status);

  //  logln("Sunrise/Sunset times for San Jose, California, USA");
  //  CalendarAstronomer *astro2 = new CalendarAstronomer(-121.55, 37.20);
  //  TimeZone *tz = TimeZone::createTimeZone("America/Los_Angeles");

  // We'll use a table generated by the UNSO website as our reference
  // From: http://aa.usno.navy.mil/
  //-Location: W079 25, N43 40
  //-Rise and Set for the Sun for 2001
  //-Zone:  4h West of Greenwich
  int32_t USNO[] = {
    6,59, 19,45,
    6,57, 19,46,
    6,56, 19,47,
    6,54, 19,48,
    6,52, 19,49,
    6,50, 19,51,
    6,48, 19,52,
    6,47, 19,53,
    6,45, 19,54,
    6,43, 19,55,
    6,42, 19,57,
    6,40, 19,58,
    6,38, 19,59,
    6,36, 20, 0,
    6,35, 20, 1,
    6,33, 20, 3,
    6,31, 20, 4,
    6,30, 20, 5,
    6,28, 20, 6,
    6,27, 20, 7,
    6,25, 20, 8,
    6,23, 20,10,
    6,22, 20,11,
    6,20, 20,12,
    6,19, 20,13,
    6,17, 20,14,
    6,16, 20,16,
    6,14, 20,17,
    6,13, 20,18,
    6,11, 20,19,
  };

  logln("Sunrise/Sunset times for Toronto, Canada");
  // long = 79 25", lat = 43 40"
  CalendarAstronomer *astro3 = new CalendarAstronomer(-(79+25/60), 43+40/60);

  // As of ICU4J 2.8 the ICU4J time zones implement pass-through
  // to the underlying JDK.  Because of variation in the
  // underlying JDKs, we have to use a fixed-offset
  // SimpleTimeZone to get consistent behavior between JDKs.
  // The offset we want is [-18000000, 3600000] (raw, dst).
  // [aliu 10/15/03]

  // TimeZone tz = TimeZone.getTimeZone("America/Montreal");
  TimeZone *tz = new SimpleTimeZone(-18000000 + 3600000, "Montreal(FIXED)");

  GregorianCalendar *cal = new GregorianCalendar(tz->clone(), Locale::getUS(), status);
  GregorianCalendar *cal2 = new GregorianCalendar(tz->clone(), Locale::getUS(), status);
  cal->clear();
  cal->set(UCAL_YEAR, 2001);
  cal->set(UCAL_MONTH, UCAL_APRIL);
  cal->set(UCAL_DAY_OF_MONTH, 1);
  cal->set(UCAL_HOUR_OF_DAY, 12); // must be near local noon for getSunRiseSet to work

  DateFormat *df_t  = DateFormat::createTimeInstance(DateFormat::MEDIUM,Locale::getUS());
  DateFormat *df_d  = DateFormat::createDateInstance(DateFormat::MEDIUM,Locale::getUS());
  DateFormat *df_dt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::MEDIUM, Locale::getUS());
  if(!df_t || !df_d || !df_dt) {
    errln("couldn't create dateformats.");
    return;
  }
  df_t->adoptTimeZone(tz->clone());
  df_d->adoptTimeZone(tz->clone());
  df_dt->adoptTimeZone(tz->clone());

  for (int32_t i=0; i < 30; i++) {
    logln("setDate\n");
    astro3->setDate(cal->getTime(status));
    logln("getRiseSet(TRUE)\n");
    UDate sunrise = astro3->getSunRiseSet(TRUE);
    logln("getRiseSet(FALSE)\n");
    UDate sunset  = astro3->getSunRiseSet(FALSE);
    logln("end of getRiseSet\n");

    cal2->setTime(cal->getTime(status), status);
    cal2->set(UCAL_SECOND,      0);
    cal2->set(UCAL_MILLISECOND, 0);

    cal2->set(UCAL_HOUR_OF_DAY, USNO[4*i+0]);
    cal2->set(UCAL_MINUTE,      USNO[4*i+1]);
    UDate exprise = cal2->getTime(status);
    cal2->set(UCAL_HOUR_OF_DAY, USNO[4*i+2]);
    cal2->set(UCAL_MINUTE,      USNO[4*i+3]);
    UDate expset = cal2->getTime(status);
    // Compute delta of what we got to the USNO data, in seconds
    int32_t deltarise = (int32_t)uprv_fabs((sunrise - exprise) / 1000);
    int32_t deltaset = (int32_t)uprv_fabs((sunset - expset) / 1000);

    // Allow a deviation of 0..MAX_DEV seconds
    // It would be nice to get down to 60 seconds, but at this
    // point that appears to be impossible without a redo of the
    // algorithm using something more advanced than Duffett-Smith.
    int32_t MAX_DEV = 180;
    UnicodeString s1, s2, s3, s4, s5;
    if (deltarise > MAX_DEV || deltaset > MAX_DEV) {
      if (deltarise > MAX_DEV) {
        errln("FAIL: (rise) " + df_d->format(cal->getTime(status),s1) +
              ", Sunrise: " + df_dt->format(sunrise, s2) +
              " (USNO " + df_t->format(exprise,s3) +
              " d=" + deltarise + "s)");
      } else {
        logln(df_d->format(cal->getTime(status),s1) +
              ", Sunrise: " + df_dt->format(sunrise,s2) +
              " (USNO " + df_t->format(exprise,s3) + ")");
      }
      s1.remove(); s2.remove(); s3.remove(); s4.remove(); s5.remove();
      if (deltaset > MAX_DEV) {
        errln("FAIL: (set)  " + df_d->format(cal->getTime(status),s1) +
              ", Sunset:  " + df_dt->format(sunset,s2) +
              " (USNO " + df_t->format(expset,s3) +
              " d=" + deltaset + "s)");
      } else {
        logln(df_d->format(cal->getTime(status),s1) +
              ", Sunset: " + df_dt->format(sunset,s2) +
              " (USNO " + df_t->format(expset,s3) + ")");
      }
    } else {
      logln(df_d->format(cal->getTime(status),s1) +
            ", Sunrise: " + df_dt->format(sunrise,s2) +
            " (USNO " + df_t->format(exprise,s3) + ")" +
            ", Sunset: " + df_dt->format(sunset,s4) +
            " (USNO " + df_t->format(expset,s5) + ")");
    }
    cal->add(UCAL_DATE, 1, status);
  }

  //        CalendarAstronomer a = new CalendarAstronomer(-(71+5/60), 42+37/60);
  //        cal.clear();
  //        cal.set(cal.YEAR, 1986);
  //        cal.set(cal.MONTH, cal.MARCH);
  //        cal.set(cal.DATE, 10);
  //        cal.set(cal.YEAR, 1988);
  //        cal.set(cal.MONTH, cal.JULY);
  //        cal.set(cal.DATE, 27);
  //        a.setDate(cal.getTime());
  //        long r = a.getSunRiseSet2(true);
  delete astro3;
  delete tz;
  delete cal;
  delete cal2;
  delete df_t;
  delete df_d;
  delete df_dt;
  closeAstro(status);
  ASSERT_OK(status);
}



void AstroTest::TestBasics(void) {
  UErrorCode status = U_ZERO_ERROR;
  initAstro(status);
  ASSERT_OK(status);

  // Check that our JD computation is the same as the book's (p. 88)
  GregorianCalendar *cal3 = new GregorianCalendar(TimeZone::getGMT()->clone(), Locale::getUS(), status);
  DateFormat *d3 = DateFormat::createDateTimeInstance(DateFormat::MEDIUM,DateFormat::MEDIUM,Locale::getUS());
  d3->setTimeZone(*TimeZone::getGMT());
  cal3->clear();
  cal3->set(UCAL_YEAR, 1980);
  cal3->set(UCAL_MONTH, UCAL_JULY);
  cal3->set(UCAL_DATE, 2);
  logln("cal3[a]=%.1lf, d=%d\n", cal3->getTime(status), cal3->get(UCAL_JULIAN_DAY,status));
  {
    UnicodeString s;
    logln(UnicodeString("cal3[a] = ") + d3->format(cal3->getTime(status),s));
  }
  cal3->clear();
  cal3->set(UCAL_YEAR, 1980);
  cal3->set(UCAL_MONTH, UCAL_JULY);
  cal3->set(UCAL_DATE, 27);
  logln("cal3=%.1lf, d=%d\n", cal3->getTime(status), cal3->get(UCAL_JULIAN_DAY,status));

  ASSERT_OK(status);
  {
    UnicodeString s;
    logln(UnicodeString("cal3 = ") + d3->format(cal3->getTime(status),s));
  }
  astro->setTime(cal3->getTime(status));
  double jd = astro->getJulianDay() - 2447891.5;
  double exp = -3444.;
  if (jd == exp) {
    UnicodeString s;
    logln(d3->format(cal3->getTime(status),s) + " => " + jd);
  } else {
    UnicodeString s;
    errln("FAIL: " + d3->format(cal3->getTime(status), s) + " => " + jd +
          ", expected " + exp);
  }

  //        cal3.clear();
  //        cal3.set(cal3.YEAR, 1990);
  //        cal3.set(cal3.MONTH, Calendar.JANUARY);
  //        cal3.set(cal3.DATE, 1);
  //        cal3.add(cal3.DATE, -1);
  //        astro.setDate(cal3.getTime());
  //        astro.foo();

  delete cal3;
  delete d3;
  ASSERT_OK(status);
  closeAstro(status);
  ASSERT_OK(status);

}

void AstroTest::TestMoonAge(void){
	UErrorCode status = U_ZERO_ERROR;
	initAstro(status);
	ASSERT_OK(status);
	
	// more testcases are around the date 05/20/2012
	//ticket#3785  UDate ud0 = 1337557623000.0;
	static const double testcase[][10] = {{2012, 5, 20 , 16 , 48, 59},
	                {2012, 5, 20 , 16 , 47, 34},
	                {2012, 5, 21, 00, 00, 00},
	                {2012, 5, 20, 14, 55, 59},
	                {2012, 5, 21, 7, 40, 40},
	                {2023, 9, 25, 10,00, 00},
	                {2008, 7, 7, 15, 00, 33}, 
	                {1832, 9, 24, 2, 33, 41 },
	                {2016, 1, 31, 23, 59, 59},
	                {2099, 5, 20, 14, 55, 59}
	        };
	// Moon phase angle - Got from http://www.moonsystem.to/checkupe.htm
	static const double angle[] = {356.8493418421329, 356.8386760059673, 0.09625415252237701, 355.9986960782416, 3.5714026601303317, 124.26906744384183, 59.80247650195558,
									357.54163205513123, 268.41779281511094, 4.82340276581624};
	static const double precision = CalendarAstronomer::PI/32;
	for (int32_t i = 0; i < (int32_t)(sizeof(testcase)/sizeof(testcase[0])); i++) {
		gc->clear();
		logln((UnicodeString)"CASE["+i+"]: Year "+(int32_t)testcase[i][0]+" Month "+(int32_t)testcase[i][1]+" Day "+
		                                    (int32_t)testcase[i][2]+" Hour "+(int32_t)testcase[i][3]+" Minutes "+(int32_t)testcase[i][4]+
		                                    " Seconds "+(int32_t)testcase[i][5]);
		gc->set((int32_t)testcase[i][0], (int32_t)testcase[i][1]-1, (int32_t)testcase[i][2], (int32_t)testcase[i][3], (int32_t)testcase[i][4], (int32_t)testcase[i][5]);
		astro->setDate(gc->getTime(status));
		double expectedAge = (angle[i]*CalendarAstronomer::PI)/180;
		double got = astro->getMoonAge();
		//logln(testString);
		if(!(got>expectedAge-precision && got<expectedAge+precision)){
			errln((UnicodeString)"FAIL: expected " + expectedAge +
					" got " + got);
		}else{
			logln((UnicodeString)"PASS: expected " + expectedAge +
					" got " + got);
		}
	}
	closeAstro(status);
	ASSERT_OK(status);
}


// TODO: try finding next new moon after  07/28/1984 16:00 GMT


#endif



