/*
 * OPTIONS:
 * instanceName: String, content_object_id (userObject_1)
 * container: HTMLDivObject, DIV container
 * flashVars: Object
 *		showControls: Boolean
 *		showPlaylist: Boolean
 *		autoPlay: Boolean
 *	colors: Object - used with jquery theme roller icons if used
 *		bg: Hex - NO #, background color 
 *		text: Hex - NO #, font-color
 *		accent: Hex - NO #
 *	playlist_position: String: right||bottom - If 'right', playlist is automatically resized to the height of the player and video/playlist widths are set in percents. If bottom playlist
 * volume: volume level to start with
 * use_theme_roller: Boolean - sets the playback control icons automatically with jquery theme roller and colors.accent
 * xmlLocation: String  
 */

var MediaPlayer = function(options) {
	//store string version of path to this for flashVars
	this.instanceName = false;
	this.container = false;
	this.flashVars = {
		showControls:false,
		showPlaylist:false,
		autoPlay:true
	};
	
	this.playlist_position = 'right';
	this.playlist_scroll = 'vertical';
	this.playlist_height = 300; //only used if playlist is bottom vertical
	this.playlist_thumb_size = '60'
	
	this.colors = { accent: 'ffffff' };
	this.use_theme_roller = true;
	this.icon_height = '16px';
	this.icon_width = '16px';
	this.hide_button_text = true;
	
	this.volume = 0.8;
	this.min_video_width = 100;
	this.xmlLocation = false;
	this.is_alive = true;
	
	jQ.extend(true, this, options);
	
	var error = 'Media Player missing required parameters:\n';
	if (!this.instanceName) error += 'instanceName\n';
	if (!this.container) error += 'container\n';
	if (this.xmlLocation == null) error += 'xmlLocation\n';
	if (error != 'Media Player missing required parameters:\n') {
		alert(error);
		return;
	}
	
	this.previousVolume = (parseFloat(this.volume) != 0.0) ? this.volume : 0.8;
	
	//check for string booleans from editor
	for (var i in this) {
		if (this[i] === 'true') {
			this[i] = true;
		} else if (this[i] === 'false') {
			this[i] = false;
		} else {
			if (typeof(this[i]) == 'object') {
				for (var j in this[i]) {
					if (this[i][j] === 'true') {
						this[i][j] = true;
					} else if (this[i][j] === 'false') {
						this[i][j] = false;
					}
				}
			}
		}
	}
	
	this.icon_location = 'http://jqueryui.com/themeroller/images/?new='+this.colors.accent+'&w=256&h=240&f=png&fltr[]=rcd|256&fltr[]=mask|icons/icons.png';
	
	this.flashContainer = jQ('#'+this.instanceName+'_flashContainer').get(0);
	this.flashName = this.instanceName+'_Embed';
	
	//set player functionality vars
	this.aspect_ratio = 1.5;
	this.playing = this.flashVars.autoPlay;
	this.muted = false;
	this.playIndex = 0;
	this.fullscreen = false;
	this.seconds_passed = null;
	
	this.face = {}; //storage for interface element references
	
	//if (!jQ('#topBar').length) this.setVideoArea(); //for display -- called in embed for editor because CSS takes a moment to load
	
	this.loadXML(); //init called from xml success callback
}

