/**
 *  Ensebl human blast
 *  Internet robot, blastN_human_ensembl, that uses form, located in page
 *  http://www.ensembl.org/Homo_sapiens/blastview.
 *  It is your responsibility to find and cite appropriate references
 *  from this page.
 *  Generated 2002.5.27  by Sight 2.0, Ulm university.
 */
package impl.Blast;

import Sight.Agents.*;
import Sight.Agents.Redirectors.*;
import Sight.Structures.*;
import Sight.dds.*;
import Sight.tools.xSignature.*;
import java.io.*;
import Sight.Agents.util.*;

public class blast_human_ensembl extends Sight.Agents.Prototypes.preformattedResponseAgent implements Serializable {
 /* Data structure to pass query to this robot. */
  public class Request extends Sight.Request implements java.io.Serializable {
   public String Sequence; // required.
     /** Choices for database:
    * 'Homo_sapiens.cdna.genscan.fa'=Homo sapiens, cDNA (genscan) 'Homo_sapiens.cdna.fa'=Homo sapiens, cDNA (known + novel)
    * 'Homo_sapiens.cdna.known.fa'=Homo sapiens, cDNA (known only) 'Homo_sapiens.cdna.novel.fa'=Homo sapiens, cDNA (novel only)
    * 'Homo_sapiens.latestgp.fa'=Homo sapiens, genomic sequence default 'Homo_sapiens.latestgp.masked.fa'=Homo sapiens, genomic sequence (masked)
    * 'Homo_sapiens.pep.genscan.fa'=Homo sapiens, peptides (genscan) 'Homo_sapiens.pep.fa'=Homo sapiens, peptides (known + novel)
    * 'Homo_sapiens.pep.known.fa'=Homo sapiens, peptides (known only) 'Homo_sapiens.pep.novel.fa'=Homo sapiens, peptides (novel only)
    * , default='Homo_sapiens.latestgp.fa'. */
   public String Database="'Homo_sapiens.latestgp.fa'"; // select
     /** Choices for blast_type:
    * wublastn=BLASTN (DNA vs.DNA) default wutblastn=TBLASTN (protein vs. transl. DNA)
    * wutblastx=TBLASTX (transl. DNA vs. transl DNA) , default=wublastn. */
   public String Blast_type="wutblastn"; // select
   /** default=0 */
   /** default=T */
   public String Repeatmasker="T"; // checkbox
   /** default=T */
   public String Filtering="T"; // checkbox
     /** Choices for matrix:
    * BLOSUM30=blosum30 BLOSUM40=blosum40 BLOSUM50=blosum50 BLOSUM60=blosum60 BLOSUM62=blosum62 default
    * BLOSUM70=blosum70 BLOSUM80=blosum80 BLOSUM90=blosum90 BLOSUM100=blosum100 DAYHOFF=dayhoff
    * DNA_MAT=dna_mat GONNET=gonnet IDENTITY=identity PAM30=pam30 PAM60=pam60 PAM90=pam90
    * PAM120=pam120 PAM150=pam150 PAM180=pam180 PAM210=pam210 PAM240=pam240 , default=BLOSUM62. */
   public String Matrix="BLOSUM62"; // select
     /** Choices for expect:
    * 0.0001=0.0001 0.01=0.01 1=1 10=10 default 100=100 1000=1000 , default=10. */
   public String Expect="10"; // select
     /** Choices for descriptions:
    * 10=10 50=50 100=100 default 250=250 500=500 , default=100. */
   public String Descriptions="100"; // select
     /** Choices for sort:
    * -sort_by_pvalue=pvalue default -sort_by_count=count -sort_by_highscore=highscore
    * -sort_by_totalscore=totalscore , default=-sort_by_pvalue. */
   public String Sort="-sort_by_pvalue"; // select
     /** Choices for filtertype:
    * seg=seg default xnu=xnu seg+xnu=seg+xnu , default=seg. */
   public String Filtertype="seg"; // select
     /** Choices for gencode:
    * 1=Standard default 2=Vertebrate Mitochondrial 3=Yeast Mitochondrial 4=Mold Mitochondrial
    * 5=Invertebrate Mitochondrial 6=Ciliate Nuclear 9=Echinoderm Mitochondrial 11=Eubacterial
    * 12=Alternative Yeast Nuclear 13=Ascidian Mitochondrial 14=Flatworm Mitochondrial
    * , default=1. */
   public String Gencode="1"; // select
   /** default= */
   public String Altoptions=""; //
       /** Submit request, compute key by SHA digesting algorithm. */
       public Sight.Agents.Request submit() { return Sight.Agents.Request.submit(Public, this, getKey()); };
       /** Submit request with the known key. */
       public Sight.Agents.Request submit(String key)
        { return Sight.Agents.Request.submit(Public, this, key); };
       };

