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

var $nextColor = 0;
var $colors = [ 'red', 'green', 'purple' ];

var $combinations = [ [ 'normal', 'tall', 'square', 'square' ],
		[ 'normal', 'tall', 'tall' ], [ 'normal', 'square', 'square', 'wide' ],
		[ 'normal', 'wide', 'square', 'square' ], [ 'normal', 'wide', 'wide' ],
		[ 'large', 'wide', 'square', 'square', 'wide' ] ];
var $combinationCounter = 1;
var $currentCombination = Math.floor(Math.random() * ($combinations.size() - 1));
var $newBox = true;

function needsNewBox() {
	return $newBox;
}

function currentBoxType() {
        return $combinations[$currentCombination][0];
}

function newBox() {
	$newBox = false;
	
	var $box = new Element('div', {
		'class' : 'box',
		'rel' : $currentCombination
	});
	
	$box.addClassName(currentBoxType());
	
	return $box;
}

function updateCounters() {
	var $boxes = $$('#content .box');
	
	$boxes.each(function(item) {
		$combinationCounter = item.childElementCount + 1;
		$currentCombination = item.readAttribute('rel');
	});

	if ($combinationCounter >= $combinations[$currentCombination].size()) {
		$combinationCounter = 1;
		$newBox = true;

		$currentCombination = Math.floor(Math.random() * ($combinations.size() - 1));
	} else if ($combinationCounter <= 0) {
		$combinationCounter = $combinations[$currentCombination].size();
		$newBox = false;

		$currentCombination = $$('#content .box').last().readAttribute('rel');
	}
}

function nextType() {
	updateCounters();
	
	return $combinations[$currentCombination][$combinationCounter++];
}

function nextColor() {
	var $next = $colors[$nextColor++];

	if ($nextColor >= $colors.size()) {
		$nextColor = 0;
	}

	return $next;
}

function setColors() {
	$nextColor = 0;

	$$('#content article').each(function(item) {
		var $article = item;
		$colors.each(function(i) {
			$article.removeClassName(i);
		});
		item.addClassName(nextColor());
	});
}

/* Social */
function shareOnTwitter() {
	var $url = window.location.href;

	addNotification(new Message('twitter', "Shortening url..."));
	var $request = "/php/shorten.php?url=" + encodeURIComponent($url);

	new Ajax.Request($request, {
		'method' : 'get',
		onComplete : function(response) {
			removeNotification('twitter');
		},
		onSuccess : function(response) {
			var $url = response.responseJSON.punyURL.ascii;
			var $link = "http://twitter.com/home?status=" + document.title + " (" + encodeURIComponent($url) + ") ";
			window.location = $link.escapeHTML();
		},
		onFailure : function(response) {
			var $link = "http://twitter.com/home?status=" + encodeURIComponent(window.location.href);
			window.location = $link;
		}
	});
}

function shareOnFacebook() {
	var $link = "https://www.facebook.com/sharer.php?u=" + encodeURIComponent(window.location.href.sub('#', '%23')) + 
					"&t=" + encodeURIComponent(document.title);
	var $facebookWindow = window.open($link, 'tvwall-facebook', 'width=780,height=640');
	if (window.focus) {
		$facebookWindow.focus();
	}
}

function addEmptyCell() {
	var $box = $$('#content .box:last-child').first();
	
	// <article class="square empty green">
	var $article = new Element('article', {
		'class' : 'empty'
	});
	$article.addClassName(nextType());
	
	if (!$box || needsNewBox()) {
		$box = newBox();
		
		$('contents-inner').insert($box);
	}
	
	// <a href="#" class="link" title="Add another show to your wall">Add show</a>
	$article.insert(new Element('a', {
		href : '#/add-show',
		'class' : 'link',
		'title' : "Add another show to your wall"
	}).update("Add Show"));
	
	// <span class="icon">+</span>
	$article.insert(new Element('span', {
		'class' : 'icon'
	}).update('+'));
	
	// <h1>Add Show</h1>
	$article.insert(new Element('h1').update("Add Show"));
	
	$article.setOpacity(0.0);
	
	$box.insert($article);
	
	new Effect.Opacity($article.identify(), {
		from : 0,
		to : 1.0,
		duration : 0.8,
		queue : {
			position : 'end',
			scope : 'empty-cells'
		}
	});
}

