define( [ "jquery", "underscore" ], function($) {
	
	var toc = {
		extensionId: "toc",
		extensionName: "Table Of Content",
        optional: true,
		settingsBloc: [
		               '
Generates tables of content using the marker [TOC].
'
		              ].join("")
	};
	
	// Used to generate an anchor
	function slugify(text)
	{
		return text.toLowerCase()
		  	.replace(/\s+/g, '-') // Replace spaces with -
			.replace(/[^\w\-]+/g, '') // Remove all non-word chars
			.replace(/\-\-+/g, '-') // Replace multiple - with single -
			.replace(/^-+/, '') // Trim - from start of text
			.replace(/-+$/, ''); // Trim - from end of text
	}
	
	// TOC element description
	function TocElement(tagName, anchor, text) {
		this.tagName = tagName;
		this.anchor = anchor;
		this.text = text;
		this.children = [];
	}
	TocElement.prototype.childrenToString = function() {
		if(this.children.length === 0) {
			return "";
		}
		var result = "";
		_.each(this.children, function(child) {
			result += child.toString();
		});
		result += "
";
		return result;
	};
	TocElement.prototype.toString = function() {
		var result = "";
		if(this.anchor && this.text) {
			result += '' + this.text + '';
		}
		result += this.childrenToString() + "";
		return result;
	};
	
	// Transform flat list of TocElement into a tree
	function groupTags(array, level) {
		level = level || 1;
		var tagName = "H" + level;
		var result = [];
		
		var currentElement = undefined;
		function pushCurrentElement() {
			if(currentElement !== undefined) {
				if(currentElement.children.length > 0) {
					currentElement.children = groupTags(currentElement.children, level + 1);
				}
				result.push(currentElement);
			}
		}
		
		_.each(array, function(element, index) {
			if(element.tagName != tagName) {
				if(currentElement === undefined) {
					currentElement = new TocElement();
				}
				currentElement.children.push(element);
			}
			else {
				pushCurrentElement();
				currentElement = element;
			}
		});
		pushCurrentElement();
		return result;
	}
	
	// Build the TOC
	function buildToc() {
		var anchorList = {};
		function createAnchor(element) {
			var id = element.prop("id") || slugify(element.text());
			var anchor = id;
			var index = 0;
			while(_.has(anchorList, anchor)) {
				anchor = id + "-" + (++index);
			}
			anchorList[anchor] = true;
			// Update the id of the element
			element.prop("id", anchor);
			return anchor;
		}
			
		var elementList = [];
		$("#wmd-preview > h1," +
				"#wmd-preview > h2," +
				"#wmd-preview > h3," +
				"#wmd-preview > h4," +
				"#wmd-preview > h5," +
				"#wmd-preview > h6").each(function() {
			elementList.push(new TocElement(
				$(this).prop("tagName"),
				createAnchor($(this)),
				$(this).text()
			));
		});
		elementList = groupTags(elementList);
		return '' + elementList.toString() + '
\[TOC\]<\/p>/g, toc);
			$("#wmd-preview").html(html);
		});
	};
	
	return toc;
});