   /** Get the AMap data structure, required by post method. */
  protected AMap getFormParameters(Object req) {
    Request request = (Request) req;

    if ( (request.Matrix.startsWith("BLOSUM") || request.Matrix.startsWith("PAM"))
        && request.Blast_type.equals("wutblastn"))
        request.Matrix = "DNA_MAT";

    AMap map = new AMap();
    map.add("connect:url", "http://www.ensembl.org/Homo_sapiens/blastview"); // connect
    map.add("connect:action", "POST"); // connect
    map.add("connect:master", "http://www.ensembl.org/Homo_sapiens/blastview"); // connect
    map.add("sequence", request.Sequence); // textarea
    map.add("type", "blast"); // hidden
    map.add("format", "karyo_format"); // hidden
    map.add("database", request.Database); // select
    map.add("blast_type", request.Blast_type); // select
    map.add("align", request.Descriptions); //
    map.add("repeatmasker", request.Repeatmasker); // checkbox
    map.add("filtering", request.Filtering); // checkbox
    map.add("histogram", "F"); // checkbox
    map.add("matrix", request.Matrix); // select
    map.add("expect", request.Expect); // select
    map.add("descriptions", request.Descriptions); // select
    map.add("statistics", "-sump"); // select
    map.add("sort", request.Sort); // select
    map.add("filtertype", request.Filtertype); // select
    map.add("gencode", request.Gencode); // select
    map.add("altoptions", request.Altoptions); //
    return map; };
  /** Get default request for this robot. */
  public static Request getDefaultRequest() {
     return Public.getRequest(); }
  private Request getRequest() { return new Request(); }; // must be non static

    /** Type definitions for Request. */
   public dStructure getRequestDds() {
    return new Sight.dds.Records(false,
     new dField[] {
        new dField("Sequence","CharSequence","Sequence to search",""),
        new dField("Database","CharSequence","Database","\'Homo_sapiens.latestgp.fa\'",new String[] {"\'Homo_sapiens.cdna.genscan.fa\'","\'Homo_sapiens.cdna.fa\'","\'Homo_sapiens.cdna.known.fa\'","\'Homo_sapiens.cdna.novel.fa\'","\'Homo_sapiens.latestgp.fa\'","\'Homo_sapiens.latestgp.masked.fa\'","\'Homo_sapiens.pep.genscan.fa\'","\'Homo_sapiens.pep.fa\'","\'Homo_sapiens.pep.known.fa\'","\'Homo_sapiens.pep.novel.fa\'"},new String[] {"Homo sapiens, cDNA (genscan)","Homo sapiens, cDNA (known + novel)","Homo sapiens, cDNA (known only)","Homo sapiens, cDNA (novel only)","Homo sapiens, genomic sequence default","Homo sapiens, genomic sequence (masked)","Homo sapiens, peptides (genscan)","Homo sapiens, peptides (known + novel)","Homo sapiens, peptides (known only)","Homo sapiens, peptides (novel only)"}),
        new dField("Blast_type","CharSequence","blast type","wutblastn",new String[] {"wublastn","wutblastn","wutblastx"},new String[] {"BLASTN (DNA vs.DNA)","TBLASTN (protein vs. transl. DNA) default","TBLASTX (transl. DNA vs. transl DNA)"}),
        new dField("Align","CharSequence",null,"0"),
        new dField("Repeatmasker","CharSequence","Mask repeats","T"),
        new dField("Filtering","CharSequence","Filter","T"),
        new dField("Matrix","CharSequence","Matrix","DNA_MAT",new String[] {"BLOSUM30","BLOSUM40","BLOSUM50","BLOSUM60","BLOSUM62","BLOSUM70","BLOSUM80","BLOSUM90","BLOSUM100","DAYHOFF","DNA_MAT","GONNET","IDENTITY","PAM30","PAM60","PAM90","PAM120","PAM150","PAM180","PAM210","PAM240"},new String[] {"blosum30","blosum40","blosum50","blosum60","blosum62 default","blosum70","blosum80","blosum90","blosum100","dayhoff","dna_mat","gonnet","identity","pam30","pam60","pam90","pam120","pam150","pam180","pam210","pam240"}),
        new dField("Expect","CharSequence","E value","10",new String[] {"0.0001","0.01","1","10","100","1000"},new String[] {"0.0001","0.01","1","10 default","100","1000"}),
        new dField("Descriptions","CharSequence","Descriptions","100",new String[] {"10","50","100","250","500"},new String[] {"10","50","100 default","250","500"}),
        new dField("Sort","CharSequence",null,"-sort_by_pvalue",new String[] {"-sort_by_pvalue","-sort_by_count","-sort_by_highscore","-sort_by_totalscore"},new String[] {"pvalue default","count","highscore","totalscore"}),
        new dField("Filtertype","CharSequence","Filter type","seg",new String[] {"seg","xnu","seg+xnu"},new String[] {"seg default","xnu","seg+xnu"}),
        new dField("Gencode","CharSequence","Genetic code (blastx only)","1",new String[] {"1","2","3","4","5","6","9","11","12","13","14"},new String[] {"Standard default","Vertebrate Mitochondrial","Yeast Mitochondrial","Mold Mitochondrial","Invertebrate Mitochondrial","Ciliate Nuclear","Echinoderm Mitochondrial","Eubacterial","Alternative Yeast Nuclear","Ascidian Mitochondrial","Flatworm Mitochondrial"}),
        new dField("Altoptions","CharSequence","Advanced options","")                 }
    );
   }
 /* Record type, used in results for this robot. */
 /* The result of this robot is an array of records. */
  public static class Record extends Sight.Record implements Serializable {
        public CharSequence chromosome;
        public CharSequence accession;
        /** accession number like NCBi but with longer suffix */
        public CharSequence accession_long;
        public CharSequence length;
        public CharSequence E;
        /** N */
        public CharSequence N;
      };
      /** The result of this robot. */
      public static class Result extends Sight.Result implements Serializable {
         public Record[] a; // array of results.
         /** Create report for one record. */
         public CharSequence getReportForRecord(Object ro, int level)
          { Record r = (Record) ro;
           switch (level) {
              case 0:   return " chr"+r.chromosome+" "+r.accession+" ("+r.E+") ";
              default:  return "<tr><td>"+r.chromosome+"</td><td>"+r.accession_long+"</td><td>"+r.E+"</td></tr>";
            }
          };

