var search_strings = [
  "Main",
  "Top",
  "Announcements",
  "Overview",
  "Syllabus",
  "Resources",
  "Homeworks",
  "Email and Piazza Group Policies",
  "Style Guide",
  "Tips",
  "Exam Format",
  "Homework #1: Intro",
  "Assignment #1",
  "Homework #2: BNFs, Higher-Order Functions, Typed Racket",
  "Assignment #2",
  "Homework #3: Basic Interpreter Extension",
  "Assignment #3",
  "Homework #4: Algae",
  "Assignment #4",
  "Homework #5: Brang",
  "Assignment #5",
  "Homework #6: Algae, part 2",
  "Assignment #6",
  "Homework #7: Brang Strikes Back",
  "Assignment #7",
  "Sample Midterm 1",
  "Sample Midterm 2",
  "Sample Midterm 3",
  "Sample Midterm 4",
  "Overview > What?",
  "Overview > Who?",
  "Overview > When? Where?",
  "Overview > Office Hours",
  "Overview > Textbook & Syllabus",
  "Overview > Grades",
  "Overview > Policies",
  "Lecture #1",
  "Lecture #2",
  "Lecture #3",
  "Lecture #4",
  "Lecture #5",
  "Lecture #6",
  "Lecture #7",
  "Lecture #8",
  "Lecture #9",
  "Lecture #10",
  "Lecture #11",
  "Lecture #12",
  "ae.rkt",
  "wae.rkt",
  "flang.rkt",
  "flang-env.rkt",
  "church.rkt",
  "church-alternative.rkt",
  "Resources > Class Notes",
  "Resources > Handouts",
  "Resources > Interpreters",
  "Resources > Software",
  "Resources > Piazza Group",
  "Resources > IRC",
  "Resources > On-line books and other materials",
  "Homeworks > Warning",
  "Homeworks > Submissions",
  "Homeworks > Handin Server",
  "Homeworks > Homeworks",
  "Homeworks > Exams",
  "Homeworks > Statistics",
  "Homeworks > Graphs",
  "Email and Piazza Group Policies > What to do with a question",
  "Email and Piazza Group Policies > How to ask a question",
  "Email and Piazza Group Policies > Email",
  "Email and Piazza Group Policies > Piazza Group",
  "Email and Piazza Group Policies > Posting code",
  "Email and Piazza Group Policies > Public posts and direct emails",
  "Email and Piazza Group Policies > Plaintext, MIME, and HTML in emails",
  "Email and Piazza Group Policies > Spelling and such",
  "Email and Piazza Group Policies > Line lengths",
  "Email and Piazza Group Policies > Signatures",
  "Email and Piazza Group Policies > Quoting",
  "Email and Piazza Group Policies > Attribution",
  "Style Guide > How can I improve my Racket coding style and efficiency?",
  "Style Guide > To improve the readability of your code",
  "Style Guide > Documentation",
  "Tips > Homework Submission",
  "Tips > Writing Good Code",
  "Tips > Working with DrRacket",
  "Tips > Keeping Up",
  "Exam Format > About the Exam Application",
  "Exam Format > Exam Options",
  "Exam Format > Option 1: In-Class Exam",
  "Exam Format > Option 2: Out-of-Class Exam",
  "Exam Format > Grading"];
