// Firebug
if (!window.console || !console.firebug || window.location.host.substr(-("devo.exalead.com".length)) != "devo.exalead.com")
{
  var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
	  "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

  window.console = {};
  for (var i = 0; i < names.length; ++i)
	window.console[names[i]] = function() {}
}

// WikifierTip
WikifierTip = {
	tipId : "wikifier_tip",
	offsetX : 16,
	offsetY : 16,
	opacity : 90,
	currentOpacity : 0,
	fadeRate: 10,
	fadeStep: 5,
	hideDelay : 100,
	hideTimer : null,
	tip : null
}

// Cross browser utilities
WikifierTip.isMouseLeaveOrEnter = function(e, handler) {
  if (e.type != 'mouseout' && e.type != 'mouseover') return false;
  var reltg = e.relatedTarget ? e.relatedTarget : 
	e.type == 'mouseout' ? e.toElement : e.fromElement;
  while (reltg && reltg != handler) reltg = reltg.parentNode;
  return (reltg != handler);
}

WikifierTip.getScrollXY = function() {
  var scrOfX = 0, scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
	//Netscape compliant
	scrOfY = window.pageYOffset;
	scrOfX = window.pageXOffset;
  } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
	//DOM compliant
	scrOfY = document.body.scrollTop;
	scrOfX = document.body.scrollLeft;
  } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
	//IE6 standards compliant mode
	scrOfY = document.documentElement.scrollTop;
	scrOfX = document.documentElement.scrollLeft;
  }
  return [ scrOfX, scrOfY ];
}

WikifierTip.getWindowSize = function()
{
  var w = 0;
  var h = 0;

  //IE
  if(!window.innerWidth) {
	//strict mode
	if(!(document.documentElement.clientWidth == 0)) {
	  w = document.documentElement.clientWidth;
	  h = document.documentElement.clientHeight;
	}
	//quirks mode
	else {
	  w = document.body.clientWidth;
	  h = document.body.clientHeight;
	}
  }
  //w3c
  else {
	w = window.innerWidth;
	h = window.innerHeight;
  }
  return {width:w,height:h};
}

WikifierTip.setOpacity = function(opacity, id) {
  this.currentOpacity = opacity;
  var object = document.getElementById(id).style;
  object.opacity = (opacity / 100);
  object.MozOpacity = (opacity / 100);
  object.KhtmlOpacity = (opacity / 100);
  object.filter = "alpha(opacity=" + opacity + ")";
}

// Tip
WikifierTip.create = function () {
  if (this.tip) return ;

  this.tip = document.createElement("div");
  this.tip.setAttribute("id", this.tipId);
  this.tip.onmouseover = function(e) { if (WikifierTip.isMouseLeaveOrEnter(e ? e : window.event, this)) { clearTimeout(WikifierTip.hideTimer); } }
  this.tip.onmouseout = function(e) { if (WikifierTip.isMouseLeaveOrEnter(e ? e : window.event, this)) { WikifierTip.hide(); } } 
  document.getElementsByTagName("body").item(0).appendChild(this.tip);

  this.title = document.createElement("div");
  this.title.setAttribute("id", this.tipId + "_title");
  this.tip.appendChild(this.title);

  this.text = document.createElement("div");
  this.text.setAttribute("id", this.tipId + "_text");
  this.tip.appendChild(this.text);
}

WikifierTip.destroy = function() {
  if (!this.tip) return ;

  this.tip.removeChild(this.title);
  this.title = null;

  this.tip.removeChild(this.text);
  this.text = null;

  this.tip.parentNode.removeChild(this.tip);
  this.tip = null;
}