MediaPlayer.prototype.loadXML = function() {
	var MP = this;
	jQ.ajax({
		type:'post',
		url: '/channel/xml',
		data:{xml_location:this.xmlLocation},
		dataType: 'text/xml',
		success: function(data) {
			MP.xml = data;
			var xml;
			try { //IE
				xml=new ActiveXObject("Microsoft.XMLDOM");
				xml.async="false";
				xml.loadXML(data);
			} catch(e) {
				parser=new DOMParser();
				xml=parser.parseFromString(data,"text/xml");
				//xml = xml.responseXML;
			}
			var playlists = xml.getElementsByTagName('playlist');
			MP.playlist = [];
			for (var i = 0; i < playlists.length; i++) {
				var p = jQ.xml2json(playlists[i]);
				var playlist_type = playlists[i].getAttribute('type');
				
				for (var j = 0; j < p.item.length; j++) {
					var newItem = p.item[j];
					newItem.type = playlist_type;
					MP.playlist.push(newItem);
				}
				
				//playlists with a single item do not have an items array
				if (typeof(p.item) != 'undefined' && typeof(p.item.length) == 'undefined') {
					var newItem = p.item;
					newItem.type = playlist_type;
					MP.playlist.push(newItem);
				}
			}
			MP.init();
		},
		error: function(x, y, z) {
			//run xml error function
				//create "error playlist" and show error text in video player space
		}
	});
}

MediaPlayer.prototype.init = function() {
	this.embed();
	this.getControls();
	this.makePlaylist();
}

MediaPlayer.prototype.setPlaylistPosition = function() {
	this.face.playlist = {};
	this.face.playlist.container = jQ('#'+this.instanceName+'_Playlist').get(0);
	
	this.face.videoContainer = jQ('#'+this.instanceName+'_VideoContainer').get(0);
	
	if (this.playlist_position == 'bottom') {
		jQ(this.face.videoContainer).add(this.face.playlist.container).css({display: 'block', 'float': 'none'}).width(jQ(this.container).width());
		if (this.playlist_scroll == 'vertical') jQ(this.face.playlist.container).height(this.playlist_height);
	}
	
	if (this.flashVars.showPlaylist) {
		jQ(this.face.videoContainer).width(jQ(this.container).width());
		jQ(this.face.playlist.container).hide();
	}
}

//Sets the height and width of the embedded video player
//based on the width of the container, factoring in 
//playlist type (flash/HTML) and position if HTML, forcing
//the embed to a 4:3 ratio
MediaPlayer.prototype.setVideoArea = function() {
	this.face.videoEmbedContainer = jQ('#'+this.instanceName+'_EmbedWrap').get(0);
	this.embed_width = jQ(this.face.videoContainer).width(); //width predetermined by user, height based on width and a 4:3 aspect ratio

	if (this.embed_width < this.min_video_width && !this.flashVars.showPlaylist) { //if the embed is smaller than allowed and playlist is in HTML
		if (this.playlist_position == 'right') { //showing HTML playlist on right, determine width of video area
			var w = (jQ(this.container).width() * this.min_video_width) / this.embed_width;
			jQ(this.container).width(w);
		} else {
			jQ(this.container).width(this.min_video_width);
		}
	} else if (this.embed_width < this.min_video_width) { //if the embed is smaller than allowed and playlist is in flash
		jQ(this.container).width(this.min_video_width); //no need for the extra calculations above
		jQ(this.face.videoContainer).width(this.min_video_width);
	}

	//do height now
	this.embed_height = this.embed_width/this.aspect_ratio;
	jQ(this.face.videoEmbedContainer).height(this.embed_height);
}

MediaPlayer.prototype.embed = function() {
	this.setPlaylistPosition();
	/*if (jQ('#topBar').length)*/ this.setVideoArea();
	
	if (this.is_alive) {
		swfobject.embedSWF("/resources/flash/hybrid-player.swf", this.flashName, this.embed_width, (this.flashVars.showControls) ? this.embed_height+30 : this.embed_height, "9.0.0", "/resources/flash/expressInstall.swf", 
			{
				xmlLocation: encodeURIComponent(this.xmlLocation),
				autoPlay: this.flashVars.autoPlay.toString(),
				volume: this.volume,
				showControls: this.flashVars.showControls.toString(),
				showPlaylist: this.flashVars.showPlaylist.toString(),
				playerWidth: this.embed_width,
				playerHeight: this.embed_height,
				apiVar: this.instanceName
			},
			{
				allowFullscreen: "true",
				allowScriptAccess: "always",
				scale: "noscale",
				wmode: 'transparent'
			}
		);
		this.checkForEmbed();
	} else {
		jQ('#'+this.instanceName+'_EmbedNotReady').html('<div style="font-size:16px; font-weight:bold; margin:20px;">Double-click this player to add videos.</div>');
		if (this.flashVars.showControls) {
			this.embed_height += 30;
			jQ(this.face.videoEmbedContainer).height(this.embed_height);	
		}
	}
}

