var selectX = 0;
var selectY = 0;
var selectSize = 28;
var maxX = 756;
var maxY = 448;
var emojiPerRow = 28;
var selectBorderSize = 1;
var observingKeys = false;
var defaultTitle = 'An Emoji Tale';

// We use letters rather than numbers to shorten the URL
var emojiIndex = ["a-", "b-", "c-", "d-", "e-", "f-", "g-", "h-", "i-", "j-", "k-", "l-", "m-", "n-", "o-", "p-", "q-", "r-", "s-", "t-", "u-", "v-", "w-", "x-", "y-", "z-", "aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al", "am", "an", "ao", "ap", "aq", "ar", "as", "at", "au", "av", "aw", "ax", "ay", "az", "ba", "bb", "bc", "bd", "be", "bf", "bg", "bh", "bi", "bj", "bk", "bl", "bm", "bn", "bo", "bp", "bq", "br", "bs", "bt", "bu", "bv", "bw", "bx", "by", "bz", "ca", "cb", "cc", "cd", "ce", "cf", "cg", "ch", "ci", "cj", "ck", "cl", "cm", "cn", "co", "cp", "cq", "cr", "cs", "ct", "cu", "cv", "cw", "cx", "cy", "cz", "da", "db", "dc", "dd", "de", "df", "dg", "dh", "di", "dj", "dk", "dl", "dm", "dn", "do", "dp", "dq", "dr", "ds", "dt", "du", "dv", "dw", "dx", "dy", "dz", "ea", "eb", "ec", "ed", "ee", "ef", "eg", "eh", "ei", "ej", "ek", "el", "em", "en", "eo", "ep", "eq", "er", "es", "et", "eu", "ev", "ew", "ex", "ey", "ez", "fa", "fb", "fc", "fd", "fe", "ff", "fg", "fh", "fi", "fj", "fk", "fl", "fm", "fn", "fo", "fp", "fq", "fr", "fs", "ft", "fu", "fv", "fw", "fx", "fy", "fz", "ga", "gb", "gc", "gd", "ge", "gf", "gg", "gh", "gi", "gj", "gk", "gl", "gm", "gn", "go", "gp", "gq", "gr", "gs", "gt", "gu", "gv", "gw", "gx", "gy", "gz", "ha", "hb", "hc", "hd", "he", "hf", "hg", "hh", "hi", "hj", "hk", "hl", "hm", "hn", "ho", "hp", "hq", "hr", "hs", "ht", "hu", "hv", "hw", "hx", "hy", "hz", "ia", "ib", "ic", "id", "ie", "if", "ig", "ih", "ii", "ij", "ik", "il", "im", "in", "io", "ip", "iq", "ir", "is", "it", "iu", "iv", "iw", "ix", "iy", "iz", "ja", "jb", "jc", "jd", "je", "jf", "jg", "jh", "ji", "jj", "jk", "jl", "jm", "jn", "jo", "jp", "jq", "jr", "js", "jt", "ju", "jv", "jw", "jx", "jy", "jz", "ka", "kb", "kc", "kd", "ke", "kf", "kg", "kh", "ki", "kj", "kk", "kl", "km", "kn", "ko", "kp", "kq", "kr", "ks", "kt", "ku", "kv", "kw", "kx", "ky", "kz", "la", "lb", "lc", "ld", "le", "lf", "lg", "lh", "li", "lj", "lk", "ll", "lm", "ln", "lo", "lp", "lq", "lr", "ls", "lt", "lu", "lv", "lw", "lx", "ly", "lz", "ma", "mb", "mc", "md", "me", "mf", "mg", "mh", "mi", "mj", "mk", "ml", "mm", "mn", "mo", "mp", "mq", "mr", "ms", "mt", "mu", "mv", "mw", "mx", "my", "mz", "na", "nb", "nc", "nd", "ne", "nf", "ng", "nh", "ni", "nj", "nk", "nl", "nm", "nn", "no", "np", "nq", "nr", "ns", "nt", "nu", "nv", "nw", "nx", "ny", "nz", "oa", "ob", "oc", "od", "oe", "of", "og", "oh", "oi", "oj", "ok", "ol", "om", "on", "oo", "op", "oq", "or", "os", "ot", "ou", "ov", "ow", "ox", "oy", "oz", "pa", "pb", "pc", "pd", "pe", "pf", "pg", "ph", "pi", "pj", "pk", "pl", "pm", "pn", "po", "pp", "pq", "pr", "ps", "pt", "pu", "pv", "pw", "px", "py", "pz", "qa", "qb", "qc", "qd", "qe", "qf", "qg", "qh", "qi", "qj", "qk", "ql", "qm", "qn", "qo", "qp", "qq", "qr", "qs", "qt", "qu", "qv", "qw", "qx", "qy", "qz", "ra", "rb", "rc", "rd", "re", "rf", "rg", "rh"];