var search_anchors = [
  "/.",
  "/.",
  "/.",
  "/overview.html",
  "/syllabus.html",
  "/resources.html",
  "/homeworks.html",
  "/policies.html",
  "/style-guide.html",
  "/tips.html",
  "/exam-format.html",
  "/homework-1.html",
  "/homework-1.html",
  "/homework-2.html",
  "/homework-2.html",
  "/homework-3.html",
  "/homework-3.html",
  "/homework-4.html",
  "/homework-4.html",
  "/homework-5.html",
  "/homework-5.html",
  "/homework-6.html",
  "/homework-6.html",
  "/homework-7.html",
  "/homework-7.html",
  "/sample-midterm-1.html",
  "/sample-midterm-2.html",
  "/sample-midterm-3.html",
  "/sample-midterm-4.html",
  "/overview.html#what",
  "/overview.html#who",
  "/overview.html#whenwhere",
  "/overview.html#officehours",
  "/overview.html#textbooksyllabus",
  "/overview.html#grades",
  "/overview.html#policies",
  "/lec01.txt",
  "/lec02.txt",
  "/lec03.txt",
  "/lec04.txt",
  "/lec05.txt",
  "/lec06.txt",
  "/lec07.txt",
  "/lec08.txt",
  "/lec09.txt",
  "/lec10.txt",
  "/lec11.txt",
  "/lec12.txt",
  "/ae.rkt",
  "/wae.rkt",
  "/flang.rkt",
  "/flang-env.rkt",
  "/church.rkt",
  "/church-alternative.rkt",
  "/resources.html#classnotes",
  "/resources.html#handouts",
  "/resources.html#interpreters",
  "/resources.html#software",
  "/resources.html#piazzagroup",
  "/resources.html#irc",
  "/resources.html#onlinebooksandothermaterials",
  "/homeworks.html#warning",
  "/homeworks.html#submissions",
  "/homeworks.html#handinserver",
  "/homeworks.html#homeworks",
  "/homeworks.html#exams",
  "/homeworks.html#statistics",
  "/homeworks.html#statistics",
  "/policies.html#whattodowithaquestion",
  "/policies.html#howtoaskaquestion",
  "/policies.html#email",
  "/policies.html#piazzagroup",
  "/policies.html#postingcode",
  "/policies.html#publicpostsanddirectemails",
  "/policies.html#plaintextmimeandhtmlinemails",
  "/policies.html#spellingandsuch",
  "/policies.html#linelengths",
  "/policies.html#signatures",
  "/policies.html#quoting",
  "/policies.html#attribution",
  "/style-guide.html#howcaniimprovemyracketcodingstyleandefficiency",
  "/style-guide.html#toimprovethereadabilityofyourcode",
  "/style-guide.html#documentation",
  "/tips.html#homeworksubmission",
  "/tips.html#writinggoodcode",
  "/tips.html#workingwithdrracket",
  "/tips.html#keepingup",
  "/exam-format.html#abouttheexamapplication",
  "/exam-format.html#examoptions",
  "/exam-format.html#option1inclassexam",
  "/exam-format.html#option2outofclassexam",
  "/exam-format.html#grading"];

function my_compare(s1, s2) {
  var i1 = 0, i2 = 0, start = 0, r, result = [];
  while (i1 < s1.length) {
    r = s2.indexOf(s1[i1], i2);
    if (r < 0) return [];
    i1++, i2=r+1;
  }
  i1-=2, i2-=2;
  while (i1 >= 0) {
    r = s2.lastIndexOf(s1[i1],i2);
    i1--, i2=r;
  }
  i1=0, start=i2;
  while (i1 < s1.length) {
    r = s2.indexOf(s1[i1], i2);
    if (r < 0) return [];
    if (r > i2) {
      if (start < i2) result.push([start,i2]);
      start = r;
    }
    i1++, i2=r+1;
  }
  if (start < i2) result.push([start,i2]);
  return result;
}

function my_selector(inst) {
  var search = inst.getToken().toLowerCase();
  var options = inst.options.array;
  var result = [], i, j, r;
  for (i=0; i<options.length; i++) {
    r = my_compare(search, options[i].toLowerCase());
    if (r.length > 0) result.push([options[i],r]);
  }
  result.sort(function(x,y){
    var d = 0, i;
    for (i=x[1].length-1;i>0;i--) d += (x[1][i][0] - x[1][i-1][1]);
    for (i=y[1].length-1;i>0;i--) d -= (y[1][i][0] - y[1][i-1][1]);
    if (d != 0) return (d<0) ? -1 : 1;
    if (x[0].length != y[0].length)
      return (x[0].length < y[0].length) ? -1 : 1;
    if (x[1][0][0] != y[1][0][0])
      return (x[1][0][0] < y[1][0][0]) ? -1 : 1;
    return (x[0] <= y[0]) ? -1 : 1;
  });
  var truncated = (result.length > inst.options.choices);
  if (truncated) result = result.slice(0, inst.options.choices);
  for (i=0; i<result.length; i++) {
    var str = result[i][0], range = result[i][1];
    r = "";
    for (j=0; j<range.length-1; j++)
      r = r + "<u>" + str.substring(range[j][0],range[j][1])
            + "</u>" + str.substring(range[j][1],range[j+1][0]);
    j = range.length-1;
    result[i] = "<li>" + str.substring(0,range[0][0]) + r +
                "<u>" + str.substring(range[j][0],range[j][1]) +
                "</u>" + str.substring(range[j][1]) + "</li>";
  }
  if (truncated) result.push("<li>...truncated...</li>");
  return "<ul>" + result.join('') + "</ul>";
}

var searcher =
  new Autocompleter.Local(
    "search-box", "search-completions", search_strings,
    { ignoreCase: true, fullSearch: true, selector: my_selector,
      choices: 12 });
searcher.oldSelectEntry = searcher.selectEntry;
searcher.selectEntry = function() {
  var r = this.oldSelectEntry();
  search_for(document.getElementById("search-box").value);
  return r;
}

function search_for(str) {
  for (var i=0; i<search_strings.length; i++) {
    if (search_strings[i] == str) {
      location.href = search_anchors[i];
      return true;
    }
  }
  return false;
}