//swfobject inconveniently omits a callback function so you have no fucking clue when this shit actually hits the page.
MediaPlayer.prototype.checkForEmbed = function() {
	if (!jQ('#'+this.instanceName+'_EmbedNotReady').length) {
		this.flashAPI = document.getElementById(this.flashName);
		if (this.flashVars.showControls) {
			this.embed_height += 30;
			jQ(this.face.videoEmbedContainer).height(this.embed_height);	
		}
	} else {
		setTimeout(this.instanceName+'.checkForEmbed()', 100);
	}
}

MediaPlayer.prototype.getControls = function() {
	this.createdMarkup = false; //set true at the end of makePlaylist
	
	this.face.controlsContainer = jQ('#'+this.instanceName+'_Controls').get(0);
	
	if (this.flashVars.showControls) {
		jQ(this.face.controlsContainer).hide();
		return;
	}
	
	var container = jQ(this.face.controlsContainer);
	this.face.controls = {};
	var c = this.face.controls;
	
	c.volumeSlider = {};
		c.volumeSlider.container = container.children('.volumeSlider').before('<div class="controlFloat volumeIcon"></div>').get(0);
		c.volumeSlider.icon = container.children('.volumeIcon').css({'height':'16px','width':'16px','cursor':'pointer'}).get(0); //hacked in volume icon
		c.volumeSlider.width = jQ(c.volumeSlider.container).width();
		c.volumeSlider.bg = jQ(c.volumeSlider.container).children('.volumeSlider_bg').get(0);
		
		c.volumeSlider.level = jQ(c.volumeSlider.container).children('.volumeSlider_level').get(0);
		c.volumeSlider.handle = jQ(c.volumeSlider.container).children('.volumeSlider_handle').get(0);
		c.volumeSlider.handle_width = jQ(c.volumeSlider.handle).width();
	
	c.timeSlider = {};
		c.timeSlider.container = container.children('.timeSlider').get(0);
		c.timeSlider.bg = jQ(c.timeSlider.container).children('.timeSlider_bg').get(0);
		c.timeSlider.loadProgress = jQ(c.timeSlider.container).children('.timeSlider_loadProgress').get(0);
		c.timeSlider.playProgress = jQ(c.timeSlider.container).children('.timeSlider_playProgress').get(0);
		c.timeSlider.handle = jQ(c.timeSlider.container).children('.timeSlider_handle').get(0);
		
		//set width of time scrubber, all other controls have set px widths
		var w = 0;
		var num = 0;
		jQ(this.face.controlsContainer).children().not(c.timeSlider.container).not('.clear').each(function() {
			var o = jQ(this);
			w += o.outerWidth();
			w += parseInt(o.css('margin-right'));
			w += parseInt(o.css('margin-left'));
			num += 2;
		});
		w = jQ(this.face.controlsContainer).width()-w;
		jQ(c.timeSlider.container).width(w-num);
		
		c.timeSlider.width = jQ(c.timeSlider.container).width();
		c.timeSlider.handle_width = jQ(c.timeSlider.handle).outerWidth();
		c.timeSlider.width_minus_handle = this.face.controls.timeSlider.width - this.face.controls.timeSlider.handle_width; //used in updateTime, reduces processor load to calculate here
		
	c.playpause = container.children('.togglePlayPause').get(0);
	c.next = container.children('.playNext').get(0);
	c.prev = container.children('.playPrev').get(0);
	
	c.timeDisplay = container.children('.timeDisplay').get(0);
	
	if (this.hide_button_text) jQ(c.playpause).add(c.next).add(c.prev).text('');
	
	if (this.use_theme_roller) this.applyIconSet();
	
	this.applyColors();
	
	if (this.is_alive) {
		this.initTimeScrub();
		this.initVolumeScrub();
		this.initVolumeIconClick();
	}
}