function updateSelectPosition(){
	$('emoji_selector').style.left = (selectX-selectBorderSize)+'px';
	$('emoji_selector').style.top = (selectY-selectBorderSize)+'px';
}

function getHashTokensAndUpdateTitle(){
	var hashString;
	if(hashString = location.href.match(/#(\S+)/)){
		hashString = hashString[1];
	}else{
		hashString = '';
	}
	var tokensAndTitle = hashString.split('&');
	var tokenString = tokensAndTitle[0];
	if(tokensAndTitle[1]) $('emoji_message_title').innerHTML = unescape(tokensAndTitle[1]);	
	return emojiTokensFromString(tokenString);
}

function emojiTokensFromString(tokenString){
	var hashTokens = [];	
	for(var hashIndex=0;hashIndex <= tokenString.length;hashIndex+=2){
		var token = tokenString.slice(hashIndex,hashIndex+2);
		hashTokens.push(token);
	}	
	return hashTokens;
}

function createLink(){
	var link = ["http://emojitales.com/#"];
	var emojiNodes = $('emoji_text').childElements();
	if(emojiNodes.length == 0){
		alert('Please create a message');
		return false;
	}else{
		emojiNodes.each(function(element,index){
			link.push(element.getAttribute('rel'));			
		});
		if(getTitle()) link.push('&'+escape($('emoji_tale_name').value));
		return link.join('');
	}	
}

function getTitle(){
	if($('emoji_tale_name').value.strip() != $('emoji_tale_name').getAttribute('value').strip()){
		return $('emoji_tale_name').value.strip();
	}else{
		return false;
	}
}

function createTweet(){
	var showTweet = function(shortURL){
		var tweet = []
		var title = "";
		if($('emoji_tale_name').value.strip() != $('emoji_tale_name').getAttribute('value').strip()){
			title = $('emoji_tale_name').value;
		}else{
			title = defaultTitle;
		}
		tweet.push(title+':');
		tweet.push(shortURL);
		tweet.push('#emojitales')
		window.open('http://twitter.com/home?status='+escape(tweet.join(' ')), 'emojitales');
	}
	shortenURL(createLink(), showTweet);
}

function insertLinkIntoTinyURLForm(){
	$('emoji_url').value = createLink();
}

function updateActionButtons(){
	if($('emoji_text').childElements().length == 0){
		$('action_buttons').style.display = 'none';
	}else{
		$('action_buttons').style.display = 'block';
	}	
}

function constructMessage(emojis,messageId){
	emojis.each(function(emoji,index){
		if(emoji != ''){
			var coords = coordsFromEmojiIndex(emoji);
			addEmoji(coords[0],coords[1],messageId);
		}
	});	
}

function reviveMessage(){
	var emojis = getHashTokensAndUpdateTitle();
	constructMessage(emojis);
}

function clearMessage(){
	$('emoji_text').innerHTML = '';	
	updateActionButtons();
}

function emojiIndexFromCoords(x,y){
	x = x || selectX;
	y = y || selectY;
	var rows = y/selectSize;
	var cols = x/selectSize;
	var index = emojiPerRow*rows + cols;
	return emojiIndex[index];
}

function coordsFromEmojiIndex(index){
	var count = emojiIndex.indexOf(index);
	var rows = Math.floor(count / emojiPerRow);
	var cols = count%emojiPerRow;
	var top = rows*selectSize;
	var left  = cols*selectSize;
	return [left, top];
}

function addEmoji(left,top,messageId){
	messageId = messageId || 'emoji_text';
	top = (top || selectY);
	left = (left || selectX);
	$(messageId).innerHTML += '<div class="emoji_square" style="background:url(emoji.jpg) -'+left+
														'px -'+top+'px no-repeat;" rel="'+emojiIndexFromCoords(left,top)+'">?</div>';

	// If this is the editor, update the action buttons
	if(messageId == 'emoji_text') updateActionButtons();
}

function removeEmoji(){
	var lastElement = $('emoji_text').childElements().last()
	if(lastElement) lastElement.remove();
	updateActionButtons();
}

function observeKeys(){

	$('emoji_grid').observe('mousemove', function(event){
		var gridCoords = $('emoji_grid').cumulativeOffset();
		var left = event.pointerX() - gridCoords.left;
		var top = event.pointerY() - gridCoords.top;
		if(left < (maxX+selectSize) && left > 0 && top < (maxY+selectSize) && top > 0){
			selectX = left;
			selectX -= selectX%selectSize;
			selectY = top;
			selectY -= selectY%selectSize;
			updateSelectPosition();			
		}
	});
	
	$('emoji_grid').observe('click', function(){
		addEmoji();
	});
	
	observingKeys = true;

}

// Revive message if there is a hash
document.observe('dom:loaded', function(){
	if(location.hash != ''){
		showPreview();
	}else{
		showRead();
	}	
});

/* Bit.ly */

var shortURLReceiver, longURLReceiver = false;
var expandedURLs = {};

function addExpandedURL(data){
  for(var r in data.results){
		var theResult = data.results[r].longUrl;
		var theCode = theResult.replace(/^[^#]+#/, '').replace(/\&.*/, '');
		var messageId = $(expandedURLs[r].id).select('.the_message')[0].id;
		var emojis = emojiTokensFromString(theCode);
		constructMessage(emojis,messageId);
	}
}

function decodeURLs(urlDict){
	for(var domID in urlDict){
		var theResult = urlDict[domID];
		var theCode = theResult.replace(/^[^#]+#/, '').replace(/\&.*/, '');
		var emojis = emojiTokensFromString(theCode);
                constructMessage(emojis,domID+'_message');
	}
}

function shortenURL(theURL, returnToFunction){
	shortURLReceiver = returnToFunction;
	BitlyClient.shorten(theURL, 'handleShortURL');
}		

function expandURL(theURL, returnToFunction){
	longURLReceiver = returnToFunction;
	BitlyClient.expand(theURL, 'handleLongURL');	
}
			
function handleShortURL(data){
  var s = '';
  var first_result;
  // Results are keyed by longUrl, so we need to grab the first one.
  for(var r in data.results){
		first_result = data.results[r]; break;
	}
  for(var key in first_result){
		s += key + ":" + first_result[key].toString() + "\n";
	}
	if(shortURLReceiver) shortURLReceiver(first_result.shortUrl);
}

function handleLongURL(data){
  var s = '';
  var first_result;
  // Results are keyed by longUrl, so we need to grab the first one.
  for(var r in data.results){
		first_result = data.results[r]; break;
	}
  for(var key in first_result){
		s += key + ":" + first_result[key].toString() + "\n";
	}
	if(longURLReceiver) longURLReceiver(first_result.longUrl);
}


/* Twitter stuff */

var indexLoaded = false;
var twitterMessages = [];

function loadTwitterJSON(json){
	twitterMessages = json;
}

function renderTwitterMessages(){
	if(!indexLoaded){
//console.log('rendering');
	var json = twitterMessages;
	var messageList = [];
	var messageURLs = {}
	for(var m=0;m<json.length;m++){
		var tweet = json[m]["text"];
		var url;
		if(url = tweet.match(/http\:\/\/\S+/)){
			url = url[0];
			// There is a URL. Display it.
			var tweetID = 'emojitale_'+m;
			messageURLs[tweetID] = url;
			tweet = tweet.replace(url, '');
			author = tweet.match(/^@([^\s:]+)\:/)[1];
			tweet = tweet.replace('@'+author+':', '');
			tweet = tweet.replace(/^ /, '').replace(/ $/, '');
			tweet = '<a href="'+url+'" target="emojitales" class="message_title">'+tweet+'</a>';
			tweet += ' <span class="credit">by <a href="http://twitter.com/'+author+'">@'+author+'</a></span>';
			messageList.push('<li id="'+tweetID+'"><div class="the_title">'+tweet+'</div><div class="the_message" id="'+tweetID+'_message"></div></li>');
		}
	}
	$('emoji_messages').innerHTML = messageList.join('\n');
	//decodeBitlyURLs(messageURLs);
	decodeURLs(messageURLs);
	}
	indexLoaded = true;
}
/*
function decodeBitlyURLs(urlDict){
	for(var domID in urlDict){
		var tweetURL = urlDict[domID];
		if(typeof(tweetURL)=='string'){						
			if(tweetURL.match('bit.ly')){
				expandedURLs[tweetURL.replace('http://bit.ly/', '')] = { id : domID , long_url : null};
			}
		}
	}
	BitlyClient.expand($H(expandedURLs).keys().join(','), 'addExpandedURL');	
}
*/
// Toggle Between States 

function showRead(){
	renderTwitterMessages();
	toggleVisibleItems('message_read');
}

function showCreate(){
	toggleVisibleItems('message_create');
	if(!observingKeys) observeKeys();
	updateActionButtons();
}

function showPreview(){
	var title = getTitle();
	// They are coming from an external URL
	if(!title && $('emoji_text').childNodes.length == 0){
		reviveMessage();
	}else{
		if(title) $('emoji_message_title').innerHTML = unescape(title);
		else $('emoji_message_title').innerHTML = defaultTitle;
	}	
	toggleVisibleItems('message_preview');
}

function toggleVisibleItems(ofKind){
	var viewTypes = ['message_preview', 'message_create', 'message_read'];
	for(var v=0;v<viewTypes.length;v++){
		viewType = viewTypes[v];
		$$('.'+viewType).each(function(el,i){  
			if(viewType == ofKind){
				el.style.display = 'block'; 
				$(viewType+'_tab').addClassName('current');			
			}else{
				el.style.display = 'none'; 
				$(viewType+'_tab').removeClassName('current');							
			}
		}.bind(this));			
	}
	$('emoji_text').style.display = (ofKind == 'message_read') ? 'none' : 'block'	
}

