package hirondelle.starfield.catalog.parser;

import hirondelle.starfield.util.Util;

/** 
 Chop up a single line of a star catalog into the parts needed by this tool.
 Bit of a hodge-podge for different format policies, as seen in different catalogs.
  
 <P>Note that the numbers passed to these methods use the 'byte numbers' typically 
 specified by a catalog, and those numbers start at 1, not 0.
*/
final class Chomper {

  /** Constructor. */
  Chomper(String aLine){
    fLine = aLine;
  }
  
  /** Chunk of text. Trims before returning the result. */
  String forText(int aStart, int aEnd){
    return fLine.substring(aStart-1, aEnd).trim();
  }
  
  /** Text for a single byte at the given index. */
  String forText(int aIndex){
    return forText(aIndex, aIndex);
  }

  /** Simple integer, no decimal. */
  int forInt(int aStart, int aEnd){
    String text = forText(aStart, aEnd);
    return Integer.valueOf(text);
  }
  
  /** Number with a decimal portion. */
  double forDouble(int aStart, int aEnd){
    String text = forText(aStart, aEnd);
    return Double.valueOf(text);
  }
  
  /** Right Ascension of a star in radians. Assumes the 'seconds' is like '05.9'. */
  double forRightAscension(int aHourStart, int aHourEnd, int aMinStart, int aMinEnd, int aSecStart, int aSecEnd){
    int hour = forInt(aHourStart, aHourEnd);
    int min = forInt(aMinStart, aMinEnd);
    double sec = forDouble(aSecStart, aSecEnd);
    double hours = hour + min/60.0D + sec/3600.0D; //be careful to avoid integer division!
    return Util.radians(hours*15.0D);
  }

  /** Declination of a star in radians. Assumes the seconds portion has no decimal. */
  double forDeclination(int aSign, int aDegStart, int aDegEnd, int aMinStart, int aMinEnd, int aSecStart, int aSecEnd){
    int deg = forInt(aDegStart, aDegEnd);
    int min = forInt(aMinStart, aMinEnd);
    int sec = forInt(aSecStart, aSecEnd);
    double degrees = deg + min/60.0D + sec/3600.0D; //be careful to avoid integer division!
    double result = Util.radians(degrees);
    String sign = forText(aSign);
    if ("-".equals(sign)){
      result = -1 * result;
    }
    return result;
  }
  
  /** The magnitude of a star. Assumes 2 decimal places, as in '6.70'. Possible leading minus sign. */
  double forMagnitude(int aMagStart, int aMagEnd){
    return forDouble(aMagStart,aMagEnd);
  }
  
  /** Return true only if the given text has no content. */
  boolean isMissing(int aStart, int aEnd){
    return ! Util.textHasContent(forText(aStart, aEnd));
  }
  
  // PRIVATE
  private String fLine;
}