/* (c) Copyright Sony Ericsson Mobile Communications AB. 2010 All rights reserved. */

// Global variables
var SEARCHANY = 1;
var SEARCHALL = 2;
var SEARCHURL = 4;
var searchType = '';
var showMatches = 10; // This variables sets the number of records to display for each results page
var currentMatch = 0;
var copyArray = new Array();

// Use this function to read any cookie when loading the search page
function readCookie() {
  var cookie = document.cookie;
  var cookiepairs = cookie.split("; ");
  for (i = 0; i < cookiepairs.length; i++) {
    if (cookiepairs[i].split("=")[0] == "reference") {
      currentMatch = cookiepairs[i].split("=")[1];
    }
  }
  // The search result should only be validated if the cookie contains an entry
  for (i = 0; i < cookiepairs.length; i++) {
    if (cookiepairs[i].split("=")[0] == "entry") {
      var entryvalue = unescape(cookiepairs[i].split("=")[1]);
      document.forms[0].query.value = entryvalue;
      validate(entryvalue, currentMatch);
    }
  }
}

// This function determines the type of search, makes sure something is entered, and makes sure it is entered correctly
function setCookie(entry, ref) {
  var pipe = new RegExp("\\u007c");
  if (entry.search(pipe) != -1) {
    alert("您的搜尋不可包含直線字符 |。");
    document.forms[0].query.focus();
    return false;
  }
  if (entry.length < 2) {
    alert("您不能搜尋少於二個字符的文字。");
    document.forms[0].query.focus();
    return false;
  }
  if (entry.charAt(0) == "+") {
    entry = entry.substring(1,entry.length);
    searchType = SEARCHALL;
  }
  else if (entry.substring(0,4) == "url:") {
    entry = entry.substring(4,entry.length);
    searchType = SEARCHURL;
  }
  else if (entry.charAt(0) == '"' && entry.charAt(entry.length - 1) == '"') {
    searchType = SEARCHALL;
  }
  else {
    searchType = SEARCHANY;
  }
  while (entry.charAt(0) == ' ') {
    entry = entry.substring(1,entry.length);
    document.forms[0].query.value = entry;
  }
  while (entry.charAt(entry.length - 1) == ' ') {
    entry = entry.substring(0,entry.length - 1);
    document.forms[0].query.value = entry;
  }
  var whitespace = new RegExp(/(\s)/);
  /* After having removed white space in beginning and end, check if the entry still has white space.
     If so, more than one word has been entered, and the search should be done on all words. */
  if (entry.search(whitespace) != -1) {
    searchType = SEARCHALL;
  }
  document.cookie = "entry=" + escape(entry) + "; path=/";
  document.cookie = "reference=" + ref + "; path=/";
  return true;
}

function validate(entry, ref) {
  var test = setCookie(entry, ref);
  if (test == true) {
    convertString(entry);
  }
}

// Set the cookie and then redirect to the search page
function redirect(entry, ref) {
  var test = setCookie(entry, ref);
  if (test == true) {
    location.href = "search.html";
  }
}

// Put the search terms in an array and call the appropriate search function
function convertString(reentry) {
  if (reentry.charAt(0) == '"' && reentry.charAt(reentry.length - 1) == '"') {
    var searchArray = new Array(reentry.substring(1,reentry.length - 1));
  }
  else {
    var searchArray = reentry.split(" ");
  }
  if (searchType == SEARCHALL) {
    requireAll(searchArray, reentry);
  }
  else {
    allowAny(searchArray, reentry);
  }
}

// Function to perform a search that requires a match of any of the terms provided
function allowAny(t, reentry) {
  var findings = new Array(0);
  for (i = 0; i < records.length; i++) {
    var compareElement = records[i].toLowerCase();
    var divide = compareElement.split("|");
    if (searchType == SEARCHANY) {
      // Search title and content
      var refineElement = divide[0] + divide[1];
    }
    else {
      // Search HTTP address only
      var refineElement = divide[2];
    }
    for (j = 0; j < t.length; j++) {
      var compareString = t[j].toLowerCase();
      if (refineElement.indexOf(compareString) != -1) {
        findings[findings.length] = records[i];
        break;
      }
    }
  }
  verifyManage(findings, reentry);
}

