/*
 * Created on 08-Feb-2005
 *
 * 
 */
package uk.ac.roe.wfau;

import net.mar.SLALIB;


/**
 * Class to calculate long/lat boundaries of a box on the sky
 * 
 * @author MAR
 *
 */
public class TangentRectangle {
    double pi=4.0*Math.atan(1.0);
    static double RADIAN=180.0/Math.PI;
    /**
     * anything greater than  this set min/max long 0,360
     */   
    static double latitudeLimit=90; 
 
    double longitudeZ=0.0;
    double latitudeZ=0.0;
    double minLongitude=0.0;
    double maxLongitude=0.0;
    double minLatitude=0.0;
    double maxLatitude=0.0;
    
    public TangentRectangle(double longitude, double latitude, double radius){
        longitudeZ=longitude/RADIAN;
        latitudeZ=latitude/RADIAN;
        double xi=Math.abs(radius/(RADIAN*60.0));
        double eta=Math.abs(radius/(RADIAN*60.0));
        //correction for tangent projection
        double ratio=eta/Math.tan(eta);
        // System.out.println(ratio);
        // calculate max min latitudes limit -90 to +90
        minLatitude=Math.max(-90.0,(latitudeZ-eta)*RADIAN);
        maxLatitude=Math.min(+90.0,(latitudeZ+eta)*RADIAN);
        // System.out.println(minLatitude+" "+maxLatitude);
        if (minLatitude <= -latitudeLimit || maxLatitude >= latitudeLimit){
            minLongitude=0.0;
            maxLongitude=360.0;
        }
        else {
        // now estimate min/max longitude, not entirely convinced this is correct!
        if (latitudeZ >= 0.0){
            double topLeft[]=SLALIB.DTP2S(-xi/ratio,0,longitudeZ,maxLatitude/RADIAN);
            double topRight[]=SLALIB.DTP2S(xi/ratio,0,longitudeZ,maxLatitude/RADIAN);  
            minLongitude=topLeft[0]*RADIAN;
            maxLongitude=topRight[0]*RADIAN;
           
        } else {
            double botLeft[]=SLALIB.DTP2S(-xi/ratio,0,longitudeZ,minLatitude/RADIAN);
            double botRight[]=SLALIB.DTP2S(xi/ratio,0,longitudeZ,minLatitude/RADIAN);
            minLongitude=botLeft[0]*RADIAN;
            maxLongitude=botRight[0]*RADIAN;  
        }
        }

        // System.out.println(minLongitude+" "+maxLongitude+" "+
           //     minLatitude+" "+maxLatitude);
        
        
    }
    public TangentRectangle(double longitude, double latitude, double x, double y){
        longitudeZ=longitude/RADIAN;
        latitudeZ=latitude/RADIAN;
        double xi=Math.abs(0.5*x/(RADIAN*60.0));
        double eta=Math.abs(0.5*y/(RADIAN*60.0));
        double ratio=eta/Math.tan(eta);
        
        double topLeft[]=SLALIB.DTP2S(-xi,eta,longitudeZ,latitudeZ);
        double topRight[]=SLALIB.DTP2S(xi,eta,longitudeZ,latitudeZ);
        double topMid[]=SLALIB.DTP2S(0,eta,longitudeZ,latitudeZ);
        double botLeft[]=SLALIB.DTP2S(-xi,-eta,longitudeZ,latitudeZ);
        double botRight[]=SLALIB.DTP2S(xi,-eta,longitudeZ,latitudeZ);
        double botMid[]=SLALIB.DTP2S(0,-eta,longitudeZ,latitudeZ);
        double topMidLat=latitudeZ+eta;
        double botMidLat=latitudeZ-eta;     
        
        maxLatitude=Math.max(topMidLat,Math.max(topMid[1],Math.max(topLeft[1],topRight[1])));
        minLatitude=Math.min(botMidLat,Math.min(botMid[1],Math.min(botLeft[1],botRight[1])));
        minLatitude=minLatitude*RADIAN;
        maxLatitude=maxLatitude*RADIAN;
        minLatitude=Math.max(-90.0,minLatitude);
        maxLatitude=Math.min(90.0,maxLatitude);
        
        /*
        minLatitude=Math.max(-90.0,(latitudeZ-eta)*RADIAN);
        maxLatitude=Math.min(+90.0,(latitudeZ+eta)*RADIAN);
        */
        //System.out.println(topLeft[1]*RADIAN+" "+topRight[1]*RADIAN+" "+
          //      topMid[1]*RADIAN+" "+topMidLat*RADIAN);
        //System.out.println(botLeft[1]*RADIAN+" "+botRight[1]*RADIAN+" "+
          //      botMid[1]*RADIAN+" "+botMidLat*RADIAN);
        //System.out.println(minLatitude+" "+maxLatitude);
 
        //System.out.println(minLatitude+" "+maxLatitude);
        if (minLatitude <= -latitudeLimit || maxLatitude >= latitudeLimit){
            minLongitude=0.0;
            maxLongitude=360.0;
        } else {
            if (latitudeZ >= 0.0){
                minLongitude=topLeft[0]*RADIAN;
                maxLongitude=topRight[0]*RADIAN;  
            }
            else{
                minLongitude=botLeft[0]*RADIAN;
                maxLongitude=botRight[0]*RADIAN;
            }
        }
        // System.out.println(minLongitude+" "+maxLongitude); 
        
    }
    /**
     * Gets the minimum latitude of search region
     * 
     * @return minimum latitude of search area
     */   
    public double getMinLatitude(){
        return minLatitude;
    }
    /**
     * Gets the maximum latitude of search region
     * 
     * @return maximum latitude of search area
     */
    public double getMaxLatitude(){
        return maxLatitude;
    }  
    /**
     * Gets the minimum longitude of search region
     * 
     * @return minimum longitude of search area
     */   
    public double getMinLongitude(){
        return minLongitude;
    }
    /**
     * Gets the maximum longitude of search region
     * 
     * @return maximum longitude of search area
     */
    public double getMaxLongitude(){
        return maxLongitude;
    }    
    
    public String getRASQL() {
        if (minLongitude <= maxLongitude) {
            return "RA >= "+minLongitude+" and RA <= "+maxLongitude;
        }
        else {
            return "((RA >= "+minLongitude+" and RA <=360) or (RA >= 0 and RA <= "+maxLongitude+"))";
            
        }
    }

}