function setModalColor(item) {
	var $modal = $('modal-inner');
	
	$modal.removeClassName('red');
	$modal.removeClassName('green');
	$modal.removeClassName('purple');
	
	if (item.hasClassName('green')){
		$modal.addClassName('green');
	}
	if (item.hasClassName('red')){
		$modal.addClassName('red');
	}
	if (item.hasClassName('purple')){
		$modal.addClassName('purple');
	}
}

function onShowInfoResponse(response) {
	var $show = cleanResponse(response.responseJSON['Series']);
	
	$('modal-inner').down('.title h1 span').update($show['SeriesName']);
	
	document.title += " :: " + $show['SeriesName'];
	
	var $top = new Element('div', {
		'class' : 'top'
	});
	$top.insert(new Element('h2', {
		'class' : 'description'
	}).update('Description'));
	
	var $description = new Element('p');
	if (Object.isString($show['Overview'])) {
		$description.update($show['Overview']);
	} else {
		$description.update('No description available.');
	}
	$top.insert($description);
	
	$top.insert(new Element('h2', {
		'class' : 'information'
	}).update('Information'));
	
	var $infoList = new Element('ul', {
		'class' : 'info'
	});
	
	if (Object.isString($show['FirstAired'])) {
		var $firstAired = new Element('li');
		$firstAired.update('<span class="title">First Aired</span> ' + $show['FirstAired']);
		$infoList.insert($firstAired);
	}
	
	if (Object.isString($show['Airs_DayOfWeek'])) {
		var $airDays = new Element('li');
		$airDays.update('<span class="title">Air Day(s)</span> ' + $show['Airs_DayOfWeek']);
		$infoList.insert($airDays);
	}
	
	if (Object.isString($show['Airs_Time'])) {
		var $airTime = new Element('li');
		$airTime.update('<span class="title">Air Time</span> ' + $show['Airs_Time']);
		$infoList.insert($airTime);
	}
	
	if (Object.isString($show['Runtime'])) {
		var $runtime = new Element('li');
		$runtime.update('<span class="title">Runtime</span> ' + $show['Runtime']);
		$infoList.insert($runtime);
	}
	
	if (Object.isString($show['Network'])) {
		var $network = new Element('li');
		$network.update('<span class="title">Network</span> ' + $show['Network']);
		$infoList.insert($network);
	}
	
	if (Object.isArray($show['Genre'])) {
		var $genres = new Element('li');
		var $genreString = '<span class="title">Genre</span> ';
		$show['Genre'].each(function(item, n) {
			if (n === 0) {
				$genreString += item;
			} else if (!item.blank()) {
				$genreString += ', ' + item;
			}
		});
		$genres.update($genreString);
		$infoList.insert($genres);
	}
	
	$top.insert($infoList);
	
	
	var $bottom = new Element('div', {
		'class' : 'bottom'
	});
	
	
	var $modalContent = $('modal-content');
	$modalContent.update($top);
	$modalContent.insert($bottom);
	
	// Add Images and Options
	var $sideBox = new Element('div', {
		'class' : 'side'
	});

	$sideBox.insert( {
		'top' : new Element('img', {
			'class' : 'box-art',
			'alt' : $('modal-inner').down('.title h1 span').innerHTML,
			'src' : '/img/boxart.png'
		})
	});

	// Options
	var $options = new Element('ul', {
		'id' : 'modal-options'
	});

	var $optionsLink = new Element('a', {
		'href' : '#/show/' + $show['SeriesName'].urlize() + 'options/'
	}).update('Show Options').observe('click', function(event) {
		event.stop();
	});

	$options.insert( {
		'top' : new Element('li').insert($optionsLink)
	});

	// Add Link
	if (!$('show-' + $show['id'])) {
		var $addLink = new Element('a', {
			'class' : 'add-link',
			'title' : 'Add show to your wall',
			'href' : '#/add/' + $show['SeriesName'].urlize(),
			'rel' : $show['id']
		}).update('Add Show to Wall').observe('click', function(event) {
			hideModal();
			var $seriesid = this.readAttribute('rel');
			onShowAdd($seriesid);
			window.location.hash = "#";
			event.stop();
		});

		$options.insert( {
			'bottom' : new Element('li', {
				'class' : 'add-link'
			}).insert($addLink)
		});
	} else {
		setModalColor($('show-' + $show['id']));
	}
	
	// Twitter
	var $twitterlink = new Element('a', {
		'href' : '#/show/' + $show['SeriesName'].urlize() + "/share/twitter",
		'title' : 'Share via Twitter'
	}).update('Twitter').observe('click', function(event) {
		shareOnTwitter();
		event.stop();
	});
	
	$options.insert( {
		'bottom' : new Element('li', {
			'class' : 'twitter'
		}).insert($twitterlink)
	});
	
	// Facebook
	var $facebooklink = new Element('a', {
		'href' : '#/show/' + $show['SeriesName'].urlize() + "/share/facebook",
		'title' : 'Share via Facebook'
	}).update('Facebook').observe('click', function(event) {
		shareOnFacebook();
		event.stop();
	});
	
	$options.insert( {
		'bottom' : new Element('li', {
			'class' : 'facebook'
		}).insert($facebooklink)
	});

	// TheTVDB
	var $tvdblink = new Element('a', {
		'href' : 'http://www.thetvdb.com/?tab=series&id=' + $show['id'],
		'title' : 'Go to TheTVDB page for this show'
	}).update('TheTVDB');

	$options.insert( {
		'bottom' : new Element('li', {
			'class' : 'thetvdb'
		}).insert($tvdblink)
	});

	$sideBox.insert( {
		'bottom' : $options
	});

	$modalContent.insert( {
		'top' : $sideBox
	});
	
	// Images
	if (Object.isString($show['poster'])) {
		var $message1 = new Message('img1', 'fetching cover image');
		$message1.priority = 3;
		addNotification($message1);
		
		var $imgRequest1 = 'php/getBanner.php?series=' + $show['id'].escapeHTML() + '&file=' + 
								$show['poster'].escapeHTML();
		new Ajax.Request($imgRequest1, {
			onSuccess : updateModalPoster,
			onFailure : function() {
				var $message = new Message('exception', "Error downloading image...");
				$message.type = 'error';
				addPopup($message);
			},
			onComplete : function() {
				removeNotification('img1');
			}
		});
	}
	if (Object.isString($show['fanart'])) {
		var $message2 = new Message('img2', 'fetching background image');
		$message2.priority = 3;
		addNotification($message2);
		
		var $imgRequest2 = 'php/getBanner.php?series=' + $show['id'].escapeHTML() + '&file=' + 
								$show['fanart'].escapeHTML();
		new Ajax.Request($imgRequest2, {
			onSuccess : updateModalBackground,
			onFailure : function() {
				var $message = new Message('exception', "Error downloading image...");
				$message.type = 'error';
				addPopup($message);
			},
			onComplete : function() {
				removeNotification('img2');
			}
		});
	}
	
	$('modal-inner').appear({
		queue : {
			position : 'end',
			scope : 'modal'
		},
		afterFinish: function() {
			updateModalTitle();			
		}
	});
}

