import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.sql.Statement;
import java.util.Calendar;
import java.util.Properties;

import javax.servlet.ServletConfig;
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.alanmaxwell.html.HTMLStrings;
import net.alanmaxwell.sql.SQLServerInfoJDBC;
import net.alanmaxwell.sql.WSASQLRetrieverThread;

import org.apache.log4j.Logger;

import uk.ac.roe.wfau.DatabaseURL;
import uk.ac.roe.wfau.StringToRADec;
import uk.ac.roe.wfau.WSAHTMLSchema;
import uk.ac.roe.wfau.WSASchema;
import uk.ac.roe.wfau.WSASession;

//import com.oreilly.servlet.UploadedFile;
import com.oreilly.servlet.multipart.FilePart;
import com.oreilly.servlet.multipart.MultipartParser;
import com.oreilly.servlet.multipart.ParamPart;
import com.oreilly.servlet.multipart.Part;


public class CrossID extends HttpServlet {  // 1
  private int serviceTotal = 0;
  private int serviceCurrent = 0;
  private static final int MAX_LINES_SMALLRADIUS = 50000;
  private static final int MAX_LINES_LARGERADIUS = 5001;
  static String resultsPageHeading = "WSA SQL Query Results";
  static String baseURL = WSAHTMLSchema.baseURL;
  // Access methods for service counter...
  protected synchronized void enteringServiceMethod() { //2
    serviceCurrent++;
    serviceTotal++;
  };

  protected synchronized void leavingServiceMethod() { //3
      
    serviceCurrent--;
  };

  protected synchronized int getServiceCurrent() { //4
    return serviceCurrent;
  };

  protected synchronized int getServiceTotal() { //5
    return serviceTotal;
  };

  private boolean shuttingDown = false;

  // Access methods for the shuttingDown flag...
  protected synchronized void setShuttingDown(boolean flag) { //6
    shuttingDown = flag;
  };

  protected synchronized boolean isShuttingDown() { //7
    return shuttingDown;
  };

  private static String tmpCrossID;
  private String dirName;
  private String tmpWeb;
  private String server;
  private String user;
  private String passwd;
  private String publicuser;
  private String publicpasswd;
  
  private String defaultUKIDSSDatabase;
  private String defaultWorldDatabase;
  static Logger logger=Logger.getLogger("wsa.simple");
  static boolean useTDS=true;

  public void init(ServletConfig config) throws ServletException {

	  super.init(config);
      String path=getServletContext().getRealPath("/");
      Properties properties = new Properties();
      try {
		  properties.load(new FileInputStream(path+"WEB-INF/WSA.properties"));
	  }
	  catch (IOException e) {
		  System.out.println("ERROR: properties file not found");
		  return;
	  }

	  server = properties.getProperty("server");
	  user = properties.getProperty("user");
	  passwd = properties.getProperty("passwd");
	 // publicuser = properties.getProperty("publicuser");
	 // publicpasswd = properties.getProperty("publicpasswd");
	  defaultUKIDSSDatabase = properties.getProperty("defaultUKIDSSDatabase");
      defaultWorldDatabase = properties.getProperty("defaultWorldDatabase");     
      dirName = properties.getProperty("WSASQLTmpDir");
      tmpWeb=properties.getProperty("WSASQLTmpWeb");
      tmpCrossID = properties.getProperty("WSASQLTmpCrossID");
  }

  // Override the service method to update the serviceCounter...
  protected void service(HttpServletRequest req,
                         HttpServletResponse resp)
                         throws ServletException,IOException {

    enteringServiceMethod();

    try
    {
      super.service(req, resp);
    }
    finally
    {
      leavingServiceMethod();
    } ;
  }; // end of service

   public void destroy() {
  
       /*
       // Check to see if there are still any services running...
    if (numServices() > 0)
    {
      setShuttingDown(true);
    };

    // Wait for all services to finish...
    while (numServices() > 0)
    {
      try
      {
        Thread.sleep(100);
      }
      catch (InterruptedException e)
      {
      };
    }; */
       logger=null;
       super.destroy();
  };