MediaPlayer.prototype.applyIconSet = function() {
	var c = this.face.controls;
	var color = jQ.fmtColor(jQ(c.timeSlider.handle).css('background-color'), 'hexadecimal').replace('#','');
	this.icon_location = 'http://jqueryui.com/themeroller/images/?new='+color+'&w=256&h=240&f=png&fltr[]=rcd|256&fltr[]=mask|icons/icons.png';
	jQ(c.playpause)
		.add(c.next)
		.add(c.prev)
		.add(c.volumeSlider.icon)
		.css({
			background: 'transparent url('+this.icon_location+') no-repeat 0 0',
			height: this.icon_height,
			width: this.icon_width
		});
	jQ(c.timeDisplay).css('color', '#'+color);
	if (this.playing) {
		jQ(c.playpause).css('background-position', '-16px -160px');
	} else {
		jQ(c.playpause).css('background-position', '0 -160px');
	}
	jQ(c.next).css('background-position', '-32px -160px');
	jQ(c.prev).css('background-position', '-48px -160px');

	if (parseFloat(this.volume) != 0.0) {
		jQ(c.volumeSlider.icon).css({'background-position':'-144px -160px'});
	} else {
		jQ(c.volumeSlider.icon).css({'background-position':'-128px -160px'});
	}
}

MediaPlayer.prototype.applyColors = function() {
	var c = this.face.controls;
	var color = jQ(c.timeSlider.handle).css('background-color');
	jQ(c.timeSlider.bg).css({'background-color': color, 'opacity': '0.3'});
	jQ(c.timeSlider.loadProgress).css({'background-color': color, 'opacity': '0.4'});
	jQ(c.timeSlider.playProgress).css({'background-color': color, 'opacity': '0.5'});
	jQ(c.volumeSlider.bg).css({'background-color': color, 'opacity': '0.3'});
	jQ(c.volumeSlider.level).css({'background-color': color, 'opacity': '0.5'});
	
	/*if (this.colors.accent) {
		jQ(c.timeSlider.handle).css('background-color', '#'+this.colors.accent);
		jQ(c.volumeSlider.handle).css('background-color', '#'+this.colors.accent);
		jQ(c.timeSlider.loadProgress).css({'background-color': '#'+this.colors.accent, 'opacity': '0.3'});
		jQ(c.timeSlider.playProgress).css({'background-color': '#'+this.colors.accent, 'opacity': '0.3'});
		jQ(c.volumeSlider.level).css({'background-color': '#'+this.colors.accent, 'opacity': '0.3'});
	}
	if (this.colors.bg) {
		jQ(c.timeSlider.container).css('background-color', '#'+this.colors.bg);
		jQ(c.volumeSlider.container).css('background-color', '#'+this.colors.bg);
	}*/
	
}

MediaPlayer.prototype.initTimeScrub = function() {
	var MP = this;
	var T = this.face.controls.timeSlider;
	var handle_half_width = T.handle_width/2;

	jQ(T.handle).draggable({
		axis: 'x',
		containment: 'parent',
		cursor: 'move'
	});
	//had to change these to binds because the events weren't firing
	jQ(T.handle).bind('dragstart', function(event, ui) {
		var w = Math.ceil(jQ(event.currentTarget).position().left+handle_half_width);
		jQ(T.playProgress).width(w);
	});
	jQ(T.handle).bind('drag', function(event, ui) {
		var w = Math.ceil(jQ(event.currentTarget).position().left+handle_half_width);
		jQ(T.playProgress).width(w);
	});
	jQ(T.handle).bind('dragstop', function(event, ui) {
		if (MP.playlist[MP.playIndex].isAd == 'false') {
			var s = ((jQ(event.currentTarget).position().left/(T.width-jQ(T.handle).width())) * MP.playlist[MP.playIndex].duration)/1000;
			MP.seekTo(s, true);
		}
	});
	
	
	var timeSlider_offset = jQ(T.container).offset().left;
	jQ(T.container).click(function(e) {
		if (e.originalTarget != T.handle) {
			var s = (((e.clientX + jQ(window).scrollLeft() - timeSlider_offset) / T.width) * MP.playlist[MP.playIndex].duration) / 1000;
			MP.seekTo(s, true);
		}
	});
}