function showShowInfo($id) {
	var $message = new Message('show-info', "fetching show info");
	$message.priority = 0;
	addNotification($message);
	
	var $request = 'php/getXML.php?series=' + $id.escapeHTML();
	new Ajax.Request($request, {
		onSuccess : onShowInfoResponse,
		onFailure : function(response) {
			$('modal-wrapper').hide();
			var $message = new Message('popup', "Error fetching show info...");
			$message.type = 'error';
			addPopup($message);
		},
		onComplete : function(response) {
			removeNotification('show-info');
		}
	});
}

function activateCell(item) {
	var $id = item.readAttribute('rel');
	showShowInfo($id);
	
	$('modal-inner').hide();
	$('modal-wrapper').show();
}

function onCellClick(event) {
	// TODO: someone clicks a cell
	var $article = Event.findElement(event, 'article');
	activateCell($article);
}

function onModalPosterClick(event) {
	var $eimg = $('modal-inner').down('.box-art.expanded');
	if (!$eimg) {
		$('modal-inner').insert({
			bottom : $('modal-inner').down('.side .box-art').clone()
					.addClassName('expanded').observe('click',
							onModalPosterClick).observe('mouseout',
							onModalPosterClick)
		});
	} else {
		$eimg.stopObserving();
		$eimg.remove();
	}
}

