<%--
  - autosuggest_search.js.jsp
  -
  - Version: $Revision: 1.6 $
  -
  - Date: $Date: 2007/06/15 13:20:22 $
  -
  - Copyright (c) 2007, Leiden University Library.
  - mail: schaik@library.leidenuniv.nl
  - All rights reserved.
  -
  - Redistribution and use in source and binary forms, with or without
  - modification, are permitted provided that the following conditions are
  - met:
  -
  - - Redistributions of source code must retain the above copyright
  - notice, this list of conditions and the following disclaimer.
  -
  - - Redistributions in binary form must reproduce the above copyright
  - notice, this list of conditions and the following disclaimer in the
  - documentation and/or other materials provided with the distribution.
  -
  - - Neither the name of the Hewlett-Packard Company nor the name of the
  - Massachusetts Institute of Technology nor the names of their
  - contributors may be used to endorse or promote products derived from
  - this software without specific prior written permission.
  -
  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  - HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  - TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  - DAMAGE.
  --%>

<%--
  - javascript for handling autosuggest search
  --%>

<%@ page contentType="application/x-javascript" %>

<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"
    prefix="fmt" %>

<%@ page import="org.dspace.core.ConfigurationManager" %>
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %>

var types = []; //['author','title','keyword','classification'];
var translation = [];
<%
int i = 1;
boolean autosuggestEnabled = false;
String type = null;
while ((type = ConfigurationManager.getProperty("ajax.autosuggest.index."+i)) != null) {
  %>types[<%=(i-1)%>] = '<%=type%>';
  <%String typeTranslation = LocaleSupport.getLocalizedMessage(pageContext, "jsp.ajax.types."+type); %>
  translation['<%=type%>'] = '<%=typeTranslation%>';
<%
  i++;
  autosuggestEnabled = true;
}
%>
<% String ps = ConfigurationManager.getProperty("ajax.autosuggest.pagesize"); %>
<% String ic = ConfigurationManager.getProperty("ajax.autosuggest.itemcount"); 
   if (ic == null) ic = "0"; %>
