package commons.collections.trie;


/*
 * Author: kst
 */
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;



public class Trie extends ITrie implements Serializable
{

   Node root = new Node();


   public INode getRoot ()
   {
      return root;
   }


   /**
    * init lex
    */
   public void initializeLexReading ()
   {
   }


   /**
    * optimizing lex?
    */
   public void finalizeLexReading ()
   {
   }


   public int getMaxDepth ()
   {
      return Node.maxdepth;
   }


   public int getMaxWidth ()
   {
      return Node.maxwidth;
   }


   //   public long getLexSize ()
   //   {
   //      return root.lexsize;
   //   }

   public long getTotalCharacters ()
   {
      return Node.rawsize;
   }


   public long getTotalStates ()
   {
      return Node.states;
   }


   public void traverseTrie ()
   {
      if (super.trieReader == null)
      {
         return;
      }

      for (int i = 0; i < root.subTrees.length; i++)
      {
         traverseNode(root.subTrees[i], -1);
      }
   }


   private int traverseNode (Node node, int d)
   {
      if (node.isFinal)
      {
         super.trieReader.lastSign(node.CHAR, node.output, d);
      }
      else
      {
         super.trieReader.nextSign(node.CHAR, d);
      }

      if (node.subTrees.length > 0)
      {
         for (int i = 0; i < node.subTrees.length; i++)
         {
            traverseNode(node.subTrees[i], d + 1);
         }
      }
      return d;
   }


   /**
    * check if a word is in the lexicon
    */
   public String accept (String word)
   {
      return root.matchSubWord(0, word, word.length());
   }


   /**
    * call back method, invoked by LexReader
    */
   public void newEntry (String wr)
   {
      String [] t = wr.split(" ");
      
      if (t.length != 2)
      {
         DictFSA.println("Invalid transducer lex, two space-separated fields expected.");
         return;
      }
      String word = t[0];
      String replacement = t[1];      
//      Main.println(word + "->" + replacement );
      

      
      int x = word.length();
      Node.lexsize++;
      Node.rawsize += x;
      root.addCurrentSuffix(0, word, x, replacement);
   }


   private void writeObject (ObjectOutputStream out) throws IOException
   {      
      out.writeObject(this.root);
      out.writeInt(Node.maxdepth);
      out.writeInt(Node.maxwidth);
      out.writeLong(Node.rawsize);
      out.writeLong(Node.states);
      out.writeObject(Node.type);
   }


   private void readObject (ObjectInputStream in) throws IOException,
         ClassNotFoundException
   {
      this.root = (Node)in.readObject();

      Node.maxdepth = in.readInt();
      Node.maxwidth = in.readInt();
      Node.rawsize = in.readLong();
      Node.states = in.readLong();
      Node.type = (Class)in.readObject();
   }
   

}