var tldre = /^(.+)(ac|ad|ae|aero|af|ag|ai|al|am|an|ao|aq|arpa|as|asia|at|aw|ax|az|ba|bb|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|bs|bt|bv|bw|by|bz|ca|cat|cc|cd|cf|cg|ch|ci|cl|cm|cn|co|com|coop|cr|cu|cv|cx|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|es|eu|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gov|gp|gq|gr|gs|gu|gw|gy|hk|hm|hn|hr|ht|hu|ie|im|in|info|int|io|ir|is|it|je|jm|jo|jobs|jp|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mil|mk|ml|mn|mo|mobi|mp|mq|mr|ms|mt|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|nl|no|np|nr|nu|nz|org|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt|pw|py|qa|re|ro|root|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|so|sr|st|su|sv|sy|sz|tc|td|tel|tf|tg|tj|tk|tl|tm|tn|to|travel|tt|tv|tw|ua|ug|um|us|uy|uz|va|vc|vg|vn|vu|wf|ws|xxx|yt|za|zm|zw)$/;
var socket;
var last = null;

var dnscache = {};

var updateDomain = function(id) {
	$('#' + id).addClass(dnscache[id]).removeClass('progress');
};

var receive = function(data) {
	dnscache[data.id] = data.status;
	updateDomain(data.id);
};

$(function(){
	socket = new io.Socket();
	socket.on('message', receive);
	socket.connect();
});

var domPop = function(id, content) {
	var li = document.getElementById(id);
	if (!li) {
		li = document.createElement('li');
		li.id = id;
		$(li).addClass('pending');
		li.innerHTML = content;
	}
	$(li).addClass('active');
	var res = $('#results')[0];
	if (res.children.length > 0) {
		res.insertBefore(li, res.firstChild);
	} else {
		res.appendChild(li);
	}
	return li;
};

var newLink = function(href, clss) {
	var a = document.createElement('a');
	a.setAttribute('href', href);
	a.setAttribute('class', clss);
	return a;
};

var queryDomain = function(domain) {
	var id = domain.replace(/\./g, '---');
	var li = domPop(id, domain, 'active');
	if (dnscache[id]) {
		updateDomain(id);
	} else {
		socket.send({ id: id, query: domain });
		$(li).addClass('progress');
	}
	if ($(li).hasClass('pending')) {
		// new item
		li.appendChild(newLink('http://domai.nr/' + domain + '/whois', 'whois'));
		li.appendChild(newLink('http://domai.nr/api/register?domain=' + domain, 'reg'));
		li.appendChild(newLink('http://' + domain, 'link'));
		setTimeout(function(){ $(li).removeClass('pending'); }, 1000);
	}
};

var stemDomains = function(base) {
	if (base.length < 2) return;
	if (base[0] == '/') return;
	$('body.start').removeClass('start');
	var tlds = $('#tlds').val().split(/[^a-zA-Z.\-]+/);
	var match;
	if (match = base.match(/(.+)\.(\w+)/)) {
		queryDomain(base);
		base = base.replace(/\./g, '');
		return;
	}
	for (var i = tlds.length - 1; i >= 0; i -= 1) {
		queryDomain(base + '.' + tlds[i]);
	}
	if (match = base.match(tldre)) {
		queryDomain(match[1] + '.' + match[2]);
	}
};

$('#search').live('keyup', function(e){
	var query = $(this).val().trim().toLowerCase().replace(/[^0-9a-zA-Z\.\- \/]+/g, ' ');
	if (e.keyCode == 13) {
		$('.pending').removeClass('pending');
	}
	if (query[0] == '/') {
		execute(query.substr(1));
		return;
	}
	if (e.keyCode == 27) {
		$(this).val('');
		query = '';
	}
	if (query == last) return;
	last = query;
	var url = window.location.href;
	window.location = url.replace(/\#.*|$/, '#' + (query + '*' + $('#tlds').val()).replace(/\s+/g, '_'));
	trigger();
}).live('focus', function() { trigger(); });
$('#tlds').live('change', function(){ trigger(); });

var trigger = function() {
	$('.active').removeClass('active');
	$('.pending').remove();
	makeQuery(last);
}

var makeQuery = function(string){
	var words = string.trim().toLowerCase().split(/[^0-9a-z\.\/]+/);
	var variants = [[]];
	var i, j, k;
	for (i = 0; i < words.length; i += 1) {
		var terms = words[i].split(/\//);
		var v = [];
		for (j = 0; j < terms.length; j += 1) {
			for (k = 0; k < variants.length; k += 1) {
				v.push(variants[k].concat(terms[j]));
			}
		}
		variants = v;
	}
	var domains = [];
	for (i = 0; i < variants.length; i += 1) {
		if (variants[i].length > 1) stemDomains(variants[i].join('-'));
		stemDomains(variants[i].join(''));
	}
};

var help = function(str) {
	domPop('help', str);
};

var commands = {
	'clear': function(){ $('#results li').remove(); $('body').addClass('start'); },
	'help': function(){ help("/help: this help\n/clear: clear the history"); }
};
function execute(command) {
	if (commands[command]) {
		commands[command]();
	}
}

function setQuery(q) {
	last = q;
	$('#search').val(q);
	trigger();
}

$(function(){
	var url = window.location.href;
	if (match = url.match(/\#(.+)/)) {
		last = match[1].replace(/_/g, ' ');
		if (match = last.match(/(.*)\*(.*)/)) {
			last = match[1];
			$('#tlds').val(match[2]);
		}
		$('#search').val(last);
		if (last.length > 0) trigger();
	}
});

$('#results li').live('click', function() {
	setQuery($(this).text());
});

