/******************* 
Written by Martin Mahoney/DIGITAS INC. 2005
with the exception of the getLD() levenshtein distance algorithm
written by Michael Gilleland, http://www.merriampark.com.
I modifed it while porting it from java to javascript to account
for javascript's lack of true multi-dimensional arrays.
*******************/
function process404(){
  var userURL = getURL('pathname');
  var userQuery = getURL('search')
  var targetUrl = isDirectMatch( userURL, userQuery );
  if( targetUrl != null ){ 
    if(targetUrl.indexOf("http") != -1) { window.location.replace(targetUrl); return; } 
    else { window.location.replace(domain + targetUrl); return; }
  }
  /* we aren't using this yet. dtw 9/27
  createLinksList(doMatchAndSort( userURL ));
  */
}
// assembles top 5 link suggestions based on Levenshtein Distance matching against user-entered URL
function createLinksList(urlData){
  var ul = document.getElementById('links');
  for(var i=0; i < urlData.length; i++){
    var li = document.createElement('li');
	 var a = document.createElement('a');
	 var linkTarget = domain + redirector;
	 linkTarget += "url=" + urlData[i].data[0] + "&uri=" + urlData[i].data[1];
	 var p = document.createElement('p');
	 var title = document.createTextNode(urlData[i].data[2]);
	 var descript = document.createTextNode(urlData[i].data[3]);
	 li.appendChild(a);
	 a.setAttribute('href',linkTarget);
	 a.appendChild(title);
	 li.appendChild(p);
	 p.appendChild(descript);
	 ul.appendChild(li);
  }
}
// takes URL path and sorts by closest match, then collapses array dimension, then returns top 5 entries.
function doMatchAndSort(str){
  var resultSet = new Array();
  var sortedResult = new Array();
  for(var i=0; i < dictionary.getTotalMaps(); i++){
    resultSet[i] = new Array( getLD(str,dictionary.getMapItem(i).data[0]),dictionary.getMapItem(i) );
  }
  resultSet.sort( sortResult );
  for(var i=0; i < resultSet.length; i++){ sortedResult[i] = resultSet[i][1]; }
  sortedResult = sortedResult.slice(0,5);
  return sortedResult;
}
// comparator to sort 2d array in ascending order 
function sortResult(a, b){ return (a[0] - b[0]);}
// Look for exact match to users URL
function isDirectMatch(url, query){
	var urls = urlTable();
	var urlStr = url.toLowerCase(); 
	var urlPlusQuery = urlStr + query.toLowerCase();
	if(urls[urlPlusQuery] != undefined ){ return urls[urlPlusQuery]; }
	if(urls[urlStr] != undefined){ return urls[urlStr] + query; }
	//getElemRefs('p404').style.display = "block";
	return null;
}
// Gets levenshtein distance
function minimum(a, b, c){var mi; mi = a; if(b < mi){mi=b;} if(c < mi){mi=c;} return mi;}
function getLD(s,t){
var n,m,i,j,s_i,t_j,cost; n = s.length; m = t.length;
if(n == 0){return m;} if(m == 0){return n;} var dy = new Array(n+1);
for (var i=0; i < dy.length; i++) dy[i]= new Array(m+1);
for(var i = 0; i <= n; i++){dy[i][0] = i;}
for(var j = 0; j <= m; j++){dy[0][j] = j;}
for(var i = 1; i <= n; i++){s_i = s.charAt (i - 1);
for(var j = 1; j <= m; j++){t_j = t.charAt (j - 1);
if(s_i == t_j){cost=0;} else{cost=1;}
dy[i][j] = minimum (dy[i-1][j]+1, dy[i][j-1]+1, dy[i-1][j-1] + cost);}}
return dy[n][m];}
// Gets current location object and returns an array of its properties.
function getURL(){
var urlParts = new Array(8);
var wl = window.location;
urlParts['href'] = wl.href;
urlParts['protocol'] = wl.protocol;
urlParts['host'] = wl.host;
urlParts['hostname'] = wl.hostname;
urlParts['port'] = wl.port;
urlParts['pathname'] = wl.pathname;
urlParts['search'] = wl.search;
urlParts['hash'] = wl.hash;
if(arguments.length < 1) return urlParts;
else if(urlParts[arguments[0]] != "undefined" ) return urlParts[arguments[0]];
else return null; 
}
// Functions to create a Map of maps, each of which can store multiple values.
// Can store by key or array index
function MultiMap(){this.mapList=new Array(); this.putMapStr=putMapItemAsStringKey; this.putMapIdx=putMapItemAsIndexedKey; this.getMapItem=getMapItem; this.getTotalMaps=getTotalMaps;}
function putMapItemAsStringKey(){args=cloneArgs(arguments); var strKey=args.shift(); this.mapList[strKey]=new DataMap(args);}
function putMapItemAsIndexedKey(){this.mapList[this.mapList.length]=new DataMap(arguments);}
function getMapItem(item){return this.mapList[item];}
function getTotalMaps(){return this.mapList.length;}
function DataMap(args){this.data=args;}
// for some reason the built-in arguments array does not support certain array methods, so we clone it.
function cloneArgs(a){var b=new Array(); for(x=0; x < a.length; x++) {b[x]=a[x];} return b;}
/* if you need to support IE 5.x browsers, use this to get the shift() method.
if(typeof(Array.shift) == "undefined"){
Array.prototype.shift = function(){
  var ret = this[0]; for(x=0; x < this.length; x++){ this[x] = this[x+1];}
  this.length = this.length-1; return ret;}
} */