/*
 * *********************************************************************************************************
 * 
 * WILDSIDE MEDIA PLAYER - JAVASCRIPT MODULE
 * 
 * *********************************************************************************************************
 * 
 * The object you see below is a singleton that handles all the player-playlist interaction for the extension.
 * You shouldn't alter this file, but you can overwrite properties or entire functions by doing something
 * like this:
 * 
 * tx_wsmediaplayer.settings.playlistFrame = ".someOtherClassName";
 * 
 * or
 * 
 * tx_wsmediaplayer.events.onPlay = function() { alert("lol"); };
 * 
 * If you instantiate your own functions AFTER this file has been loaded, for example inside the templates,
 * you should have no trouble... but I've done my best to make this thing as flexible as possible, so you
 * could do much just by editing the CSS.
 * 
 * I've commented the tricky parts; the rest should be easily digested if you know your javascript syntax.
 * 
 */


var tx_wsmediaplayer = {
	
	settings : {
		autostart : false,
		hidePlaylist : false,
		forcedID : 0,
		defaultID : 0,
		selectors : {
			playlistFrame : ".playlistFrame",
			playlistEntry : ".playlistEntry",
			playlistIDprefix : "playlistEntry_"
		},
		repeatMode : "list",
		shuffleMode : false,
		apiURL : false,
		labels : {
			tooManyPlayers : ""
		}
	},
	
	jQueryWarned : false,
	
	tooManyPlayersWarningIssued : false,
	playerInstantiated : false,
	
	hasPlaylist : false,
	listPlayCount : {},
	forceStop : false,
	
	knownFileList : {},
	knownFileCount : {},
	knownPlaylists : [],
	
	playingFrom : false,
	
	events : {
		
		onPlay : function() {
			if (tx_wsmediaplayer.hasPlaylist) {
				jQuery(".tx-wsmediaplayer-pi2 " + tx_wsmediaplayer.settings.selectors.playlistFrame + " .active").removeClass("paused loading").addClass("playing");
			};
		},
		
		onPause : function() {
			if (tx_wsmediaplayer.hasPlaylist) {
				jQuery(".tx-wsmediaplayer-pi2 " + tx_wsmediaplayer.settings.selectors.playlistFrame + " .active").removeClass("playing loading").addClass("paused");
			};
		},
		
		onComplete : function() {
			if (tx_wsmediaplayer.hasPlaylist) {
				
				// If the playlist has been hidden, show it now.
				if (tx_wsmediaplayer.settings.hidePlaylist) {
					jQuery(".tx-wsmediaplayer-pi2 .playlistFrame").fadeIn();
					tx_wsmediaplayer.settings.hidePlaylist = false;
				};
				
				var selItem = jQuery("#" + tx_wsmediaplayer.playingFrom + " " + " .active");
				selItem.removeClass("playing paused loading");
				
				if (!tx_wsmediaplayer.forceStop) {
				
					// Find out what we should do next, based on the repeat-settings
					switch (tx_wsmediaplayer.settings.repeatMode) {
						case "none":
							// Do not start another video - the user needs to do that himself.
							break;
						case "list":
							// If shuffle-mode is on, skip to random - otherwise just load the next video.
							if (tx_wsmediaplayer.settings.shuffleMode) {
								// Jump to random, but not if the entire list has been played by now (that's what "true" does)
								tx_wsmediaplayer.skipToRandomInPlaylist(true);
							} else {
								tx_wsmediaplayer.skipToNextInPlaylist();
							};
							break;
						case "always":
							// If shuffle-mode is on, skip to random - otherwise just load the next video.
							if (tx_wsmediaplayer.settings.shuffleMode) {
								tx_wsmediaplayer.skipToRandomInPlaylist();
							} else {
								tx_wsmediaplayer.skipToNextInPlaylist();
							};
							break;
						case "single":
							// Repeat the file that's already been played.
							tx_wsmediaplayer.loadPlaylistEntry.call(selItem);
							break;
					};
				};
			};
		},
		
		onError : function(e) {
			if (e.error) {
				alert(e.error);
			};
			tx_wsmediaplayer.forceStop = true;
			return false;
		}
		
	},
	
	skipToNextInPlaylist : function() {
		
		if (tx_wsmediaplayer.knownFileCount[tx_wsmediaplayer.playingFrom]) {
			
			// Find previously selected entry, if any.
			var sel = jQuery("#" + tx_wsmediaplayer.playingFrom + " " + " .active");
			var nextVideo = "";
			if (sel.length) {
				// A video is already active - get the entry after it.
				nextVideo = sel.next();
				
				if (!nextVideo.length) {
					// No video was selected - we must be at the end of the list. Will the repeat-settings allow us to start from the top?
					if (tx_wsmediaplayer.settings.repeatMode == "always") {
						// Start over.
						nextVideo = jQuery("#" + tx_wsmediaplayer.playingFrom + " " + " " + tx_wsmediaplayer.settings.selectors.playlistEntry + ":visible:first");
					};
				};
			} else {
				// No video is active, so we'll start from the top.
				nextVideo = jQuery("#" + tx_wsmediaplayer.playingFrom + " " + " " + tx_wsmediaplayer.settings.selectors.playlistEntry + ":visible:first");
			};
			
			if (nextVideo.length) {
				tx_wsmediaplayer.loadPlaylistEntry.call( nextVideo );
			};
			
		};
		
	},
	
	skipToRandomInPlaylist : function(doNotStartNewListIteration) {
		
		var allowedEntries = [];
		
		// Get all playlist entries.
		var selection = jQuery("#" + tx_wsmediaplayer.playingFrom + " " + " " + tx_wsmediaplayer.settings.selectors.playlistEntry + ":visible");
		
		// First, run through all the entries in the playlist.
		selection.each(function(){
			
			// Allow only entries that haven't been played in this iteration yet.
			var curPC = parseInt(jQuery(this).data("playCount"));
			if (isNaN(curPC)) curPC = 0;
			if (curPC < tx_wsmediaplayer.listPlayCount[tx_wsmediaplayer.playingFrom]) {
				allowedEntries.push(this);
			};
			
		});
		
		// Now, are there any entries for us to play?
		if (allowedEntries.length) {
			// Yes - so pick one at random and play it, oh yeah!
			var selectedEntry = Math.floor(Math.random() * allowedEntries.length);
			tx_wsmediaplayer.loadPlaylistEntry.call( allowedEntries[selectedEntry] );
		} else {
			
			// All entries have been played an equal amount of times. Should we start another iteration?
			if (!doNotStartNewListIteration) {
				tx_wsmediaplayer.listPlayCount[tx_wsmediaplayer.playingFrom]++;
				
				// Pick a video at random and play it.
				var selectedEntry = Math.floor(Math.random() * selection.length);
				tx_wsmediaplayer.loadPlaylistEntry.call( selection.eq(selectedEntry) );
				
			} else {
				
				tx_wsmediaplayer.listPlayCount[tx_wsmediaplayer.playingFrom]++;
				
				// Remove all flags from all entries
				jQuery(".tx-wsmediaplayer-pi2 " + tx_wsmediaplayer.settings.selectors.playlistFrame + " " + tx_wsmediaplayer.settings.selectors.playlistEntry).removeClass("active playing paused loading");
				
				// Unload current file.
				jwplayer().stop()
				
			};
			
		};
		
		
	},
	
	initPlayer : function(o) {
		
		if ((tx_wsmediaplayer.settings.forcedID || tx_wsmediaplayer.settings.defaultID) && tx_wsmediaplayer.settings.autostart) {
			
			// Do stuff if "forcedID" is set (meaning we need to force-load an entry, regardless of it being on the playlist or not)
			if (tx_wsmediaplayer.settings.forcedID) {
				
				// On the off-chance that the video is already in the playlist, try to mark it as playing
				// (it will already have been marked active by registerPlaylist())
				var curItem = jQuery(".tx-wsmediaplayer-pi2 " + tx_wsmediaplayer.settings.selectors.playlistFrame + " .active");
				curItem
					.removeClass("paused loading")
					.addClass("playing")
					.data("playCount", 1)
				;

				
				// Update play stats for the video we're about to play
				tx_wsmediaplayer.updateStatsForUID(tx_wsmediaplayer.settings.forcedID);
			}
			
			// Tell the player to start playing.
			jwplayer().play();
		}
		
		// If we're here, there wasn't any forced ID or default ID. However, autostart may still be
		// valid, in which case we load the first entry from the first playlist and just go at it!
		else if (tx_wsmediaplayer.settings.autostart && tx_wsmediaplayer.hasPlaylist) {
			
			tx_wsmediaplayer.playingFrom = tx_wsmediaplayer.knownPlaylists[0];
			
			// If shuffle-mode is on, play a random file - otherwise just play the first one.
			if (tx_wsmediaplayer.settings.shuffleMode) {
				// Jump to random
				tx_wsmediaplayer.skipToRandomInPlaylist();
			} else {
				tx_wsmediaplayer.skipToNextInPlaylist();
			};
		
			
		};
	},
	
	registerPlaylist : function(id) {
		if (this.checkForJQuery()) {
			
			// Tell ourselves that we do have access to a playlist.
			this.hasPlaylist = true;
			tx_wsmediaplayer.knownPlaylists.push(id);
			tx_wsmediaplayer.listPlayCount[id] = 1;
			
			jQuery(document).ready(function() {
				
				
				// If the player config calls for hiding the playlist(s), do so now.
				if (tx_wsmediaplayer.settings.hidePlaylist) jQuery("#" + id).hide();
				
				// Set event handlers for the playlist entries
				var playlistHolder = jQuery("#"+ id);
				playlistHolder.find(tx_wsmediaplayer.settings.selectors.playlistEntry)
					.hover(
						function() { jQuery(this).addClass("hover"); },
						function() { jQuery(this).removeClass("hover"); }
					)
					.click( tx_wsmediaplayer.loadPlaylistEntry )
				;
				
				// If "forcedID" is set, we need to force-load a video entry from the database. In case that video is
				// already in the playlist, mark it as being active.
				if (tx_wsmediaplayer.settings.forcedID) {
					var selAct = jQuery("#" + id + " *[class*='" + tx_wsmediaplayer.settings.selectors.playlistIDprefix + tx_wsmediaplayer.settings.forcedID + "_']");
					if (selAct.length && !tx_wsmediaplayer.playingFrom) {
						selAct.addClass("active");
						tx_wsmediaplayer.playingFrom = id;
					}
				};
				
				// Store the amount of videos in the playlist.
				tx_wsmediaplayer.knownFileCount[id] = jQuery("#" + id + " " + tx_wsmediaplayer.settings.selectors.playlistEntry).length;
			});
			
		};
	},
	
	updateStatsForUID : function(uid) {
		
		// Phone home and tell the backend that a video has been played.
		if (tx_wsmediaplayer.settings.apiURL) {
			jQuery.ajax({
				url : tx_wsmediaplayer.settings.apiURL,
				data : { uid : uid }
			});
		};
		
	},
	
	
	loadPlaylistEntry : function() {
		
		// Store ID of parent playlist
		curID = jQuery(this).parents(tx_wsmediaplayer.settings.selectors.playlistFrame + ":first").attr("id");
		if (curID) tx_wsmediaplayer.playingFrom = curID;
		
		tx_wsmediaplayer.forceStop = false;
		
		// Get some placeholders and stuff
		var entryHolder = jQuery(this);
		var uid = entryHolder.find(".uid").text();
		
		// Update the play stats for this movie
		tx_wsmediaplayer.updateStatsForUID(uid);
		
		// Remove "active"-flag from all entries
		jQuery(".tx-wsmediaplayer-pi2 " + tx_wsmediaplayer.settings.selectors.playlistFrame + " " + tx_wsmediaplayer.settings.selectors.playlistEntry).removeClass("active playing paused loading");
		
		// Update internal play-count, so we know how many times this video has been played.
		var newPlaycount = parseInt(entryHolder.data("playCount")) + 1;
		if (isNaN(newPlaycount)) newPlaycount = 1;
		entryHolder.addClass("active loading").data("playCount", newPlaycount);
		
		// Now, deal with the entry itself. Its data is already stored... if it's a string, 
		// it must be a location; otherwise we'll consider it to be a playlist entry for the player.
		if (typeof( tx_wsmediaplayer.knownFileList[uid] ) == "string") {
			window.location = tx_wsmediaplayer.knownFileList[uid];
		} else {
			jwplayer().stop().load( tx_wsmediaplayer.knownFileList[uid] ).play(true);
		};
	},
	
	
	checkForJQuery : function() {
		if (typeof(jQuery) != "function") {
			if (!tx_wsmediaplayer.jQueryWarned) {
				alert("You need jQuery installed to utilize the playlist module. Please install it manually, or use the t3jquery extension!");
				tx_wsmediaplayer.jQueryWarned = true;
			};
			return false;
		};
		return true;
	},
	
	setupPlayer : function(id, settings, preInitFunction) {
		
		if (!tx_wsmediaplayer.playerInstantiated) {
		
			tx_wsmediaplayer.playerInstantiated = true;
			preInitFunction.call(this);
			
			jwplayer(id).setup(settings);
			
			jwplayer(id).onPlay( tx_wsmediaplayer.events.onPlay );
			jwplayer(id).onPause( tx_wsmediaplayer.events.onPause );
			jwplayer(id).onComplete( tx_wsmediaplayer.events.onComplete );
			jwplayer(id).onError( tx_wsmediaplayer.events.onError );
			jwplayer(id).onReady( tx_wsmediaplayer.initPlayer );
			
		} else {
			
			if (!tx_wsmediaplayer.tooManyPlayersWarningIssued) {
				alert(tx_wsmediaplayer.settings.labels.tooManyPlayers);
				tx_wsmediaplayer.tooManyPlayersWarningIssued = true;
			};
			
			if (typeof(jQuery)=="function") {
				jQuery("#" + id).remove();
			};
			
		};
	}
	
};
