var Glossary = function() {
	this.defs = [];
	this.hooks = [];
};

var glossary = new Glossary();

Glossary.prototype.empty = function() {
	return this.defs.length == 0;
};

Glossary.prototype.defId = function(def) {
	for (var i = 0; i < this.defs.length; i++) {
		if (def == this.defs[i])
			return i + 1;
	}
	return false;
;}

Glossary.prototype.addDefinitionLabel = function(node, def, label, cb) {
	var text = node.nodeValue;
	var pos = text.indexOf(label);
	if (pos > 0) {
		var item = def ? new GlossaryItem(label, def, cb) : false;
		var itemNode = item ? item.node : document.createTextNode(label);

		var left = text.substr(0, pos);
		var endpos = pos + label.length;
		var right = text.substr(endpos, text.length - endpos);

		node.nodeValue = left;
		node.parentNode.insertBefore(itemNode, node.nextSibling);
		node.parentNode.insertBefore(document.createTextNode(right), itemNode.nextSibling);
	}
};

Glossary.prototype.addDefinitionText = function(node, hook, cb) {
	this.addDefinitionLabel(node, hook.def, hook.str, cb);
};

Glossary.prototype.addDefinitionsText = function(node, cb) {
	for (var i = 0; i < this.hooks.length; i++) {
		this.addDefinitionText(node, this.hooks[i], cb);
	}
};

Glossary.prototype.addDefinitions = function(node, cb) {
	for (var child = node.firstChild; child != null; child = child.nextSibling) {
		if (child.nodeType == Node.ELEMENT_NODE) {
			this.addDefinitions(child, cb);
		}
		else if (child.nodeType == Node.TEXT_NODE) {
			this.addDefinitionsText(child, cb);
		}
	}
};

Glossary.prototype.append = function(defs) {
	for (var i = 0; i < defs.length; i++) {
		var def = defs[i];
		this.defs.push(def);
		for (var j = 0; j < def.search.length; j++) {
			this.hooks.push({"str": def.search[j], "def": def});
		}
		if ("exclude" in def) {
			for (var j = 0; j < def.exclude.length; j++) {
				this.hooks.push({"str": def.exclude[j], "def": false});
			}
		}
	}
	this.hooks.sort(function(a, b) {
		if (a.str.length > b.str.length)
			return -1;
		if (a.str.length < b.str.length)
			return 1;
		return 0;
	});
};

var GlossaryItem = function(label, def, cb) {
	this.node = document.createElement("abbr");
	this.node.className = "glossaryItem";
	this.node.appendChild(document.createTextNode(label));
	this.node.setAttribute("title", def.definition);
	this.def = def;
	this.node.onclick = function() { if (cb) cb(def); };
};

var GlossaryWidget = function(glossary) {
	this.node = document.createElement("div");
	this.glossary = glossary;
	this.init();
};

GlossaryWidget.prototype.init = function() {
	this.node.className = "glossary";

	var div = document.createElement("section");
	this.node.appendChild(div);

	var nodeClose = document.createElement("button");
	nodeClose.className = "close";
	nodeClose.appendChild(document.createTextNode("Fermer"))
	div.appendChild(nodeClose);
	
	var h1 = document.createElement("h1");
	h1.appendChild(document.createTextNode("Glossaire"));
	div.appendChild(h1);

	var dl = document.createElement("dl");
	div.appendChild(dl);

	for (var i = 0; i < this.glossary.defs.length; i++) {
		var def = this.glossary.defs[i];

		var dfn = document.createElement("dfn");
		dfn.id = glossary.defId(def);
		dfn.appendChild(document.createTextNode(def.title));

		var dt = document.createElement("dt");
		dt.appendChild(dfn);
		dl.appendChild(dt);

		var dd = document.createElement("dd");
		dd.innerHTML = def.definition;
		dl.appendChild(dd);
	}
	this.setVisibility(false);

	var self = this;
	this.node.onclick = function() { self.setVisibility(false) };
};

GlossaryWidget.prototype.setVisibility = function(value) {
	this.node.style.display = value ? "" : "none";
};

GlossaryWidget.prototype.getVisibility = function() {
	return this.node.style.display == "" ? true : false;
};

GlossaryWidget.prototype.swVisibility = function() {
	this.setVisibility(!this.getVisibility());
};

GlossaryWidget.prototype.show = function(def) {
	this.setVisibility(true);
	if (def) location.hash = glossary.defId(def);
};