// Function to perform a search that requires a match of all terms provided
function requireAll(t, reentry) {
  var findings = new Array();
  for (i = 0; i < records.length; i++) {
    var allConfirmation = true;
    var allString = records[i].toLowerCase();
    var divide = allString.split("|");
    var refineAllString = divide[0] + divide[1];
    for (j = 0; j < t.length; j++) {
      var allElement = t[j].toLowerCase();
      if (refineAllString.indexOf(allElement) == -1) {
        allConfirmation = false;
        continue;
      }
    }
    if (allConfirmation) {
      findings[findings.length] = records[i];
    }
  }
  verifyManage(findings, reentry);
}

// Function to count the number of occurrences of a word in a text string
function count(string, word) {
  var stringLowerCase = string.toLowerCase();
  var wordLowerCase = word.toLowerCase();
  var substrings = stringLowerCase.split(wordLowerCase);
  return substrings.length - 1;
}

// Function to sort numbers in descending order
function compareNumbers(a, b) {
  divideA = a.split("|");
  divideB = b.split("|");
  return divideB[3].toString() - divideA[3].toString();
}

// Function to verify the search result
function verifyManage(resultSet, reentry) {
  if (resultSet.length == 0) {
    noMatch(reentry);
  }
  else {
    // Go through each row and add the number of occurrences of the search word, later use that to sort the result
    // Set a higher weight for occurrences of the search word in the title
    var divide = new Array();
    for (var i = 0; i < resultSet.length; i++) {
      divide = resultSet[i].split("|");
      title = divide[0].toString();
      content = divide[1].toString();
      resultSet[i] =  resultSet[i] + "|" + 5 * count(title, reentry) + count(content, reentry);
    }
    copyArray = resultSet.sort(compareNumbers);
    var cookie = document.cookie;
    var cookiepairs = cookie.split("; ");
    for (i = 0; i < cookiepairs.length; i++) {
      cookievalue = cookiepairs[i].split("=");
      if (cookievalue[0] == "reference") {
        currentMatch = ((cookievalue[1])/10)*showMatches;
      }
    }
    formatResults(copyArray, currentMatch, showMatches, reentry);
  }
}

// Function that indicates that the search returned no results
function noMatch(reentry) {
  var elem;
  elem = document.createElement("p");
  elem.appendChild(document.createTextNode("找不到任何搜尋結果。"));

  var count = 0;
  for (var i = 0; i < document.body.childNodes.length; i++) {
    count++;
    if (document.body.childNodes[i].nodeName.toLowerCase() == 'form') {
      break;
    }
  }

  while (document.body.childNodes.length > count) {
    document.body.removeChild(document.body.lastChild);
  }
  document.body.appendChild(elem);
}

