import java.io.*;
import java.util.*;

//import BufferLoad;
//import Title;
//import FAQ;
//import Folder;
//import LinkFolder;

/**
 *  This type represents a chunk of text containing
 *  a question and answer section, known as an 'faq' or
 *  'frequently asked questions' although the questions
 *  and ansers are usually written by a programmer.
 *
 *  The document may also contain the listing of the
 *  contents of a directory.
 *
 *  The text is not 'marked up' particularly, or at least
 *  only in a minimalistic way.
 *
 *  @see FaqItem, Question, Answer
 *  @author http://bumble.sf.net
 */
 
  
public class FaqDocument extends Object
{
  //--------------------------------------------
  private static String NEWLINE = System.getProperty("line.separator");
  //--------------------------------------------
  private boolean isGood;
  //--------------------------------------------
  private String errors;
  //--------------------------------------------
  private FAQ faq;
  //--------------------------------------------
  private Folder folder;
  //--------------------------------------------
  private LinkFolder linkFolder;
  //--------------------------------------------
  private Date startTime;
  //--------------------------------------------
  private Date finishTime;
  //--------------------------------------------
  private StringBuffer text;
  //--------------------------------------------
  private Title title;
  //--------------------------------------------
  private String styleSheet;

  public FaqDocument()
  {
    this.errors = "";
    this.faq = new FAQ();
    this.folder = new Folder();
    this.linkFolder = new LinkFolder();
    this.text = new StringBuffer("");
    this.title = new Title();
    this.errors = "";
    this.styleSheet = "/style.css";
  } 

  //--------------------------------------------
  public FaqDocument(String sText)
  {
    this();
    this.loadData(sText);
  } 

  //--------------------------------------------
  /** return the number of milliseconds taken to load. */
  public long getLoadDuration()
  {
    if (this.finishTime == null) { return 0; }
    if (this.startTime == null) { return 0; }
    return this.finishTime.getTime() - this.startTime.getTime();
  } 

  //--------------------------------------------
  /** parse the document and try to find the component
   *  objects in their text representation.   
   *                                          */
  public void loadData(String sText)
  {

    this.startTime = new Date();
    this.isGood = this.isFaqDocument(sText);
    if (!this.isGood)
    {
      this.finishTime = new Date();
      return;
    }

    String sFaqDocumentContents = sText.trim();
    StringReader srText = new StringReader(sFaqDocumentContents);

    int iCurrentCharacter = 0;
    StringBuffer sbText = new StringBuffer("");
    
    while (iCurrentCharacter != -1)
    {
      sbText.append((char)iCurrentCharacter);
      //-- System.out.println("sbText=" + sbText);

      //-- The title must be the first thing in the
      //-- document
      //--
      if (Title.isTitle(sbText.toString().trim()))
      {
        //-- System.out.println("<found title>");
        this.title = new Title(sbText.toString());
        sbText.setLength(0);
      } 

      if (sbText.toString().trim().endsWith(Folder.INDICATOR))
      {
        this.text.append(
          sbText.toString().substring(0,
          sbText.toString().length() - Folder.INDICATOR.length()));
        sbText.setLength(0);
        sbText.append(Folder.INDICATOR);
      }

      if (sbText.toString().trim().endsWith(LinkFolder.INDICATOR))
      {
        this.text.append(
          sbText.toString().substring(0,
          sbText.toString().length() - LinkFolder.INDICATOR.length()));
        sbText.setLength(0);
        sbText.append(LinkFolder.INDICATOR);
      }

      if (sbText.toString().trim().endsWith(FAQ.INDICATOR))
      {
        this.text.append(
          sbText.toString().substring(0,
          sbText.toString().length() - FAQ.INDICATOR.length()));
        sbText.setLength(0);
        //--
        //-- push the 'q:' back on the buffer since we are
        //--
        sbText.append(FAQ.INDICATOR);
      }

      if (Folder.isFolder(sbText.toString()))
      {
        //-- System.out.println("<found folder>");
        this.folder = new Folder(sbText.toString());
        sbText.setLength(0);
      } 

      if (LinkFolder.isLinkFolder(sbText.toString()))
      {
        //-- System.out.println("<found link folder>");
        this.linkFolder = new LinkFolder(sbText.toString());
        sbText.setLength(0);
      } 

      if (FAQ.isFAQ(sbText.toString()))
      {
        //-- System.out.println("<found faq>");
        this.faq = new FAQ(sbText.toString());
        sbText.setLength(0);
      } 

      try
      {
        iCurrentCharacter = srText.read();
      }
      catch (IOException e)
      {
        this.errors =
          "An IO Exception occurred while reading " + e;
        this.finishTime = new Date();
        return;
      }
    } //-- while

    srText.close();
    this.finishTime = new Date();

  } //-- m: loadData()

  //--------------------------------------------
  /** checks if this looks like an FaqDocument but
   *  no structure checks will be made now. */
  public static boolean isFaqDocument(String sText)
  {
    return true;
  }

  //--------------------------------------------
  /** is there any data */
  public boolean isEmpty()
  {
     return false;
  }
  
  //--------------------------------------------
  /** is there an faq */
  public boolean hasFAQ()
  {
    return this.faq.isEmpty();
  }


