

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.mar.SLALIB;

import org.apache.log4j.Logger;

public class SSS_SIAP extends HttpServlet {
    //private DBConnectionManager connMgr; // previous connection pool
    static final short NOOFPLATES=7421;
    static final double [] RACENTRES = new double [NOOFPLATES];
    static final double [] DECCENTRES = new double [NOOFPLATES];
    static final short [] FIELDS = new short [NOOFPLATES];
    static final double [] COEFFS0 = new double [NOOFPLATES];
    static final double [] COEFFS1 = new double [NOOFPLATES];
    static final double [] COEFFS2 = new double [NOOFPLATES];
    static final double [] COEFFS3 = new double [NOOFPLATES];
    static final double [] COEFFS4 = new double [NOOFPLATES];
    static final double [] COEFFS5 = new double [NOOFPLATES];
    static final double [] ALPHA = new double [NOOFPLATES];
    
    static final short [] PLATENUMBERS = new short [NOOFPLATES];
    static final double [] MJD = new double [NOOFPLATES];
    static final short [] SURVEYID = new short [NOOFPLATES];
    static final short [] COMPMMFLAG = new short [NOOFPLATES];
    
    private static Logger logger;
    static final double DECOFFSET=3.4;
    static final double MAXRADIUS=4.81;
    static final float MAXSIZE=0.5f;
    static final double DISCO=-0.333333333333333333333333;
    static final double UKST_MINX=16.22;
    static final double UKST_MINY=UKST_MINX;
    static final double UKST_MAXX=338.78;
    static final double UKST_MAXY=UKST_MAXX;
    static final double FUNNY_MINX=17.50;
    static final double FUNNY_MINY=FUNNY_MINX;
    static final double FUNNY_MAXX=337.50;
    static final double FUNNY_MAXY=FUNNY_MAXX;
    static final double ESO_MINX=39.26;
    static final double ESO_MINY=ESO_MINX;
    static final double ESO_MAXX=315.74;
    static final double ESO_MAXY=ESO_MAXX;
    static final double HA_MINX=39.26;
    static final double HA_MINY=HA_MINX;
    static final double HA_MAXX=315.74;
    static final double HA_MAXY=HA_MAXX;
    static final double PALI_MINX=10.46;
    static final double PALI_MINY=PALI_MINX;
    static final double PALI_MAXX=344.54;
    static final double PALI_MAXY=PALI_MAXX;
    static final double PALII_MINX=UKST_MINX;
    static final double PALII_MINY=PALII_MINX;
    static final double PALII_MAXX=UKST_MAXX;
    static final double PALII_MAXY=PALII_MAXX;
    static final double PLATESCALE=67.14;
    static final short MINPIX=1;
    static final int UKST_MAXPIX=(int)(UKST_MAXX*100-UKST_MINX*100);    
    static final int PALI_MAXPIX=(int)(PALI_MAXX*100-PALI_MINX*100);
    static final int ESO_MAXPIX=(int)(ESO_MAXX*100-ESO_MINX*100);
    static final int HA_MAXPIX=(int)(HA_MAXX*100-HA_MINX*100);
    
    static final short UKJSURVEYID=1;
    static final short UKRSURVEYID=2;
    static final short UKISURVEYID=3;
    static final short ESORSURVEYID=4;
    static final short PAESURVEYID=5;
    static final short PAJSURVEYID=6;
    static final short PARSURVEYID=7;
    static final short PAISURVEYID=8;
    static final short PNESURVEYID=9;
    static final short UKSSURVEYID=10;
    static final short HALSURVEYID=11;
    static final short HARSURVEYID=12;
    static final short F287USURVEYID=13;
    static final short F287JSURVEYID=14;
    static final short F287RSURVEYID=15;
    static final short F287ISURVEYID=16;
    static final String UKSTINST="SuperCOSMOS scan of UKST plate";
    static final String PALINST="SuperCOSMOS scan of Palomar plate";
    static final String ESOINST="SuperCOSMOS scan of ESO plate";
 //   static final
 //   static final String VOTHEADER = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
    static final String VOTHEADER = "<?xml version=\"1.0\" ?>"+
    "<VOTABLE xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
    "xsi:schemaLocation=\"http://www.ivoa.net/xml/VOTable/v1.0 http://www.ivoa.net/xml/VOTable/v1.0\" " +
    "xmlns=\"http://www.ivoa.net/xml/VOTable/v1.0\">\n<RESOURCE type=\"results\">";
    
//"<VOTABLE xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
//"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://vizier.u-strasbg.fr/xml/VOTable-1.1.xsd\">\n<RESOURCE type=\"results\">";
    static final String VOTFOOTER="</TABLEDATA>\n</DATA>\n</TABLE>\n</RESOURCE>\n</VOTABLE>";
//    static final String ERRORLINESTART="<INFO name=\"QUERY_STATUS\" value=\"ERROR\">";
    static final String [] ERRORMSGS = {
            "Error parsing cooords POS=",
            "Error parsing size parameter, SIZE should be in degrees, SIZE=",
            "Supplied POS out of range. POS should in degrees POS=",
            "Requested image size not in range 0.0-0.5 degreee. SIZE should be in degrees. SIZE=",
            "Requested FORMAT not available, choices are: "
    };
    static final String [] FORMATS = {"ALL","image/fits","METADATA"};
    