function updateModalPoster(response) {
	var $img = $('modal-content').down('.side .box-art');
	
	$img.writeAttribute('src', response.responseJSON['file'].unescapeHTML()).observe('click', onModalPosterClick);
}

function updateModalBackground(response) {
	var $modal = $('modal-content');

	var $img = new Element('div', {
		'class' : 'background'
	});

	$img.writeAttribute( {
		'style' : 'background-image: url("' + response.responseJSON['file']
				.unescapeHTML() + '");'
	});

	$modal.insert( {
		'top' : $img
	});
}

function updateModalTitle() {
	var $modal = $('modal-inner');
	var $fade = $modal.down('.fadet');
	
	if ($modal.visible()) {
	var $x = $modal.down('.title h1 span').getWidth();
	var $y = $modal.getHeight();

	if ($x > ($y + 10)) {
		if (!$fade) {
			$modal.down('.title').insert({
				top : new Element('span', {
					'class' : 'fadet'
				})
			});
		}
		
		$modal.down('.title h1').setStyle( {
			'paddingLeft' : ($x - $y + 10) + "px"
		});
	} else {
		if ($fade) {
			$fade.remove();
		}
		
		$modal.down('.title h1').setStyle( {
			'paddingLeft' : ""
		});
	}
	}
}

function updateCellImage(response) {
	var $show = cleanResponse(response.responseJSON);
	
	var $cellID = 'show-' + $show['SeriesID'];
	if ($($cellID)) {
		var $img = $($cellID).down('img');

		if ($img) {
			$img.writeAttribute({
				'src' : $show['file'].unescapeHTML()
			}).show().setOpacity(1).setStyle({
				  'width': 'auto'
			});
		}
	}
}