MediaPlayer.prototype.initVolumeScrub = function() {
	var MP = this;
	var V = this.face.controls.volumeSlider;
	var handle_half = V.handle_width/2;
	jQ(V.handle).draggable({
		axis: 'x',
		containment: 'parent',
		cursor: 'move'
	});
	//had to change these to binds because the events weren't firing
	jQ(V.handle).bind('dragstart', function(event, ui) {
		var w = Math.ceil(jQ(event.currentTarget).position().left+handle_half);
		jQ(V.level).width(w);
	});
	jQ(V.handle).bind('drag', function(event, ui) {
		var w = Math.ceil(jQ(event.currentTarget).position().left+handle_half);
		jQ(V.level).width(w);
	});
	jQ(V.handle).bind('dragstop', function(event, ui) {
		var w = Math.ceil(jQ(event.currentTarget).position().left+handle_half);
		jQ(V.level).width(w);
		var v = jQ(event.currentTarget).position().left/(V.width+V.handle_width);
		MP.setVolume(v);
	});
	
	jQ(V.handle).css('left', (this.volume*100)+'%');
	jQ(V.level).width(jQ(V.handle).css('left'));
}

MediaPlayer.prototype.initVolumeIconClick = function() {
	var MP = this;
	var V = this.face.controls.volumeSlider;
	jQ(V.icon).click(function() {
		if (parseFloat(MP.volume) == 0.0) {
			var v = MP.previousVolume;
			MP.setVolume(v);
		} else {
			MP.previousVolume = MP.volume;
			MP.setVolume(0.0);
		}
		jQ(V.handle).draggable('destroy');
		MP.initVolumeScrub();
	});
}

MediaPlayer.prototype.makePlaylist = function() {

	if (this.flashVars.showPlaylist) {
		this.createdMarkup = true;
		return;
	}
	
	if (this.playlist_position == 'right') {
		var ph = this.embed_height+jQ(this.face.controlsContainer).outerHeight();
		ph = ph - (parseInt(jQ(this.face.playlist.container).css('padding-top')) + parseInt(jQ(this.face.playlist.container).css('padding-bottom')));
		jQ(this.face.playlist.container).height(ph);
	}
	//append and store playlist items
	this.face.playlist.items = [];
	jQ(this.face.playlist.container).empty();
	
	for (var j=0; j<this.playlist.length; j++) {
		var p = this.playlist[j];
		var html = '<li onclick="'+this.instanceName+'.playFromIndex('+j+')">';
			
		if (p.thumb) {
			html += '<img style="height:'+this.playlist_thumb_size+'px;width:'+this.playlist_thumb_size+'px;vertical-align:middle;" src="'+p.thumb.split('?')[0]+'?w='+this.playlist_thumb_size+'&h='+this.playlist_thumb_size+'&b=c&bg=000000000">';
		} else {
			html += '<div style="display:inline;height:0;width:0;padding:'+(this.playlist_thumb_size/2)+'px;"></div>';
		}
				
		html += '<div title="'+p.title+' - '+p.description+'" class="playlistTitle"> '+p.title+'</div>\
				<div style="clear:both;"></div>\
			</li>';
			
		jQ(this.face.playlist.container).append(html);
		this.face.playlist.items.push(jQ(this.face.playlist.container).children('li:last').get(0));
	}
	
	jQ(this.face.playlist.container).after('<div style="clear:both;"></div>');
	
	this.highlightPlaylist();
	
	this.specialPlaylistScroll();
	
	this.createdMarkup = true;
}