    static final String SUCCESS = "<INFO name=\"QUERY_STATUS\" value=\"OK\" /> ";
    static final String ERROR = "<INFO name=\"QUERY_STATUS\" value=\"ERROR\">";
    static final String ERROREND = "</INFO>";
    static final double DEG2RAD=Math.PI/180.0;
    static final double RAD2DEG=180.0/Math.PI;
    static DecimalFormat dFormat = new DecimalFormat("#0.0000000");
    static DecimalFormat i3Format = new DecimalFormat("000");
    static DecimalFormat i4Format = new DecimalFormat("0000");
    static final String COORDREFRAME="FK5";
    static final String NAXES="2";
    static final String EQUINOX="2000.0";
    static final String PROJECTION="TAN";
    static final String BASECGIURL="http://www-wfau.roe.ac.uk/sss/cgi-bin/siap.cgi?";
    static final String SOUTHDIR="/scats/scos/";
    static final String NORTHDIR="/scatn/scos/";
    
    public void init() throws ServletException {
        //super.init(conf);
        logger=Logger.getLogger("wsa.simple");
        logger.debug("initailizing Imagelist servlet");
        // read in global properties
  //      InputStream inStr = getClass().getClassLoader().getResourceAsStream("fields.lis");
        InputStream inStr = getClass().getClassLoader().getResourceAsStream("siapsss.csv");
        int field;
        short surveyID;
        short plateNumber;
        double ra;
        double dec;
        String line ;
        double coeff0;
        double coeff1;
        double coeff2;
        double coeff3;
        double coeff4;
        double coeff5;
        
        int i=0;
    	try
        {
          BufferedReader in = new BufferedReader(new InputStreamReader(inStr)) ;
          do
          {
            line = in.readLine( )  ;
            if (line != null)
            {
    		
              StringTokenizer st = new StringTokenizer(line,",") ;
              SURVEYID[i]=Short.parseShort(st.nextToken().trim()) ;
              FIELDS[i] = Short.parseShort(st.nextToken().trim()) ;
              PLATENUMBERS[i]=Short.parseShort(st.nextToken().trim()) ;
              RACENTRES[i] = Double.parseDouble(st.nextToken().trim()) ;
              DECCENTRES[i] = Double.parseDouble(st.nextToken().trim()) ;
              COEFFS0[i] = Double.parseDouble(st.nextToken().trim()) ;
              COEFFS1[i] = Double.parseDouble(st.nextToken().trim()) ;
              COEFFS2[i] = Double.parseDouble(st.nextToken().trim()) ;
              COEFFS3[i] = Double.parseDouble(st.nextToken().trim()) ;
              COEFFS4[i] = Double.parseDouble(st.nextToken().trim()) ;
              COEFFS5[i] = Double.parseDouble(st.nextToken().trim()) ;
              MJD[i]=Double.parseDouble(st.nextToken().trim()) ;
              COMPMMFLAG[i]=Short.parseShort(st.nextToken().trim()) ;
              ALPHA[i] = Double.parseDouble(st.nextToken().trim()) ;
  /*
              FIELDS[i]=field;
              RACENTRES[i]=ra;
              DECCENTRES[i]=dec;
              SURVEYID[i]=surveyID;
              PLATENUMBERS[i]=plateNumber;
              COEFFS0[i]= coeff0;
              COEFFS1[i]= coeff1;
              COEFFS2[i]= coeff2;
              COEFFS3[i]= coeff3;
              COEFFS4[i]= coeff4;
              COEFFS5[i]= coeff5;
 */             
              i++;
            }
          } while (line != null) ;
          in.close( ) ;
        }
        catch(IOException e)
        {
           e.printStackTrace( ) ;
           
        }
        
    }

        

 
 

    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        HttpSession session = req.getSession();
        res.setContentType("text/xml");

        PrintWriter out=null;
        double userRA=-99.0;
        double userDec=-99.0;
        float sizeX=0.025f;
        float sizeY=0.0f;
        
        String pos=null;
        String size=null;
        String format="ALL";
        
        boolean ok = true;
        int startPos=-1;
        String [] coords=new String [2];
        String [] sizes=new String [2];
        StringBuffer errorMsg=new StringBuffer(ERROR);
        
        out = res.getWriter();
        out.println(VOTHEADER);
        try {
            if (req.getParameter("POS") != null ) {
                pos=req.getParameter("POS").trim();
                coords=pos.split(",");
                userRA=Double.parseDouble(coords[0]);
                userDec=Double.parseDouble(coords[1]);
                }
            if (req.getParameter("ra") != null ) {
                userRA=Double.parseDouble(req.getParameter("ra"));             
                }
        if (req.getParameter("dec") != null ) {
            userDec=Double.parseDouble(req.getParameter("dec"));
            }
 
        
        }
        catch (Exception e) {
            ok=false;
            errorMsg.append(ERRORMSGS[0]+pos+". ");
        }
        
