// deprecated use uk.ac.roe.wfau version
package net.mar;

import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;

import uk.ac.roe.wfau.WSAHTMLSchema;
import uk.ac.roe.wfau.WSASchema;
import uk.ac.starlink.ast.AstObject;
import uk.ac.starlink.ast.FitsChan;
;
public class ImageSelect{
PrintWriter out=null;

static String blankColumns [] = {"filename","cd11","cd12","cd22","cd21","axis1length",
        "axis2Length","cTypeX","cTypeY","crValX","crValY","crPixX","crPixY",
        "projP1","projP3","xpixsize","ypixsize"};
ResultSetMetaData md;
ResultSet rs;
int row=0;
int rc=0;
double userRA;
double userDec;
double userX;
double userY;

double distance=0.0;
double area=0.0;

double areaRequested=0.0;
int filenameCol;
int multiframeIDCol;
int filterIDCol;
int extNumCol;
int numaxesCol;
int axis1lengthCol;
int axis2lengthCol;
int ctypeXCol;
int ctypeYCol;
int crpixXCol;
int crvalXCol;
int crpixYCol;
int crvalYCol;
int cd11Col;
int cd12Col;
int cd21Col;
int cd22Col;
int projp1Col;
int projp3Col;
int xpixelsizeCol;
int ypixelsizeCol;
int objNumCol;
int userRACol;
int userDecCol;

StringBuffer tableStart=new StringBuffer("<table><tr bgcolor=\""+WSAHTMLSchema.headRow+"\"><td><b>Link</b></td>");
FormatRS frs;
String[] RSArray;
boolean [] showCol;
boolean doMap=false;
String cgiURL=null;
String uniqueID="";
Map map=new HashMap();
public void setUniqueID(String uniqueID){
    this.uniqueID=uniqueID;
}
public void setCgiURL(String cgiURL){
    this.cgiURL=cgiURL;
}
public void setPrintWriter(PrintWriter out){
    this.out=out;
}
public void setDoMap(boolean doMap){
    this.doMap=doMap;
}
public int getMumberRows(){
    return row;
}

public String getQueryString(String [] inArray){
    return "file="+inArray[0]+
    "&mfid="+inArray[1]+
    "&extNo="+inArray[3]+
    "&lx="+inArray[4]+
    "&hx="+inArray[5]+
    "&ly="+inArray[6]+
    "&hy="+inArray[7]+
    "&rf="+inArray[16]+
    "&flip="+inArray[17]+
    "&uniq="+inArray[18]+
    "&xpos="+inArray[8]+"&ypos="+inArray[9]+
    "&ra="+ParseCoords.formatP(userRA,7)+"&dec="+ParseCoords.formatP(userDec,6);    
}
	public boolean setRSMD(ResultSetMetaData md){
    boolean isOK=false;
	this.md=md;
	
	try {
	    showCol=new boolean[md.getColumnCount()];
    for (int i = 1; i <= md.getColumnCount(); i++) {
        showCol[i-1]=true;
        for (int j = 0; j < blankColumns.length; j++) {
            if (md.getColumnName(i).equalsIgnoreCase(blankColumns[j])){
              showCol[i-1]=false;
            }
        }
        if (showCol[i-1]){
        tableStart.append("<td><b>"+md.getColumnName(i)+"</b></td>");
        }
		if (md.getColumnName(i).equalsIgnoreCase("filename")){
					filenameCol=i;					
		}
		if (md.getColumnName(i).equalsIgnoreCase("multiframeID")){
		  	multiframeIDCol=i;
		  	}
		if (md.getColumnName(i).equalsIgnoreCase("filterID")){
			filterIDCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("extnum")){
					extNumCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("numaxes")){
		    numaxesCol=i;				
		}
		if (md.getColumnName(i).equalsIgnoreCase("axis1length")){
		    axis1lengthCol=i;					
		}
		if (md.getColumnName(i).equalsIgnoreCase("axis2length")){
		    axis2lengthCol=i;		
		}
		if (md.getColumnName(i).equalsIgnoreCase("CTYPEX")){
		    ctypeXCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CTYPEY")){
		    ctypeYCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CRPIXX")){
		    crpixXCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CRVALX")){
		    crvalXCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CRPIXY")){
		    crpixYCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CRVALY")){
		    crvalYCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CD11")){
		    cd11Col=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CD12")){
		    cd12Col=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CD21")){
		    cd21Col=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("CD22")){
		    cd22Col=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("PROJP1")){
		    projp1Col=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("PROJP3")){
		    projp3Col=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("XPIXSIZE")){
		    xpixelsizeCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("YPIXSIZE")){
		    ypixelsizeCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("objNum")){
		    objNumCol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("userRA")){
		    userRACol=i;
		}
		if (md.getColumnName(i).equalsIgnoreCase("userDec")){
		    userDecCol=i;
		}
    }
    frs=new FormatRS();
    frs.setRSMD(md);
    RSArray = new String[md.getColumnCount()];
        isOK=true;
    } 
    catch (Exception e){
        isOK=false;
    }

    return isOK;
}