// Function to print the results of a successful search
function formatResults(results, reference, offset, reentry) {
  var elem, anchor, currentRecord, divide, br, hits, entryLength, highlight;
  currentRecord = (results.length < reference + offset ? results.length : reference + offset);
  elem = document.createElement("p");
  elem.appendChild(document.createTextNode("結果 " + (reference + 1) + " - " + currentRecord + " ， " + results.length));
  var count = 0;
  for (var i = 0; i < document.body.childNodes.length; i++) {
    count++;
    if (document.body.childNodes[i].nodeName.toLowerCase() == 'form') {
      break;
    }
  }

  while (document.body.childNodes.length > count) {
    document.body.removeChild(document.body.lastChild);
  }
  document.body.appendChild(elem);

  if (searchType == SEARCHURL) {
    for (var i = reference; i < currentRecord; i++) {
      divide = results[i].split("|");
      elem = document.createElement("p");
      anchor = document.createElement("a");
      anchor.setAttribute("href", divide[2]);
      anchor.appendChild(document.createTextNode(divide[2]));
      elem.appendChild(anchor);
      br = document.createElement("br");
      elem.appendChild(br);
      elem.appendChild(document.createTextNode(divide[1].substring(0, 100) + " ..."));
      document.body.appendChild(elem);
    }
  }
  else {
    for (var i = reference; i < currentRecord; i++) {
      divide = results[i].split("|");
      elem = document.createElement("p");
      anchor = document.createElement("a");
      anchor.setAttribute("href", divide[2]);
      hits = countIndexOf(divide[0].toLowerCase(), reentry);
      entryLength = reentry.length;
      // If the search word is within the text, highlight it
      if (hits.length > 0) {
        for (var j = 0; j < hits.length; j++) {
          if (j > 0) {
            anchor.appendChild(document.createTextNode(divide[0].substring(hits[j - 1] + entryLength, hits[j])));
            highlight = document.createElement("b");
            highlight.appendChild(document.createTextNode(divide[0].substring(hits[j], hits[j] + entryLength)));
            anchor.appendChild(highlight);
          }
          else {
            anchor.appendChild(document.createTextNode(divide[0].substring(0, hits[j])));
            highlight = document.createElement("b");
            highlight.appendChild(document.createTextNode(divide[0].substring(hits[j], hits[j] + entryLength)));
            anchor.appendChild(highlight);
          }
        }
        anchor.appendChild(document.createTextNode(divide[0].substring(hits[hits.length - 1] + entryLength, divide[0].length)));
      }
      // Otherwise just display the text as normal
      else {
        anchor.appendChild(document.createTextNode(divide[0]));
      }

      elem.appendChild(anchor);
      br = document.createElement("br");
      elem.appendChild(br);

      hits = countIndexOf(divide[1].substring(0, 100).toLowerCase(), reentry);
      // If the search word is within the text, highlight it
      if (hits.length > 0) {
        for (var j = 0; j < hits.length; j++) {
          if (j > 0) {
            elem.appendChild(document.createTextNode(divide[1].substring(hits[j - 1] + entryLength, hits[j])));
            highlight = document.createElement("b");
            highlight.appendChild(document.createTextNode(divide[1].substring(hits[j], hits[j] + entryLength)));
            elem.appendChild(highlight);
          }
          else {
            elem.appendChild(document.createTextNode(divide[1].substring(0, hits[j])));
            highlight = document.createElement("b");
            highlight.appendChild(document.createTextNode(divide[1].substring(hits[j], hits[j] + entryLength)));
            elem.appendChild(highlight);
          }
        }
        elem.appendChild(document.createTextNode(divide[1].substring(hits[hits.length - 1] + entryLength, 100) + " ..."));
      }
      // Otherwise just display the text as normal
      else {
        elem.appendChild(document.createTextNode(divide[1].substring(0, 100) + " ..."));
      }
      document.body.appendChild(elem);
    }
  }
  document.cookie = "reference=" + reference + "; path=/";
  resultLinks(results.length, reference, offset, reentry);
}

// Function to return an array with the index positions of where the "search" word is found in the "text"
function countIndexOf(text, search) {
  var count = 0;
  var positions = new Array();
  for (var fromIndex = 0; fromIndex > -1; count++) {
    fromIndex = text.indexOf(search, fromIndex + ((count > 0) ? 1 : 0));
    if (fromIndex != -1) {
      positions[count] = fromIndex;
    }
  }
  return positions;
}

// Function to dynamically display results links
function resultLinks(ceiling, reference, offset, reentry) {
  var anchor, numberoflinks, elem, current;
  numberoflinks = Math.ceil(ceiling/offset);

  if (ceiling > offset) {
    elem = document.createElement("div");
    elem.setAttribute("class", "result");
    elem.setAttribute("className", "result");
    for (var i = 1; i <= numberoflinks; i++) {
      anchor = document.createElement("a");
      anchor.setAttribute("class", "result");
      anchor.setAttribute("className", "result");
      anchor.setAttribute("id", i);
      anchor.setAttribute("href", "#");
      function link(e) {
        var e = e ? e : window.event;
        var element = e.target ? e.target : e.srcElement;
        formatResults(copyArray, (element.id - 1)*offset, offset, reentry);
        window.scrollTo(0,0);
        return false;
      }
      // Detection for Firefox
      if (anchor.addEventListener) {
        anchor.addEventListener('click', link, false);
      }
      // Detection for Internet Explorer
      else if (anchor.attachEvent) {
        anchor.attachEvent('onclick', link);
      }
      txt = document.createTextNode(i);
      anchor.appendChild(txt);
      if (reference / offset + 1 == i) {
        current = document.createElement("span");
        current.setAttribute("class", "current");
        current.setAttribute("className", "current");
        current.appendChild(txt);
        elem.appendChild(current);
      }
      else {
        elem.appendChild(anchor);
      }
    }
    document.body.appendChild(elem);
  }
}