        try  {
            
            if (req.getParameter("SIZE") != null ) {
                size=req.getParameter("SIZE").trim();
                sizes=size.split(",");
                if (sizes[0] !=null) {
                    sizeX=Float.parseFloat(sizes[0]);  
                }
                if (sizes.length > 1 && sizes[1] !=null && !sizes[1].equals("")) {
                    sizeY=Float.parseFloat(sizes[1]);  
                }
                }
        }
        catch (Exception e) {
            ok=false;
            errorMsg.append(ERRORMSGS[1]+size+". ");
        }
        
        if (sizeY==0.0){
            sizeY=sizeX;
        }
        if ( userRA < 0.0 || userRA > 360.0 || userDec < -90.0 || userDec > 90.0) {
            ok=false;
            errorMsg.append(ERRORMSGS[2]+pos+". ");
        }
        if ( sizeX <= 0.0 || sizeY <= 0.0 ) {
            ok=false;
            errorMsg.append(ERRORMSGS[3]+size+". ");
        }
        
        if ( sizeX > MAXSIZE || sizeY >  MAXSIZE ) {
            sizeX=Math.min(sizeX,MAXSIZE);
            sizeY=Math.min(sizeX,MAXSIZE);
        }
        
        
        if (req.getParameter("FORMAT") != null ) {
            format=req.getParameter("FORMAT").trim();
        }
         boolean formatOK=false;
        for (int i=0; i< FORMATS.length;i++) {
            if (format.equalsIgnoreCase(FORMATS[i])) {
                formatOK=true;
            }
        }
        
        if (!formatOK) {
            ok=false;
            errorMsg.append(ERRORMSGS[4]+". ");
                    for (int i=0; i< FORMATS.length;i++) {
                        errorMsg.append(FORMATS[i]+", ");
                    }
                    errorMsg.append(format+". ");
        }
        
        if (ok) {
            out.println(SUCCESS);            
        }
        else {
            errorMsg.append(ERROREND);
            out.println(errorMsg.toString());
        }

 /*       for (int i=0; i< 894; i++) {
            out.println("<br> "+plates[i][0]+" "+plates[i][1]+" "+plates[i][2]);
        }
        */
        
        
        
        out.println("<PARAM datatype=\"char\" name=\"INPUT:POS\" value=\"0,0\" arraysize=\"*\" />");
        out.println("<PARAM datatype=\"double\" name=\"INPUT:SIZE\" value=\"0\" />"); 
        out.println("<PARAM datatype=\"char\" name=\"INPUT:FORMAT\" value=\"ALL\" arraysize=\"*\">"); 
        out.println("<VALUES>\n<OPTION value=\"image/fits\"/>\n<OPTION value=\"METADATA\" />\n<OPTION value=\"ALL\" />\n</VALUES>\n</PARAM>");
        out.println("<TABLE>\n");
        out.println("<FIELD name=\"title\" ucd=\"VOX:Image_title\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"instrument\" ucd=\"INST_ID\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"modified-Julian-date\" ucd=\"VOX:Image_MJDateObs\" datatype=\"double\" />");
        out.println("<FIELD name=\"ra\" ucd=\"POS_EQ_RA_MAIN\" datatype=\"double\" />");
        out.println("<FIELD name=\"dec\" ucd=\"POS_EQ_DEC_MAIN\" datatype=\"double\" />");
        out.println("<FIELD name=\"naxes\" ucd=\"VOX:Image_Naxes\" datatype=\"int\" />");
        out.println("<FIELD name=\"naxis\" ucd=\"VOX:Image_Naxis\" datatype=\"int\" arraysize=\"*\" />");
        out.println("<FIELD name=\"scale\" datatype=\"double\" ucd=\"VOX:Image_Scale\" arraysize=\"*\" /> ");
        out.println("<FIELD name=\"format\" ucd=\"VOX:Image_Format\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"coordRefFRame\" ucd=\"VOX:STC_CoordRefFrame\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"equinox\" ucd=\"VOX:STC_CoordEquinox\" datatype=\"double\" />");
        out.println("<FIELD name=\"coordProj\" ucd=\"VOX:WCS_CoordProjection\" datatype=\"char\" arraysize=\"3\" />");
        out.println("<FIELD name=\"bandpassID\" ucd=\"VOX:BandPass_ID\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"url\" ucd=\"VOX:Image_AccessReference\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"fileSize\" ucd=\"VOX:Image_FileSize\" datatype=\"int\" />");
        out.println("<FIELD name=\"surveyID\" ucd=\"meta.id\" datatype=\"int\" />");
        out.println("<FIELD name=\"field\" ucd=\"meta.id\" datatype=\"int\" />");
        out.println("<FIELD name=\"plateNum\" ucd=\"meta.id\" datatype=\"int\" />");
        out.println("<FIELD name=\"Flag\" ucd=\"meta.code.qual\" datatype=\"char\" arraysize=\"4\" />");
        
  
    /*    out.println("<FIELD name=\"test1\" ucd=\"test1\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"tset2\" ucd=\"test2\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"tset3\" ucd=\"test2\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"tset4\" ucd=\"test2\" datatype=\"char\" arraysize=\"*\" />");
        out.println("<FIELD name=\"tset5\" ucd=\"test2\" datatype=\"char\" arraysize=\"*\" />");
      */  
        