WikifierTip.move = function (evt) {
  var x = 0, y = 0;
  if (document.all) { // IE
	x = (document.documentElement && document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft;
	y = (document.documentElement && document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
	x += window.event.clientX;
	y += window.event.clientY;
  } else {
	x = evt.pageX;
	y = evt.pageY;
  }
  x = x + this.offsetX;
  y = y + this.offsetY;

  var scroll = WikifierTip.getScrollXY();
  var wSize = WikifierTip.getWindowSize();

  if ((x + this.tip.offsetWidth - scroll[0]) > wSize['width'])
	x = x - this.offsetX - this.tip.offsetWidth - this.offsetX;
  if ((y + this.tip.offsetHeight - scroll[1]) > wSize['height']) {
	var tmp_y = y - this.offsetY - this.tip.offsetHeight - this.offsetY;
	if (tmp_y - scroll[1] > 0) {
	  y = tmp_y;
	}
  }

  this.tip.style.left = x + "px";
  this.tip.style.top = y + "px";
}

WikifierTip.show = function (evt, title, text) {
  clearTimeout(this.hideTimer);
  clearTimeout(this.fadeTimer);

  WikifierTip.create();
  WikifierTip.setOpacity(0, this.tip.id);
  this.title.innerHTML = title;
  this.text.innerHTML = text;
  this.move(evt);
  WikifierTip.fadeIn();
}

WikifierTip.hide = function() {
  clearTimeout(this.hideTimer);
  clearTimeout(this.fadeTimer);

  this.hideTimer = setTimeout("WikifierTip.fadeOut()", this.hideDelay);
}

WikifierTip.fadeIn = function() {
  if (this.currentOpacity >= this.opacity) {
	return;
  }
  WikifierTip.setOpacity(this.currentOpacity + this.fadeStep, this.tip.id);
  this.fadeTimer = setTimeout("WikifierTip.fadeIn()", this.fadeRate);
}

WikifierTip.fadeOut = function() {
  if (this.currentOpacity <= 0) {
	WikifierTip.destroy();
	return;
  }
  WikifierTip.setOpacity(this.currentOpacity - this.fadeStep, this.tip.id);
  this.fadeTimer = setTimeout("WikifierTip.fadeOut()", this.fadeRate);
}

// Wikifier

Wikifier = {
  baseUrl : 'http://wikifier.labs.exalead.com',
  serviceUrl : '/Wikifier/',
  loadingImageUrl: '/images/spinner.gif',
  styleClassName: 'wikifier_highlight',
  cssUrl: '/wikifier.css',
  cssInject: true,
  maxContentLength: 300,
  rootNode: null,
  thumbnailerUrl: 'http://thumbnailer.labs.exalead.com/120x90/constrain/',
  silentLoading : false,
  lang: 'auto',
  highlightEntities: [ 'All' ]
};

Wikifier.formatData = function(data) {
  var content = data.description;
  if (content.length > Wikifier.maxContentLength) {
	content = content.substr(0, Wikifier.maxContentLength);
	content += '...';
  }
  var html = '';
  if (data.image) {
	html += '<img src="' + Wikifier.thumbnailerUrl + data.image + '" />';
  }
  html += '<p>' + content + '</p>';
  html += '<br/><p style="text-align: center">Find more on<br/>'
  html += '<a target="_blank" href="' + data.url + '">' + data.source + '</a>';
  html += ' | <a target="_blank" href="http://www.exalead.fr/search?q=' + escape(data.name) + '">Exalead</a>';
  if (data.kind == "People") {
	html += ' | <a target="_blank" href="http://miiget.labs.exalead.com/?q=' + escape(data.name) + '">Miiget</a>';
  }
  html += '</p>'; 
 return html;
}

Wikifier.processNode = function(node) {
	// Do not double process: skip already highlighted elements
  var classNames = node.parentNode.className.split(" ");
  for (i in classNames) {
	if (classNames[i] == Wikifier.styleClassName) {
	  return node;
	}
  }

  var match = Wikifier.matchRegexp.exec(node.data);
  if (!match || match[0] == "") {
	return node;
  }
  return Wikifier.highlightNode(node, match);
};

Wikifier.highlightNode = function(node, match) {
  var data = Wikifier.wikiObjects[match[0]];
  var shouldHighlight = false;
  for (i in Wikifier.highlightEntities) {
	if (Wikifier.highlightEntities[i] == 'All' || Wikifier.highlightEntities[i] == data.kind) {
	  shouldHighlight = true;
	}
  }
  if (shouldHighlight == false) {
	return node;
  }

  // Suppress alt and title attributes in order to prevent the default tip
  if (node.parentNode.tagName == "A") {
	node.parentNode.removeAttribute('alt');
	node.parentNode.removeAttribute('title');
  }
  var data = Wikifier.wikiObjects[match[0]];

  var matchNode = node.splitText(match.index);
  matchNode.splitText(match[0].length);

  var span = document.createElement('span');
  span.className = Wikifier.styleClassName + " wikifier_" + data.type;
  span.onmouseover = function(e) {
	if(WikifierTip.isMouseLeaveOrEnter(e ? e : window.event, this)) {
	  WikifierTip.show(e, data.name, Wikifier.formatData(data))
	}
  }
  span.onmouseout = function(e) {
	if(WikifierTip.isMouseLeaveOrEnter(e ? e : window.event, this)) {
	  WikifierTip.hide()
	}
  }

  node.parentNode.replaceChild(span, matchNode);
  span.appendChild(matchNode);

  return node;
};

Wikifier.walkNodes = function(node, fct) {
  var element_node = node.ELEMENT_NODE || 1;
  var text_node = node.TEXT_NODE || 3;

  if (node.nodeType == element_node) {
	for (var i = 0; i < node.childNodes.length; ++i) {
	  Wikifier.walkNodes(node.childNodes[i], fct);
	}
  } else if (node.nodeType == text_node) {
	node = fct(node); 
  }
};

Wikifier.callService = function(method, vars, callbackFunction) {
  var lang = Wikifier.lang;
  if (lang == 'auto') {
	lang = window.navigator.language.split("-")[0];
  }
  var wsConf = '?noCache=' + (new Date()).getTime() + "&output=json&lang=" + lang + "&js_callback=" + callbackFunction;
  var wsUrl = Wikifier.baseUrl + Wikifier.serviceUrl + method + wsConf + "&" + vars;
  console.debug("Wikifier Request: " + wsUrl);
  var scriptObj = document.createElement("script");
  scriptObj.setAttribute("type", "text/javascript");
  scriptObj.setAttribute("src", wsUrl);
  var headLoc = document.getElementsByTagName("head").item(0);
  headLoc.appendChild(scriptObj);
}

Wikifier.handleResponse = function(response) {
  console.debug("Got response from the Wikifier server");
 Wikifier.wikiObjects = response;

  var words = Array();
  for (var i in response) {
	words.push('\\b' + i +'\\b');
  }
  if (words.length == 0) {
	Wikifier.hideLoading();
	return;
  }
  Wikifier.matchRegexp = new RegExp('\\b' + words.join("|") + '\\b');
  Wikifier.walkNodes(Wikifier.rootNode || document.body, Wikifier.processNode);
  Wikifier.hideLoading();
}

Wikifier.showLoading = function() {
  if (Wikifier.silentLoading == true)
	return ;
  Wikifier.loadingDiv = document.createElement("div");
  Wikifier.loadingDiv.id = "wikifier_loading";
  Wikifier.loadingDiv.innerHTML = "Wikification...";
  document.body.appendChild(Wikifier.loadingDiv);

  var spinner = document.createElement("img");
  spinner.src = Wikifier.baseUrl + Wikifier.loadingImageUrl;
  Wikifier.loadingDiv.appendChild(spinner);
}

Wikifier.hideLoading = function() {
  if (Wikifier.silentLoading == true)
	return ;
  document.body.removeChild(Wikifier.loadingDiv);
}

Wikifier.getLocation = function() {
  /* Avoid recursive requests */
  if (location.host == Wikifier.baseUrl.split("/")[2]) {
	var regex = new RegExp("[\\?&]u=([^&#]*)");
	var results = regex.exec(window.location.href);
	if (results != null)
	  return results[1];
  }
  return location.href;
}

Wikifier.wikifyPage = function() {
  Wikifier.showLoading();
  Wikifier.callService("WikifyUrl", "url=" + Wikifier.getLocation(), "Wikifier.handleResponse");
}

Wikifier.whenDomReady = function(callBack,scope){
    var scope = scope || window;
    var args = [];
    for (var i=2, len = arguments.length; i < len; ++i) {
        args.push(arguments[i]);
    };
    if (navigator.userAgent.match(/WebKit/))
    {
        (function(){
            if(document.readyState != 'complete' && document.readyState != 'loaded') return setTimeout(arguments.callee, 1);
            callBack.apply(scope, args);
        })();
    }
    else if (document.addEventListener) {
       document.addEventListener("DOMContentLoaded", function(){callBack.apply(scope, args);}, false);
    }
    else if (document.all)
    {   
        if(!document.getElementById('WhenDomReady_element'))
        {document.write("<scr" + "ipt id=\"WhenDomReady_element\" defer=true " + "src=//:><\/scr" + "ipt>");  } 
        document.getElementById('WhenDomReady_element').attachEvent("onreadystatechange",function(){
            if (document.getElementById('WhenDomReady_element').readyState=="complete"){
                callBack.apply(scope, args);
            }
        });
    }
}

Wikifier.init = function() {
  if (Wikifier.cssInject == true) {
	var cssObj = document.createElement("link");
	cssObj.setAttribute("rel", "stylesheet");
	cssObj.setAttribute("type", "text/css");
	cssObj.setAttribute("href", Wikifier.baseUrl + Wikifier.cssUrl);
	var headLoc = document.getElementsByTagName("head").item(0);
	headLoc.appendChild(cssObj);
	console.debug("Wikifier: Successfully injected the CSS");
	Wikifier.cssInject = false;
  }
}

Wikifier.wikify = function() {
  Wikifier.init();
  Wikifier.whenDomReady(Wikifier.wikifyPage);
}

Wikifier.wikifyElement = function(element) {
  Wikifier.init();
  Wikifier.showLoading();
  Wikifier.rootNode = element;
  Wikifier.callService("WikifyText", "text=" + escape(element.innerHTML), "Wikifier.handleResponse");
}
