import objectdraw.*;

import java.awt.*;
import java.awt.event.*;

import java.io.*;

import java.net.*;

import javax.swing.*;

// A class that allows one to fetch an HTML file from the web and obtain
// a list of all the links contained within the HTML.
//@width 800
//@height 550
public class HTMLLinkFinder extends Controller implements ActionListener,
ItemListener {
  // Width of area for URL entry
  private static final int URLFIELDWIDTH = 45;

  // Dimensions for HTML display area
  private static final int HTMLWIDTH = 60;
  private static final int HTMLHEIGHT = 14;

  // Dimensions for links display area
  private static final int LINKSWIDTH = 60;
  private static final int LINKSHEIGHT = 10;

  // Large font for GUI controls
  private Font bigFont = new Font("Times", Font.PLAIN, 16);

  // Area in which HTML is displayed
  private JTextArea html;

  // Link display area
  private JTextArea links;

  // The "load" button
  private JButton doit;

  // Url controls
  private JTextField urlName;
  private JComboBox favorites;

  // Set up all GUI controls and their listeners
  public void begin() {
    this.resize(800, 600);

    Container pane = getContentPane();
    pane.setLayout(new FlowLayout());

    // Create a "bookmarks" menu
    pane.add(new JLabel("Favorites:"));
    favorites = new JComboBox();
    favorites.setFont(bigFont);
    favorites.addItem("http://wso.williams.edu");
    favorites.addItem("http://www.williams.edu");
    favorites.addItem("http://www.cs.williams.edu");

    favorites.addItem("http://www.cs.williams.edu/~cs134/index.html");
    favorites.addItem("file:///Volumes/Freund/simple.html");
    favorites.addItemListener(this);
    pane.add(favorites);

    // Create a text area into which a URL may be entered
    urlName = new JTextField("Enter URL", URLFIELDWIDTH);
    urlName.setFont(bigFont);
    pane.add(urlName);

    // Create the button used to start fetching a web page
    doit = new JButton("Fetch HTML");
    doit.setFont(bigFont);
    doit.addActionListener(this);
    pane.add(doit);

    // Create the text areas in which HTML and links will be displayed.
    html = new JTextArea(HTMLHEIGHT, HTMLWIDTH);
    html.setFont(bigFont);
    pane.add(new JScrollPane(html));

    links = new JTextArea(LINKSHEIGHT, LINKSWIDTH);
    links.setFont(bigFont);
    pane.add(new JScrollPane(links));

    pane.validate();
  }

  // If item is selected from "favorites" menu, enter it as current URL
  public void itemStateChanged(ItemEvent e) {
    urlName.setText(favorites.getSelectedItem().toString());
  }

  // Fetch the web page at "urlString" and return its contents as a String
  private String getWebPage(String urlString) {
    String page = "";

    try {
      URL url = new URL(urlString);
      BufferedReader input = new BufferedReader(new InputStreamReader(url.openStream()));

      String line = input.readLine();

      while (line != null) {
        page = page + line + "\n";
        line = input.readLine();
      }

      input.close();
    } catch (Exception ex) {
      JOptionPane.showMessageDialog(this, ex);
    }

    return page;
  }

  // Extract all the links from a web page
  private String findLinks(String fullPage) {

    // A lower case only version of the page for searching
    fullPage = fullPage.toLowerCase();

    // The A tags found so far
    String result = "";

    // Start of <A tag specification
    int tagStart = fullPage.indexOf("<a ", 0);

    while (tagStart > -1) {
      int tagEnd = fullPage.indexOf(">", tagStart);
      String tag = fullPage.substring(tagStart, tagEnd + 1);
      result = result + tag + "\n";
      tagStart = fullPage.indexOf("<a ", tagEnd);
    }

    return result;
  }

  // When the "Fetch" button is pressed, 
  // try to get the HTML, display and search it.
  public void actionPerformed(ActionEvent e) {
    String url = urlName.getText();
    String fullPage = getWebPage(url);
    html.setText(fullPage);
    links.setText(findLinks(fullPage));
  }
}
