/********************************************************************
 * COPYRIGHT:
 * Copyright (c) 1996-2004, 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);
    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());
  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);

}


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


#endif