      /** Get BLAST report. Use generalizer for the first level. */
      public String getReport(Object[] x, int verbosityLevel)
       {
         boolean singleLine = x.length<=1;
         StringBuffer b = new StringBuffer();
         if (verbosityLevel>=1)
          { b.append(getAgentSignature());
            b.append(": ");
          };

         if (verbosityLevel==0)
          {
           Record r;
           for (int i = 0; i < x.length; i++) {
             b.append(getReportForRecord(x[i], 0));
             b.append(", ");
             if (i>12)
              {
               b.append(" ... ("+x.length+" hits)");
               break;
              };
             };
          }
          else
          {
           b.append(Sight.Agents.Variants.sBlaster.defaultTableHeader);
           b.append("<tr><td>Chr</td><td>accession</td><td>E</td></tr>");
           for (int i = 0; i < x.length; i++) {
             b.append(getReportForRecord(x[i], verbosityLevel));
             if ( (i>=5 && verbosityLevel==1) || i>=21)
              {
                b.append("<tr><td colspan=\"3\">(truncated, "+x.length+" hits in total)<td></tr>");
                break;
              };
           }
           b.append("</table>");
          };
         return  b.toString();
       };
      }

    /** Type definitions for Result. */
   public dStructure getResultDds() {
    return new Sight.dds.Records(true,
     new dField[] {
        new dField("chromosome","CharSequence",null,""),
        new dField("accession","CharSequence","NCBI compatible accession",""),
        new dField("accession_long","CharSequence","accession number like NCBI but with longer suffix",""),
        new dField("length","CharSequence",null,""),
        new dField("E","CharSequence",null,""),
        new dField("N","CharSequence","N","number of hits?")                 }
    );
   }

  public Sight.Record createRecord(String[] row) throws Exception
    { return fillRecord(row); };
  public Class getRecordClass() { return Record.class; };
   Record fillRecord(String[] fields) throws Exception {
        Record r = new Record();
        r.chromosome=fields[0];
        r.accession_long=noHtml(fields[2]);

        String ac = r.accession_long.toString();
        int a = ac.indexOf('.');
        if (a>=0) r.accession = ac.substring(0,a);
             else r.accession = ac;

        r.length=fields[3];
        r.E=fields[4];
        r.N=fields[5];
        return r;
   };

   /** Get result from the given html content. */
  public Sight.Result resultFromString(String html) throws Exception {
     Result r = new Result();
     r.a = (Record[]) createResultArray(html);
     return r;
   };