  protected void doGet(HttpServletRequest req, HttpServletResponse res)
                 throws ServletException, IOException {
      res.setContentType("text/html");
      PrintWriter out = res.getWriter();
      String database;
 //     float max_lines=MAX_LINES_SMALLRADIUS;
      HttpSession session = req.getSession();
      boolean loginboolean=false;
      boolean upNamePresent=false;
      boolean errorFlag=false;
      StringBuffer errorMess= new StringBuffer("");
      String programmeID=null;
      int intProgrammeID=0;
      String radius=null;
      String email=null;
      String email1=null;
      String filename=null;
      BufferedReader br;
      File savedUploadFile=null;
      String line = null;
      int numberOfLines=0;
      float dRadius=0.0F;
      String formatParam=null;
      String compressParam=null;
      String rows=null;
      String emailAddress=null;
      //String select=null;
      String tableName=null;
      String baseTable=null;
      String whereClause=null;
      String otherTables=null;
      String otherTableConstraints=null;
      String selectList=null;
      String colID="objID";
      String qType="form";
      boolean doFree=false;
      String sqlStmt=null;
      int nearest=0;
      String community = String.valueOf(session.getAttribute("community"));
      String user = String.valueOf(session.getAttribute("user"));
      try {
      loginboolean=((Boolean)session.getAttribute("login")).booleanValue();
      }
      catch (Exception e){
          loginboolean=false;
      }
     if (loginboolean) {
         if (!community.equalsIgnoreCase("nonSurvey")){
             database=defaultUKIDSSDatabase;
         } else {
             database=user;
         }
     }
     else {
         database=defaultWorldDatabase;
     }
    try {
       if (server == null){
		   res.sendError(
	           res.SC_BAD_REQUEST,
	            "INVALID SQL Server. Check properties file."
	            );
			}
       out.println(
               HTMLStrings.getHTMLHeadWithScript(
                 resultsPageHeading,
                 baseURL + "configurestyles.js"
               )
             );

             out.println(
               "    <h1>" + resultsPageHeading + "</h1> \n"
             );
       try {

           MultipartParser mp = new MultipartParser(req, 10 * 1024 * 1024); // 10MB

           Part part;
           out.println("<p>Parsing input .....");
           while ((part = mp.readNextPart()) != null) {
               String name = part.getName();
               if (part.isParam()) {
                   
 
                   
                   
                   
                   // it's a parameter part
                   ParamPart paramPart = (ParamPart) part;
                   String value = paramPart.getStringValue();
 //                  out.print("<p>"+name+" "+value)
   	  		  	 if (name.equalsIgnoreCase("format")){
    				   formatParam=value;
    	  		  	 }
    	  		  	 if (name.equalsIgnoreCase("compress")){
    				   compressParam=value;
    	  		  	 }
    	  		  	 if (name.equalsIgnoreCase("rows")){
    				   rows=value;
    	  		  	 }
    	  		  	 if (name.equalsIgnoreCase("emailAddress")){
    				   emailAddress=value;
    				   if (!emailAddress.equals("")) {
    				   out.println("<p>Email: "+emailAddress);
    				   }
    	  		  	 }
    				 if (name.equalsIgnoreCase("selectList")){
    				   selectList=value;
    	  		  	 }
    				 if (name.equalsIgnoreCase("whereClause")){
      				   whereClause=value.trim();
      	  		  	 }
     				 if (name.equalsIgnoreCase("database")){
      				   database=value;
      	  		  	 }
    				 if (name.equalsIgnoreCase("qType")){
        				   qType=value;
        	  		  	 }
       				 if (name.equalsIgnoreCase("sqlStmt")){
      				   sqlStmt=value;
      	  		  	 }
                   
                   
                   
                   if (name.equalsIgnoreCase("programmeID")) {
                       out.println("<p>Programme: ");
                       programmeID = value.trim();
                       if (programmeID.equalsIgnoreCase("null") || programmeID == null) {
                           errorFlag=true;
                           errorMess.append("<p><b>No survey selected.</b>");
                       }
                       try {
                           intProgrammeID=Integer.valueOf(programmeID).intValue();
                           out.println(WSASchema.getSurveyName(intProgrammeID));
                           
                       }
                       catch (Exception e) {
                           errorFlag=true;
                           errorMess.append("<p><b>Invalid survey/progammeID</b>");
                           
                       }
                       
                   }
                   if (name.equalsIgnoreCase("baseTable")) {
                       baseTable=value.trim();
                       if (baseTable.equalsIgnoreCase("null") || baseTable == null) {
                           errorFlag=true;
                           errorMess.append("<p><b>No table selected.</b>");
                       }
                       if (baseTable.equalsIgnoreCase("source") || baseTable.equalsIgnoreCase("sourceView")){
                           colID="sourceID";
                       }
             
                   }
                   if (name.equalsIgnoreCase("nearest")) {
                       nearest=Integer.valueOf(value.trim()).intValue();
                       if (nearest==0) {
                           out.println("<p>All nearby objects:");
                       }
                       else {
                           out.println("<p>Nearest object only:");
                       }
                   }
                   if (name.equalsIgnoreCase("otherTables")) {
                       otherTables=value.trim();
                   }
                   if (name.equalsIgnoreCase("otherTableConstraints")) {
                       otherTableConstraints=value.trim();
                   }

                   if (name.equalsIgnoreCase("radius")) {
                       radius = value.trim();
                       out.println("<p>radius: "+radius);
                       try {
                       dRadius=Float.valueOf(radius).floatValue();
                    
                   }
                   catch (Exception e) {
                       errorFlag=true;
                       errorMess.append("<p><b>Invalid radius (not a number?)</b>");
                       
                   }
                //   out.println("<p>radius: "+max_lines);
                   }
    
  

                   //  out.println("param: name=" + name + "; value=" +
                   // value);
               } else if (part.isFile()) {

                   // it's a file part

                   FilePart filePart = (FilePart) part;

                   filename = filePart.getFileName();

                   if (filename == null) {
                       errorFlag=true;
                       errorMess.append("<p><b>No file name supplied</b>");
                   }


                   out.println("<p>Parsing upload file ...");
                   out.flush();
                   
                   
                   if (filename != null) {
                       
                       File dir = new File(tmpCrossID);
                       savedUploadFile = File.createTempFile("upload_crossID", "tmp",
                               dir);
                       // out.println("<br>"+savedUploadFile.getAbsolutePath());
                       //out.println("<br>"+savedUploadFile.getName());
                       long size = filePart.writeTo(savedUploadFile);
                
                       if (size == 0) {
                           errorFlag=true;
                           errorMess.append("<p><b>Upload file contain zero bytes, check filename</b>");
                       }
                      
                       if (!errorFlag) {
                       br = new BufferedReader(new InputStreamReader(
                               new FileInputStream(savedUploadFile)));
                       //out.println("heres");
                       line="";
                       Object [] tempobjs = new Object[4];
                       while ((line=br.readLine()) !=null && numberOfLines < MAX_LINES_SMALLRADIUS+1) {
                           numberOfLines++;
                           
                           try {
                           tempobjs=StringToRADec.getRADec(line.trim(),false);
                          
                               if (tempobjs[3] != null && tempobjs[3].toString() != null && !tempobjs[3].toString().equals(StringToRADec.nullStr)) {
                                   upNamePresent=true;
                                   
                               }
                           
  
                           }
                           catch (NumberFormatException nfe) {
 
                               errorFlag=true;
                               errorMess.append("<br> error reading coords at line "+numberOfLines);
                               
                           }
                           catch (Exception e) {
                               
                           }

                       }
                       tempobjs=null;
                       if (upNamePresent) {
                           logger.info("CrossID logical upNamePres: " + upNamePresent);
                       }
                       br.close();
                       }
                       
                       
                       out.println("<p>"+filename+" uploaded file size: " + size
                               + " bytes, " + numberOfLines + " rows loaded");
                       out.flush();
                       

                   } 
               }
               
               
  
               
               
           }
           
           if (dRadius >= 5.0 && numberOfLines > MAX_LINES_LARGERADIUS) {
               errorFlag=true;
               errorMess.append("<p><b>File contained more than "+MAX_LINES_LARGERADIUS+ " lines</b>");
            
           }
           if (dRadius < 5.0 && numberOfLines > MAX_LINES_SMALLRADIUS) {
               errorFlag=true;
               errorMess.append("<p><b>File contained more than "+MAX_LINES_SMALLRADIUS+ " lines</b>");
            
           }
   
           out.flush();
/*
           if (numberOfLines*dUserX > MAX_LINES * 1.0) {
               errorFlag=true;
               errorMess.append("<p><b>Total area requested: number objects x size &gt; "+MAX_LINES+" sq arcmin</b>");
           }
*/         
           
           
 
           
           
           if (dRadius < 0.1F || dRadius > 300.0F) {
               errorFlag=true;
               errorMess.append("<p><b>Size should be &gt; 0.1 arcsec and &lt; 300 arcsec</b>");
           }
           if (emailAddress != null && !emailAddress.equals("")) {
               if (emailAddress.length() < 3 || emailAddress.indexOf('@') < 0) {
                   errorFlag=true;
                   errorMess.append("<p><b>Invalid email supplied</b>"); 
               }
             
           } 
           
           if (errorFlag) {
               out.print(errorMess+"<p>Use the browser's back button to return to the form");
               return;
           } 
       
           
           
       } catch (IOException IOEx) {
           out.println(IOEx);
       }
       
       String defaultSelect=null;
       
       if (community.equalsIgnoreCase("nonSurvey")) {
           tableName=user.trim()+baseTable;
           int [] reqFilters=null;
           if (session.getAttribute("reqFilters") !=null){
               reqFilters=((int [])session.getAttribute("reqFilters"));
               }
           defaultSelect=WSASchema.getDefaultList(reqFilters,tableName,WSASession.getSchemaVersion(session));
       }
       else
       {
           if (baseTable.equalsIgnoreCase("sourceView")) {
               tableName=WSASchema.getSourceViewName(intProgrammeID);
           }
           else if (baseTable.equalsIgnoreCase("source")) {
           tableName=WSASchema.getSourceTableName(intProgrammeID);
       }
           else if (baseTable.equalsIgnoreCase("detection")) {
               tableName=WSASchema.getDetectionTableName(intProgrammeID);
           }
           defaultSelect=WSASchema.getDefaultList(WSASchema.getReqFilters(intProgrammeID),tableName,database);
       }
      // String where="";
      // if (whereClause.length() > 2) {
      //     where=" and "+whereClause+" ";
      // }
       String select=selectList.replaceAll("default",defaultSelect);
       
       
		if (qType != null && qType.equalsIgnoreCase("free")) {
		    doFree=true;
		    out.print("<br><b>Where:</b> "+whereClause + " used in initial crossID");
		   
		}
		else {
       
       out.print("<br><b>From:</b> "+tableName);
       out.print("<br><b>Where:</b> "+whereClause);
       
		}
       
      // FIRST THING: Extract and verify all the provided parameters...
      SQLServerInfoJDBC SQLServer = null;
      String SQLQueryString = "";
      String ra=null;
      String dec=null;
      String ra2000=null;
      String dec2000=null;
      
      String name=null;
      String sys=null;
      
      String action=null;
      
      String from=null;
      int tableid=0;
      
      

      int rowsHTML = WSASQLRetrieverThread.SQLROWS_DEFAULT;
      boolean doRowTotal = true;

      int OutputFormat = WSASQLRetrieverThread.OUTPUT_NONE;
      int OutputCompression = WSASQLRetrieverThread.COMPRESS_NONE;

 
 
      String emailTAR = null;
      
      boolean fg=true;
      Statement retrieverStmt=null;
      String dbURL=DatabaseURL.getDatabaseURL(session,useTDS,server,database,database);
      
      if (sqlStmt != null) {
         
              if (sqlStmt.toLowerCase().indexOf("bestdr3..") > 0 ||
                  sqlStmt.toLowerCase().indexOf("seguedr6..") > 0 ||
                  sqlStmt.toLowerCase().indexOf("thutmose..") > 0 ||
                  sqlStmt.toLowerCase().indexOf("bestdr5..") > 0 ||
                  sqlStmt.toLowerCase().indexOf("bestdr7..") > 0 ||
                  sqlStmt.toLowerCase().indexOf("bestdr2..") > 0) {
                  dbURL=DatabaseURL.getDatabaseURL(session,useTDS,"thutmose",database,database);
          }
      }
      
      
      //String dbURL=DatabaseURL.getDatabaseURL(session,useTDS,server,database,database);
      database=DatabaseURL.getDatabaseNameFromURL(dbURL,true);
      //out.println(dbURL);
      //resultsPageHeading = "WSA Database - Query Results"; 


		  // baseURL= "http://thoth.roe.ac.uk/wsa/";
		   resultsPageHeading = "WSA Database - CrossID Query Results";


  

  

        String extraFrom="";
        String extraWhere="";
		if (otherTables !=null && !otherTables.equals("")) {
		    extraFrom=","+otherTables;
		}
		if (otherTableConstraints !=null && !otherTableConstraints.equals("")) {
		    extraWhere=" where "+otherTableConstraints;
		}
		
		
		if (doFree) {
		    SQLQueryString=sqlStmt;
		   // session.setAttribute("CrossIDSQLStmt",SQLQueryString);
		    out.println("<p>"+SQLQueryString);
		   
		}
		else {
        SQLQueryString="select #upload.*,#proxtab.distance,"+select+" from  #upload left outer join #proxtab on #upload.upload_id=upid " +
        		"left outer join "+tableName+" on "+tableName+"."+colID+"=archiveID "+extraFrom+" "+extraWhere+" order by upload_id";
        out.println("\n<!-- SQL QUERY : "+SQLQueryString+" -->");
		}
        
        //out.println("<p>"+SQLQueryString);
        if (SQLQueryString == null)
        {
          res.sendError(
            res.SC_BAD_REQUEST,
            "No SQL query was provided as parameter 'sql'."
          );
          return; // Finish this method immediately...
        }
        else if (SQLQueryString.length() > 4096)
        {
          res.sendError(
            res.SC_BAD_REQUEST,
            "The SQL query parameter 'sql' cannot exceed a length of 4096 characters."
          );
          return;
        }
        else
        {
          // Now we can extract the final OPTIONAL parameters...
 
/*
	      if (req.getParameter("emailAddress") != null && !req.getParameter("emailAddress").equals(""))
	      {
	        emailAddress = req.getParameter("emailAddress");
             if (
                   ( emailAddress.length() < 3) ||
                   (emailAddress.indexOf("@") == -1)
                 )
              {
                res.sendError(
                  res.SC_BAD_REQUEST,
                  "You must also include a VALID e-mail address  " +
                  "(your emailAdddress= parameter seems to be empty or " +
                  "incorrect) "
                );
                return;
			}
		  }
		  else
		  {
			  emailAddress=null;
		  }

*/

          
     
            try
            {
            	rowsHTML = Integer.parseInt(rows);
            }
            catch (NumberFormatException e)
            {
              rowsHTML = WSASQLRetrieverThread.SQLROWS_DEFAULT;
            };

            if (rowsHTML < 0)
            {
              rowsHTML = 0;
            };
         
           
          // When more rows are returned than displayed in summary,
          // does the user want to know the total rows returned?
          // Default, yes, takes slightly more time to run...
    
          // What about compression?
         
            if (compressParam.equalsIgnoreCase("ZIP"))
            {
              OutputCompression = WSASQLRetrieverThread.COMPRESS_ZIP;
            }
            else if (compressParam.equalsIgnoreCase("GZIP"))
            {
              OutputCompression = WSASQLRetrieverThread.COMPRESS_GZIP;
            }
            else
            {
              OutputCompression = WSASQLRetrieverThread.COMPRESS_NONE;
            };
         
    
          // Any special format (in addition to HTML) requested?
   
            if (formatParam.equalsIgnoreCase("CSV"))
            {
              OutputFormat = WSASQLRetrieverThread.OUTPUT_CSV;
            }
            else

            if (formatParam.equalsIgnoreCase("FITS"))
            {
			  OutputFormat = WSASQLRetrieverThread.OUTPUT_FITS;
		    }
            else
            if (formatParam.equalsIgnoreCase("VOT"))
			            {
						  OutputFormat = WSASQLRetrieverThread.OUTPUT_VOT;
		    }
		    else
            {
              OutputFormat = WSASQLRetrieverThread.OUTPUT_NONE;
            };
          

 
   

          // Now we should have everything we need, attempt to get the data...

          // Connect to the database and attempt to execute the provided SQL
          // Set the content type and then formulate the normal response...
        
          //String procSQL="EXEC master..spTest1 "+dRadius/60.0+",'ukidssr1..spectra','specid',1,' and specid <=100'";
          //out.print("<p> "+procSQL);
          WSASQLRetrieverThread retrieverThread = null;
          Thread runner = null;

          try
          {
            //out = res.getWriter();

            // Prepare the heading of the HTML document:
        
       //     out.println(":"+SQLQueryString);
            if (OutputFormat != WSASQLRetrieverThread.OUTPUT_NONE)
            {
              out.println(
                "    <p> \n" +
                "      Data file generating queries can take a bit longer to execute \n" +
                "      as they write to a file ALL rows returned by the query. \n" +
                "    </p> \n"
              );

              out.println(
                "    <p> \n" +
                "      A web link to your generated output file will appear at the \n" +
                "      bottom of this page. \n" +
                "    </p> \n"
              );
            };

            out.println(
              "    <p>"
            );
            
                out.println("<b>Using database "+database+"</b><br>");
            
                
            out.print(
              "      <b>QUERY STARTED:</b> " +
                Calendar.getInstance().getTime() +
                "&nbsp;&nbsp;&nbsp;[" + getServiceCurrent() + " active, " +
                getServiceTotal() + " total] \n"
            );

            out.println(
              "    </p> \n"
            );

            out.println(
              "    <p> \n" +
              "      Please keep this browser window open and wait for your results to appear below... \n" +
              "    </p> \n"
            );

            res.flushBuffer();

            // THIS SECTION WILL DO THE QUERY:


             // retrieverThread = new WSASQLRetrieverThread(SQLServer); // Server we setup earlier...
            retrieverThread = new WSASQLRetrieverThread(dbURL);
            retrieverThread.setDatabaseName(database);
            
            //retrieverThread.updateWebqueries=true;
//            retrieverThread.setCrossIDParameters(database,tableName,select,whereClause,colID,dRadius,nearest);
            retrieverThread.setCrossIDParameters(database,tableName,select,whereClause,colID,dRadius,nearest,otherTables,otherTableConstraints);
            if (doFree) {
            retrieverThread.showSQL=true;
            }
            retrieverThread.setOutputBaseDIR(
//                "/home/6df/public_html/"
				dirName
              );
              retrieverThread.setOutputBaseURL(
//                "http://www-wfau.roe.ac.uk/6dFGS/"
                   tmpWeb
              );
              retrieverThread.setOutputAppendage(
                "/crossID/"
              );



            // Pass through any parameters to the retriever...
             String IPAddress=req.getRemoteAddr();
            logger.info("CROSSID,Login,"+(String)session.getAttribute("user")+","+(String)session.getAttribute("community")+","+IPAddress);
            logger.info("CROSSID,URL,"+dbURL+","+IPAddress);
            logger.info("CROSSID,Query,"+SQLQueryString.replaceAll("\n"," ").replaceAll("\r"," ")+","+IPAddress); 
            retrieverThread.setUser(WSASession.getUser(session));
            retrieverThread.setIPAddress(IPAddress);
            retrieverThread.setSQLQuery(SQLQueryString);
            retrieverThread.upNamePresent=upNamePresent;
            //retrieverThread.setSQLQuery(SQLQueryString);
            retrieverThread.setRowsHTML(rowsHTML);
            retrieverThread.setDoRowTotal(doRowTotal);
            retrieverThread.setOutputFormat(OutputFormat);
            //out.println(OutputFormat);
            retrieverThread.setOutputCompression(OutputCompression);
            //out.println(savedUploadFile.getAbsolutePath());
            retrieverThread.setUploadFile(savedUploadFile.getAbsolutePath());
            retrieverThread.setRadius(radius);
           // retrieverThread.setPair(pair);

            
            if (emailAddress != null && emailAddress.equals("")) {
                emailAddress=null;
            }
            
            if ( emailAddress != null)
            {
				retrieverThread.setMightBeBackground(true);
			}



            // Start a separate thread running to retrieve the SQL...
            runner = new Thread(retrieverThread);
            retrieverStmt=retrieverThread.setConnection();
            if (retrieverStmt != null) {
                out.println("Connected to database");
            runner.start();
            }
            else {
                out.println("<h3>Unable to connect to database</h3><br>Please try again at a later time, if the problem persists send an " +
                		"email to mar@roe.ac.uk");
            }

    // Calls the the resolving method with the command line argument

         

            out.println("    <p>");
             
            int dotCount = 0;

            while (
                    (!isShuttingDown()) &&
                    (runner.isAlive()) &&
                    (retrieverThread.isQueryProcessing() && fg == true)
                  )
            {
	             if ( emailAddress != null && dotCount >= 27 )
	             {
					 retrieverThread.setEmailAddress(emailAddress);
					 fg = false;
				  }
              try
              {
                Thread.sleep(3000);
              }
              catch (InterruptedException ie)
              {
                // Do nothing when interrupted...
              }

              out.print(
                "&#8226;&#8226;&#8226;<!--               -->"     
              );

              
              res.flushBuffer();

              //dotCount++;
                dotCount=dotCount+3;
              if ((dotCount % 30) == 0)
              {
                out.println(" "+
                   retrieverThread.getRowsReturned() + " rows returned so far <br>"
                );

                //dotCount = 0;
              }
            }

            

			if (fg || !retrieverThread.isQueryProcessing()) {

            fg=true;
			out.println("      OK");
            out.println("    </p> \n");

            retrieverThread.setQueryTerminated(true);
            retrieverThread.setMightBeBackground(false);
            out.println(retrieverThread.getResultsHTML());

            out.println(
              "    <p> \n" +
              "      <b>QUERY FINISHED:</b> " + Calendar.getInstance().getTime() + " \n" +
              "    </p> \n"
            );

            out.println(
              "    <p> \n" +
              "      Click your browsers 'BACK' button to try another query...\n" +
              "    </p> \n"
            );

            if (action.equalsIgnoreCase("radial")) {
				out.println(
					"<form action=\"pixel.jsp?ra="+ra2000+"&dec="+dec2000+
					"&radius="+radius+"&sys="+sys+"\" method=\"post\">" +
					"<input class=\"FontSans\" type=\"submit\" value=\"getAreaImage\" /> </form> "+
					"Click the getAreaImage button to retrieve an image of the searched area"
					);
				}


            out.println(
              HTMLStrings.getHTMLTail(baseURL + "browserversion.js")
            );

			}
			else
			{
				out.println("<p> Query moved to background. "+
								"On completion you will be informed where to retrieve your results by email to <b>"+
				emailAddress+"</b><p> Click your browsers 'BACK' button to return to the WSA pages. </body></html>");

			}




            // QUERY DONE!
          }
          finally
          {
              out.flush();
            // Free up resources...
//            System.out.println("here");
//            File fooFile = new File("/home/6df/tada.txt");
//            fooFile.createNewFile();
//				File fooFile = new File("/home/avo/mar/tada.txt");
 //           fooFile.createNewFile();

            if (fg == true) {

            	if (retrieverThread != null)
            	{
					/*
					if (retrieverThread.isQueryProcessing()){
						System.out.println("resorting to close");
						retrieverThread.setDBConnectionClosed();
					}
                    */
            	    if (retrieverThread.isQueryProcessing()){
            	       
            	        logger.info("CROSSID,CANCEL,cancelling");
            	        try {
            	        retrieverStmt.cancel();
            	        retrieverStmt=null;
            	    }
            	    catch (Exception se) {
            	        System.out.println(	se);
            	    }
            	    }

            	  retrieverThread.setQueryTerminated(true);
            	  //System.out.println("stopped");
            	};

			}

				runner = null;
        	    retrieverThread = null;

            if (out != null)
            {
              out.close();
            };

            out = null;
          }; // try..finally
        }; // end of valid SQL string
      //}; // end of valid server if (SQLServer == null) else...
    } // end of initail try or doGet
    catch (Exception e)
    {
/*       
      res.sendError(
        res.SC_INTERNAL_SERVER_ERROR,
        e + ""
      );
      */
      return;
    };
  }; // END of doGet()

  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()

  public String getServletInfo() {
    return "SQLGet v1.20 by Alan Maxwell";
  }; // END of getServletInfo()
};
