var ACME = {};

ACME.current = {
	project:'',
	projects:{},
	block:'',
	rows:[],
	page:0,
	pages:0,
	pagec:50,
	labels:[],
	current_label:null,
	current_label_click:null,
	svn_path:'/svn',
	info:{}
};

function loadInfo() {
	$.ajax({
		type: "GET", url: ("/info.json"), dataType: 'json',
		success: function(obj) {
			ACME.current.info = obj;
			ACME.updateProjects();
		},
		error: function (XMLHttpRequest, textStatus, errorThrown) { alert('error! ACME.getInfo'); }
	});
}

//setTimeout(loadInfo, 1000);
loadInfo();

if (document.location.host.match(/(^|\.)dev\./)) {
	ACME.current.svn_path = '/svn.proxy';
}

//setInterval(function() { ACME.reposLabel(); }, 200);
$(document).scroll(function() { ACME.reposLabel(); });

ACME.reposLabel = function() {
	var obj = ACME.current.current_label;
	if (obj === null) {
		obj = ACME.current.current_label_click;
	}
	if (obj !== null) {
		var offset = $(obj).offset();
		var offset2 = $('.rowl').offset();
		var left = (offset2.left -  2);
		var top  = (offset.top   + 16);
		var label_height = $('#label').height();
		var window_height = $(window).height();
		var document_scroll_top = $(document).scrollTop();

		//alert(top + $('#label').height());
		//alert($(document).height());

		if (top + label_height > $(document).height()) {
			top = offset.top - label_height - 24;
		}

		if (top + label_height > document_scroll_top + window_height) {
			top = offset.top - label_height - 24;
		}

		if (top < document_scroll_top + 32) {
			top  = document_scroll_top + 32;
		}

		if (top + label_height > document_scroll_top + window_height) {
			top = document_scroll_top + window_height - label_height;
		}

		var label = $('#label').get(0);
		label.style.left = left + 'px';
		label.style.top  = top + 'px';
		$('#label').get(0).style.display = 'block';
	} else {
		$('#label').get(0).style.display = 'none';
	}
};

ACME.closeLabel = function() {
	ACME.current.current_label_click = null;
	ACME.current.current_label = null;
	ACME.reposLabel();
};

ACME.clickLabel = function(obj, label) {
	if ((ACME.current.current_label_click === null) || (obj != ACME.current.current_label_click)) {
		ACME.current.current_label = null;
		ACME.current.current_label_click = null;
		ACME.showLabel(obj, label);
		ACME.current.current_label_click = obj;
	} else {
		ACME.closeLabel();
	}
};

ACME.showLabel = function(obj, labprojectsel) {
	// Avoid change the label when we have already clicked on a label.
	if (ACME.current.current_label_click != null) return;

	// Filter to trigger only once.
	if (ACME.current.current_label == obj) return; ACME.current.current_label = obj;

	var labels = ACME.current.labels;
	var label = $(obj).text();
	for (var n = 0; n < labels.length; n++) {
		var regexp = new RegExp(labels[n].pattern, 'i');
		if (label.match(regexp)) {
			html = labels[n].text.replace(/\{IMG:([^\}]*)\}\n?/gi, function(all, img_src) {
				return '<img src="' + ACME.current.svn_path + '/' + ACME.current.project + '/' + img_src + '" />';
			}).replace(/\n/gi, "<br />\n");

			//alert(html);

			$('#labelContent').html(html);

			$('#label img').load(function() {
				ACME.reposLabel();
			});

			ACME.reposLabel();

			return;
		}
	}
};

