/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Community System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.htmlcheck.dict;

import java.io.*;
import org.apache.log4j.*;
import com.silverwrist.venice.htmlcheck.SpellingDictionary;

public class LazyLexicon implements Runnable, SpellingDictionary
{
  /*--------------------------------------------------------------------------------
   * Static data values
   *--------------------------------------------------------------------------------
   */

  private static Category logger = Category.getInstance(LazyLexicon.class.getName());

  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private Lexicon inner_lex = null;
  private String[] filenames;

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  public LazyLexicon(String[] filenames)
  {
    this.filenames = filenames;  // save off the file names to be loaded

    // spin off the load process into the background
    Thread thrd = new Thread(this);
    thrd.start();

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Internal functions
   *--------------------------------------------------------------------------------
   */

  private synchronized Lexicon getLex()
  {
    while (inner_lex==null)
    { // wait for the inner thread to finish creating the lexicon
      if (logger.isDebugEnabled())
	logger.debug("LazyLexicon: waiting for lex to load...");

      try
      { // park the thread here until we know what's up
	wait();

      } // end try
      catch (InterruptedException e)
      { // do nothing
      } // end catch

    } // end while

    return inner_lex;

  } // end getLex

  /*--------------------------------------------------------------------------------
   * Implementations from interface Runnable
   *--------------------------------------------------------------------------------
   */

  public void run()
  {
    Lexicon lex = new Lexicon();

    if (logger.isDebugEnabled())
      logger.debug("LazyLexicon loading " + String.valueOf(filenames.length) + " lexicon(s)");

    for (int i=0; i<filenames.length; i++)
    { // load data into the lexicon in turn
      if (logger.isDebugEnabled())
	logger.debug("LazyLexicon loading file: " + filenames[i]);

      try
      { // start reading the file
	lex.readFile(filenames[i]);

      } // end try
      catch (IOException e)
      { // trap it and go on to the next one
	logger.error("IOException loading lexfile " + filenames[i] + ": " + e.getMessage());

      } // end catch

    } // end for

    if (logger.isDebugEnabled())
      logger.debug("LazyLexicon load complete.");

    synchronized (this)
    { // set the lexicon reference and wake up all waiting threads
      inner_lex = lex;
      notifyAll();

    } // end synchronized block

    System.gc();  // free any extra crap generated by the lexicon load

  } // end run

  /*--------------------------------------------------------------------------------
   * Implementations from interface SpellingDictionary
   *--------------------------------------------------------------------------------
   */

  public int size()
  {
    return getLex().size();

  } // end size

  public boolean checkWord(String word)
  {
    return getLex().checkWord(word);

  } // end checkWord

} // end class LazyLexicon