        out.println("<DATA>\n<TABLEDATA>\n");
   
 //       out.println("<FIELD name=\"naxes\" ucd=\"VOX:Image_Naxes\" datatype=\"int\" />");
 //       out.println("<FIELD name=\"naxis\" ucd=\"VOX:Image_Naxis\" datatype=\"int\" arraysize=\"2\" />");
 //       out.println("<FIELD name=\"format\" ucd=\"VOX:Image_Format\" datatype=\"char\" arraysize=\"*\" />");
 //       out.println("<FIELD name=\"accref\" ucd=\"VOX:Image_AccessReference\" datatype=\"char\" arraysize=\"*\" />");
 //       out.println("<FIELD name=\"band-id\" ucd=\"VOX:BandPass_ID\" datatype=\"char\" arraysize=\"*\" />");
 //       out.println("<FIELD name=\"band-unit\" ucd=\"VOX:BandPass_Unit\" datatype=\"char\" arraysize=\"*\" />");
 //       out.println("<FIELD name=\"band-upper\" ucd=\"VOX:BandPass_HiLimit\" datatype=\"double\" unit=\"m\" />");
 //       out.println("<FIELD name=\"band-ref\" ucd=\"VOX:BandPass_RefValue\" datatype=\"double\" unit=\"m\" />");
 //       out.println("<FIELD name=\"band-lower\" ucd=\"VOX:BandPass_LoLimit\" datatype=\"double\" unit=\"m\" />");
 //       out.println("<FIELD name=\"processing\" ucd=\"VOX:Image_PixFlags\" datatype=\"char\" arraysize=\"*\" />");
        if (!ok){
            out.println(VOTFOOTER);
            return;
        }
            
            if (format.equalsIgnoreCase(FORMATS[2]) ) {
                out.println("<TR></TR>"+VOTFOOTER);
                return;
            }
//        out.println("<p> pos "+pos+" "+coords[0]+" "+coords[1]);
//        out.println("<p> size"+size+" "+sizeX+" "+sizeY);
//        out.println("<p> Ra/DEC "+userRA+" "+userDec);
        startPos=Arrays.binarySearch(DECCENTRES, (userDec-DECOFFSET)*Math.PI/180.0);
//        out.println("<p> startpos "+startPos);
        
