import java.net.*;
import java.io.*;
import java.util.*;

import Reference;

/** This class is a document containing just references, which
 *  in an Html sense means the targets of hyperlinks.
 *  This appears to be working under jvm1.1 
 *  
 *  @author matth3wbishop<at>yahoo!<dot>com 
 */
 
  
public class ReferenceDocument extends Object
{
  //--------------------------------------------
  private static String NEWLINE = System.getProperty("line.separator");
  //--------------------------------------------
  private Vector references;
  //--------------------------------------------
  private boolean isGood;
  //--------------------------------------------
  private String errors;
  //--------------------------------------------
  private StringBuffer errorMessages;  
  //--------------------------------------------
  private Date startTime;
  //--------------------------------------------
  private Date finishTime;

  //--------------------------------------------
  public ReferenceDocument()
  {
    this.references = new Vector();
    this.errors = "";
    this.errorMessages = new StringBuffer("");
  } //-- constr: ()

  //--------------------------------------------
  public ReferenceDocument(Reader rdDocument)
  {
    this();
    BufferedReader brReader = new BufferedReader(rdDocument);

    int iCurrentCharacter = 0;
    StringBuffer sbText = new StringBuffer("");
    StringBuffer sbReferenceText = new StringBuffer("");
    
    while (iCurrentCharacter != -1)
    {
      sbText.append((char)iCurrentCharacter);
      //System.out.println("sbText=" + sbText);

      if (Reference.isReference(sbText.toString()))
      {
        this.references.addElement(new Reference(sbText.toString()));
        sbText.setLength(0);
      }

      if (sbText.toString().toLowerCase().endsWith("href"))
      {
        sbText.setLength(0);
        sbText.append("href");
      }

      try
      {
        iCurrentCharacter = brReader.read();
      }
      catch (IOException e)
      {
        
        this.errors = "An IO Exception occurred while reading";
        this.errorMessages.append(e);
        return;
      }

    } //-- while

    try
    {
      brReader.close();
    }
    catch (IOException e)
    {
      this.errors = "An IO Exception occurred while closing";
      this.errorMessages.append(e);
      return;
    }
    

  } //-- constr: (reader)

  //--------------------------------------------
  /** returns an array of the links in the document */
  public Reference[] getReferences()
  {
    Reference[] rrReturn = new Reference[this.references.size()];
    Reference rCurrent = new Reference();

    for (int ii = 0; ii < rrReturn.length; ii++)
    {
      rrReturn[ii] = (Reference)this.references.elementAt(ii);
    }
    return rrReturn;    
  }

  //--------------------------------------------
  public String toString()
  {
    StringBuffer sbReturn = new StringBuffer("");
    Reference rCurrent = new Reference();
    Enumeration ii = references.elements();
    while (ii.hasMoreElements())
    {
      rCurrent = (Reference)ii.nextElement();      
      sbReturn.append("<a " + rCurrent.toString() + ">");
      sbReturn.append(rCurrent.getTarget().toStringNoQuotes());
      sbReturn.append("</a>");
      sbReturn.append(NEWLINE);
    }
    sbReturn.append("");
    return sbReturn.toString();
  }

  //--------------------------------------------
  public String printReport()
  {
    StringBuffer sbReturn = new StringBuffer("");
    sbReturn.append("");
    sbReturn.append(NEWLINE);
    sbReturn.append("Number of references :");
    sbReturn.append(this.references.size());
    sbReturn.append(NEWLINE);
    sbReturn.append("Errors :");
    sbReturn.append(this.errors);
    sbReturn.append(NEWLINE);
    sbReturn.append("Error messages generated :");
    sbReturn.append(this.errorMessages);
    sbReturn.append(NEWLINE);
    return sbReturn.toString();
  }

  //--------------------------------------------
  public String print()
  {
    StringBuffer sbReturn = new StringBuffer("");
    Reference rCurrent = new Reference();
    Enumeration ii = references.elements();
    while (ii.hasMoreElements())
    {
      rCurrent = (Reference)ii.nextElement();      
      sbReturn.append(rCurrent.print());
      sbReturn.append(NEWLINE);
    }
    sbReturn.append("");
    return sbReturn.toString();
  }


  //--------------------------------------------
  /** a main method for testing */
  public static void main(String[] args) throws Exception
  {

    
    StringBuffer sbUsageMessage = new StringBuffer("");
    sbUsageMessage.append("test usage: java ReferenceDocument .|url");
    sbUsageMessage.append(NEWLINE);
    sbUsageMessage.append("eg:         java ReferenceDocument .");
    sbUsageMessage.append(NEWLINE);
    sbUsageMessage.append(" tests from standard in");
    sbUsageMessage.append(NEWLINE);
    sbUsageMessage.append("eg:         java ReferenceDocument url");
    sbUsageMessage.append(NEWLINE);
    sbUsageMessage.append(" tests from the url");
    sbUsageMessage.append(NEWLINE);


    if (args.length == 0)
    {	    
      System.out.println(sbUsageMessage);
      System.exit(-1);
    }

    BufferedReader brInput;

    if (args[0].equals("."))
    {
      brInput =
       new BufferedReader(new InputStreamReader(System.in));
      char cInput = ' ';

      StringBuffer sbInput = new StringBuffer("");

      System.out.println("Testing the ReferenceDocument Class");
      System.out.println("Type * to finish");
      while (cInput != '*')
      {
        sbInput.append(cInput);
        cInput = (char)brInput.read();
      }
      StringReader srInput = new StringReader(sbInput.toString());
    }
    else
    {
      URL urlTest = new URL(args[0]);
      brInput =
        new BufferedReader(new InputStreamReader(urlTest.openStream()));

    }

    //System.out.println(sbInput);
    ReferenceDocument rTest = new ReferenceDocument(brInput);

    System.out.println("");
    StringBuffer sbMessage = new StringBuffer("");
    sbMessage.append(rTest.print());
    sbMessage.append(rTest.toString());
    sbMessage.append(NEWLINE);
    sbMessage.append(rTest.printReport());
    System.out.println(sbMessage);

  } //-- main()
  
} //-- ReferenceDocument class