ACME.hideLabel = function() {
	ACME.current.current_label = null;
	ACME.reposLabel();
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

ACME.getLabels = function(project, callback) {
	$.ajax({
		type: "GET", url: (ACME.current.svn_path + "/" + project + '/meta/labels.txt'),
		success: function(msg){
			var lines = msg.split("\n");
			var label = undefined, labels = [];
			for (var n = 0; n < lines.length; n++) { var line = lines[n];
				switch (line.substr(0, 1)) {
					// New ID.
					case '@':
						var base = line.substr(1).replace(/^\s+/, '').replace(/\s+$/, '');
						label = {text:"", pattern:base};
						labels.push(label);
					break;
					// Comment.
					case '#': break;
					// Other value.
					default:
						if (label !== undefined) label.text += line + "\n";
					break;
				}
			}
			ACME.current.labels = labels;
			//alert(labels[6].text);
			if (callback !== undefined) callback(labels);
		},
		error: function (XMLHttpRequest, textStatus, errorThrown) { alert('error! ACME.getLabels'); }
	});
};

ACME.getProjects = function(callback) {
	$.ajax({
		type: "GET", url: (ACME.current.svn_path + "/"),
		success: function(msg){
			var regexp = /<li><a href="(.*)">(.*)<\/a><\/li>/gi;
			//<li><a href="dividead/">dividead/</a></li>

			var projects = [];
			var matches = msg.match(regexp);
			for (var n = 0; n < matches.length; n++) {
				var match = matches[n];
				var rmatch = /<li><a href=".*">(.*)\/<\/a><\/li>/.exec(match);
				projects.push(rmatch[1]);
			}

			ACME.current.projects = projects;
			if (callback !== undefined) callback(projects);
		},
		error: function (XMLHttpRequest, textStatus, errorThrown) { alert('error! ACME.getProjects'); }
	});
};

ACME.getBlocks = function(project, callback) {
	$.ajax({
		type: "GET",
		url: (ACME.current.svn_path + "/" + project),
		success: function(msg){
			var regexp = /<li><a href="(.*)">(.*)<\/a><\/li>/gi;

			var list = [];
			var matches = msg.match(regexp);
			for (var n = 0; n < matches.length; n++) {
				var match = matches[n];
				var rmatch = /<li><a href=".*">([^\/]*)\/?<\/a><\/li>/.exec(match);
				if (rmatch) {
					if (rmatch[1].substr(0, 1) == '.') continue;
					list.push(rmatch[1]);
				}
			}

			callback(list);
		},
		error: function (XMLHttpRequest, textStatus, errorThrown) { alert('error! ACME.getBlocks'); }
	});
};

ACME.getRows = function(project, block, callback) {
	$.ajax({
		type: "GET",
		url: (ACME.current.svn_path + "/" + project + "/" + block),
		success: function(msg){
			var lines = msg.split("\n");
			var row = {texts_empty:false}, rows = [];

			for (var n in lines) { var line = lines[n].replace(/\s+$/, '');
				switch (line.substr(0, 1)) {
					case '/': // C++ Comment
						if (line.substr(0, 2) != '//') continue;
						line = line.substr(1);
					case '#': // Comment
						var comment_text = line.substr(1).replace(/^\s+/, '').replace(/\s+$/, '');
						if (row.texts_empty) {
							if (row.comment.length) comment_text += "\n";
							row.comment += comment_text;
						} else {
							if (!rows.length || rows[rows.length - 1].type != 'comment') {
								rows.push({type:'comment', text:comment_text});
							} else {
								var crow = rows[rows.length - 1];
								if (crow.text.length) crow.text += "\n";
								crow.text += comment_text;
							}
						}
					break;
					case '@': // Id
						row = {type:'text', texts:{}, texts_empty:true, comment:'', id:line.substr(1).replace(/^\s+/, '').replace(/\s+$/, '')};
						rows.push(row);
					break;
					case '<': // Text
						texts_empty = false;
						var matches = (line).match(/^<(\w+)>(.*)$/);
						var text = stripslashes(matches[2]);
						row.texts[matches[1]] = text;
						//alert(text); return;
						//continue;
					break;
					case '': // Empty line
					default: // Other
						//continue;
					break;
				}
			}
			ACME.current.rows = rows;
			if (callback !== undefined) callback(rows);
		},
		error: function (XMLHttpRequest, textStatus, errorThrown) { alert('error! ACME.getRows'); }
	});
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

ACME.updateLocation = function() {
	var hash = '';
	var title = 'Soywiz';
	if (ACME.current.project != '') {
		hash += ACME.current.project;
		title += ' > ' + ACME.current.project;
		if (ACME.current.block != '') {
			hash += ',' + ACME.current.block;
			hash += ',' + ACME.current.page;

			title += ' > ' + ACME.current.block;
			title += ' > ' + (ACME.current.page + 1);
		}
	}
	document.location.hash = hash;
	document.title = title;
	$('#project-list select').get(0).value = ACME.current.project;
	$('#block-list select').get(0).value = ACME.current.block;
	$('#page-list select').get(0).value = ACME.current.page;
	if (ACME.current.project != '') {
		$('#logo').attr('src', (ACME.current.svn_path + '/' + ACME.current.project + '/meta/logo.png'));
		$('#logo').get(0).style.display = 'block';
	} else {
		$('#logo').get(0).style.display = 'none';
	}
};

ACME.updateProjects = function() {
	var projects = ACME.current.projects;

	var pinfo = {};
	var info = ACME.current.info;
	for (var k in info) {
		var ll = k.split('/');
		var pname = ll[0];
		if (pinfo[pname] === undefined) pinfo[pname] = {};
		for (var kk in info[k]) {
			if (pinfo[pname][kk] === undefined) pinfo[pname][kk] = 0;
			pinfo[pname][kk] += parseInt(info[k][kk]);
		}
	}

	var options = $('#project-list select').get(0).options;
	while (options.length) options[0] = null;
	options.add(new Option('', ''));
	for (var n in projects) { var project = projects[n];

		var ptext = project;
		if (pinfo[project] !== undefined) {
			ptext = sprintf('%s (%.2f%%)  ', project, pinfo[project].es * 100.0 / pinfo[project].en);
		}
		options.add(new Option(ptext, project));
	}

	ACME.updateLocation();
};

ACME.updateBlocks = function(project) {
	ACME.current.project = project;

	if (project == '') return;

	ACME.getLabels(project, function(labels) {
		ACME.current.labels = labels;
		//alert(labels[0].text);
		ACME.updatePage();
	});

	ACME.getBlocks(project, function(blocks) {
		var options = $('#block-list select').get(0).options;
		var info = ACME.current.info;
		while (options.length) options[0] = null;
		options.add(new Option('', ''));
		for (var n in blocks) { var block = blocks[n];
			var btext = block;
			if (info[project + '/' + block] !== undefined) {
				var binfo = info[project + '/' + block];
				btext = sprintf("%s (%.2f%%)", block, binfo.es * 100.0 / binfo.en);
				//alert(block);
			}
			options.add(new Option(btext, block));
		}
		ACME.updateLocation();
	});
};

ACME.updatePage = function(page) {
	if (page !== undefined) {
		ACME.current.page = page = parseInt(page);
		$('#page-list input[type=button]:first').get(0).disabled = ((page - 1) < 0                  );
		$('#page-list input[type=button]:last' ).get(0).disabled = ((page + 1) >= ACME.current.pages);
	}
	var rpp = ACME.current.pagec;
	var pos = 0;
	var posl = page * rpp;
	var posr = (page + 1) * rpp;

	//alert(posl + ":" + posr);

	//alert(ACME.current.labels);
	var patterns = [];
	for (var n = 0; n < ACME.current.labels.length; n++) {
		var label = ACME.current.labels[n];
		patterns.push(label.pattern.replace('<', '&lt;'));
	}

	//var regexp = new RegExp('\\b(' + patterns.join('|') + ')\\b', 'gi');
	var regexp = new RegExp('(^|\\W)(' + patterns.join('|') + ')($|\\W)', 'gi');
	var url_pattern = /\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]/i;
	var url_callback = function(t) { return '<a href="' + t + '" target="_blank">' + t + '</a>'; };

	function replaceCallback(all, pre, text, post) {
		var pre  = arguments[1], post = arguments[3];
		var text = arguments[2];
		return pre + '<span class="label" onclick="ACME.clickLabel(this, this.innerHTML);" onmouseover="ACME.showLabel(this, this.innerHTML);" onmouseout="ACME.hideLabel();">' + text + '</span>' + post;
	}

	var html = '';
	html += '<table style="width:880px;">';
	for (var n = posl; n < posr; n++) {
		var row = ACME.current.rows[n]; if (row === undefined) continue;

		switch (row.type) {
			default:
				alert("Unknown row type '" + row.type + "'");
			break;
			case 'comment':
				html += '<tr class="comment">';
				html += '<td style="width:80px;">##</td>';
				html += '<td colspan="2" style="width:800px;">' + row.text.replace('<', '&lt;').replace(regexp, replaceCallback).replace(url_pattern, url_callback) + '</td>';
				html += '</tr>';
			break;
			case 'text':
				var textl = row.texts.en;
				var textr = row.texts.es;

				if (textl === undefined) textl = '-';
				if (textr === undefined) textr = '-';

				if (textr.length) {
					rowtype = 'translated';
				} else {
					rowtype = 'untranslated';
					textr = textl;
				}
				if (row.comment.length) {
					html += '<tr class="inner_comment">';
					html += '<td style="width:80px;">##</td>';
					html += '<td colspan="2" style="width:800px;">' + row.comment.replace('<', '&lt;').replace(regexp, replaceCallback).replace(url_pattern, url_callback) + '</td>';
					html += '</tr>';
				}
				html += '<tr class="' + rowtype + '">';
				html += '<td style="width:80px;">' + row.id.replace('<', '&lt;') + '</td>';
				html += '<td style="width:400px;"><div class="row rowl">' + textl.replace('<', '&lt;').replace(regexp, replaceCallback) + '</div></td>';
				html += '<td style="width:400px;"><div class="row rowr">' + textr.replace('<', '&lt;') + '</div></td>';
				html += '</tr>';
			break;
		}
	}
	html += '</table>';
	$('#row-list').html(html);
	ACME.updateLocation();
};

ACME.updateRows = function(project, block, page) {
	if (page === undefined) page = 0;
	ACME.current.project = project;
	ACME.current.block = block;
	ACME.current.page = parseInt(page + '');

	if (block == '') return;

	ACME.getRows(project, block, function(rows) {
		//alert(rows.length);
		//ACME.current.pagec = 100;
		ACME.current.pages = Math.ceil(rows.length / ACME.current.pagec);
		ACME.current.rows = rows;

		var options = $('#page-list select').get(0).options;
		while (options.length) options[0] = null;
		for (var n = 0; n < ACME.current.pages; n++) {
			options.add(new Option('Page ' + (n + 1) + "/" + ACME.current.pages, n));
		}
		options.value = ACME.current.page;

		ACME.updatePage(ACME.current.page);
	});
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

$(document).ready(function() {
	$('#project-list select').change(function() {
		ACME.updateBlocks(this.value);
		ACME.current.block = '';
		ACME.updateLocation();
	});

	$('#block-list select').change(function() {
		ACME.updateRows($('#project-list select').get(0).value, this.value);
		ACME.updateLocation();
	});

	$('#page-list select').change(function() {
		ACME.updatePage($('#page-list select').get(0).value);
		ACME.updateLocation();
	});

	$('#page-list input[type=button]:first').click(function() {
		var obj = $('#page-list select').get(0);
		if (obj.selectedIndex - 1 < 0) return;
		obj.selectedIndex = obj.selectedIndex - 1;
		$('#page-list select').change();
	});

	$('#page-list input[type=button]:last').click(function() {
		var obj = $('#page-list select').get(0);
		if (obj.selectedIndex + 1 >= obj.length) return;
		obj.selectedIndex = obj.selectedIndex + 1;
		$('#page-list select').change();
		//alert(2);
	});

	// Get projects.
	ACME.getProjects(ACME.updateProjects);

	var hash = document.location.hash;
	var types = hash.substr(1).split(',');

	ACME.current.project = types[0];
	ACME.current.block   = types[1];
	ACME.current.page    = types[2];

	if (types[0] !== undefined) {
		ACME.updateBlocks(types[0]);
	}
	if (types[1] !== undefined) {
		ACME.updateRows(types[0], types[1], types[2]);
	}

	//updateRows('edelweiss', '00106.txt');
});
