/**
 *
 *  THIS AGENT IS NOT COMPLETE.
 *  It is skeleton for a wrapper that computes result from request.
 *  You must complete the go(..) method self dependently.
 *  Generated 2002.9.16  by Sight 2.0, Ulm university.
 */
package impl.manipulators;

import Sight.Agents.*;
import Sight.Agents.Prototypes.*;
import Sight.dds.*;
import java.io.*;
import java.util.*;
import Sight.Agents.util.*;

public class rangeSelector extends Wrapper implements Serializable, Fast {
  /* Data structure to pass query to this robot. */
  public class Request extends Sight.Request implements java.io.Serializable {
        /** Sequence to manipulate */
        public CharSequence Sequence;
        /** Take from, inclusive (-1=from start) */
        public CharSequence from;
        /** Take to, inclusive (-1=till end) */
        public CharSequence to;
        /** The whole region. */
        public CharSequence Region = null;
        /** Fragment to take */
        public CharSequence take = "inside";
        /** Maximal region length. */
        public CharSequence reg_len = "-1";
       /** 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 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(true,
     new dField[] {
        new dField("take","CharSequence","Take region","inside",
         new String[] {"left","inside","right","all","outside"},new String[]
          {"left","inside (default)","right","all three as separate records","left and right regions"}),
        new dField("from","CharSequence","Take from, inclusive (0=from start)",""),
        new dField("to","CharSequence","Take to, inclusive (-1=till end)",""),
        new dField("Region","CharSequence","Region to take, has priority if set.",""),
        new dField("reg_len","CharSequence",
         "Region length (valid for left and right sub-regions only, -1=unlimited)","-1"),
        new dField("Sequence","CharSequence","Sequence to manipulate",""),
        }
    );
   }


 /* 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 {
        /** Truncated sub-sequence */
        public CharSequence Sequence;
        public String howTaken = "";
      };
      /** 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 r.howTaken+", length "+r.Sequence.length();
              case 1:  return r.howTaken+", length "+r.Sequence.length();
              default: return r.howTaken+", length "+r.Sequence.length()+
              "<br><textarea>"+r.Sequence+"</textarea>";
            }
          };
      }
    /** Type definitions for Result. */
   public dStructure getResultDds() {
    return new Sight.dds.Records(false,
     new dField[] {
        new dField("Sequence","CharSequence","Truncated sub-sequence","")                 }
    );
   }

   /** Implementation of the central go method.  */
   public Object go(Object o_request) throws Exception
    {
     try {
     /** @todo: complete the go(...) method for this wrapper. */
     Request request = (Request) o_request;
     Result  result  = new Result();
     // we suppose only one record in the response of this robot:
     Record record = new Record();
     // .... (now fill in your record somehow):

     int from, to;
     if (request.Region==null || request.Region.toString().trim().length()==0)
      {
        from = Integer.parseInt(request.from.toString().trim());
        to   = Integer.parseInt(request.to.toString().trim());
      } else
      {
        StringTokenizer st = new StringTokenizer(request.Region.toString()," \t\r\n.,-(){}[];:");
        from = 0;
        if (st.hasMoreTokens()) from =
         Integer.parseInt(st.nextToken());
        to   = request.Sequence.length();
        if (st.hasMoreTokens()) to =
         Integer.parseInt(st.nextToken());
      };

     if (to<0) to = request.Sequence.length()+1;

     CharSequence sLeft   = request.Sequence.subSequence(0, from);
     CharSequence sRight  = request.Sequence.subSequence(to, request.Sequence.length());
     CharSequence sInside = request.Sequence.subSequence(from, to+1);

     try {
          int limit = Integer.parseInt(request.reg_len.toString().trim());
          if (limit>0)
           {
            if (sLeft.length()>limit)
             sLeft = sLeft.subSequence(sLeft.length()-limit, sLeft.length());
            if (sRight.length()>limit)
             sRight = sRight.subSequence(0, limit);
           };
     } catch (NumberFormatException exc) {};

     String mLeft  = " left before "+from+" ";
     String mRight = " right after "+(to-1)+" ";
     String mInside = " inside ["+from+".."+to+"] ";

     if (request.take.equals("all"))
      {
        result.a = new Record[3];
        for (int i = 0; i < result.a.length; i++) {
          result.a[i] = new Record();
        }

        result.a[0].Sequence=sLeft;
        result.a[0].howTaken=mLeft;

        result.a[1].Sequence=sInside;
        result.a[1].howTaken=mInside;

        result.a[2].Sequence=sRight;
        result.a[2].howTaken=mRight;
      } else
     if (request.take.equals("outside"))
      {
        result.a = new Record[2];
        for (int i = 0; i < result.a.length; i++) {
          result.a[i] = new Record();
        }

        result.a[0].Sequence=sLeft;
        result.a[0].howTaken=mLeft;

        result.a[1].Sequence=sRight;
        result.a[1].howTaken=mRight;
      } else

      {
       if (request.take.equals("left"))
       {
        record.Sequence = sLeft;
        record.howTaken = mLeft;
       }
         else
       if (request.take.equals("right"))
       {
        record.Sequence = sRight;
        record.howTaken = mRight;
       }
         else
       if (request.take.equals("inside"))
       {
        record.Sequence = sInside;
        record.howTaken = mInside;
       };

       result.a = new Record[1];
       result.a[0] = record;
       };
     // set the agent signature:
     result.setAgentSignature(getHTMLSignature());
     return result;
     } catch (Exception exc)
      { exc.printStackTrace();
      };
      return null;
    };


  public rangeSelector() {
   setDescription("Allows to select the specified sub-sequence in a sequence.");
   setMasterURL("");
   // this robot newer uses caching:
   setWriteCache(false);
   setReadCache(false);
   };
  /** Public instance of agent for user. */
  public static rangeSelector Public = new rangeSelector();
  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:
        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();
         };
   }
;
  }