/**
 * @project TV Wall
 * @version 2010.06
 * @author Luís Nabais
 * @copyright 2010 by the author
 * @license CC-BY-SA
 */

/**
 * Ajax.Request.abort
 * extend the prototype.js Ajax.Request object so that it supports an abort method
 */
Ajax.Request.prototype.abort = function() {
    // prevent and state change callbacks from being issued
    this.transport.onreadystatechange = Prototype.emptyFunction;
    // abort the XHR
    this.transport.abort();
    // update the request counter
    if (Ajax.activeRequestCount > 0) {
		Ajax.activeRequestCount--;
    }
};
/**
 * end of extension
 */

/**
 * Orginal: http://adomas.org/javascript-mouse-wheel/
 * prototype extension by "Frank Monnerjahn" themonnie@gmail.com
 */
Object.extend(Event, {
        wheel:function (event){
                var delta = 0;
                if (!event) event = window.event;
                if (event.wheelDelta) {
                        delta = event.wheelDelta/120;
                        if (window.opera) delta = -delta;
                } else if (event.detail) { delta = -event.detail/3;     }
                return Math.round(delta); //Safari Round
        }
});
/**
 * end of extension
 */

String.prototype.urlize = function() {
	return this.toLowerCase().gsub(' ', '-').escapeHTML();
};

Array.prototype.contains = function(v) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == v) {
			return i;
		}
	}
	return false;
};

function errorHandler(response, exception) {
	if (console) {
		console.log(exception);
	}
	// TODO: warn me of errors
}

function cleanResponse(item) {
	if (Object.isUndefined(item)) {
		return item;
	}

	if (Object.isArray(item)) {
		for(var $i = 0; $i < item.size(); $i++) {
			item[$i] = cleanResponse(item[$i]);
		}
	} else if (!Object.isString(item)) {
		$H(item).each(function(obj) {
			item[obj.key] = cleanResponse(obj.value);
		});
	} else if (Object.isString(item)) {
		var $array = item.split("|");
		if ($array.size() <= 1) {
			return $array[0].trim();
		} else {
			var $output = [""];
			var $j = 0;
			
			$array.each(function(obj){
				if (!obj.blank()) {
					$output[$j++] = obj.trim();
				}
			});
			return $output;
		}
	}
	return item;
}

var $code = [ Event.KEY_UP, Event.KEY_UP, Event.KEY_DOWN, Event.KEY_DOWN,
		Event.KEY_LEFT, Event.KEY_RIGHT, Event.KEY_LEFT, Event.KEY_RIGHT, 'b',
		'a', Event.KEY_RETURN ];
var $coden = 0;

function code(event) {
	switch (event.keyCode) {
	case 0:
		if (String.fromCharCode(event.charCode) == $code[$coden]) {
			$coden++;
		} else {
			$coden = 0;
		}
		break;
	case $code[$coden]:
		$coden++;
		break;
	default:
		$coden = 0;
	}
	
	if ($coden >= $code.size()) {
		if ($('konami')) {
			$('konami').remove();
		} else {
			$('global').up().insert( {
				top : new Element('p', {
					'id' : 'konami'
				}).update('42')
			});
		}
		$coden = 0;
		event.stop();
	}
}

function onKeyPress(event) {
	code(event);
	
	var $addShowForm = $('add-show');
	
	switch(event.keyCode) {
	case Event.KEY_ESC:
		if ($('modal-wrapper').visible()) {
			hideModal();
		}
		if ($addShowForm.visible()) {
			hideAddForm();
		} else {
			clearSelectedCells();
		}
		break;
	case Event.KEY_UP:
	case Event.KEY_DOWN:
	case Event.KEY_LEFT:
	case Event.KEY_RIGHT:
		if (!$addShowForm.visible()) {
			selectMove(event.keyCode);
		}
		break;
	case Event.KEY_RETURN:
	case Event.KEY_DELETE:
		if (!$addShowForm.visible()) {
			selectedClick(event.keyCode);
		}
		break;
	case Event.KEY_INSERT:
		showAddForm();
		break;
	default:
		if ($addShowForm.visible()) {
			var $input = $('show-name');
			if (!$input.hasFocus) {
				$input.activate();
				if (event.charCode > 0) {
					$input.value = String.fromCharCode(event.charCode);
				}
				event.stop();
			}
		}
		break;
	}
}

function onContentsClick(event) {
	var $article = Event.findElement(event, 'article');

	if ($article) {
		if ($article.hasClassName('empty')) {
			showAddForm();
		} else if (Event.findElement(event).hasClassName('close')) {
			closeCellClick(event);
		} else {
			onCellClick(event);
		}
	} else {
		clearSelectedCells();
	}

	if ($('add-show').visible()) {
		hideAddForm();
	}
}

function stopBubbling(event) {
	event.stop();
}

function hideModal(event) {
	$('modal-inner').fade({
		duration: 0.8,
		afterFinish: function(obj) {
			inputEnable();
		}
	});
	
	document.title = "TV Wall";
}