MediaPlayer.prototype.highlightPlaylist = function() {
	jQ('.active_index_in_playlist').removeClass('active_index_in_playlist');
	jQ(this.face.playlist.items[this.playIndex]).addClass('active_index_in_playlist');
}

MediaPlayer.prototype.specialPlaylistScroll = function() {
	var MP = this;
	var p = this.face.playlist.container;
	var first_li = jQ(p).children('li:first');
	
	if (this.playlist_scroll == 'vertical' ) {
		p.height = jQ(p).outerHeight();
		p.child_height = first_li.outerHeight();
		p.original_margin_top = parseInt(first_li.css('margin-top'));
		p.child_height += p.original_margin_top + parseInt(first_li.css('margin-bottom'));
		p.original_height = p.child_height * this.playlist.length;
		if (p.original_height > jQ(p).height()) { //no need to scroll if the playlist doesn't overflow
			p.height_diff = p.original_height - p.height;
			p.scale = p.height_diff / p.height;
	
			jQ(p).mouseenter(function() {
				this.offsetY = jQ(this).offset().top;
			}).mousemove(function(e) {
				var x = (this.offsetY - e.clientY - jQ(window).scrollTop()) * this.scale;
				first_li.css('margin-top', x+'px');
			}).mouseleave(function() {
				//MP.scrollPlaylistToPlayIndex();
			}).css('overflow', 'hidden');
		}
	} else if (this.playlist_position == 'bottom') {
		
		if (first_li.css('float') == 'left') {
			p.width = jQ(p).outerWidth();
			p.child_width = first_li.outerWidth();
			p.child_width += parseInt(first_li.css('margin-left')) + parseInt(first_li.css('margin-right'));
			p.original_width = p.child_width * this.playlist.length;
			jQ(p).width(p.original_width).wrap('<div id="horizontalPlaylistWrap"></div>');
			var wrap = jQ('#horizontalPlaylistWrap').css({position: 'relative', overflow: 'auto', backgroundColor: jQ(p).css('background-color')}); //pos:rel IE overflow fix, fuck microsoft
		
			var MP = this;
			wrap.css({overflow: 'hidden'});
			if (p.original_width > wrap.width()) { //no need to scroll if the playlist doesn't overflow
				p.width_diff = p.original_width - p.width;
				wrap.get(0).scale = p.width_diff / p.width;
				wrap.get(0).offsetH = wrap.offset().left;
				wrap.mousemove(function(e) {
					var x = (this.offsetH - e.clientX + jQ(window).scrollLeft()) * this.scale;
					jQ(p).css('margin-left', x+'px');
				}).mouseleave(function() {
					//MP.scrollPlaylistToPlayIndex();
				}).css('overflow', 'hidden');
			}
			
			if (jQ.browser.msie && this.playlist_scroll == 'scrollbar') {
				jQ('#horizontalPlaylistWrap').height(wrap.height()+17);
			}
		} else if (first_li.length) { //bottom vertical scrollbar
			jQ(p).height(this.playlist_height);
		}
	} else {
		jQ(p).css({overflow: 'auto'});
	}
	
	if (this.playlist_position == 'right' || (this.playlist_position == 'bottom' && first_li.css('float') == 'left')) {
		var mediaTitleHoverHelper = jQ(first_li).children('.playlistTitle').clone().empty().attr('title', '').css({position:'absolute','font-weight':'bold','width':'auto','max-width':'200px','display':'block'});
		if (this.playlist_position == 'right') mediaTitleHoverHelper.css('left', jQ(this.container).width()+'px');
		jQ(this.container).append(mediaTitleHoverHelper);
	
		jQ(p).children('li').hover(function(e) {
			var text = jQ(this).children('.playlistTitle').text();
			var width = text.length * (parseInt(jQ(this).children('.playlistTitle').css('font-size'))*0.6);
			if (width > 200) width = 200;
			mediaTitleHoverHelper.text(text).css({'background-color':jQ(this).css('background-color'), 'color':jQ(this).css('color'),'padding':'10px','width':width+'px'}).show();
			if (this.playlist_position == 'bottom') {
				var left = (e.clientX + jQ(window).scrollLeft() - jQ(MP.container).offset().left) - (mediaTitleHoverHelper.outerWidth() / 2);
				if (left < 0) left = 0;
				mediaTitleHoverHelper.css({left: left+'px'});
			} else {
				var top = jQ(this).position().top + (jQ(this).outerHeight()/2) - (mediaTitleHoverHelper.outerHeight() / 2);
				mediaTitleHoverHelper.css({top: top+'px'});
			}
		}, function() {
			mediaTitleHoverHelper.empty().hide();
		}).mousemove(function() {
			if (this.playlist_position == 'bottom') {
				var left = (e.clientX + jQ(window).scrollLeft() - jQ(MP.container).offset().left) - (mediaTitleHoverHelper.outerWidth() / 2);
				if (left < 0) left = 0;
				mediaTitleHoverHelper.css({left: left+'px'});
			} else {
				var top = jQ(this).position().top + (jQ(this).outerHeight()/2) - (mediaTitleHoverHelper.outerHeight() / 2);
				mediaTitleHoverHelper.css({top: top+'px'});
			}
		});
	
		mediaTitleHoverHelper.mousemove(function() { jQ(this).hide(); }); //if scrollbar is present and mouse leaves playlist item through scrollbar the helper won't disappear
	}
}

