//Add tooltips to .portrait_items
jQuery(document).ready(function() {
	jQuery(".portrait_item, .text_list_item").each(function() {
		new Tooltip(this);
		jQuery(this).attr("title", "");
	});
});

//Add search Suggestions
jQuery(document).ready(function() {
	try {
		new Suggestion("#search_field");
	} catch (e) {} //Ignore
});

//Add autocomplete
jQuery(document).ready(function() {
	jQuery("button.no_autocomplete, input.no_autocomplete").attr("autocomplete", "off");
});

//Transform mailto-links
jQuery(document).ready(function() {
	jQuery(".mailto_link").each(function() {
		var link = jQuery(this);
		var link_address = link.attr("href");
		link_address = link_address.replace(/!/g, ".");
		link_address = link_address.replace(/\^/g, "@");
		link_address = "mailto:"+link_address;
		link.attr("href", link_address);
	});
});

//Init collapsable areas
jQuery(document).ready(function() {
  var openers = jQuery(".opener");
  openers.click(function() {
    var opener = jQuery(this);
    var collapsable = opener.next();
    opener.toggleClass("opened");
    collapsable.slideToggle();
  });
});

//Init main navigation
jQuery(document).ready(function() {
	var main_nav_items = jQuery(".main_nav_item");
	var over_handler = function() {
		this.image.attr("src", this.over_image_url);
	};
	var out_handler = function() {
		this.image.attr("src", this.normal_image_url);
	};
	main_nav_items.each(function() {
		var link = jQuery(this);
		this.image = link.children("img");
		if(this.image.attr("src").indexOf("_inactive.") === -1) {
			return;
		}
		this.over_image_url = this.image.attr("src").replace(/_inactive\./, "_active.");
		this.normal_image_url = this.image.attr("src");
	});
	main_nav_items.hover(over_handler, out_handler);
});

//Classes
var Tooltip = function(opener) {
	this.opener = jQuery(opener);
	this.content = jQuery(arguments[1] || this.opener.next());
	opener.tooltip = this;
	this.content.appendTo(document.getElementsByTagName('body')[0]);
	this.enable();
};

Tooltip.prototype.display = function() {
	this.content.show();
};

Tooltip.prototype.hide = function() {
	this.content.hide();
};

Tooltip.prototype.setPosition = function(x, y) {
	this.content.css("left", x+10);
	this.content.css("top", y+10);
};

Tooltip.prototype.enable = function() {
	this.opener.bind("mouseenter", this.handleMouseover);
	this.opener.bind("mouseleave", this.handleMouseout);
	this.opener.mousemove(this.handleMousemove);
	this.hide();
};

Tooltip.prototype.handleMouseover = function(event) {
	var tooltip = this.tooltip;
	tooltip.setPosition(event.pageX, event.pageY);
	tooltip.display();
};

Tooltip.prototype.handleMouseout = function(event) {
	var tooltip = this.tooltip;
	tooltip.hide();
};

Tooltip.prototype.handleMousemove = function(event) {
	var tooltip = this.tooltip;
	tooltip.setPosition(event.pageX, event.pageY);
};


//Add bind to function
Function.prototype.bind = function() {
	var __method = this;
	var args = jQuery.makeArray(arguments);
	var object = args.splice(0, 1)[0];
	return function() {
		args = args.concat(jQuery.makeArray(arguments));
		args[args.length] = this;
		return __method.apply(object, args);
	};
};

//Add trim to string
String.prototype.trim = function() {
	var	str = this.replace(/^\s\s*/, '');
	var ws = /\s/;
	var i = str.length;
	while (ws.test(str.charAt(--i)));
	return str.slice(0, i + 1);
};

window.getInnerHeight = function() {
	return window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight;
};

var Suggestion = function(searchField) {
	this.searchField = jQuery(searchField);
	if(this.searchField.length !== 1) {
		throw "Suggestion must apply to only one element.";
	}
	this.options = arguments[1] || {};
	this.timer = null;
	this.latestWord = null;
	this.currentRequest = null;
	
	this.displayLayer = jQuery(document.createElement("div"));
	this.displayLayer.addClass("suggest_results");
	this.displayLayer.appendTo(document.body);
	this.layerIsVisible = false
	
	this.requestUrl = SITE_DIR+FILE_PREFIX+"/suggest_ajax";;
	
	this.attach();
};

