package hirondelle.starfield.physics;

import hirondelle.starfield.util.Util;
import junit.framework.TestCase;

public class BoostTEST extends TestCase {

  /** Run the test cases.  */
  public static void main(String args[]) {
    String[] testCaseName = { BoostTEST.class.getName() };
    junit.textui.TestRunner.main(testCaseName);
  }

  public BoostTEST(String aName) {
    super(aName);
  }
  
  public void testAberration(){
    //theta prime = (90 - declination)
    
    //zero boost doesn't change the direction of any star
    testAbber(0,90,0);
    testAbber(0,45,45);
    testAbber(0,0,90);
    testAbber(0,-45,90+45);
    
    //for any boost, the direction of a star in the direction of motion remains the same
    testAbber(0.1,90,0);
    testAbber(0.5,90,0);
    testAbber(0.9,90,0);
    testAbber(0.9999,90,0);
    
    //some typical boosts
    testAbber(0.5,45,26.8989511);
    testAbber(0.5,30,36.8698979);
    testAbber(0.5,-30,90);
  }
  
  public void testDoppler(){
    testDopp(0,90,1);
    testDopp(0.6,90,2);
    testDopp(0.6,90,2);
    testDopp(0.6,30,1.625); //theta 60deg, thetaprime 32.204deg
  }

  public void testMagnitude(){
    testMag(0.6,30,6,3050,6-2.75127); //doppler = 1.625
  }

  private void testAbber(double aBeta, double aDeclination, double aExpectedThetaPrime){
    Boost boost = new Boost();
    Star star = new Star();
    star.Declination = Util.radians(aDeclination);
    star.RightAscension = 0;
    star.Magnitude = 0;
    star.Temperature = 3050;
    BoostedStar boostedStar = boost.applyBoostTo(star, aBeta);
    double expected = Util.radians(aExpectedThetaPrime);
    assertTrue(Math.abs(boostedStar.ThetaPrime - expected) < 0.0000001);
  }
  
  private void testDopp(double aBeta, double aDeclination, double aExpectedDoppler){
    Boost boost = new Boost();
    Star star = new Star();
    star.Declination = Util.radians(aDeclination);
    star.RightAscension = 0;
    star.Magnitude = 0;
    star.Temperature = 1000;
    BoostedStar boostedStar = boost.applyBoostTo(star, aBeta);
    double expected = aExpectedDoppler * star.Temperature;
    assertTrue(Math.abs(boostedStar.Temperature - expected) < 0.0000001);
  }
  
  private void testMag(double aBeta, double aDeclination, double aInitialMag, double aInitialTemp, double aExpectedMag){
    Boost boost = new Boost();
    Star star = new Star();
    star.Declination = Util.radians(aDeclination);
    star.RightAscension = 0;
    star.Magnitude = aInitialMag;
    star.Temperature = aInitialTemp;
    BoostedStar boostedStar = boost.applyBoostTo(star, aBeta);
    assertTrue(Math.abs(boostedStar.Magnitude - aExpectedMag) < 0.001);
  }
  
}