MediaPlayer.prototype.scrollPlaylistToPlayIndex = function() {
	var p = this.face.playlist.container;
	var first_li = jQ(p).children('li:first');
	var play_index = jQ(p).children('li.active_index_in_playlist');
	if (this.playlist_scroll == 'vertical') {
		var play_index_top = (this.playIndex == 0) ? (parseInt(play_index.css('margin-top')) + play_index.position().top) : play_index.position().top;
		var play_index_bottom = play_index_top + p.child_height;
		if (this.playlist_position == 'bottom') play_index_top -= jQ(this.face.videoContainer).outerHeight();
		if (this.playlist_position == 'bottom') play_index_bottom -= jQ(this.face.videoContainer).outerHeight();
		if (play_index_top < 0) { //current play index is not visible above
			var new_margin = (parseInt(first_li.css('margin-top')) - play_index_top)+5;
			if (new_margin > p.original_margin_top) new_margin = p.original_margin_top;
			first_li.animate({marginTop: new_margin+'px'}, 200, 'linear');
		} else if (play_index_bottom > p.height) { //current play index is not visible below
			var new_margin = (parseInt(first_li.css('margin-top')) - (play_index_bottom - p.height))-8;
			if (new_margin > 0) new_margin = 0;
			first_li.animate({marginTop: new_margin+'px'}, 200, 'linear');
		}
	} else if (this.playlist_scroll == 'horizontal') {
		var play_index_left = (this.playIndex == 0) ? (parseInt(play_index.css('margin-left')) + play_index.position().left) : play_index.position().left;
		var play_index_right = play_index_left + p.child_width;
		if (play_index_left < 0) { //current play index is not visible above
			var new_margin = (parseInt(jQ(p).css('margin-left')) - play_index_left)+5;
			if (new_margin > 0) new_margin = 0;
			jQ(p).animate({marginLeft: new_margin+'px'}, 200, 'linear');
		} else if (play_index_right > p.width) { //current play index is not visible below
			var new_margin = (parseInt(jQ(p).css('margin-left')) - (play_index_right - p.width))+8;
			if (new_margin > 0) new_margin = 0;
			jQ(p).animate({marginLeft: new_margin+'px'}, 200, 'linear');
		}
	}
}