Suggestion.prototype.positionLayer = function () {
	this.displayLayer.css("left", this.searchField.offset().left);
	this.displayLayer.css("bottom", window.getInnerHeight()-this.searchField.offset().top);
	this.displayLayer.width(this.searchField.width());
};

Suggestion.prototype.attach = function() {
	var suggestion = this;
	
	this.searchField.bind("keyup", function(event) {
		var position = this.selectionStart;
		if(position !== this.selectionEnd) {
			return;
		}
		
		if(event.keyCode === 13 || (event.keyCode >= 37 && event.keyCode <= 40)) {
			return;
		}
				
		var stringTillPosition = this.value.substring(0, position);
		var lastWord = stringTillPosition.split(/\b/);
		if(lastWord.length === 0) {
			return;
		}
		
		lastWord = lastWord[lastWord.length-1];
		
		if(lastWord === suggestion.latestWord) {
			if(!suggestion.layerIsVisible) {
				suggestion.showLayer();
			}
			return;
		}
		
		if(lastWord.trim().length === 0) {
			return;
		}
		
		suggestion.latestWord = lastWord;
		
		if(suggestion.timer !== null) {
			window.clearTimeout(suggestion.timer);
		}
		
		suggestion.timer = window.setTimeout(suggestion.execute.bind(suggestion), 700);
	});
	
	this.searchField.bind("keypress", function(event) {
		if(!suggestion.layerIsVisible) {
			return;
		}
		if(event.keyCode === 40) {
			suggestion.moveFocusDown();
		} else if(event.keyCode === 38) {
			suggestion.moveFocusUp();
		} else if(event.keyCode === 13) {
			suggestion.activateCurrentSuggestion();
		} else {
			suggestion.hideLayer();
			return;
		}
		event.preventDefault();
	});
	
	this.positionLayer();
};

Suggestion.prototype.execute = function() {
	this.timer = null;
	jQuery.get(this.requestUrl, {word: this.latestWord}, this.fetchResults.bind(this));
};

Suggestion.prototype.fetchResults = function(xmlDocument, status) {
	if(status !== "success") {
		return;
	}
	
	this.displayLayer.empty();
	
	xmlDocument = xmlDocument.documentElement;
	var allResults = jQuery("word", xmlDocument);
	if(allResults.length === 0) {
		this.displayLayer.hide();
		return;
	}
	
	var suggestion_object = this;
	allResults.each(function(resultCounter) {
		suggestion_object.addSuggestion(this, resultCounter);
	});
	
	this.showLayer();
};

Suggestion.prototype.hideLayer = function() {
	this.displayLayer.hide();
	this.layerIsVisible = false;
};

Suggestion.prototype.showLayer = function() {
	this.displayLayer.show();
	this.layerIsVisible = true;
};

Suggestion.prototype.addSuggestion = function(suggestionNode, resultCounter) {
	var suggestionResult = document.createElement("a");
	suggestionResult.setAttribute("href", "#");
	jQuery(suggestionResult).addClass("suggest_result");
	this.displayLayer.append(suggestionResult);
	suggestionResult.appendChild(document.createTextNode(suggestionNode.getAttribute("name")));
	suggestionResult.missingWordPart = suggestionNode.getAttribute("missing");
	jQuery(suggestionResult).bind("click", this.activateSuggestion.bind(this, suggestionResult));
	if(resultCounter === 0) {
		jQuery(suggestionResult).addClass("active");
	}
};

Suggestion.prototype.activateSuggestion = function(suggestionResult) {
	var firstPart = this.searchField.val().substring(0, this.searchField.get(0).selectionStart);
	var secondPart = this.searchField.val().substring(this.searchField.get(0).selectionEnd);
	this.searchField.val(firstPart+suggestionResult.missingWordPart+secondPart);
	this.searchField.get(0).focus();
	this.hideLayer();
};

Suggestion.prototype.activateCurrentSuggestion = function() {
	var currentResult = this.displayLayer.children(".active");
	this.activateSuggestion(currentResult.get(0));
};

Suggestion.prototype.moveFocusUp = function() {
	var currentResult = this.displayLayer.children(".active");
	var previous = currentResult.prev();
	if(previous.length === 0) {
		previous = this.displayLayer.children(":last");
	}
	currentResult.removeClass("active");
	previous.addClass("active");
};

Suggestion.prototype.moveFocusDown = function() {
	var currentResult = this.displayLayer.children(".active");
	var next = currentResult.next();
	if(next.length === 0) {
		next = this.displayLayer.children(":first");
	}
	currentResult.removeClass("active");
	next.addClass("active");
};
