/*
 * Author: kst 
 */
package commons.collections.trie;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;



/**
 * @author kst
 */
public abstract class ITrie implements Serializable
{
   private String        packageName = "";

   protected ITrieReader trieReader  = null;

   
   public String        lexname = "";

   
   public abstract String accept (String word);


   public abstract int getMaxDepth ();


   public abstract int getMaxWidth ();


   public abstract long getTotalCharacters ();


   public abstract long getTotalStates ();


   public abstract void initializeLexReading ();


   public abstract void newEntry (String word);


   public abstract void finalizeLexReading ();


   public abstract void traverseTrie ();


   public abstract INode getRoot ();


   public void registerTrieReader (ITrieReader reader)
   {
      this.trieReader = reader;
   }


   public static ITrie getTrie (String triePackage)
   {
      String parserclass = "de.brsh.jnlp.dict." + triePackage.trim() + ".Trie";

      Class clazz = null;
      ITrie P = null;

      try
      {
         clazz = Class.forName(parserclass);
      }
      catch (ClassNotFoundException e)
      {
         DictFSA.println("ITrie not found: " + parserclass);
      }

      if (clazz != null)
      {
         try
         {
            P = (ITrie) clazz.newInstance();
         }
         catch (IllegalAccessException e)
         {
            DictFSA.println("No access: " + clazz.getName());
         }
         catch (InstantiationException e)
         {
            DictFSA.println("Instantiation of Trie failed: " + clazz.getName());
         }
      }

      P.packageName = triePackage.trim();

      return P;
   }


   public String getPackageName ()
   {
      return packageName;
   }


   public void storeTrie (String lexFile)
   {
      ObjectOutputStream oos = null;
      
      File f = new File(lexFile + ".bin");

      this.lexname = f.getName();
      
      try
      {
         oos = new ObjectOutputStream(new FileOutputStream(f));
         oos.writeObject(this);
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
      finally
      {
         if (oos != null)
         {
            try
            {
               oos.flush();
            }
            catch (IOException ioe)
            {
            }
            try
            {
               oos.close();
            }
            catch (IOException ioe)
            {
            }
         }
      }

   }


   public ITrie loadTrie (String lexFile)
   {
      ITrie trie = getTrie(packageName);

      File f = new File(lexFile + ".bin");
      
      
      if (!f.exists() || !f.canRead())
      {
         return null;
      }
      
      DictFSA.println("Reading " + f + " ...");
      
      
      String filename = f.getName();
      
      ObjectInputStream ois = null;
      try
      {
         ois = new ObjectInputStream(new FileInputStream(f));

         long startTime = System.currentTimeMillis();

         trie = (ITrie) ois.readObject();
         
         if (!filename.equals(trie.lexname))
         {
            DictFSA.println("Filename not matching...");
            return null;
         }
         
         
         long currTime = System.currentTimeMillis() - startTime;

         DictFSA.println("Data read in " + currTime + " ms");
         
         return trie;
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
      finally
      {
         if (ois != null)
         {
            try
            {
               ois.close();
            }
            catch (IOException ioe)
            {
            }
         }
      }
      return null;
   }
}