/**
 *  NCBI protein BLAST
 *  Internet robot, blastP_ncbi, that uses form, located in page
 *  http://www.ncbi.nlm.nih.gov/blast/Blast.cgi.
 *  It is your responsibility to find and cite appropriate references
 *  from this page.
 *  This robots is written manually by Audrius Meskauskas, assisting
 *  Sight 2.0, Ulm university.
 *
 *  Form auto-resubmission will be taken automatically by code
 *  in sightGeneratedAgent.go(..)
 */
package impl.Blast;

import Sight.Agents.*;
import Sight.Agents.Variants.*;
import Sight.Structures.*;
import Sight.dds.*;
import java.io.*;
import java.util.*;
import Sight.Agents.util.*;

public class blastP_ncbi extends Sight.Agents.Variants.sBlaster implements Serializable {
 /* Data structure to pass query to this robot. */
  public class Request extends sBlaster.Request implements java.io.Serializable {
   public String Sequence; // required.
   public String Query_from="";
   public String Query_to="";
   public String Entrez_query = ""; // limit by Entrez query
   public String Database = "nr";   // database where to search
   /** default=10 */
   public String Expect="1"; // text
   /** default= */
   public String Other_advanced=""; // text
   /** default= */
   /** Service: plain, psi, phi, rpsblast, megablast */
   public String Service = "plain";
     /** Choices for WORD_SIZE:
    * 2 or 3, default=3, DO NOT SET OTHER VALUES! */
   public String Word_size="3"; // select
   public String Filter="T"; // checkbox
   public String Lcase_mask="F"; // checkbox

   /** Program to run: blastn, blastp, blastx, tblastn, tblastx */
       /** 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;
    AMap map = new AMap();
    map.add("connect:url", "http://www.ncbi.nlm.nih.gov/blast/Blast.cgi"); // connect
    map.add("connect:action", "POST"); // connect
    map.add("connect:master", "http://www.ncbi.nlm.nih.gov/blast/Blast.cgi"); // connect
    map.add("QUERY", request.Sequence); // textarea
    map.add("QUERY_FROM", request.Query_from); // text
    map.add("QUERY_TO", request.Query_to); // text
    map.add("DATABASE", request.Database); // select
    map.add("ENTREZ_QUERY", ""); // text
    map.add("ENTREZ_QUERY", ""); // select
    map.add("FILTER", request.Filter); // checkbox
    map.add("LCASE_MASK", request.Lcase_mask); // checkbox
    map.add("EXPECT", request.Expect); // text
    map.add("WORD_SIZE", request.Word_size); // select
    map.add("MATRIX_NAME", "BLOSUM62"); // others not supported
    map.add("OTHER_ADVANCED", request.Other_advanced); // text
    map.add("SHOW_OVERVIEW", "F"); // checkbox
    map.add("SHOW_LINKOUT", "T"); // checkbox
    map.add("NCBI_GI", "T"); // checkbox
    map.add("FORMAT_OBJECT", "Alignment"); // select
    map.add("FORMAT_TYPE", "HTML"); // select
    map.add("DESCRIPTIONS", request.Descriptions); // select
    map.add("ALIGNMENTS", "0"); // select
    map.add("ALIGNMENT_VIEW", "Pairwise"); // select
    map.add("RUN_PSIBLAST", "F"); // checkbox
    map.add("I_THRESH", "0.005"); // text
    map.add("FORMAT_ENTREZ_QUERY", ""); // text
    map.add("FORMAT_ENTREZ_QUERY", ""); // select
    map.add("PROGRAM", "blastp"); // hidden
    map.add("SET_DEFAULTS", "Yes"); // image
    map.add("CLIENT", "web"); // hidden
    map.add("SERVICE", request.Service); // hidden
    map.add("PAGE", "Proteins"); // hidden
    map.add("CMD", "Put"); // hidden
    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","protein sequence",""),
        new dField("Database","CharSequence","database","nr", new String[] {"nr","swissprot","pat","yeast","ecoli","pdb","Drosophila genome","month"}),
        new dField("Service","CharSequence","Sevice to perform","plain",new String[] {"plain","psi","phi","rpsblast","megablast"}),
        new dField("Expect","CharSequence","Expected E value","10"),
        new dField("Word_size","CharSequence","2 or 3, other values not supported by NCBI","3",new String[] {"2","3"},new String[] {"2","3 default"}),
        //new dField("MATRIX_NAME","CharSequence","protein scoring matrix","BLOSUM62",new String[] {"BLOSUM62","PAM30","PAM70","BLOSUM80","BLOSUM45"}),
        new dField("Entrez_query","CharSequence","Limit search by Entrez query","",
         new String[] {"","Viruses [ORGN]","Archaea [ORGN]","Bacteria [ORGN]","Eukaryota [ORGN]",
          "Viridiplantae [ORGN]","Fungi [ORGN]","Metazoa [ORGN]","Arthropoda [ORGN]",
          "Vertebrata [ORGN]","Mammalia [ORGN]","Rodentia [ORGN]","Primates [ORGN]",
          "Aeropyrum pernix [ORGN]","Aquifex aeolicus [ORGN]","Arabidopsis thaliana [ORGN]",
          "Bacillus subtilis [ORGN]","Bos taurus [ORGN]","Caenorhabditis elegans [ORGN]",
          "Danio rerio [ORGN]","Dictyostelium discoideum [ORGN]","Drosophila melanogaster [ORGN]",
          "Escherichia coli [ORGN]","Gallus gallus [ORGN]","Homo sapiens [ORGN]",
          "Human immunodeficiency virus type 1 [ORGN]","Methanococcus jannaschii [ORGN]",
          "Mus musculus [ORGN]","Oryctolagus cuniculus [ORGN]","Oryza sativa [ORGN]","Ovis aries [ORGN]",
          "Plasmodium falciparum [ORGN]","Rattus norvegicus [ORGN]","Saccharomyces cerevisiae [ORGN]",
          "Schizosaccharomyces pombe [ORGN]","Simian immunodeficiency virus [ORGN]","Synechocystis PCC6803 [ORGN]",
          "Takifugu rubripes [ORGN]","Xenopus laevis [ORGN]","Zea mays [ORGN]"}),
        new dField("descriptions","CharSequence","Maximal number of descriptions to receive","400"),
        new dField("Query_from","CharSequence","Left boundary of the sequence",""),
        new dField("Query_to","CharSequence","Right boundary of the sequence",""),
        new dField("Other_advanced","CharSequence","Other advanced BLAST options",""),
        }
    );
   }

  /** Public instance of agent for user. */
  public static blastP_ncbi Public = new blastP_ncbi();
  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 = Public.getRequest();
        // Now modify and assign request fields in accordance with task:
        request. Sequence="MPSSGRALLDSPLDSGSLTSLDSSVFCSEGEGEPLALGDCFTVNV";
        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();
         };
   };

   /** Visit these URL's on end, deleting RID records from NCBI query system. */
   SortedSet visitOnEnd = new TreeSet();

   // removing "Synchronized" may cause Redirector to fail.
   // This is because value rid in redirector may be lost.
   // BLAST is very time consuming search and there is no sense
   // to do multiple submissions anyway.
   public synchronized Object go(Object req) throws Exception
    {
      Object rt = super.go(req);

      try {
      {
       Iterator iter = visitOnEnd.iterator();
       String d;
       while (iter.hasNext()) {
         d = (String) iter.next();
         p("Visit on end: "+d);
         readToString(d);
       }
      }
      visitOnEnd.clear();
      } catch (Exception exc)
         {
         };

      return rt;
    };
}