  /** Signatures to get RID. */
  multiSignatures bQsignatures;
  public blast_human_ensembl() {

   signatures = new Sight.tools.xPlain.multiSignatures();
   signatures.far_start=null;
   signatures.top="Sequences producing significant alignments:                  Score  P(N)      N";
   signatures.bottom=" </center> </pre>";
   signatures.Columns = 6;

   bQsignatures = new multiSignatures();
   bQsignatures.far_start=null;
   bQsignatures.top="BLAST RETRIEVAL ID";
   bQsignatures.bottom="</table>";
   bQsignatures.signatures =
   new Signature[] {
   new Signature(" <td align=\"center\"><a href=\"","\"")
   };
   setDescription("Ensebl human blast");
   setFormURL("http://www.ensembl.org/Homo_sapiens/blastview");
   setMasterURL("http://www.ensembl.org/Homo_sapiens/blastview");
   // define pre scan section.
   preScan = new preScan();

   addRedirector(new Ensembl_BLAST_Redirector());
   };
  /** Public instance of agent for user. */
  public static blast_human_ensembl Public = new blast_human_ensembl();
  public static Agent getAvailableAgent() { return Public; };
  /** main(..) method provided to check robot, launching it
   * as standalone program. */
  public static void main(String[] args) {
  Sight.Agents.util.Pind.showConsoles();
      try {
        Request request = getDefaultRequest();
        // Now modify and assign request fields in accordance with task:
        request. Sequence="GTTATTGCAATACATACAAAAAAGTTAAAGATTTTATGTATCACTAACATTAGAAGTTTTTTGCACCACTAATTTTTTAAAAATGGAAGGTAAACTGCATAGCCCAGAGAAAGATAAGTAAATATTTAAGAACATATTGAACAACTTTGCTATTTAAAGATATTATCCAAGTACATAAATTACTCCGTTCTCTATCAGTTAAAGCTATTGAATATAATACTTAGCTTTACAAGAGAAAACCCATATTTGATGGGCAGAGATTATATCCCTATCTTCTTTTTCATGTAAACCACTGGTCACAAATGAACTGATCTCTGTATCCCATTATTACTATAAGAGGTGGGAATCCCAAAACTGCTTAGATTGCAGTACATGAGTTTACACAAAGACTTCAACAATTGCACATCTTCATTCTCCCAACTGAGTGTAGTATGTGGAGCATAAAACAGCATATTCTTAGTATTTCATGAATATCAGATGGTCTTTAAATGTCTCTTTATGGATGTATTGTTCACATTATGGCTTTAAAATAATGAATATGTAAAAGTGAGGTAGTGAACATCCTAAATTTCTACACTGGAATTACTAAATAATCTTATTTCATAAAATGGGAAATATATGTTAAATGACATCACTGGATGAACTTGAAGATCTTTTACTTGTTAACAAAAAAATACTATGGACAGCTTTCTGATTGTTGGGGTAAATAG";
        Sight.Agents.Request submission = request.submit();
        // processing now started in separate thread:
        Result response = (Result) submission.getResult();
        // print report, verbosity level 2:
        System.out.println(response.getReport(2));
      } catch (Exception exc)
         { if (exc!=null) System.out.println(exc.getMessage());
           exc.printStackTrace();
         };
   };

   public class Ensembl_BLAST_Redirector extends preScan implements RedirectionProvider, Cloneable
    {
      String rid = null;
      int rtoe = 10;

       public Redirection getRedirection(String text) throws SpecialStateException
        {
          if (text.indexOf("query has been added to the queue")>=0)
           {  try {
              // look for the RID information using bQsignatures:
              String [][] ids = bQsignatures.getIds(text);
              if (ids!=null)
               if (ids.length!=0)
                rid = ids[0][0];

               if (rid!=null)
                { p("Rid "+rid+" expected time "+rtoe);
                  return new Redirection(
                    rid, rtoe, "Initiation"+rid);
                };

              } catch (Exception exc)
                 {
                   exc.printStackTrace();
                 };
            } else
           if (text.indexOf("RESULTS NOT READY")>=0)
            { if (rid==null)
               { p("Rid lost!!!!");
                 return null;
               } else
                  { rtoe = rtoe + 20; // add 20 sec.
                    return new Redirection(
                     rid, rtoe, "still not ready "+rid);
                  }
            };
            /*
            else
            if (text.indexOf("View standard format BLAST results")>=0)
             {
               // ready - follow one more hyperlink
               int b = text.indexOf("\">View standard format BLAST results");
               int a = text.lastIndexOf('\"', b-1);
               String url = getURL(text.substring(a,b));
               return new Redirection(
                     rid, 25, "Final "+url);

             };
             */

          rid = null; rtoe = 120;
          return null;
        };

  /** !!!!! keep RedirectionSystem you loaded the response.
   *  This finaliser removes RID from NCBI database.
   *  Default sightGeneratedAgent go method follows this
   *  condition.
   */
  protected void finalize() throws java.lang.Throwable {
    if (rid!=null)
     { // delete this record from BLAST database:
       // feature not provided by this server at the moment of writing.
       super.finalize();
     };
   }

  public RedirectionProvider getCopy()
   { try {
      return (RedirectionProvider) (this.clone());
      } catch (CloneNotSupportedException exc)
         {
           throw new Error("This should never happen.");
         }
   }
  }



  }
// zero case
// "No hits resulted from this blast query"