
// whack.
// from http://groups.google.com/group/jquery-en/browse_thread/thread/e0d6c199552dd1f7/2f05ad6d400dd962?lnk=gst&q=array+sorting#2f05ad6d400dd962
jQuery.fn.sort = function() { 
  return this.pushStack( [].sort.apply( this, arguments ), []); 
}; 

//function CarouselReleaseView(releasediv, releaseModel)
function CarouselReleaseView(settings, player, overrideDiv)
{
	this.Player= player;
	this.ReleaseDIV= $('#'+settings.releaseDiv);
	this.LastCategory= null;
	this.LastSearch= null;
	this.LastAuthenticated= false;
	if(overrideDiv != undefined) {
		this.ReleaseDIV= $("#"+overrideDiv);
	}

	// generate a unique id
	var carouselCount= 0;
	do {
		this.ReleaseGalleryID= 'mygallery'+carouselCount;
		carouselCount++;
	} while($('#'+this.ReleaseGalleryID).length > 0);

	// now save it...
	$(".stepcarousel", this.ReleaseDIV).attr("id", this.ReleaseGalleryID);

	// for closures.	
	var releaseView= this;
	
	// now required for the tab browsing.
	this.SetModel= function(model) {
		this.Model= model;
	};
	
	this.SyncToCurrentRelease= function(model) {
		// set a now-playing or something if it's in the release view (FIXME)
	};
	
	this.DisplayLoading= function(model) {
		var releaseView= this;

		if(this.NeedsFullReload(model))
		{
			var contentsBelt= $(".belt", this.ReleaseDIV);
			contentsBelt.empty();
			
			contentsBelt.css('width', '920px');
			$('<div class="loading-graphic"/>').appendTo(contentsBelt);		
		}
	};
	
	this.NeedsFullReload= function(model) {
		return (this.LastCategory != model.CurrentCategory || 
		   this.LastSearch != model.SearchField ||
		   this.LastAuthenticated != this.Player.WebService.Authenticated());
	};

	this.Refresh= function(model) {
		// load them...
		var contentsBelt= $(".belt", this.ReleaseDIV);

		// Build the releases...
		var episodeOrPreview= "Preview";
		if(!settings.requireLogin || this.Player.WebService.Authenticated()) {
			episodeOrPreview= "Episode";
		}
		
// alert("Total Count: "+model.TotalCount+" Release Length: "+model.Releases.length);

		if(this.NeedsFullReload(model))
		{
			// empty the carousel
			contentsBelt.empty();

			if(model.TotalCount==0) {
				contentsBelt.css('width', '920px');
				$('<div class="no-results">No matches found.</div>').appendTo(contentsBelt);
			} else {
				var ii;
				
				this.EpisodeMap= new Array(model.TotalCount);
				for(ii= 0; ii<this.EpisodeMap.length; ii++)
				{
					this.EpisodeMap[ii]= null;
				}
		
				// add all the "loading" images...
				for(ii= 0; ii<this.EpisodeMap.length; ii++)
				{
					var str= '<div class="release-item">';
	
					str += '<div class="play-button-hover" style="visible: false" >';
					str += '<a class="play"><img src="../images/btn-play-big.png" height="32" width="33" border="0"/></a>';
					str += '<a class="info_hover">';
					str += '<img src="images/loaderA32.gif" class="thumbnail" border="0" alt="Loading..." width="32" height="32" '+
						'title="" style="width: 32px; height: 32px; margin-left: 56px; margin-top: 24px;"/>';
					str += '</a>';
					str += '</div>';
					str += '<p style="text-align: center">Loading...</p>';
	
					str+= "</div>";
					$(str).appendTo(contentsBelt);
				}
	
				// build them... (only the first time)
				stepcarousel.reload(this.ReleaseGalleryID, true);
			}
			
			// and remember
			this.LastCategory= model.CurrentCategory;
			this.LastSearch= model.SearchField;
			this.LastAuthenticated= this.Player.WebService.Authenticated();
		}

//var xx= "Start Index: "+model.StartIndex+" end: "+model.EndIndex()+"\n";		
		// now add the episodes to the EpisodeMap...
		for(ii= 0; ii<model.Releases.length; ii++)
		{	
			if(!this.EpisodeMap[(model.StartIndex-1)+ii])
			{
				var item= {};
				item.release= model.Releases[ii];
				item.is_new= true;
				this.EpisodeMap[(model.StartIndex-1)+ii]= item;
			}
		}
//for(var ii= 0; ii<this.EpisodeMap.length; ii++) {
//xx+= "["+ii+"] => "+this.EpisodeMap[ii]+"\n";
//}
//alert(xx);
				
		// now update the carousel
		$("div.release-item", contentsBelt).each(function(ii) {
			// don't have to do this unless it was just added...
			if(releaseView.EpisodeMap[ii] && releaseView.EpisodeMap[ii].is_new) {
				var release= releaseView.EpisodeMap[ii].release;
				var thumb_dimensions= release.td.split('-');
//				var leftOffset= Math.floor((160-parseInt(thumb_dimensions[0]))/2) - 7; // fudge; fix later.
//				var topOffset= Math.floor((80-parseInt(thumb_dimensions[1]))/2);
			
				// clone the release template item...
				$(this).html($('.release-template > *', releaseView.releaseDIV).html());
			
				var containerWidth= parseInt($('.play-button-hover', $(this)).css('width'));
				var containerHeight= parseInt($('.play-button-hover', $(this)).css('height'));
				var leftOffset= Math.floor((containerWidth-parseInt(thumb_dimensions[0]))/2);
				var topOffset= Math.floor((containerHeight-parseInt(thumb_dimensions[1]))/2);

			
				// select the last one...
				// it'll have the "template" class on it. so we replace that one's data, then remove the template class
				$('.thumbnail', $(this)).attr('src', release.thumbnailURL);
				$('.thumbnail', $(this)).attr('alt', release.title);
				$('.thumbnail', $(this)).attr('width', thumb_dimensions[0]);
				$('.thumbnail', $(this)).attr('height', thumb_dimensions[1]);
				$('.thumbnail', $(this)).css({
					'width': thumb_dimensions[0]+'px', 
					'height': thumb_dimensions[1]+'px', 
					'margin-left': leftOffset+'px',
					'margin-top': topOffset+'px'});
				$('.title', $(this)).html(release.title);
				$('.author', $(this)).html(release.author);
				$('.duration', $(this)).html(releaseView.Model.DurationString(release.length));
				$('.type', $(this)).html(episodeOrPreview);
				$('.description', $(this)).html(release.description);
	 			if(typeof(release.series) != 'undefined') $('.series', $(this)).html(release.series);
 				if(typeof(release.series_thumbnail) != 'undefined') $('.series_thumbnail', $(this)).attr('src', release.series_thumbnail);
				
				// add the info hover..
				if(settings.releaseViewShowsHoverBalloons) {
					$('.info_hover', $(this)).attr('title', release.title+'|'+release.description);
					$('.info_hover', $(this)).cluetip({
						arrows: true,
						splitTitle: '|'
					});
				}

/*			
				var str= '';
				str += '<div class="play-button-hover" style="visible: false" >';
				str += '<a class="play"><img src="../images/btn-play-big.png" height="32" width="33" border="0"/></a>';
				str += '<a class="info_hover">';
				str += '<img src="'+release.thumbnailURL+'" class="thumbnail" border="0" alt="'+release.title+
					'" width="'+thumb_dimensions[0]+
					'" height="'+thumb_dimensions[1]+'" title="" '+
					'style="width: '+thumb_dimensions[0]+'px; height: '+thumb_dimensions[1]+'px;'+
					' margin-left: '+leftOffset+'px; '+
					' margin-top: '+topOffset+'px; '+
					'"/>';
				str += '</a>';
				str += '</div>';
				str += '<a class="info_hover release_title">'+release.title+'</a>';
				str += '<span class="video-info">'+episodeOrPreview+
						'&nbsp;&nbsp;&nbsp;('+model.DurationString(release.length)+')</span>';
*/
				$(this).attr('id', release.EpisodeCode+'-'+release['sort-field']);
//				$(this).html(str);
							
				// hide the play buttons..
				$('.play', this).hide();
				$('.play-button-hover', this).hover(
					function() { 
						$(".play", this).show(); 
					}, 
					function(){ 
						$(".play", this).hide(); 
					});

				// bind the play button
				$("div.play-button-hover", this).bind("click", function(e) {
					var theID= $(this).parents("div.release-item").attr('id').split('-')[0];
					for(var ii= 0; ii<model.Releases.length; ii++)
					{
						var release= model.Releases[ii];
						if(release.EpisodeCode==theID)
						{
							player.SetCurrentRelease(release);
							break;
						}
					}
				});

				$("a.release_title", this).bind("click", function(e) {
					var theID= $(this).parents("div.release-item").attr('id').split('-')[0];
					for(var ii= 0; ii<model.Releases.length; ii++)
					{
						var release= model.Releases[ii];
						if(release.EpisodeCode==theID)
						{
							player.SetCurrentRelease(release);
							break;
						}
					}
				});

				
				// don't do this one again...
				releaseView.EpisodeMap[ii].is_new= false;
			}
		});

/*				
		// hide the play buttons..
		$('.play', contentsBelt).hide();
		$('.play-button-hover', contentsBelt).hover(function() { $(".play", this).show(); }, function(){ $(".play", this).hide(); })

		$("div.play-button-hover", contentsBelt).bind("click", function(e) {
			var theID= $(this).parent("div.release-item").attr('id').split('-')[0];
			for(var ii in model.Releases)
			{
				var release= model.Releases[ii];
				if(release.EpisodeCode==theID)
				{
					player.SetCurrentRelease(release);
					break;
				}
			}
		});

		$("a.release_title", contentsBelt).bind("click", function(e) {
			var theID= $(this).parent("div.release-item").attr('id').split('-')[0];
			for(var ii in model.Releases)
			{
				var release= model.Releases[ii];
				if(release.EpisodeCode==theID)
				{
					player.SetCurrentRelease(release);
					break;
				}
			}
		});
*/		
		// add the sort orders...
		$('ul.sort-order', this.ReleaseDIV).empty();
		/*
		$('ul.sort-order', this.ReleaseDIV).html('<b>Sort by:</b>');
		for(var ii in model.SortFields) {
			if(ii==0) { // assume initially sorted by the first field.
				$('<li class="active">'+model.SortFields[ii]+'</li>').appendTo($('ul.sort-order', this.ReleaseDIV));
			} else {
				$('<li>'+model.SortFields[ii]+'</li>').appendTo($('ul.sort-order', this.ReleaseDIV));
			}
		}
		*/

		$(".sort-order > li", this.ReleaseDIV).each(function (pos) 
		{	
			$(this).bind("click", function(e) {
				$(".release-item", releaseView.ReleaseDIV).sort(function(a,b){ 
					var part_index= pos+1;
					var a_parts= a.id.split('-');
					var b_parts= b.id.split('-');
			
					// 0 is code, 1 is airdate, 2 is most pop today, 3 is most pop all time, 4 is user rating
					return a_parts[part_index] > b_parts[part_index] ? 1 : -1;
				}).remove().appendTo(".belt"); 

				// reload...
				stepcarousel.reload(releaseView.ReleaseGalleryID, true);

				// and change the style of the li so that it is "current"
				$(this).siblings().removeClass("active");
				$(this).addClass("active");
		
				// rebind the button hovers...
				$('.play', releaseView.ReleaseDIV).hide();
				$('.play-button-hover', releaseView.ReleaseDIV).hover(
					function() { $(".play", this).show(); }, 
					function(){ $(".play", this).hide(); }
				);
			});
		});
	};
	
//	|< < [n] of N >
function NewHuluBuildPageIndexer(
		sortContainer,
		firstItem,
		itemsPerPage,
		totalItems,
		nextFunction,
		prevFunction,
		gotoFunction,
		userData)
	{
		var pageSections= 3;
		var pageIndex= Math.floor(firstItem/itemsPerPage)+1;
		var pageCount= Math.floor(totalItems/itemsPerPage) + ((totalItems%itemsPerPage)?1:0);
		var startIndex= Math.max(pageIndex-1, 1);
		var endIndex= Math.min(startIndex+pageSections-1, pageCount);
	//alert("First:"+firstItem+ " IPP: "+itemsPerPage+" Total: "+totalItems+" Start: "+startIndex+" End: "+endIndex+" Page Index: "+pageIndex);
//		var sortContainer= $(containerDiv);
		sortContainer.empty();
		$('<li><span class="first">&nbsp;</span></li>').appendTo(sortContainer);
		$('<li><span class="prev">&nbsp;</span></li>').appendTo(sortContainer);
		$('<li class="goto"><input autocomplete="off" name="page" type="text" value="'+pageIndex+'"/></li>').appendTo(sortContainer);
		$('<li class="max_pages">of '+pageCount+'</li>').appendTo(sortContainer);
		$('<li><span class="next">&nbsp;</span></li>').appendTo(sortContainer);

		$('input', sortContainer).keydown(function(event) {
			if(event.keyCode == 13) {
				var pg= parseInt($(this).val(), 10);
				if(pg>=1 && pg<=pageCount) {
					gotoFunction(userData, pg);
				} else {
					$(this).val(pageIndex);
					$(this).select();
				}
			}
		});

		sortContainer.children("li").bind("click", 
			function(e) {
				if($(this).hasClass('goto') || $(this).hasClass('max_pages')) {
					// the text input one.  don't do anything.
					$('input', $(this)).select();
					return false;
				} else {
					var sp= $('span', $(this));
					if(sp.hasClass('prev')) {
						prevFunction(userData);
					} else if(sp.hasClass('next')) {
						nextFunction(userData);
					} else if(sp.hasClass('first')) {
						gotoFunction(userData, 1);
					}					
				}
			}
		);
	};

	
	// now perform setup code...
	stepcarousel.setup({
		galleryid: this.ReleaseGalleryID, //id of carousel DIV
		beltclass: 'belt', //class of inner "belt" DIV containing all the panel DIVs
		panelclass: 'release-item', //class of panel DIVs each holding content
//		fixed_panel_width: 160, 
		fixed_panel_width: 188, 
		onslide: function() {
			/*
			$(".debug").empty();
			for(xx in this) {
				$(".debug").text($(".debug").text() + 'this['+xx+']=> '+this[xx]+'\n');
			
			}
			alert('Panel Count: '+this['$panels'].length+' First: '+this['currentpanel']+' Last: '+this['lastvisiblepanel']);
			*/
			var gallery_id= this['galleryid'];
			var config=stepcarousel.configholder[gallery_id];
			var firstPanel= parseInt(this['currentpanel'], 10);
			var totalPanels= this['$panels'].length;
			var panelsPerPage= config.defaultbuttons.moveby;
			var pageSections= 3;
	
			/*
			$(".debug").empty();
			$(".debug").text(
				' First Panel: '+firstPanel+ 
				' Page Index: '+pageIndex+ 
				' Panels Per Page: '+panelsPerPage+
				' PageCount: '+pageCount+
				' Total Panels: '+totalPanels+
				' Start: '+startIndex+
				' End: '+endIndex);
			*/
			var sorter= $('.sort-nav', releaseView.ReleaseDIV);
//			Utilities.BuildPageIndexer(sorter, firstPanel, panelsPerPage, totalPanels, 
			NewHuluBuildPageIndexer(sorter, firstPanel, panelsPerPage, totalPanels, 
				function(userData) { // next function
					if(stepcarousel.stepBy(gallery_id, panelsPerPage))
					{
						releaseView.Model.NextPage();
					}
				},
				function(userData) { // prev function
					if(stepcarousel.stepBy(gallery_id, -panelsPerPage))
					{
						releaseView.Model.PrevPage();
					}
				},
				function(userData, page) { // goto function
					var panel_index= ((page-1)*panelsPerPage)+1;
					if(stepcarousel.stepTo(gallery_id, panel_index))
					{
						releaseView.Model.SetStartIndex(panel_index);
					}
				},
				this);
		},
		autostep: {enable:false, moveby:1, pause:3000},
		panelbehavior: {speed:500, wraparound:false, persist:false},
		defaultbuttons: {enable: false, moveby: settings.itemsPerPage, 
			leftnav: ['http://i34.tinypic.com/317e0s5.gif', -5, 40], 
			rightnav: ['http://i38.tinypic.com/33o7di8.gif', -20, 40]},
	//	statusvars: ['statusA', 'statusB', 'statusC'], //register 3 variables that contain current panel (start), current panel (last), and total panels
		contenttype: ['inline'] //content setting ['inline'] or ['external', 'path_to_external_file']
	});
}
