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

public class SearchPage extends TokenReplacer {
  protected SearchEntry se;
  protected String url, queryString, templatePath, queryBase, searchText, searchDomain;
  protected HttpServletRequest req;
  protected int nh, st;
  public static final String FIRSTTEXT = "st";
  public static final String NUMTEXT = "nh";
  public static final String SEARCHTEXT = "search_for_what";
  public static final String SEARCHDOMAIN = "search_what";

  public SearchPage(HttpServletRequest r, String tp, String u) throws IOException, URLFileException, APIException, InternalException {
    //    System.out.println("in SearchPage constructor");
    url = u;
    req = r;
    templatePath = tp;

    queryString = req.getQueryString();

    se = new SearchEntry(url, queryString);

    searchText = new String("");
    searchDomain = new String("");
    Hashtable h = HttpUtils.parseQueryString(queryString);
    Enumeration e = h.keys();
    String name;
    String[] value;
    int numpairs = 0;
    queryBase = new String();
    while(e.hasMoreElements()) {
      try {
	name = (String)e.nextElement();
	value = (String[])h.get(name);
//	System.err.println("name: " + name + ", value: " + value[0]);
	if(value.length > 1)
	  throw new InternalException("Search query format error: duplicate key: " + queryString);
	if(name.equals(FIRSTTEXT))
	  st = Integer.parseInt(value[0]);
	else if(name.equals(NUMTEXT))
	  nh = Integer.parseInt(value[0]);
	else if(name.equals(SEARCHTEXT)) {
	  int k = 0;
	  int lastk = 0;
	  String rv = new String(value[0]);

	  String first, last;
	  while((k = rv.indexOf("\"", lastk)) != -1) {
	    first = rv.substring(0, k);
	    last = rv.substring(k+1, rv.length());
	    rv = first + "\\\"" + last;
	    lastk = k + 2;
	  }
	  searchText = rv;
//	  System.err.println("found search text: " + searchText);
	} else if(name.equals(SEARCHDOMAIN)) {
	  searchDomain = new String(value[0]);
//	  System.err.println("found search domain: " + searchDomain);
	}
	if(!name.equals(FIRSTTEXT)) {
	  if(numpairs > 0)
	    queryBase += "&";
	  queryBase += name + "=" + URLEncoder.encode(value[0]);
	  numpairs++;
	}
      }
      catch (NumberFormatException nf) {
	throw new InternalException("bad number format in search query: " + queryString);
      }
    }

  }

  public String replaceToken(String line, String token) throws IOException, URLFileException, TemplateReadException, APIException {
    String s = new String();
    if(token.equals("query"))
      s = se.getQuery();
    else if(token.equals("searchtext"))
      s = searchText;
    else if(token.equals("searchdomain"))
      s = searchDomain;
    else if(token.equals("number"))
      s = se.getNumber();
    else if(token.equals("total"))
      s = se.getTotal();
    else if(token.equals("results"))
      if(se.getTotal().equals("0"))
	s = "0";
      else
	s = se.getResults();
    else if(token.equals("nextresults")) {
      boolean rb = se.getReturnBlank();
      se.setReturnBlank(true);
      String nr = se.getNextResults();
      s = "";
      if(!nr.equals("")) {
	int newst = st + nh;
	s = "<a href=\"" + req.getServletPath() + req.getPathInfo() + "?" + queryBase + "&st=" + newst + "\">next page &gt;&gt;</a>";
      }
    } else if(token.equals("prevresults")) {
      s = "";
      if(st > 1) {
	int newst = Math.max(1, st - nh);
	s = "<a href=\"" + req.getServletPath() + req.getPathInfo() + "?" + queryBase + "&st=" + newst + "\">&lt;&lt; previous page</a>";
      }
    } else if(token.startsWith("linefile:")) {
      String linefilename = chopToken(token);
      String lineUrl = new String(templatePath + linefilename);
      File f = new File(lineUrl);
      FileInputStream fin = new FileInputStream(f);
      DataInputStream lin = new DataInputStream(fin);

      String repline = new String();
      String u;
      try {
	while((u = lin.readLine()) != null)
	  repline += u + "\n";
      }
      catch (IOException ioe) {
	throw new TemplateReadException(lineUrl);
      }
      s = replaceLineToken(repline);
    }
    return inPlaceReplace(line, token, s);
  }

  protected String replaceLineToken(String origline) throws IOException, APIException {
    String line;              // token line from linefile
    String r = new String();  // return string
    String t;                 // token

    int num = 0;
    while(se.getNextEntry()) {
      line = origline;
      while((t = getNextToken(line)) != null) {
	if(t.equals("url"))
	  line = inPlaceReplace(line, t, se.getURL());
	else if(t.equals("title"))
	  line = inPlaceReplace(line, t, se.getTitle());
	else if(t.equals("score"))
	  line = inPlaceReplace(line, t, se.getScore());
	else if(t.equals("date"))
	  line = inPlaceReplace(line, t, se.getDate());
	else if(t.equals("size"))
	  line = inPlaceReplace(line, t, se.getSize());
	else if(t.equals("summary"))
	  line = inPlaceReplace(line, t, se.getSummary());
      }
      r += line;
      num++;
    }
    return r;
  }
}
