// Smaple JS to retrieve tweet data via AJAX and JSON
// and display it on the sample page.
// Needs prototype.js

var App = Class.create();
App.prototype = {
	
	initialize: function() {
		this.renderer = 'Html';
	},
	
	// prepare event listeners and load data
	boot: function() {
		Event.observe($('options'), 'click', (function(e) {
			var el = Event.element(e);
			if (!el.hasClassName('trigger')) {
				return;
			}
			if (el.hasClassName('filter_show_all')) {
				this.load_data({renderer: this.renderer});
			}
		}).bindAsEventListener(this));
		Event.observe($('tweets'), 'click', (function(e) {
			var el = Event.element(e);
			if (el.hasClassName('tag_trigger')) {
				var value = el.firstChild.nodeValue;
				this.load_data({renderer: this.renderer, tag_filter: value});
			}
			return false;
		}).bindAsEventListener(this));

		// this.load_data({renderer: this.renderer});
	},

	load_data: function(parameters) {
		new Ajax.Request('tweets/tweets.php', {
			parameters: parameters,
			onSuccess: function(transport) {
				var method = 'show_data_' + parameters['renderer'];
				app[method](transport, parameters).bind(app);
			},
			onFailure: function(transport) {
		    var container = $('tweets').show();
	      container.update('Error loading Tweets: ' + transport.status + " " + transport.statusText).setStyle({ background: '#fdd' });
		  }
		});
	},
	
	show_data_Html: function(transport, parameters) {
		var container = $('tweets').show();
		container.update(transport.responseText);
		$('options').childElements().invoke('hide');
		if (parameters.tag_filter) {
			var filter = $('filter');
			filter.show().select('.filter_tag')[0].update(parameters.tag_filter);
		}
	},
	
	// load json data via ajax and put it on the page using the hidden templates
	// could have generated the html on the server, you say?
	// but then I would not have a json demo... ;)
	show_data_Json: function(transport) {
		json = transport.responseText.evalJSON(true);
		if (app.is_array(json.results)) {
			return;
		}
		$('options').childElements().invoke('hide');
		if (typeof json.options === 'object' && !app.is_array(json.options)) {
			if (json.options.tag_filter) {
				var filter = $('filter');
				filter.show().select('.filter_tag')[0].update(json.options.tag_filter);
			}
		}
		$H(json.results).each(function(pair) {
			var tag_node = $('tweet_template').cloneNode(true);
			tag_node.id = '';
			tag_node.select('.keyword')[0].update(pair.key);
			
			var tag_container = tag_node.select('.tags_per_keyword')[0];
			var tag_template =  tag_container.select('.tag_container')[0];
			$H(pair.value.tags).each(function(tag_info) {
				var tag_el = tag_template.cloneNode(true);
				tag_el.select('.single_tag')[0].update(tag_info.key);
				tag_el.select('.counter')[0].update(tag_info.value);
				tag_container.insert(tag_el);
			});
			tag_template.remove();
			
			var tweet_tpl = tag_node.select('.tweet')[0];

			if (!pair.value.items) {
				tag_node.select('.tweets_per_tag').invoke('remove');
			}
			else {
				pair.value.items.each(function(item) {
					var tweet_node = tweet_tpl.cloneNode(true);

					tweet_node.select('.content')[0].update(item._title);
					tweet_node.select('.username')[0].update(item._username);
					tweet_node.select('.detail_link')[0].href = item.link;
					tweet_node.select('.date')[0].update(item._human_date);
					tweet_node.select('.tags')[0].update(item._tags.map(function(tag) {
						return '<span class="tag_link tag_trigger trigger">'+tag+'</span>';
					}).join(', '));

					var regexp = new RegExp('('+item._tags.join('|')+')', 'gi');
					var title = item._title.replace(regexp, '<em>$1</em>');
					tweet_node.select('.content')[0].update(title);
					// http://search.twitter.com/search?q=
					tweet_tpl.parentNode.appendChild(tweet_node);
				});
			}
			tweet_tpl.remove();
			$('tweets').appendChild(tag_node);
		});
		new $('tweets').show();
		// new Effect.BlindDown('tweets');
  },
	
	// helper function to distinguish arrays from objects
	is_array: function(value) {
		// Thanks to Douglas Crockford
		return value &&
			typeof value === 'object' &&
			typeof value.length === 'number' &&
			typeof value.splice === 'function' &&
			!(value.propertyIsEnumerable('length'));
	}
	
};

var app = new App();
document.observe('dom:loaded', app.boot.bind(app));