  //--------------------------------------------
  public String toString()
  {
    StringBuffer sbReturn = new StringBuffer("");

    sbReturn.append(NEWLINE);
    sbReturn.append(this.title);
    sbReturn.append(NEWLINE);
    sbReturn.append(this.text);
    sbReturn.append(NEWLINE);
    sbReturn.append(this.folder.toString());
    sbReturn.append(NEWLINE);
    sbReturn.append(this.linkFolder.toString());
    sbReturn.append(NEWLINE);
    sbReturn.append(this.faq.toString());

    return sbReturn.toString();
  }

  //--------------------------------------------
  public String printHtml()
  {

    StringBuffer sbReturn = new StringBuffer("");
    sbReturn.append("<html>");
    sbReturn.append(NEWLINE);
    sbReturn.append("<head>");
    sbReturn.append(NEWLINE);
    sbReturn.append("<link href='");
    sbReturn.append(this.styleSheet);
    sbReturn.append("' rel='stylesheet' type='text/css'>");
    sbReturn.append(NEWLINE);
    sbReturn.append("<title>");
    sbReturn.append(NEWLINE);
    sbReturn.append(this.title.getContents());
    sbReturn.append(NEWLINE);
    sbReturn.append("</title>");
    sbReturn.append(NEWLINE);
    sbReturn.append("</head>");
    sbReturn.append(NEWLINE);
    sbReturn.append("<body>");
    sbReturn.append(NEWLINE);
    sbReturn.append(this.title.printHtml());
    sbReturn.append(NEWLINE);
    sbReturn.append("<table><tr>");
    sbReturn.append(NEWLINE);
    sbReturn.append(this.text);
    sbReturn.append("<br/>");
    sbReturn.append(NEWLINE);
    sbReturn.append("<td valign='top'>");
    sbReturn.append(NEWLINE);
    sbReturn.append(this.faq.printHtml());
    sbReturn.append(NEWLINE);
    sbReturn.append("</td>");
    sbReturn.append(NEWLINE);
    sbReturn.append("<td valign='top'>");
    sbReturn.append(NEWLINE);
    sbReturn.append(this.linkFolder.printHtml());
    sbReturn.append(NEWLINE);
    sbReturn.append(this.folder.printHtml());
    sbReturn.append(NEWLINE);
    sbReturn.append("</td>");

    sbReturn.append(NEWLINE);
    sbReturn.append("</tr></table>");
    sbReturn.append(NEWLINE);
    sbReturn.append("</body>");
    sbReturn.append(NEWLINE);
    sbReturn.append("</html>");
    return sbReturn.toString();
  }

  //--------------------------------------------
  public String printReport()
  {
    StringBuffer sbReturn = new StringBuffer("");
    sbReturn.append("");
    sbReturn.append(NEWLINE);
    sbReturn.append("Document title  >");
    sbReturn.append(this.title.toString());
    sbReturn.append(NEWLINE);
    sbReturn.append("has an faq      >");
    sbReturn.append(this.hasFAQ());
    sbReturn.append(NEWLINE);
    sbReturn.append("folder listing  >");
    sbReturn.append(this.folder.getAbsoluteName());
    sbReturn.append(NEWLINE);
    sbReturn.append("link folder list>");
    sbReturn.append(this.folder.getAbsoluteName());
    sbReturn.append(NEWLINE);
    sbReturn.append("Load time       >");
    sbReturn.append(this.getLoadDuration());
    sbReturn.append(NEWLINE);
    sbReturn.append("last data good  >");
    sbReturn.append(this.isGood);
    sbReturn.append(NEWLINE);
    sbReturn.append("error messages  >");
    sbReturn.append(this.errors);
    sbReturn.append(NEWLINE);
    return sbReturn.toString();
  }

  //--------------------------------------------
  public String print()
  {
    StringBuffer sbReturn = new StringBuffer("");
    return this.toString();
  }


  //--------------------------------------------
  /** a main method for testing */
  public static void main(String[] args) throws Exception
  {

    StringBuffer sbUsageMessage = new StringBuffer("");
    sbUsageMessage.append("test usage: java FaqDocument faq-file [show]");
    sbUsageMessage.append(NEWLINE);
    sbUsageMessage.append("");
    sbUsageMessage.append(NEWLINE);

    if (args.length == 0)
    {	    
      System.out.println(sbUsageMessage);
      System.exit(-1);
    }


    StringBuffer sbTest = new StringBuffer("");
    sbTest.append(NEWLINE);


    //-- show all data, not just the html.
    if (args.length == 2)
    {	    
      System.out.println("Using data");
      System.out.println(NEWLINE);
      System.out.println(BufferLoad.loadBuffer(args[0]));
    }

    FaqDocument faqTest = new FaqDocument(BufferLoad.loadBuffer(args[0]));

    if (args.length == 2)
    {	    
      System.out.println(NEWLINE);
      System.out.println(faqTest.toString());
      System.out.println(NEWLINE);
      System.out.println(faqTest.printReport());
    }

    System.out.println(faqTest.printHtml());

  } //-- main()
  
} //-- FAQ class






