package taskspaces.rna;

import org.apache.xerces.parsers.SAXParser;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import java.io.IOException;
import java.util.*;

/**
 * Parses XML (using Apache Xerces SAX parser) documents conforming 
 * to Motifs.dtd definition and
 * creates java.util.ArrayList of DatabaseEntry objects.
 * @author Rob Markel
 * @version 1.0
 */
public class MotifsParser extends DefaultHandler
{
   /** Holds name of the motif. */
   private String motifName="";

   /** Holds name of the current element. */
   private String elementName="";

   /** Holds the parsed entries. */
   private static ArrayList entries=new ArrayList();

   /** Holds entry sequence modules. */
   private ArrayList modules=new ArrayList(); 

   /** Holds entry structures. */
   private ArrayList structures=new ArrayList(); 

   /** Holds entry constraint arrays. */
   private ArrayList constraints=new ArrayList(); 

   /** Holds entry constraint values. */
   private int[] constraint=new int[5];

   /**
    * Parses Entry XML file.
    * @param xmlFile path or URL of the XML file.
    */
   public MotifsParser(String xmlFile)
   {
      SAXParser parser=new SAXParser();
      parser.setContentHandler(this);
      try {parser.parse(xmlFile);} 
      catch(SAXException e) {e.printStackTrace();System.err.println(e);}
      catch(IOException e) {e.printStackTrace();System.err.println(e);}
   }

   /**
    * Catches a start element event.
    * @return void
    */
   public void startElement(String uri,String local,String qName,Attributes atts)
   {
      try
      {
         elementName=local;

         /*
         String attributeName,attributeType,attributeValue="";
         for(int i=0; i<atts.getLength(); i++) 
         {
            attributeName=atts.getLocalName(i);
            attributeType=atts.getType(attributeName);
            attributeValue=atts.getValue(attributeName);
         }
         */
      } catch(Exception e) {e.printStackTrace();}
   }

    /**
     * Catches data from element.
     * @return void
     */  
   public void characters(char[] text,int start,int length)
   {
      try
      {
         String content=new String(text,start,length);
         if(!content.trim().equals(""))
         {
            if(elementName.equals("name")) motifName=content;
            if(elementName.equals("sequence")) modules.add(content);
            if(elementName.equals("structure")) structures.add(content);
            if(elementName.equals("number_of_pairs")) constraint[0]=Integer.parseInt(content); 
            if(elementName.equals("first_module_id")) constraint[1]=Integer.parseInt(content); 
            if(elementName.equals("first_start_position")) constraint[2]=Integer.parseInt(content); 
            if(elementName.equals("second_module_id")) constraint[3]=Integer.parseInt(content); 
            if(elementName.equals("second_start_position")) constraint[4]=Integer.parseInt(content); 
         }
      } catch(Exception e) {e.printStackTrace();}
   }

    /**
     * Catches end element event.
     * @return void
     */  
   public void endElement(String uri,String local,String qName)
   {
      try
      {
         if(local.equals("constraint")) 
         {
            //System.out.println("Adding constraint array for motif: "+motifName);
            constraints.add(constraint.clone());
         }
         if(local.equals("motif"))
         {
            String[] mods=new String[modules.size()];
            for(int i=0; i<mods.length; i++) mods[i]=(String)modules.get(i);
            String[] structs=new String[structures.size()];
            for(int i=0; i<structs.length; i++) structs[i]=(String)structures.get(i);
            ArrayList cons=new ArrayList(constraints.size());
            for(int i=0; i<constraints.size(); i++) { cons.add(constraints.get(i)); }
            entries.add(new DatabaseEntry(motifName,mods,structs,cons));
            cons=null;

            // Reset
            motifName="";
            modules.clear();
            structures.clear();
            constraints.clear();
         }
      } catch(Exception e) {e.printStackTrace();}
   }

   //public ArrayList getEntries(String xmlFileUrl)
   //public static void main(String[] a)
   //{
      /*
      try
      {
         MotifsParser mp=new MotifsParser("http://128.138.146.229/event/rna/Motifs.xml");
         System.out.println("Entries.size: "+entries.size());
         for(int i=0; i<entries.size(); i++)
         {
            DatabaseEntry entry=(DatabaseEntry)entries.get(i);
            String[] structures=entry.getStructures(); 
            String[] modules=entry.getModules();
            for(int j=0; j<modules.length; j++)
            {
               System.out.println("Module["+j+"]:"+modules[j]);
               System.out.println("Structure["+j+"]:"+structures[j]);
            }
            ArrayList constraints=entry.getConstraints();
            System.out.println("Constraints: "+constraints.size());
            for(int k=0; k<constraints.size(); k++)
            {
               int[] constraint=(int[])constraints.get(k);
               for(int l=0; l<constraint.length; l++)
               {
                  System.out.print(constraint[l]+",");
               }
               System.out.println();
            }
         }
      } catch(Exception e) {e.printStackTrace();}
      */
   //}

   /**
    * Returns the parsed entries.
    * @return the DatabaseEntry objects.
    */
   public static ArrayList getEntries()
   {
      return entries;
   }
  
   /**
    * Resets the entries ArrayList.
    * @return void
    */
   public static void reset()
   {
      entries.clear();
   }
}
