/**
 * This is the class for our fancypants search field that lives at the 
 * top of e'ery page.
 */
BLIP.Class.create("BLIP.Unit.SearchField", BLIP.Unit, 
	function(config) {
		this.onOpened = config.onOpened;

		BLIP.Unit.call(this, config);
	},
	{
		selector: ".SearchHeader",

		init: function () {
			if ($.browser.msie && parseInt($.browser.version, 10) === 8) {
				return;
			}

			this.searchForm = $(this.selector);
			this.searchField = this.searchForm.children('input');
			this.initContents();
			this.initEvents();

			// Someone typed something in before we were loaded up
			if (this.searchField.val() !== "") {
				this.list.append($('<li class="Loading">Loading...</li>'));
				this.search();
				this.searchForm.addClass('Open');
				this.results.show();

				if (this.onOpened) {
					this.onOpened();
				}
			}
		},

		initContents: function () {
			if (!this.results) {
				this.results = $('<div class="SearchResults" style="display: none;"></div>');
				this.list = $('<ul></ul>');

				if ($('#Logout').length > 0) {
					this.results.addClass("LoggedIn");
				}

				this.results.append(this.list);

				this.searchForm.parent()
					.append($('<div class="Clear"></div>'))
					.append(this.results);
			}
		},

		initEvents: function () {
			var thisContext = this;

			this.searchField.keyup(this.delegate(this.onKeyUp));
			this.searchField.keydown(this.delegate(this.onKeyDown));
			this.searchField.keypress(this.delegate(this.onKeyDown));
			$('body').live('click', this.delegate(this.onClickOutside));
		},

		marquee: function (e) {

		},

		onKeyDown: function (e) {
			if ((e.keyCode === '13' || e.keyCode === 13) && this.searchField.val().match(/inception/i)) {
				e.preventDefault();
				this.bwah();
				return false;
			}


			if ((e.keyCode === '13' || e.keyCode === 13) && this.list.children('.Selected').length > 0) {
				e.preventDefault();
				window.location = this.list.children('li.Selected').children('a').attr('href');
			}

			return false;
		},

		/**
		 * moveDown() moves our selector down one row. If nothing is selected,
		 * it selects the first row.
		 */
		moveDown: function () {
			var currentlySelected;

			if (this.list.children('li.Selected').length === 0) { // nothing is selected
				this.list.children('li.Selectable:first').trigger('mouseover');
			}
			else {
				currentlySelected = this.list.children('.Selected');
				currentlySelected.nextAll('li.Selectable:first').trigger('mouseover');
			}

			this.onSelectedChange();
		},

		/**
		 * moveUp() moves our selector up one row. If nothing is selected, 
		 * it selects the last row.
		 */
		moveUp: function () {
			var currentlySelected;

			if (this.list.children('li.Selected').length === 0) { // nothing is selected
				this.list.children('li.Selectable:last').trigger('mouseover');
			}
			else {
				currentlySelected = this.list.children('.Selected');
				currentlySelected.prevAll('li.Selectable:first').trigger('mouseover');
			}

			this.onSelectedChange();
		},

		onKeyUp: function (e) {
			if (this.searchField.val() === "") {
				return false;
			}

			if (e.which === 38 || e.which === 40) { // don't search on arrow events	
				if (e.which === 40) { //down
					this.moveDown();
				}
				else if (e.which === 38) { // up
					this.moveUp();
				}
				
				return false;
			}

			if (e.which === 13) {
				return false;
			}

			if (!this.hasReceivedResultsOnce && $('.Loading').length === 0) {
				this.list.append($('<li class="Loading">Loading...</li>'));
			}

			clearTimeout(this.timeout);
			this.timeout = setTimeout(this.delegate(this.search), 500);

			this.searchForm.addClass('Open');
			this.results.show();
			if (this.onOpened) {
				this.onOpened();
			}
		},

		search: function () {
			var searchTerm = this.searchField.val();

			if (searchTerm === "") {
				this.searchForm.removeClass('Open');
				this.results.hide();
				return;
			}

			$.get('/search/get_auto_complete', {
				q: searchTerm,
				no_wrap: 1
			}, this.delegate(this.onSearchResponse),
				'json'
			);
		},

		clearResultList: function () {
			this.list.children('li').each(function () {
				$(this).remove();
			});
		},

		removeLoadingText: function () {
			this.list.children('.Loading').each(function () {
				$(this).remove();
			});
		},

		searchUrlFor: function (str) {
			return "/search?q=" + str;
		},

		noResults: function () {
			var item = $('<li class="NoResults"></li>'),
					link = $('<a>No immediate results. You need to go deeper.</a>');

			this.clearResultList();

			link.attr('href', this.searchUrlFor(this.searchField.val()));

			link.click(this.delegate(this.inceptionCheck));

			item.append(link);
			this.list.append(item);
		},

		inceptionCheck: function (event) {
			if (typeof(HTMLVideoElement) !== "undefined" && this.searchField.val().match(/inception/i)) {
				event.stopPropagation();
				event.preventDefault();
				this.bwah();
				return false;
			}
		},

		bwah: function (callback) {
			var thisContext = this,
					host = document.location.hostname.indexOf("blip.tv") > -1 ? "http://a.blip.tv" : ""; // use CDN in prod

			$('body')
				.append($('<video src="' + host + '/uploadedFiles/inception.m4v" style="display: none;" id="BWAH" volume="0.5"></video>'));

			$('#BWAH')[0].addEventListener("ended", function () {
				window.location = thisContext.searchUrlFor(thisContext.searchField.val());
			});

			$('#BWAH')[0].play();
		},

		onSearchResponse: function (data) {
			var show,
					channel;

			this.hasReceivedResultsOnce = true;
			this.clearResultList();
			this.removeLoadingText();

			if (data.shows.length === 0 && data.channels.length === 0) {
				this.noResults();
				return;
			}

			for (channel in data.channels) {
				if (!data.channels.hasOwnProperty(channel) || !data.channels[channel]) {
					continue;
				}

				this.addChannelToResults(data.channels[channel], channel === "0");
			}

			for (show in data.shows) {
				if (!data.shows.hasOwnProperty(show) || !data.shows[show].name) {
					continue;
				}

				this.addShowToResults(data.shows[show], data.channels.length === 0);
			}

			//this.createSearchMoreShowsResult();

			this.createAllResults();

			this.list.children('li.Selectable:first').addClass('Selected');
		},

		createSearchMoreShowsResult: function () {
			var more = $('<li class="clearfix MoreResults"></li>'),
					link = $('<a>See more show results</a>');

			link.attr('href', '/search?q=' + this.searchField.val());

			more.append(link);

			this.list.append(more);
		},

		addShowToResults: function (show, first) {
			var firstRow = $('<li class="clearfix Selectable"></li>'),
					secondRow = $('<li class="clearfix Selectable Last"></li>'),
					showName = $('<div class="ShowName"></div>'),
					showNameOverflowWrapper = $('<div class="ShowNameOverflowWrapper"></div>'),
					showNameWrapper = $('<div class="ShowNameWrapper"></div>'),
					showNameSizeSpanWrapper = $('<span></span>'),
					showPageLink = $('<a>Visit Show Page</a>'),
					latestEpisodeLink = $('<a>Watch Latest Episode</a>'),
					thisContext = this;

			if (!first) {
				firstRow.addClass('Separator');	
			}

			showNameSizeSpanWrapper.html(show.name);
			showPageLink.attr('href', show.page_url);
			latestEpisodeLink.attr('href', show.episode_url);

			showName.append(showNameSizeSpanWrapper);
			
			showNameOverflowWrapper.append(showName);

			showNameWrapper.append(showNameOverflowWrapper);

			firstRow
				.append(showNameWrapper)
				.append(showPageLink);

			secondRow
				.append($('<div class="ShowNameWrapper" style="display: none;"><div class="ShowNameOverflowWrapper"><div class="ShowName"><span>' + show.name+ '<span></div></div></div>'))
				.append(latestEpisodeLink);

			firstRow.mouseover(function (e, item) {
				thisContext.onRowOver(this);
				thisContext.onSelectedChange();
			});

			//secondRow.mouseover(this.onRowOver);
			secondRow.mouseover(function (e, item) {
				thisContext.onRowOver(this);
				thisContext.onSelectedChange();
			});

			firstRow.mouseout(this.onRowOut);
			secondRow.mouseout(this.onRowOut);

			firstRow.click(function () {
				window.location = showPageLink.attr('href');
				return false;
			});

			secondRow.click(function () {
				window.location = latestEpisodeLink.attr('href');
				return false;
			});

			this.list
				.append(firstRow)
				.append(secondRow);
		},

		addChannelToResults: function (channel, first) {
			var row = $('<li class="clearfix Selectable Channel Last"></li>'),
					name = $('<div class="ShowName"></div>'),
					channelNameWrapper = $('<div class="ShowNameWrapper"></div>'),
					channelOverflowWrapper = $('<div class="ShowNameOverflowWrapper"></div>'),
					link = $('<a>Visit Category</a>'),
					thisContext = this;

			name.html(channel.name);
			link.attr('href', channel.page_url);

			row.click(function () {
				window.location = link.attr('href');
			});

			if (!first) {
				row.addClass('Separator');
			}

			channelOverflowWrapper.append(name);

			channelNameWrapper.append(channelOverflowWrapper);

			row	
				.append(channelNameWrapper)
				.append(link);

			row.mouseover(function () {
				thisContext.onRowOver(this);
				thisContext.onSelectedChange();
			});

			row.mouseout(this.onRowOut);

			this.list.append(row);
		},

		/**
		 * onRowOver handles the logic for when the mouse moves
		 * over a row in the search results list. We need to
		 * select it and possible move a show title.
		 */
		onRowOver: function (context) {
			var row = $(context);

			row.siblings('.Selected').removeClass('Selected');
			row.addClass('Selected');

			// Don't do anything fancy if we're dealing with channels.
			if (row.hasClass('Channel')) {
				return;
			}

			// Move the show title up and down if we're dealing with shows
			if (row.hasClass('Last')) {
				row.children('.ShowNameWrapper').show();
				row.prev().children('.ShowNameWrapper').hide();
			}
			else {
				row.children('.ShowNameWrapper').show();
				row.next().children('.ShowNameWrapper').hide();
			}
		},

		onSelectedChange: function () {
			var selected = this.list.children('.Selected');

			if (selected.hasClass('Channel')) {
				return;
			}

			if (selected.hasClass('Last')) {
				selected.prev().children('span.ShowNameWrapper').hide();
				selected.children('span.ShowNameWrapper').show();
			}
			else {
				selected.next().children('span.ShowNameWrapper').hide();
				selected.children('span.ShowNameWrapper').show();
			}


			// LEFTOFF This needs to be cleaned up and abstracted out into separate
			// methods
			/*
			if (selected.find('.ShowName span').width() >= 120) {
				selected.find('.ShowName').animate({
						left: '-220px',
					}, 2000, 'linear',
					function () {
						selected.find('.ShowName').animate({
							left: '0px',
						}, 2000, 'linear');
					}
				);
			}
			*/
		},

		onRowOut: function () {
			$(this).removeClass('Selected');
		},

		addChanneltoResults: function (channel) {

		},

		createAllResults: function () {
			var all = $('<li class="clearfix AllResults"></li>'),
					link = $('<a>See all results</a>');

			link.attr('href', '/search?q=' + this.searchField.val());

			all.append(link);

			this.list.append(all);
		},

		onClickOutside: function (e) {
			if (this.clickOutside(e)) {
				this.close();
				//this.hasReceivedResultsOnce = false;
			}
		},

		close: function () {
			this.results.hide();
			this.searchForm.removeClass('Open');
			this.clearResultList();
			this.hasReceivedResultsOnce = false;
		},

		clickOutside: function (e) {
			if (e.clientX > this.searchField.offset().left && e.clientY > this.searchField.offset().top && 
				e.clientX < this.searchField.offset().left + this.searchField.width() && 
				e.clientY < this.searchField.offset().top + this.searchField.height()) {
				return false;
			}

			if (this.results) {
				if (e.clientX > this.results.offset().left && e.clientY > this.results.offset().top && 
					e.clientX < this.results.offset().left + this.results.width() && 
					e.clientY < this.results.offset().top + this.results.height()) {
					return false;
				}
			}

			return true;
		}
	}
);