function addShow(response) {
	var $show = cleanResponse(response.responseJSON['Series']);
	
	var $cell = $$('#content article.empty').first();
	
	$cell.setOpacity(0);
	
	var $newID = 'show-' + $show['id'];
	
	$cell.removeClassName('empty');
	$cell.writeAttribute( {
		'id' : $newID,
		'rel' : $show['id']
	});
	
	// Clear the contents of the empty cell
	var $children = $cell.childElements();
	$children.each(function(item) {
		item.remove();
	});
	
	// Add the new contents
	// <a href="#" class="close" title="Remove this entry from your wall">x</a>
	$cell.insert(new Element('a', {
		href : '#/remove/' + $show['SeriesName'].urlize(),
		'class' : 'close',
		'title' : 'Remove this entry from your wall'
	}).update('x'));
	
	// <a href="#" class="link" title="More info on SERIES NAME">More info on SERIES NAME</a>
	var $infoText = 'More info on ' + $show['SeriesName'];
	$cell.insert(new Element('a', {
		href : '#/show/' + $show['SeriesName'].urlize(),
		'class' : 'link',
		'title' : $infoText
	}).update($infoText));
	
	// Show image
	//var $img = 'http://www.thetvdb.com/banners/' + $show['poster'];
	var $img = new Element('img', {
		'src' : '',
		'class' : 'tall-img'
	});
	$cell.insert($img);
	$img.setOpacity(0);
	
	// Meta
	var $meta = new Element('div', {
		'class' : 'meta'
	});
	
	$meta.insert(new Element('span', {
		'class' : 'fadel'
	}));
	$meta.insert(new Element('span', {
		'class' : 'fader'
	}));
	
	// Title
	// <h1><a href="#" title="More info on Series Name">Series Name</a></h1>
	var $h1Link = new Element('a', {
		href : '#/show/' + $show['SeriesName'].urlize(),
		'title' : $infoText
	}).update($show['SeriesName']);
	var $header = new Element('h1');
	
	$header.insert($h1Link);
	$meta.insert($header);
	
	// <p class="description"><a href="#" title="More info on SERIES NAME">OVERVIEW</a></p>
	if (Object.isString($show['Overview'])) {
		var $descriptionLink = new Element('a', {
			href : '#/show/' + $show['SeriesName'].urlize(),
			'title' : $infoText
		}).update($show['Overview'].truncate(64, '...'));
		var $description = new Element('p', {
			'class' : 'description'
		});

		$description.insert($descriptionLink);
		$meta.insert($description);
	}
	
	$cell.insert($meta);
	
	// Only request the image after the article is in place
	if (Object.isString($show['poster'])) {
		var $message = new Message('img', 'fetching image');
		$message.priority = 4;
		addNotification($message);
		
		var $imgRequest = 'php/getBanner.php?series=' + $show['id'].escapeHTML() + '&file=' + 
							$show['poster'].escapeHTML();
		new Ajax.Request($imgRequest, {
			onSuccess : updateCellImage,
			onFailure : function(response) {
				var $message = new Message('exception', "Error downloading image...");
				$message.type = 'error';
				addPopup($message);
			},
			onComplete : function(response) {
				removeNotification('img');
			}
		});
	}
	
	new Effect.Opacity($newID, {
		from : 0,
		to : 1.0,
		duration : 0.8,
		queue : {
			position : 'end',
			scope : $newID
		}
	});
	
	// Add show to storage
	addShowToStorage($show['id']);
	
	addEmptyCell();
	setColors();
	resizeContent();
	updateScrollBar();
	moveScrollBar(100);
}

//Remove a cell from the wall
function onRemoveComplete(obj) {
	// Update the counters
	updateCounters();

	setColors();
	resizeContent();
	updateScrollBar();
	removeNotification('remove');
}

function moveBack(origin, destiny) {
	var $classes = $w(destiny.className);
	
	new Effect.Opacity(destiny.identify(), {
		from : 1.0,
		to : 0,
		duration : 0.2,
		queue : {
			position : 'end',
			scope : 'cells'
		},
		afterFinish: function(obj) {
			var $new = origin.clone(true);
			
			$new.removeClassName('wide');
			$new.removeClassName('tall');
			$new.removeClassName('square');
			$classes.each(function(item) {
				$new.addClassName(item);
			});
			
			$new.setOpacity(0);

			destiny.replace($new);

			//$new.show();
			new Effect.Opacity($new.identify(), {
				from : 0,
				to : 1.0,
				duration : 0.2,
				queue : {
					position : 'end',
					scope : 'cells'
				}
			});
		}
	});
}

function closeCellClick(event) {
	var $cell = Event.findElement(event, 'article');
	removeCell($cell);
	window.location.hash = "#";
	event.stop();
}

function removeCell($cell) {
	addNotification(new Message('remove', 'Removing...'));
	
	var $found = false;

	var $previous = $cell;

	// Remove show from storage
	removeShowFromStorage($cell.readAttribute("rel"));
	
	$$('#content article').each(function(item) {
		if ($found) {
			moveBack(item, $previous);
			$previous = item;
		}

		if (item === $cell) {
			$found = true;
		}
	});

	// Remove the last one
	new Effect.Opacity($previous.identify(), {
		from : 1.0,
		to : 0,
		duration : 0.2,
		queue : {
			position : 'end',
			scope : 'cells'
		},
		afterFinish: function(obj) {
			$previous.remove();
			onRemoveComplete();
		}
	});
}