//js >> flash
MediaPlayer.prototype.togglePlay = function() {
	if (!this.is_alive || this.playlist[this.playIndex].isAd == 'true') return;
	
	var s = this.seconds_passed || 0;
	this.flashAPI.togglePlay(s);
	this.playing = !this.playing;
	
	if (this.use_theme_roller) {
		jQ(this.face.controls.playpause).css('background-position', (this.playing) ? '-16px -160px' : '0 -160px');
	}
}

MediaPlayer.prototype.playNext = function() {
	if (!this.is_alive) return;
	if (this.playlist[this.playIndex].isAd == 'true') return;
	
	var success = this.flashAPI.playNext();
	if (success) {
		this.playing = true;
		this.seconds_passed = 0;
		this.highlightPlaylist();
	}
}

MediaPlayer.prototype.playPrevious = function() {
	if (!this.is_alive) return;
	if (this.playlist[this.playIndex].isAd == 'true') return;
	
	var success = this.flashAPI.playPrevious();
	if (success) {
		this.playing = true;
		this.seconds_passed = 0;
	}
}

MediaPlayer.prototype.playFromIndex = function(n) {
	if (!this.is_alive) return;
	if (this.playlist[this.playIndex].isAd == 'true') return;
	
	var success = this.flashAPI.playFromIndex(n);
	if (success) {
		this.playIndex = n;
		this.playing = true;
		this.mediaTime = null;
		this.highlightPlaylist();
	}
}

MediaPlayer.prototype.seekTo = function(n, play) {
	if (!this.is_alive) return;
	this.flashAPI.seekTo(Math.floor(n), play.toString());
	this.playing = play;
}

MediaPlayer.prototype.setVolume = function(n) {
	if (!this.is_alive) return;
	this.flashAPI.setVolume(n);
	this.volume = n;
	var icon = this.face.controls.volumeSlider.icon;
	if (parseFloat(this.volume) != 0.0) {
		jQ(icon).css('background-position', '-144px -160px');
	} else {
		jQ(icon).css('background-position', '-128px -160px');
	}
}


//flash >> js
MediaPlayer.prototype.updateTime = function(t, s, p) {
	//if (this.seconds_passed == s) return;
	
	this.seconds_passed = s; //needed for togglePlay arg, AS3 needs it for audio tracks
	
	if (this.createdMarkup && !this.fullscreen) {
		jQ(this.face.controls.timeDisplay).text(t);
		
		if (!jQ(this.face.controls.timeSlider.handle).hasClass('ui-draggable-dragging')) {
			var pdeci = p/100;
			var handleLeft = this.face.controls.timeSlider.width_minus_handle*pdeci;
			this.face.controls.timeSlider.handle.style.left = handleLeft+'px';
			this.face.controls.timeSlider.playProgress.style.width = p+'%';
		}
	}
}

MediaPlayer.prototype.updateLoadProgress = function(t) {
	if (this.createdMarkup) {
		jQ(this.face.controls.timeSlider.loadProgress).width(t*100+'%');
	}
}

MediaPlayer.prototype.updatePlayIndex = function(i) {
	this.playIndex = i;
	if (typeof(this.initialUpdatePlayIndexCallMade) == 'undefined') {
		this.initialUpdatePlayIndexCallMade = 'Thanks Matt';
	} else {
		this.playing = true;
		if (this.use_theme_roller) {
			jQ(this.face.controls.playpause).css('background-position', (this.playing) ? '-16px -160px' : '0 -160px' );
		}
	}
	this.highlightPlaylist();
	this.scrollPlaylistToPlayIndex();
}

MediaPlayer.prototype.toggleFullscreen = function() {
	this.fullscreen = !this.fullscreen;
}