	public String[][] setRS(ResultSet rs, double userRA, double userDec, double userX, double userY){
	return this.setRS (rs, userRA, userDec, userX, userY,1);
	}
public String[][] setRS(ResultSet rs, double userRA, double userDec, double userX, double userY, int noObj){
    int objNum=0;
	this.userRA=userRA;
	this.userDec=userDec;
	this.userX=userX;
	this.userY=userY;

	String bestFile=null;
	this.rs=rs;

	areaRequested=userX*userY*3600.;

	String filename=null;
	double xPixelSize=0.0;
	double yPixelSize=0.0;
	double nx=0;
	double ny=0;
	int lowx=0;
	int highx=0;
	int lowy=0;
	int highy=0;
	int extNum=0;
	String multiframeID=null;
	String filterID=null;
	String filterName=null;
	String CD1_1=null;
	String CD1_2=null;
	String CD2_2=null;
	String CD2_1=null;
    String PROJP1=null;
    String PROJP3=null;
	String options=null;
	String bestArray [][]= new String[noObj][21];
	String [] strArray = new String [21];
	double [] areaCovered= new double [noObj];
	double [] minDistance= new double [noObj];
	for (int i=0; i < noObj; i++){
	    minDistance[i]=2000000000.0; // pixel distance centre image to ra/dec,a big initial value set
	}
	
	String CD11P;
	String CD12P;
	String CD21P;
	String CD22P;
	double CD11D;
	double CD12D;
	double CD21D;
	double CD22D;
	double xinc;
	double yinc;
	String PROJP1P;
	String PROJP3P;

	double [] xypixN;
	double [] xypixE;
	double paNorth;
	double paEast;
	double imrot;
    int imflip=0;
    int imrotFlag=0;
	String RAString=null;
	String DecString=null;
	
	try{

	AstObject newao;
	FitsWcs newfw = new FitsWcs();
	if (out!=null){
	out.println(tableStart);
	}
            while (rs.next()) {
            	try {
            		if (userRACol > 0) {
            		    userRA=rs.getDouble(userRACol);
            		}
            		if (userDecCol > 0) {
            		    userDec=rs.getDouble(userDecCol);
            		}	
            		} catch (SQLException se){
            		    userRA=999.0;
            		    userDec=999.0;
            		}
            		RAString=ParseCoords.formatP(userRA,7);
            		DecString=ParseCoords.formatP(userDec,6);
            	    if (noObj==1) {
            	        objNum=0;
            	    }
            	    else {
            	        try {
            	        objNum=rs.getInt(objNumCol);
            	        }
            	        catch (SQLException se) {
            	            objNum=0;
            	        }
            	    }
                
                //System.out.println(userRA+" "+userDec+" "+objNum);
                
            	FitsChan fc=new FitsChan();
                rc=rc+1;
               
                newao=null;
              //  System.out.println("row "+row+" rowcount "+rc);
             //   fc.clear("Card");         
                fc.setCard(1);
                filename=rs.getString(filenameCol);
                multiframeID=rs.getString(multiframeIDCol);                
                filterID=rs.getString(filterIDCol);
                try {
                    WSASchema.getFilterName(Integer.valueOf(filterID).intValue());
                }
                catch (Exception e){
                    filterName="NULL";
                }
                extNum=rs.getInt(extNumCol);                
                extNum=extNum-WSASchema.FITS_OFFSET; 
                try {
                fc.putFits("NAXIS   = "+rs.getString(numaxesCol),true);
                } catch (Exception e){
                    fc.putFits("NAXIS   = 2",true); 
                }
                fc.putFits("NAXIS1  = "+rs.getString(axis1lengthCol),true);
                fc.putFits("NAXIS2  = "+rs.getString(axis2lengthCol),true);
                fc.putFits("CTYPE1  = '"+rs.getString(ctypeXCol)+"'",true);
                fc.putFits("CTYPE2  = '"+rs.getString(ctypeYCol)+"'",true);
                fc.putFits("CRPIX1  = "+rs.getString(crpixXCol),true);
                fc.putFits("CRVAL1  = "+rs.getString(crvalXCol),true);
                fc.putFits("CRPIX2  = "+rs.getString(crpixYCol),true);
                fc.putFits("CRVAL2  = "+rs.getString(crvalYCol),true);
                CD11P=rs.getString(cd11Col);
                CD1_1="CD1_1   = "+CD11P+ " / from database";
                fc.putFits(CD1_1,true);
                CD12P=rs.getString(cd12Col);
                CD1_2="CD1_2   = "+CD12P+ " / from database";
                fc.putFits(CD1_2,true);
                CD21P=rs.getString(cd21Col);
                CD2_1="CD2_1   = "+CD21P+ " / from database";
                fc.putFits(CD2_1,true);
                CD22P=rs.getString(cd22Col);
                CD2_2="CD2_2   = "+CD22P+ " / from database";
                fc.putFits(CD2_2,true);
                PROJP1P=rs.getString(projp1Col);
                PROJP1="PROJP1  = "+PROJP1P+ " / from database";
                fc.putFits(PROJP1,true);
                PROJP3P=rs.getString(projp3Col);
                PROJP3="PROJP3  = "+PROJP3P+ " / from database";
                fc.putFits(PROJP3,true);
                xPixelSize=Double.valueOf(rs.getString(xpixelsizeCol)).doubleValue();
                yPixelSize=Double.valueOf(rs.getString(ypixelsizeCol)).doubleValue();                
            
                fc.putFits("PCOUNT  =                    0 / required keyword; must = 0                    ",true);
                fc.putFits("GCOUNT  =                    1 / required keyword; must = 1                    ",true);
                fc.putFits("CRUNIT1 = 'deg     '           / Unit of right ascension co-ordinates          ",true);
                fc.putFits("CRUNIT2 = 'deg     '           / Unit of declination co-ordinates              ",true);
 
            
                newao = newfw.setFits(fc);
                fc=null;
  

					nx=newfw.getNX();
					ny=newfw.getNY();
				//	out.println(filename+" nx "+nx+" ny "+ny+"<br>");
					double [] xypix=newfw.getXPixYPix(userRA,userDec);
		
					
					double [] centre=newfw.getRADec(nx/2,ny/2);
					//out.println("center"+centre[0]+" : "+centre[1]);
					//System.out.println(nx+" "+ny+" "+xypix[0]+" "+xypix[1]);
					if (xypix[0] > 0 & xypix[0] < nx & xypix[1] > 0 & xypix[1] <ny)
					{
			               row=row+1;
			               CD11D=Double.valueOf(CD11P).doubleValue();
			               CD12D=Double.valueOf(CD12P).doubleValue();
			               CD21D=Double.valueOf(CD21P).doubleValue();
			               CD22D=Double.valueOf(CD22P).doubleValue();
			               xinc=Math.sqrt(CD11D*CD11D+CD21D*CD21D);
			               yinc=Math.sqrt(CD22D*CD22D+CD12D*CD12D);
			               xypixN=newfw.getXPixYPix(userRA,userDec+yinc);
			               xypixE=newfw.getXPixYPix(userRA+xinc,userDec);
			               paNorth=Math.atan2(xypixN[1]-xypix[1],xypixN[0]-xypix[0])
			               *180.0/Math.PI;
			               paEast=Math.atan2(xypixE[1]-xypix[1],xypixE[0]-xypix[0])
			               *180.0/Math.PI;       
			               
			               if (paNorth < -90.0){
			                   paNorth=paNorth+360.0;
			               }
			               if (paEast < -90.0){
			                   paEast=paEast+360.0;
			               }
			               /* Compute image rotation angle from North */
			               if (paNorth < -90.0) {
			           	    imrot = 270.0 + paNorth;
			               }
			               else {
			           	   imrot = paNorth - 90.0;
			               }
			               if (imrot < 0.0){
			                   imrot=imrot + 360.0;
			               }
			               if (imrot >=360.0){
			                   imrot=imrot - 360.0;
			               }
			               

			               if ((paEast - paNorth) < -80.0 &&
			                   	(paEast - paNorth) > -100.0){
			                   	imflip = 1;
			               }
			               if ((paEast - paNorth) < 280.0 &&
			                   	(paEast - paNorth) > 260.0) {
			                   	imflip = 1;
			               }
			               if ((paNorth - paEast) > 80.0 &&
			                   	(paNorth - paEast) < 100.0){
			                   	imflip = 1;
			               }
			               imrotFlag=Math.round((float)imrot/90.0F);
			               if (imrotFlag >= 4 ) {
			                   imrotFlag=imrotFlag-4;
			               }
	
			             double sizeX=userX;
			             double sizeY=userY;
			             if (imrotFlag == 1 || imrotFlag ==3){
			                 sizeX=userY;
			                 sizeY=userX;
			             }
						lowx=(int)Math.ceil(Math.max(1.,(xypix[0]-sizeX*60.0/(2.0*xPixelSize))-1));
						highx=(int)Math.floor(Math.min(nx,(xypix[0]+sizeX*60.0/(2.0*xPixelSize))+1));
						lowy=(int)Math.ceil(Math.max(1.,(xypix[1]-sizeY*60.0/(2.0*yPixelSize))-1));
						highy=(int)Math.floor(Math.min(ny,(xypix[1]+sizeY*60.0/(2.0*yPixelSize))+1));
						if (out != null || doMap){
					    strArray[0]=filename.substring(filename.indexOf(":")+1,filename.length()).trim().toString();
					    strArray[1]=multiframeID;
					    strArray[2]=filterID;
					    strArray[3]=String.valueOf(extNum);
					    strArray[4]=String.valueOf(lowx);
						strArray[5]=String.valueOf(highx);
					    strArray[6]=String.valueOf(lowy);
						strArray[7]=String.valueOf(highy);
						strArray[8]=ParseCoords.formatP((xypix[0]-lowx+1.),1);					   
						strArray[9]=ParseCoords.formatP((xypix[1]-lowy+1.),1);
						strArray[10]=CD1_1;
						strArray[11]=CD1_2;
						strArray[12]=CD2_1;
						strArray[13]=CD2_2;
						strArray[14]=PROJP1;
						strArray[15]=PROJP3;
						strArray[16]=String.valueOf(imrotFlag);
						strArray[17]=String.valueOf(imflip);
						strArray[18]=uniqueID+"_"+row;
						strArray[19]=RAString;
						strArray[20]=DecString;
						}
	
			               if (out !=null){
				               if (row % 2 == 0){
				                    out.println("<tr bgcolor="+WSAHTMLSchema.evenRow+">");
				                }
				                else {
				                out.println("<tr bgcolor="+WSAHTMLSchema.oddRow+">");
				                }
				             out.println("<td><a href=\""+cgiURL+
				                     getQueryString(strArray)+
				                     "\" target=show>show</a>" +
				                     "</td>");
				             RSArray=frs.setRS(rs);
				             for (int j = 0; j < RSArray.length; j++){
				                 if (showCol[j]){
				                 out.println("<td nowrap>"+RSArray[j].trim()+"</td>");
				                 }			             
				             }
				               }
					   // System.out.println("times "+System.currentTimeMillis());

					    if (doMap){
					    map.put(String.valueOf(row),strArray);
					    }
					   // System.out.println("timee "+System.currentTimeMillis());
                        area=(highx-lowx)*(highy-lowy)*xPixelSize*yPixelSize;
                        distance=(xypix[0]-nx/2)*(xypix[0]-nx/2)+(xypix[1]-ny/2)*(xypix[1]-ny/2);
					    if (area > areaCovered[objNum] || area >= areaRequested)
					    {
					//		System.out.println(filename);
					//		System.out.println(distance+" "+area);
							areaCovered[objNum]=area;
							if (distance < minDistance[objNum]) {
								minDistance[objNum]=distance;
					        bestArray[objNum][0]=filename.substring(filename.indexOf(":")+1,filename.length()).trim().toString();
					        //options=" "+extNum+" "+lowx+" "+highx+" "+lowy+" "+highy+" ";
					        bestArray[objNum][1]=multiframeID;
					        bestArray[objNum][2]=filterID;
					        bestArray[objNum][3]=String.valueOf(extNum);
					        bestArray[objNum][4]=String.valueOf(lowx);
					        bestArray[objNum][5]=String.valueOf(highx);
					        bestArray[objNum][6]=String.valueOf(lowy);
					        bestArray[objNum][7]=String.valueOf(highy);
					        bestArray[objNum][8]=ParseCoords.formatP((xypix[0]-lowx+1.),1);
					        bestArray[objNum][9]=ParseCoords.formatP((xypix[1]-lowy+1.),1);
					        bestArray[objNum][10]=CD1_1;
					        bestArray[objNum][11]=CD1_2;
					        bestArray[objNum][12]=CD2_1;
					        bestArray[objNum][13]=CD2_2;
					        bestArray[objNum][14]=PROJP1;
					        bestArray[objNum][15]=PROJP3;
					        bestArray[objNum][16]=String.valueOf(imrotFlag);
					        bestArray[objNum][17]=String.valueOf(imflip);
					        bestArray[objNum][18]=uniqueID+"_"+row;
					        bestArray[objNum][19]=RAString;
					        bestArray[objNum][20]=DecString;
						//System.out.println(bestFile);
							}
						}
					}


				} //rs loop
            if (out !=null){
			    out.println("</table>");
			    out.flush();
            }
			
				//System.out.println("mappppping");
	/*			Set keyValuePairs=map.keySet();
				Iterator it=keyValuePairs.iterator();
				//System.out.println(map.size());
				while (it.hasNext()){
					//System.out.println("here");
                    String name =(String)it.next();
					String [] sa=(String [])map.get(name);
					//System.out.println(sa[0]+" "+sa[1]);
				}*/


			}

		catch (Exception e){
			System.out.println("AAA"+e);
		}

    return bestArray;

}

public int getNoRows() {
	return row;
}
public Map getResMap() {
	return map;
}


}