        startPos=-startPos;
        int loop=Math.max(startPos-1,0);
//        out.println("<p> startpos "+startPos+" "+loop);
        double sepDeg=0;
        double [] xy = new double [2];
        double minX,minY,maxX,maxY,midX,midY;
        int midPixX;
        int midPixY;
        int startPixX;
        int startPixY;
        int endPixX;
        int endPixY;
        int pixWidthX=(int)Math.round(100.0*sizeX*3600.0/PLATESCALE);
        int pixWidthY=(int)Math.round(100.0*sizeY*3600.0/PLATESCALE);
        double midXMM;
        double midYMM;
        double [] midRADec;
        boolean fieldOK;
        while ( loop < DECCENTRES.length && (userDec+DECOFFSET)*Math.PI/180.0 > DECCENTRES[loop]) {
            //System.out.println(FIELDS[loop]+"filed id "+SURVEYID[loop]);
            pixWidthX=(int)Math.round(100.0*sizeX*3600.0/PLATESCALE);
            pixWidthY=(int)Math.round(100.0*sizeY*3600.0/PLATESCALE);
            
            fieldOK=true;
            if (SURVEYID[loop]==9 && FIELDS[loop]==797) fieldOK=false;
            if (SURVEYID[loop]==3 && FIELDS[loop]==263) fieldOK=false;
            sepDeg=SLALIB.DSEP(userRA*Math.PI/180.0,userDec*Math.PI/180.0,RACENTRES[loop],DECCENTRES[loop])*180.0/Math.PI;
            
            if (sepDeg < MAXRADIUS  && fieldOK) {
                //System.out.println(FIELDS[loop]+"filed sep id "+SURVEYID[loop]);  
//            out.println("<p> loop "+loop+" sep "+sepDeg+ " field "+ FIELDS[loop]);
            xy=getXY(userRA*Math.PI/180.0,userDec*Math.PI/180.0,RACENTRES[loop],DECCENTRES[loop],COEFFS0[loop],
                    COEFFS1[loop],COEFFS2[loop],COEFFS3[loop],COEFFS4[loop],COEFFS5[loop]);
//            out.println("<p> x "+xy[0]+" y "+xy[1]);
//            out.println("<p> minx "+getMinX(SURVEYID[loop])+" miny "+getMinY(SURVEYID[loop]));
//            out.println("<p> maxx "+getMaxX(SURVEYID[loop])+" maxy "+getMaxY(SURVEYID[loop]));
            
            if (xy[0] >= getMinX(SURVEYID[loop],PLATENUMBERS[loop])&& xy[0] <= getMaxX(SURVEYID[loop],PLATENUMBERS[loop]) 
                    && xy[1] >= getMinY(SURVEYID[loop],PLATENUMBERS[loop]) && xy[1] <= getMaxY(SURVEYID[loop],PLATENUMBERS[loop])) {
 //               minX=Math.max(xy[0]-sizeX*3600.0/2.0,getMinX(SURVEYID[loop]))
  
            double [] RADec=getRADec(xy[0],xy[1],RACENTRES[loop],DECCENTRES[loop],COEFFS0[loop],
                    COEFFS1[loop],COEFFS2[loop],COEFFS3[loop],COEFFS4[loop],COEFFS5[loop]);
           // System.out.println(FIELDS[loop]+"filed xy "+SURVEYID[loop]);
 
            midPixX=(int)Math.floor(getPixX(xy[0],SURVEYID[loop],ALPHA[loop],PLATENUMBERS[loop]))+1;
            midPixY=(int)Math.floor(getPixY(xy[1],SURVEYID[loop],PLATENUMBERS[loop]))+1;
  
            startPixX=midPixX-pixWidthX/2;
            startPixY=midPixY-pixWidthY/2;
            endPixX=startPixX+pixWidthX-1;
            endPixY=startPixY+pixWidthY-1;
            
            if (startPixX < MINPIX || startPixY < MINPIX || endPixX > getMaxPix(SURVEYID[loop]) || endPixY > getMaxPix(SURVEYID[loop]) ) {
                startPixX=Math.max(startPixX,MINPIX);
                startPixY=Math.max(startPixY,MINPIX);
                endPixX=Math.min(endPixX,getMaxPix(SURVEYID[loop]));
                endPixY=Math.min(endPixY,getMaxPix(SURVEYID[loop]));
                pixWidthX=Math.min(pixWidthX,endPixX-startPixX-1);
                pixWidthY=Math.min(pixWidthY,endPixY-startPixY-1);
            }
            midXMM=getMMX(((double)(startPixX+endPixX))/2.0,SURVEYID[loop],ALPHA[loop],PLATENUMBERS[loop]);
            midYMM=getMMY(((double)(startPixY+endPixY))/2.0,SURVEYID[loop],PLATENUMBERS[loop]);
            midRADec=getRADec(midXMM,midYMM,RACENTRES[loop],DECCENTRES[loop],COEFFS0[loop],
                    COEFFS1[loop],COEFFS2[loop],COEFFS3[loop],COEFFS4[loop],COEFFS5[loop]);
            out.println("<TR>");
            out.println("<TD>"+getTitle(SURVEYID[loop],FIELDS[loop])+"</TD>");
            out.println("<TD>SuperCOSMOS scan of photographic plate</TD>");
            out.println("<TD>"+MJD[loop]+"</TD>");
            out.println("<TD>"+dFormat.format(midRADec[0]*RAD2DEG)+"</TD>");
            out.println("<TD>"+dFormat.format(midRADec[1]*RAD2DEG)+"</TD>");
            out.println("<TD>"+NAXES+"</TD>");
            out.println("<TD>"+pixWidthX+" "+pixWidthY+"</TD>");
            out.println("<TD>"+dFormat.format(PLATESCALE/(100.0*3600.0))+" "+dFormat.format(PLATESCALE/(100.0*3600.0))+"</TD>");
            out.println("<TD>"+FORMATS[1]+"</TD>");
            out.println("<TD>"+COORDREFRAME+"</TD>");
            out.println("<TD>"+EQUINOX+"</TD>");
            out.println("<TD>"+PROJECTION+"</TD>");
            out.println("<TD>"+getBandPassID(SURVEYID[loop])+"</TD>");
            out.println("<TD><![CDATA["+BASECGIURL+"id="+SURVEYID[loop]+"&field="+FIELDS[loop]+
                    "&ra="+userRA+"&dec="+userDec+
                    "&pixWidthX="+pixWidthX+"&pixWidthY="+pixWidthY+
                    "&path="+getPath(SURVEYID[loop],FIELDS[loop],PLATENUMBERS[loop],DECCENTRES[loop])+
                    "&comp="+COMPMMFLAG[loop]+"&plate="+PLATENUMBERS[loop]+
                    "&x="+sizeX+"&y="+sizeY+
                    "&startPixX="+startPixX+"&startPixY="+startPixY+
                    "]]></TD>");
            out.println("<TD>"+getFileSize(SURVEYID[loop],pixWidthX,pixWidthY)+"</TD>");
            out.println("<TD>"+SURVEYID[loop]+"</TD>");
            out.println("<TD>"+FIELDS[loop]+"</TD>");
            out.println("<TD>"+PLATENUMBERS[loop]+"</TD>");
            //System.out.println(xy[0]+" "+xy[1]);
            if (isItOK(SURVEYID[loop],PLATENUMBERS[loop],(int)(xy[0]*100000),(int)(xy[1]*100000))) {
                out.println("<TD>GOOD</TD>");
            }
            else {
                out.println("<TD>POOR</TD>");
            }
        /*    out.println("<TD>"+FIELDS[loop]+" "+PLATENUMBERS[loop]+" "+UKST_MAXPIX+" "+ESO_MAXPIX+" "+PALI_MAXPIX+" "+HA_MAXPIX+"</TD>");
            out.println("<TD>"+userRA+" "+userDec+" "+xy[0]+" "+xy[1]+" "+RADec[0]*RAD2DEG+" "+RADec[1]*RAD2DEG+"</TD>");
            out.println("<TD>"+midPixX+" "+midPixY+"</TD>");
            out.println("<TD>"+pixWidthX+" "+pixWidthY+"</TD>");
            out.println("<TD>"+startPixX+" "+startPixY+" "+endPixY+" "+endPixY+"</TD>");
          */  
            //           double [] coeffs={COEFFS0[loop],COEFFS1[loop],COEFFS2[loop],COEFFS3[loop],COEFFS4[loop],COEFFS5[loop]};
 //           double [] bckcoeffs=SLALIB.INVF(coeffs);
 //           out.println("<TD>"+bckcoeffs[0]+" "+bckcoeffs[3]+"</TD>");
            out.println("</TR>");
            }
            
            }
            loop++; 
        }
        out.println(VOTFOOTER);
        System.gc();
        }
  
    public static boolean isItOK(short surveyID, short pnum, int ix, int iy) {
        boolean flag=true;
        double r2=0.0;
        double minr2=0.0;
        
        /*
         *   static final short UKJSURVEYID=1;
    static final short UKRSURVEYID=2;
    static final short UKISURVEYID=3;
    static final short ESORSURVEYID=4;
    static final short PAESURVEYID=5;
    static final short PAJSURVEYID=6;
    static final short PARSURVEYID=7;
    static final short PAISURVEYID=8;
    static final short PNESURVEYID=9;
    static final short UKSSURVEYID=10;
    static final short HALSURVEYID=11;
    static final short HARSURVEYID=12;
    static final short F287USURVEYID=13;
    static final short F287JSURVEYID=14;
    static final short F287RSURVEYID=15;
    static final short F287ISURVEYID=16;
         */
        if ((surveyID >=1 && surveyID <=3) || surveyID >=10) {
            if (surveyID==11) {
                //c  Special job for H-alpha films:
                r2=Math.pow((ix-17750000),2.0) + Math.pow((iy-17750000),2.0);
                if (ix > 17750000 && iy < 17750000) {
                 minr2=Math.pow(1.53e7,2.0);
                }else {
                 minr2=Math.pow(1.468e7,2.0);
                }
                if (r2 > minr2) flag=false;  
            }
            else {
               //  NE plate label (all plates - note no account taken of incorrect position of
               //  plate label, which is a very small percentage anyway according to MAR):                
                if (ix < 4000000 && iy > 33500000) {
                    flag= false;
                    //System.out.println("code 1");
                }
               //c  NW wedge (all plates):                 
                if (iy > 33000000 && ix > 27000000 && ix < 33000000) flag=false;
               //c E/SE wedge dependent on plate number:
                if (pnum < 5715) {
                                 if (ix < 3000000 && iy > 10000000 && iy < 15500000) {
                                     flag= false ;
                                    // System.out.println("code 2");
                                 }
                }
                else {
                    if (pnum > 5715 && pnum < 6296) {
                        minr2=Math.pow(4.0E6,2.0);
                        r2=Math.pow((ix-1622000),2.0) + Math.pow((iy-7000000),2.0);
                                 if (r2 < minr2) {
                                     flag= false;
                                     //System.out.println("code 3");
                                 }
                    }
                    else {
                                 minr2=Math.pow(4.378E6,2.0);
                                 r2=Math.pow((ix-1622000),2.0) + Math.pow((iy-1622000),2.0);
                                 if (r2 < minr2) {
                                     flag=false;
                                    // System.out.println("code 4 "+ix+" "+iy);
                                 }
                    }
                }                                                          
            }            
        }
        else if (surveyID==4) {
          //  c  NE label:
                if (ix < 5000000 && iy > 31000000) flag=false;
         // c  E wedge:
                if (ix < 5000000 && iy > 17000000 && iy < 22000000) flag=false;
         //c  W wedge:
                if (ix > 30500000 && iy > 13000000 && iy < 18000000) flag=false;
        }
        else if (surveyID==5 || surveyID==9) {
        //    c  Palomar POSS-I survey: no flags as yet
        }
        else if (surveyID==6 || surveyID==7 || surveyID==8) {
        // c  Palomar POSS-II survey: SW 16-stpe wedge only:
            if (ix > 28000000 && iy < 6000000) flag=false;
        }
        return flag;
    }
    public static double getPixX (double x, short surveyID, double alpha,short plate) {
        double xPix=(x*100.0/(1.0-alpha)-getMinX(surveyID,plate)*100)-0.5;
        return xPix;
    }
    public static double getPixY (double y, short surveyID,short plate) {
        double yPix=(y*100.0-getMinY(surveyID,plate)*100)-0.5;
        return yPix;
    }
    public static double getMMX (double xPix,short surveyID, double alpha,short plate) {
        double xMM=(xPix+0.5+getMinX(surveyID,plate)*100)*(1.0-alpha)/100.0;
        return xMM;
    }
    public static double getMMY (double yPix,short surveyID,short plate) {
        double yMM=(yPix+0.5+getMinY(surveyID,plate)*100)/100.0;
        return yMM;
    }
    
    public static double [] getXY(double userRARad, double userDecRad, double RACenter, double decCentre, double coeffs0, double coeffs1, double coeffs2, double coeffs3, double coeffs4, double coeffs5) {
        double [] xy2 = new double [2];
        double [] coeffs={coeffs0,coeffs1,coeffs2,coeffs3,coeffs4,coeffs5};
        double [] tp=SLALIB.DS2TP(userRARad,userDecRad,RACenter,decCentre);
 //       System.out.println("xi= "+tp[0]+" xn= "+tp[1]);
        tp=SLALIB.PCD(DISCO,tp[0],tp[1]);
 //       System.out.println("tp= "+tp[0]+" tp= "+tp[1]);
        xy2=SLALIB.XY2XY(tp[0],tp[1],coeffs);
        
        return xy2;        
    }
    
    public static double [] getRADec(double x, double y, double RACenter, double decCentre, double coeffs0, double coeffs1, double coeffs2, double coeffs3, double coeffs4, double coeffs5) {
        double [] coeffs={coeffs0,coeffs1,coeffs2,coeffs3,coeffs4,coeffs5};
        double [] bckcoeffs=SLALIB.INVF(coeffs);
        double [] tpres=SLALIB.XY2XY(x,y,bckcoeffs);
        tpres=SLALIB.UNPCD(DISCO,tpres[0],tpres[1]);
        double RADec [] = SLALIB.DTP2S(tpres[0],tpres[1],RACenter,decCentre);
        return RADec;
    }
    
    public static String getPath (short surveyID, int field, int plate, double decCentre) {
        switch(surveyID){
        case UKJSURVEYID:
            return SOUTHDIR+"UKJsurvey/UKJ"+i3Format.format(field);
		case UKRSURVEYID:
		    return SOUTHDIR+"UKRsurvey/UKR"+i3Format.format(field);
		case UKISURVEYID:	
		    return SOUTHDIR+"UKIsurvey/UKI"+i3Format.format(field);
		case PAJSURVEYID:
		    return NORTHDIR+"PAJsurvey/PAJ"+i3Format.format(field);
		case PARSURVEYID:
		    return NORTHDIR+"PARsurvey/PAR"+i3Format.format(field);
		case PAISURVEYID:
		    return NORTHDIR+"PAIsurvey/PAI"+i3Format.format(field);
		case F287USURVEYID:
		    return SOUTHDIR+"F287/U"+plate;
		case F287JSURVEYID:
		    return SOUTHDIR+"F287/J"+plate;
		case F287RSURVEYID:
		    return SOUTHDIR+"F287/R"+plate;
		case F287ISURVEYID:
		    return SOUTHDIR+"F287/I"+plate;
		case UKSSURVEYID:    
		    return SOUTHDIR+"UKSsurvey/UKS"+i3Format.format(field);
		case ESORSURVEYID:
		    return SOUTHDIR+"ESORsurvey/ESOR"+i3Format.format(field);
		case PAESURVEYID:
		    if (decCentre < 2.5*DEG2RAD) {
		        return SOUTHDIR+"PAEsurvey/PAE"+i4Format.format(field);   
		    }else {
		        return NORTHDIR+"PAEsurvey/PAE"+i4Format.format(field);
		    }
		case PNESURVEYID:
		    if (decCentre < 2.5*DEG2RAD) {
		        return SOUTHDIR+"PAEsurvey/PAE"+i4Format.format(field);   
		    }else {
		        return NORTHDIR+"PAEsurvey/PAE"+i4Format.format(field);
		    }	
		case HALSURVEYID:
		    return SOUTHDIR+"HAsurvey/HAL"+i4Format.format(field);
		case HARSURVEYID:
		    return SOUTHDIR+"HAsurvey/HAR"+i4Format.format(field);
		default :
		return "Null survey";
    } 
    }
 
    
    public static String getBandPassID (short surveyID) {
        switch(surveyID){
        case UKJSURVEYID:
            return "UKST_Bj";
		case UKRSURVEYID:
	        return "UKST_R";
		case UKISURVEYID:	
	        return "UKST_I";
		case PAJSURVEYID:
	        return "POSSII_B";
		case PARSURVEYID:
	        return "POSSII_R";
		case PAISURVEYID:  
	        return "POSSII_I";
		case F287USURVEYID:
		    return "UKST_U";
		case F287JSURVEYID:
		    return "UKST_Bj";
		case F287RSURVEYID:
		    return "UKST_R";
		case F287ISURVEYID:
	        return "UKST_I";
		case UKSSURVEYID:    
	        return "UKST_R";
		case ESORSURVEYID:
	        return "ESO_R";
		case PAESURVEYID:
	        return "POSSI_E";
		case PNESURVEYID:
	        return "POSSI_E";	
		case HALSURVEYID:
	        return "UKST_H-alpha";
		case HARSURVEYID:
		    return "UKST_R";
		default :
		return "Null survey";
    } 
    }
 
    
    public static String getTitle (short surveyID, int field) {
        switch(surveyID){
        case UKJSURVEYID:
            return "UKST_J_field_"+field;
		case UKRSURVEYID:
	        return "UKST_R_field_"+field;
		case UKISURVEYID:	
	        return "UKST_I_field_"+field;
		case PAJSURVEYID:
	        return "POSSII_B_field_"+field;
		case PARSURVEYID:
	        return "POSSII_R_field_"+field;
		case PAISURVEYID:  
	        return "POSSII_I_field_"+field;
		case F287USURVEYID:
		    return "UKST_F287_U-band";
		case F287JSURVEYID:
		    return "UKST_F287_J-band";
		case F287RSURVEYID:
		    return "UKST_F287_R-band";
		case F287ISURVEYID:
	        return "UKST_F287_I-band";
		case UKSSURVEYID:    
	        return "UKST_SR_field_"+field;
		case ESORSURVEYID:
	        return "ESO_R_field_"+field;
		case PAESURVEYID:
	        return "POSSI_E_field_"+field;
		case PNESURVEYID:
	        return "POSSI_E_field_"+field;	
		case HALSURVEYID:
	        return "UKST_H-alpha_field_"+field;
		case HARSURVEYID:
		    return "UKST_Short-Red_from_H-alpha_survey_field_"+field;
		default :
		return "Null_survey";
    } 
    }
   
    public static int getMaxPix (short surveyID) {
        switch(surveyID){
        case UKJSURVEYID:
		case UKRSURVEYID:
		case UKISURVEYID:	
		case PAJSURVEYID:
		case PARSURVEYID:
		case PAISURVEYID:  
		case F287USURVEYID:
		case F287JSURVEYID:
		case F287RSURVEYID:
		case F287ISURVEYID:
		case UKSSURVEYID:    
		    return UKST_MAXPIX;
		case ESORSURVEYID:
		    return ESO_MAXPIX;
		case PAESURVEYID:
		case PNESURVEYID:
		    return PALI_MAXPIX;	
		case HALSURVEYID:
		case HARSURVEYID:
		    return HA_MAXPIX;
		default :
		return 0;
    } 
    }
    public static double getMinX (short surveyID,short plate) {
        switch(surveyID){
        case UKJSURVEYID:
		case UKRSURVEYID:
		case UKISURVEYID:	
		case PAJSURVEYID:
		case PARSURVEYID:
		case PAISURVEYID:  
		case F287USURVEYID:
		case F287JSURVEYID:
		case F287RSURVEYID:
		case F287ISURVEYID:
		    if (plate ==15564 ||plate == 16149 || plate ==16224 || plate ==16703 || plate ==16747 || plate ==16754 || plate == 17108 ) {
		      //  System.out.println("funny "+plate);
		        return FUNNY_MINX;
		       
		    }
		    else {
		        return UKST_MINX;
		    }
		case UKSSURVEYID:    
		    return UKST_MINX;
		case ESORSURVEYID:
		    return ESO_MINX;
		case PAESURVEYID:
		case PNESURVEYID:
		    return PALI_MINX;	
		case HALSURVEYID:
		case HARSURVEYID:
		    return HA_MINX;
		default :
		return 999.9;
    } 
    }

    public static double getMinY (short surveyID, short plate) {
        return getMinX(surveyID,plate);
    }
    
    public static int getFileSize (short surveyID,int xPix, int yPix) {
        switch(surveyID){
        case UKJSURVEYID:
		case UKRSURVEYID:
		case UKISURVEYID:	
		case PAJSURVEYID:
		case PARSURVEYID:
		case PAISURVEYID:  
		case F287USURVEYID:
		case F287JSURVEYID:
		case F287RSURVEYID:
		case F287ISURVEYID:
		case UKSSURVEYID:    
		case ESORSURVEYID:
		case PAESURVEYID:
		case PNESURVEYID:
		    return 	2880*2+xPix*yPix*2;
		case HALSURVEYID:
		case HARSURVEYID:
		    return 2880*2+xPix*yPix*4;
		default :
		return 2880*2+xPix*yPix*2;
    } 
    }

    
    public static double getMaxX (short surveyID, short plate) {
        switch(surveyID){
        case UKJSURVEYID:
		case UKRSURVEYID:
		case UKISURVEYID:	
		case PAJSURVEYID:
		case PARSURVEYID:
		case PAISURVEYID:  
		case F287USURVEYID:
		case F287JSURVEYID:
		case F287RSURVEYID:
		case F287ISURVEYID:
		    if (plate ==15564 ||plate == 16149 || plate ==16224 || plate ==16703 || plate ==16747 || plate ==16754 || plate == 17108 ) {
		        return FUNNY_MAXX;
		    }
		    else {
		        return UKST_MAXX;
		    }
		        
		case UKSSURVEYID:    
		    return UKST_MAXX;
		case ESORSURVEYID:
		    return ESO_MAXX;
		case PAESURVEYID:
		case PNESURVEYID:
		    return PALI_MAXX;	
		case HALSURVEYID:
		case HARSURVEYID:
		    return HA_MAXX;
		default :
		return 999.9;
    } 
    }

    public static double getMaxY (short surveyID, short plate) {
        return getMaxX(surveyID,plate);
    } 
    
    
    
    public void destroy() {
        //          connMgr.release();
        
        super.destroy();
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        // Data received by an HTTP POST is handled the same way
        // as data sent with a HTTP GET request... simply pass on to above...
        doGet(req, res);
    }; // END of doPost()

   
}