function parseHash() {
	// TODO: check hash
	var $hash = window.location.hash.split("/");
	
	switch($hash[1]) {
	case "add-show":
		showAddForm();
		break;
	case "clear":
		clearStorage();
		addPopup(new Message('storage', "Your wall has been cleared. It is now a clean slate ready for your shows."));
		break;
	case "show":
	case "add":
		if ($hash[2]) { 
			var $name = $hash[2].gsub('-', ' ').escapeHTML();
			var $url = 'php/search.php?series=' + $name;
			addNotification(new Message('search', 'searching'));

			var $returnFunction;
			var $failureFunction;
			if ($hash[1] == 'show') {
				inputDisable();
				
				$returnFunction = function(response) {
					var $series = cleanResponse(response.responseJSON['Series']);
					
					if (Object.isArray($series)) {
						$series = $series[0];
					}
					
					showShowInfo($series['seriesid']);
				};
				
				$failureFunction = function(response) {
					var $message = new Message('popup', "The show you requested wasn't found in the database...");
					$message.type = 'error';
					addPopup($message);
					inputEnable();
				};
			} else {
				$returnFunction = function(response) {
					var $series = cleanResponse(response.responseJSON['Series']);
					
					if (Object.isArray($series)) {
						$series = $series[0];
					}
					
					onShowAdd($series['seriesid']);
				};
				
				$failureFunction = function(response) {
					var $message = new Message('popup', "The show you requested wasn't found in the database...");
					$message.type = 'error';
					addPopup($message);
					window.location.hash = "#";
					
				};
			}

			new Ajax.Request($url, {
				onSuccess : $returnFunction,
				onFailure : $failureFunction,
				onComplete : function(response) {
					removeNotification('search');
				}
			});
			return false;
		}
		break;
	default:
		window.location.hash = "#";
		break;
	}
	
	return true;
}

function loadTVWall(obj) {
	// Parse the URL hash
	var $loading = !parseHash();
	// Restore shows from storage
	if (restoreShowsFromStorage()) {
		inputDisable();
		addPopup(new Message('session', "Restoring Session"));
		Event.observe(window, 'tvwall:notificationEnd', function(event) {
			if (event.memo['last']) {
				addNotification(new Message('session', 'restoring session'));
				
				var $time = 1000;
				var $queue = Effect.Queues.get('empty-cells');
				if ($queue.size() > 0) {
					$time = $queue.effects.last().finishOn - new Date().getTime();
				}
				
				setTimeout(function() {
								removeNotification('session');
								inputEnable();
								updateScrollBar();
							}, $time);
				Event.stopObserving(window, 'tvwall:notificationEnd');
			}
		});
	} else if (!$loading) {
		inputEnable();
	} else {
		inputDisable();
	}
	
	$('modal-wrapper').down('.close').show();
	$('content').observe('click', onContentsClick);
	Element.observe(window, 'keypress', onKeyPress);
}

Event.observe(document, 'dom:loaded', function() {
	var $testPassed = true;
	
	$('add-show').hide();
	toogleSpinner();
	toggleNotification();
	
	$$('ul.features li').each(function(item) {
		if (!eval("Modernizr." + item.identify())) {
			$testPassed = false;
		} else {
			item.removeClassName('no').addClassName('yes');
		}
	});
	
	// code yanked from the Yahoo media player. Thanks, Yahoo.
	if (! ("console" in window) || !("firebug" in console)) {
	    window.console = null;
	}
	
	// Analytics
	Ajax.Responders.register({
		onComplete: function(request){
			try {
				if(request && request.url){
					piwikTracker.setDocumentTitle(document.title);
					piwikTracker.setCustomUrl(request.url);
					piwikTracker.trackPageView();
				}
			} catch (e){
			}
		},
		onException : errorHandler
	});
	
	if (!$testPassed) {
		$('modal-content').down('.failure-message').show();
	} else {
		resizeFooter();
		resizeContent();
		addScrollBar();
		
		if (loadFromStorage("hideStartupMessage")) {
			$('modal-inner').hide();
			loadTVWall();
		} else {
			$('modal-content').down('.success-message').show();
			$('modal-content').down('.bottom-buttons').show().down('.button').observe('click', function(event) {
				if ($('modal-content').down('#hideStartupMessage').checked) {
					var $tmp = saveToStorage("hideStartupMessage", true);
				}
				
				$('modal-inner').fade( {
					afterFinish : loadTVWall
				});
				event.stop();
			});
		}

		// Make the placeholder work via javascript since only webkit has support
		// for it
		var $form = $$('form');
		if ($form) {
			$$('form input, form textarea').each(function(item) {
				item.observe('focus', formOnFocus);
				item.observe('blur', formOnBlur);
			});
		}
		
		$('modal-wrapper').down('.close').observe('click', hideModal);
		

		$$('#add-show .close').each(function(item) {
			item.observe('click', hideAddForm);
		});
		
		var $formObserver = new Form.Element.Observer('show-name', 0.7, formOnChange);
		setFormObserver($formObserver);
		Element.observe('add-show', 'submit', formOnSubmit);
		
		$('add-show').observe('click', stopBubbling);
		
		Event.observe(window, 'resize', resizeFooter);
		Event.observe(window, 'resize', resizeContent);
		Event.observe(window, 'resize', updateModalTitle);

		addEmptyCell();
		resizeFooter();
		resizeContent();
		setColors();

		Event.observe(window, 'resize', updateScrollBar);
		
		/* Mouse Wheel Scroll */
		$$('#content, #scrollbar').each(function(item) {
			item.observe('mousewheel', onScrollWheelMove);
			item.observe('DOMMouseScroll', onScrollWheelMove); // Firefox
		});
	}
});

