import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;

public class SearchEntry extends Object {
  public static final String NULLTEXT = "(none)";
  public static final String QUERY = "Query";
  public static final String NUMBER = "Number";
  public static final String TOTAL = "Total";
  public static final String RESULTS = "Results";
  public static final String NEXTRES = "Next Results";
  public static final String COLLECTIONS = "Collections";
  public static final String SITES = "Sites";
  public static final String URL = "URL";
  public static final String TITLE = "Title";
  public static final String SCORE = "Score";
  public static final String DATE = "Date";
  public static final String SIZE = "Size";
  public static final String SUMMARY = "Summary";
  public static final String SEP = ":";

  protected String queryString;
  protected Hashtable header, entry;
  protected DataInputStream din;
  protected boolean returnBlank, foundEntry;

  public SearchEntry(String url, String qs) throws IOException, URLFileException, APIException {
    returnBlank = false;
    foundEntry = false;
    header = new Hashtable();

    URL p;
    URLConnection page;
    InputStream in;
    String finalUrl = new String(url + "?" + qs);

    try {
      p = new URL(finalUrl);
      page = p.openConnection();
      in = page.getInputStream();
      din = new DataInputStream(in);

      String line, key, value;
      boolean done = false, inHeader = true;
      int numlines = 0;

      while(!done) {
	line = din.readLine();
	//	System.out.println("line " + numlines + " (" + done + "):" + line);

	if(line == null)
	  throw new APIException("SearchEntry: unexpected blank line (" + numlines + ")");
	numlines++;

	if(line.length() == 0)
	  continue;

	int i = line.indexOf(SEP);
	if(i < 1)
	  continue;
	key = line.substring(0, i);
	//	System.out.println("key: " + key);
	try {
	  value = line.substring(i + SEP.length() + 1);    // account for space after separator
	}
	catch (StringIndexOutOfBoundsException sioob) {
	  value = new String();
	}
	if(!value.equals(""))
	  header.put(key, value);
	if(key.equals(SITES))
	  done = true;
      }  // while
    }
    catch (FileNotFoundException fnf) {
      throw new URLFileException(fnf.getMessage());
    }
  }

  public boolean getNextEntry() throws IOException, APIException {
    String line, key, value;
    entry = new Hashtable();
    boolean gotLine = false;
    //    System.out.println("entering getNextEntry()");
    while((line = din.readLine()) != null) {
      //      System.out.println("line: " + line);
      gotLine = true;
      if(line.length() == 0)                   // blank line
	if(!foundEntry) {                      // ignore first blank line
	  foundEntry = true;
	  continue;
	} else                                   // otherwise, is separator
	  return true;
      else {
	int i = line.indexOf(SEP);
	if(i < 1)
	  throw new APIException("search result format exception: " + line);
	key = line.substring(0, i);
	try {
	  value = line.substring(i + SEP.length() + 1);     // account for space after separator
	}
	catch (StringIndexOutOfBoundsException sioob) {
	  value = new String();
	}
	if(!value.equals(""))
	  entry.put(key, value);
      }
    }
    return gotLine;                       // only reach here if EOF.  call succeeded if lines were read before EOF.
  }

  public String checkNull(String s) {
    if(s != null)
      return s;
    else if(returnBlank)
      return new String("");
    else
      return new String(NULLTEXT);
  }

  public boolean getReturnBlank() {
    return returnBlank;
  }

  public void setReturnBlank(boolean b) {
    returnBlank = b;
  }

  public String getQuery() {
    return checkNull((String)header.get(QUERY));
  }

  public String getNumber() {
    return checkNull((String)header.get(NUMBER));
  }

  public String getTotal() {
    return checkNull((String)header.get(TOTAL));
  }

  public String getResults() {
    return checkNull((String)header.get(RESULTS));
  }

  public String getNextResults() {
    return checkNull((String)header.get(NEXTRES));
  }

  public String getURL() {
    return checkNull((String)entry.get(URL));
  }

  public String getTitle() {
    return checkNull((String)entry.get(TITLE));
  }

  public String getScore() {
    return checkNull((String)entry.get(SCORE));
  }

  public String getDate() {
    String ds;
    if((ds = (String)entry.get(DATE)) == null)
      return checkNull(ds);
    Date d = null;
    try {
      long l = Long.parseLong(ds) * 1000;
      d = new Date(l);
    }
    catch (IllegalArgumentException ia) {
      d = null;
    }
    if(d == null)
      return checkNull(null);

    SimpleDateFormat simpleDate = new SimpleDateFormat("dd MMM yy");
    return simpleDate.format(d);
  }

  public String getSize() {
    return checkNull((String)entry.get(SIZE));
  }

  public String getSummary() {
    return checkNull((String)entry.get(SUMMARY));
  }
}