<% if (autosuggestEnabled && ps != null) { %>
var pagesize = <%=ps%>;
var itemcount = <%=ic%>;
var requests = new Array();
var aslayer;
var timeoutId;
var selection = -1;
var olfunc = window.onload;
window.onload = function() {
  appendSugStyles();
  var es = document.getElementsByName("query");
  if (es) { 
    for (var i=0;i<es.length;i++) {
      var e = es[i];
      e.setAttribute("autocomplete","off");
      e.form.setAttribute("autocomplete","off");
      e.onfocus = function(oEvent) {
        if (!oEvent) {
          oEvent = window.event;
        }
        clearTimeout(timeoutId);
        var oTarget = oEvent.target || oEvent.srcElement;
        timeoutId = setTimeout( function() { requestSuggestions(oTarget) }, 450); 
      };
      e.onkeyup = function(oEvent) {
        if (!oEvent) {
          oEvent = window.event;
        }
        var kc = oEvent.keyCode;
        if (kc == 38 || kc == 40 || kc == 27 || kc == 13) {  // up/down arrow, esc, enter
          return;
        }
        clearTimeout(timeoutId);
        var oTarget = oEvent.target || oEvent.srcElement;
        timeoutId = setTimeout( function() { requestSuggestions(oTarget) }, 450); 
      }
      e.onkeydown = function(oEvent) {
        if (!oEvent) {
          oEvent = window.event;
        }
        var prevent = false;
        switch(oEvent.keyCode) {
          case 38: // up arrow
            changeSelection(-1);
            prevent = true;
            break;
          case 40: // down arrow
            changeSelection(1);
            prevent = true;
            break;
          case 27: // esc 
            selection = -1;
            hideSuggestions(); 
            prevent = true;
            break;
          case 13: // enter
            var link = aslayer.childNodes[selection].childNodes[0];
            document.location.href = link.href;
            prevent = true;
            break;
        }
        if (prevent) {
          oEvent.returnValue = false;
          if (oEvent.preventDefault) {
            oEvent.preventDefault();
          }
        }
      }
      e.onblur = function(oEvent) {
        setTimeout( function() { hideSuggestions() }, 450);
      }
    }
    createDropDown();
  }
  if (olfunc != void 0) {
    olfunc();
  }
}

function changeSelection(diff) {
  var max = aslayer.childNodes.length - 1;
  if (selection >= 0 && selection <= max) {
    var oldNode = aslayer.childNodes[selection];
    oldNode.style.backgroundColor = 'white';
  }
  selection += diff;
  if (selection < 0) selection = max;
  if (selection > max) selection = 0;
  var newNode = aslayer.childNodes[selection];
  newNode.style.backgroundColor = 'silver';
}

function appendSugStyles() {
  var rules = {
      '.suggestions' : 'border: 1px solid black; position: absolute; display: none; width: 200px; background-color: white; font-family: small Verdana, Sans-serif; font-size: 10pt; color: #4A7184;',
      '.suggestions A' : 'color: #4A7184; text-decoration: none;',
      '.suggestions A:hover' : 'color: #252645; text-decoration: underline;',
      '.asss0' : 'margin-left: 0px;',
      '.asss0item' : 'margin-left: 5px;',
      '.asss1' : 'margin-left: 10px;',
      '.asss1item' : 'margin-left: 15px;',
      '.asss2' : 'margin-left: 10px;',
      '.asss2item' : 'margin-left: 15px;',
      '.asss3' : 'margin-left: 10px;',
      '.asss3item' : 'margin-left: 15px;',
      '.sugitem' : 'margin-left: 20px; color: gray; overflow: hidden; height: 1.2em;'
    };
  var ss = document.styleSheets[0];
  for (var sel in rules) {
    if (ss.addRule) {
      ss.addRule(sel,rules[sel]);
    }
    else if (ss.insertRule) {
      ss.insertRule(sel+" {"+rules[sel]+"}",0);
    }
  } 
}

function createDropDown() {
  aslayer = document.createElement("div");
  aslayer.className = 'suggestions';
  document.body.appendChild(aslayer);    
}

function requestSuggestions(forElement) {
  hideSuggestions();
  if (forElement.value.length < 2
     || forElement.value.match(/[()*:"']/)) {
    return;
  }
  var l = forElement.form.elements["location"];
  var handle = void 0;
  var html = "";
  removeChildren(aslayer);
  while(requests.length > 0) {
   requests.pop().abort();
  }
  if (l) {
    for (var i = l.selectedIndex;i<l.length;i++) {
      handle = l.options[i].value;
      handle = handle.replace(/\/$/,"");
      if (i==0) {
        aslayer.appendChild(makeDiv("ass"+i,"asss0","<fmt:message key="jsp.general.location"/> "+l.options[i].text));
      }
      else {
        aslayer.appendChild(makeDiv("ass"+i,"asss1"));
      }
      _requestSuggestions(forElement,handle,'ass'+i);
      for (var t=0;t<types.length;t++) {
        var type = types[t];
        aslayer.appendChild(makeDiv('ass'+i+type,"asss"+i+"item"));
        _requestSuggestions(forElement,handle,'ass'+i+type,type);
      }
      break; // stop after first... uncomment if subcollections need to be searched too
    }
  }
  else {
    aslayer.appendChild(makeDiv("ass0","asss0","<fmt:message key="jsp.general.location"/> <fmt:message key="jsp.general.genericScope"/>"));
    _requestSuggestions(forElement,handle,'ass0');
    for (var t=0;t<types.length;t++) {
      var type = types[t];
      aslayer.appendChild(makeDiv('ass'+i+type,"asss0item"));
      _requestSuggestions(forElement,handle,'ass'+i+type,type);
    }
  }
}

function makeDiv(id,className,text) {
  document.createElement("div");
  try {
    element = document.createElement("<div id=\""+id+"\" style=\"display: none\" class=\""+className+"\"></div>");
  } catch (e) {
    element = document.createElement("div");
    element.setAttribute("id", id);
    element.setAttribute("class", className);
    element.setAttribute("style", "display: none");
  }
  if (text != void 0 && text.length > 0) {
    element.innerHTML = text;
  }
  return element;
}

function removeChildren(e) {
  e.innerHTML = "";
  return;
  var doIt = true;
  while (doIt) {
    try {
      var oChild = e.children(0);
      e.removeChild(oChild);
    }
    catch(x) {
      doIt = false;
    }
  }
}

function _requestSuggestions(forElement,handle,id,type) {
  var ajRequest = getAjaxRequest();
  requests.push(ajRequest);
  if (ajRequest.readystate != 0) {
    ajRequest.abort();
  }
<%
String dspace_url = ConfigurationManager.getProperty("dspace.url");
%>
  var aUrl = '<%=dspace_url%>';
  aUrl += "/ajax-search?mode=ajax";
  if (handle) {
    aUrl += "&handle="+handle;
  }
  aUrl += "&query="+forElement.value;
  aUrl += "&id="+id;
  aUrl += "&pagesize="+pagesize;
  if (type != void 0) {
    aUrl += "&itemcount="+itemcount;
    aUrl += "&searchkey="+type;
  }
  aUrl += "&time="+new Date();
  ajRequest.open("get",aUrl,true);
  ajRequest.onreadystatechange = function() {
    if (ajRequest.readyState == 4) {
      var sug;
      if (ajRequest.status != 200) {
        //alert("An errror occured: ("+ajRequest.status+")\n");
        return;
      }
      eval("(sug = "+ajRequest.responseText+")");
      showSuggestions(forElement,sug);
    }
  }
  ajRequest.send(null);
}

function showSuggestions(forElement,sug) {
  var html = "";
 
  if (sug != void 0) {
    var e = document.getElementById(sug.id);
    if (e) {
      if (sug.count > 0) {
        html += "<a href=\""+sug.url+"\">";
        if (sug.text == '*') {
          html += '<fmt:message key="jsp.general.location"/> <fmt:message key="jsp.general.genericScope"/>'; 
        }
        else {
          html += '<fmt:message key="jsp.general.location"/> '+((translation[sug.text] != void 0)?translation[sug.text]:sug.text);
        }
        html += "</a>";
        if (sug.count >= pagesize) {
          html += " (>"+(pagesize-1)+")";
        }
        else if (sug.count != 0) {
          html += " ("+sug.count+")"; 
        }
        e.innerHTML = html;
        if (sug.items && sug.items.length > 0) {
          var tot = 0;
          var be = null;
          for (var i=0;i<aslayer.childNodes.length - 1;i++) {
            if (e == aslayer.childNodes[i]) {
              be = aslayer.childNodes[i+1];
            }
          }
          for (var i=0;i<sug.items.length;i++) {
            var item = sug.items[i];
            var newDiv = makeDiv("sugitem"+sug.id+i,"sugitem");
            html = "<a href=\""+item.url+"\">"+item.text+"</a>";
            if (sug.id.indexOf("title") == -1) {
              if (item.count >= pagesize) {
                html += " (>"+(pagesize-1)+")";
              }
              else {
                html += " ("+item.count+")";
              }
            }
            tot += item.count;
            newDiv.innerHTML = html;
            if (be == null) {
              aslayer.appendChild(newDiv);
            }
            else {
              aslayer.insertBefore(newDiv,be); 
            }
            newDiv.style.display = 'block';
          } 
          if (tot < sug.count) {
            var newDiv = makeDiv("sugitem"+sug.id+"no","sugitem");
            newDiv.style.fontSize = '6pt';
            newDiv.innerHTML = '. . . .';
            if (be == null) {
              aslayer.appendChild(newDiv);
            }
            else {
              aslayer.insertBefore(newDiv,be); 
            }
            newDiv.style.display = 'block';
          }
        }
        e.style.display = "block";

        displaySuggestions(forElement);
      }
      else if (sug.count == 0 && sug.id.match(/^ass\d+$/)) {
        if (sug.text == '*') {
          html += '<fmt:message key="jsp.general.location"/> <fmt:message key="jsp.general.genericScope"/>';
        }
        else {
          html += '<fmt:message key="jsp.general.location"/> '+sug.text;
        }
        html += " (0)";
        e.innerHTML = html;
        e.style.display = "block";
        displaySuggestions(forElement);
      }
    }
  }
  else {
    hideSuggestions();
  }
}

function displaySuggestions(forElement) {
  aslayer.style.left = getLeft(forElement) + "px";
  aslayer.style.top = (getTop(forElement)+forElement.offsetHeight)+"px";
  var width = forElement.offsetWidth;
  if (width < 350) width = 350;
  aslayer.style.width = width + "px";
  aslayer.style.display = "block";
}

function hideSuggestions() {
  aslayer.style.display = "none";
}

function getLeft(oNode) {
  var iLeft = 0;
  
  while(oNode.tagName != "BODY") {
    iLeft += oNode.offsetLeft;
    oNode = oNode.offsetParent;        
  }
  
  return iLeft;
};

function getTop(oNode) {
  var iTop = 0;
    
  while(oNode.tagName != "BODY") {
    iTop += oNode.offsetTop;
    oNode = oNode.offsetParent;
  }
  
  return iTop;
}

function log_it(message) {
    if (!log_it.window_ || log_it.window_.closed) {
        var win = window.open("", null, "width=400,height=200," +
                              "scrollbars=yes,resizable=yes,status=no," +
                              "location=no,menubar=no,toolbar=no");
        if (!win) return;
        var doc = win.document;
        doc.write("<html><head><title>Debug Log</title></head>" +
                  "<body></body></html>");
        doc.close();
        log_it.window_ = win;
    }
    var logLine = log_it.window_.document.createElement("div");
    logLine.appendChild(log_it.window_.document.createTextNode(message));
    log_it.window_.document.body.appendChild(logLine);
}
<% } %>
