// Copyright (c) 2007 Sonic Foundry, Inc. and Sonic Foundry 
// Media Systems, Inc. Neither this code nor any portion 
// thereof maybe reproduced, altered,or otherwise changed, 
// distributed or copied,without the express written 
// permission of Sonic Foundry. 
// All rights reserved.
SL1PlayerArea.prototype = new PlayerArea();
function SL1PlayerArea (container, containingWindow, ID)
{
	this.PlayerType = PlayerType.SL1;
	
	this._embeddedPlayer = null;
	this._media = null;
	this._pci = null;
	this._timerManager = null;
	this._volume = null;

	this.SlideCheckInterval = 5000;

	// Need to add the following line because
	// when you call .prototype this gets executed	
	if (container && containingWindow && ID)
	{
		this.InitializeArea(container, containingWindow, ID);
	}
	
	//!!!
//	this.Debug = function(msg)
//	{
//		window.console.log(msg);
//	}
	
	this.SetupPlayer = function()
	{
		this.Debug("SetupPlayer()");
		this._CreateObject();
		
		//!! hack
		if (typeof(ThumbNailsAreaInstance) != 'undefined')
		{
			ThumbNailsAreaInstance.Hide();
		}
 	}
 	
 	this._CreateObject = function()
 	{
 		Silverlight.createObjectEx({
 			source: this.LayoutLocation + '/SL1.xaml', 
 			parentElement:$('SilverlightHost'), 
 			id:'EmbeddedPlayer', 
 			properties:
 				{width:this.Width + "px", 
 				height:this.Height + "px", 
 				background:'black', 
 				isWindowless:'false', 
 				framerate:'24', 
 				version:'1.0'}, 
 			events:
 				{onError:this._OnError.bind(this), onLoad:this._OnLoad.bind(this)}, context:null});
 	}

	this._OnLoad = function()
	{
		this.Debug('_OnLoad()');
		
		this._embeddedPlayer = $('EmbeddedPlayer');
		this._media = this._embeddedPlayer.content.findName('media');
		
		if (MainHelper.Presentation.IsStandAlone == true)
		{
			this._media['width'] = this.Width;
			this._media['height'] = this.Height;
		}
		
		this._AttachMediaEvents();
		
		this._pci = new SL1_PlayerControl(this._media);
		this._timerManager = new SL1_TimerManager(this, this._pci);
		this._volume = new Volume(this._pci);
		this._volume.InitializeVolume();
	
		this._pci.SetMedia(this._GetVideoUrl());
		
		if (this.StartTime != -1)
		{
			this._SetStartTime(Number(this.StartTime));
		}
	}
	
	this._GetVideoUrl = function()
	{
		if (MainHelper.Presentation.Status == PresentationStatus.CaptureInProgress
			&& MainHelper.Presentation.IsMulticast == true
			&& this.RolloverMulticastLocation != null)
		{
			return this.RolloverMulticastLocation;
		}

		return MainHelper.Presentation.VideoUrl;
	}
	
	this._OnError = function(sender, args)
	{
		alert('_OnError()');
	}
	
	this._AttachMediaEvents = function()
	{
		this._media.addEventListener('mediaFailed', this._OnMediaFailed.bind(this));
		this._media.addEventListener('loaded', this._OnMediaLoaded.bind(this));
		this._media.addEventListener('mediaOpened', this._OnMediaOpened.bind(this));
		this._media.addEventListener('currentStateChanged', this._OnMediaCurrentStateChanged.bind(this));
		this._media.addEventListener('markerReached', this._OnMediaMarkerReached.bind(this));
	}

	this._OnMediaOpened = function()
	{
		this.Debug('_OnMediaOpened()');
		
		this._AddEventHandlers();

		this._PostMediaLengthObtainedEvent();

		this._AddMarkersForMac();

		this._timerManager.Start();
		
		MainHelper.EventPlayerSetupComplete.Post(new SfEventArgs());
	}
	
	this._AddMarkersForMac = function()
	{
		// Only add markers for on-demand
		if(MainHelper.Presentation.Status == PresentationStatus.ReplayReady)
		{
			this.Debug('_AddMarkersForMac()');
		
			var markers = this._media['markers'];
		
			markers.clear();

			var slideTimings = MainHelper.Presentation.SlideTimings;

			for (var i=0; i<slideTimings.length; ++i)
			{
				var marker = this._embeddedPlayer.content.createFromXaml("<TimelineMarker Time='" + this.GetFormattedTiming(slideTimings[i].Time) + "' Type='MSL' Text='HE(\"S\", " + (i+1) + ")' />");
				markers.add(marker);
			}

			var marker = this._embeddedPlayer.content.createFromXaml("<TimelineMarker Time='" + this.GetFormattedTiming(Math.floor(this._pci.GetMediaDuration())) + "' Type='MSL' Text='HE(\"E\")' />");
			markers.add(marker);
		}
	}
	
	this._ParseTime = function(timeInSeconds)
	{
		var hh = Math.floor(timeInSeconds/3600);
		
		var remainingSeconds = timeInSeconds - hh*3600;
		var mm = Math.floor(remainingSeconds/60);
		
		remainingSeconds = remainingSeconds - mm*60;
		var ss = Math.floor(remainingSeconds);
		
		var fraction = remainingSeconds - ss;
		var ff = Math.floor(fraction*1000);

		return {HH:hh, MM:mm, SS:ss, FF:ff};		
	}
	
	this.GetFormattedTiming = function(posInSeconds)
	{
		var parsed = this._ParseTime(posInSeconds);
		return parsed.HH + ":" + parsed.MM + ":" + parsed.SS + "." + parsed.FF;
	}
	
	this._OnMediaCurrentStateChanged = function(sender, args)
	{
		var playState = this._pci.GetPlayState();
		MainHelper.EventPlayerStateChanged.Post(playState);
	}

	this._OnMediaLoaded = function()
	{
		this.Debug('_OnMediaLoaded()');
	}
	
	this._OnMediaFailed = function(sender, args)
	{
 		if (MainHelper.Presentation.Status == PresentationStatus.CaptureInProgress)
		{
//			var errorMessage = args['errorMessage'];
//			if (!Util.IsNullOrEmpty(errorMessage))
//			{
//				if (errorMessage.toUpperCase().indexOf('NETWORK_ERROR') != -1)
//				{
					this.Debug('Possible End of Stream');
					MainHelper.EventPlayerStateChanged.Post(PlayState.Ready) ;
					
					return;
//				}
//			}
		}
		alert('Mediasite Viewer cannot connect to the streaming server. The streaming server name might not be correct, the streaming server might not be available or the media stream format may not be supported: ' + args['errorMessage']);
	}
	
	this._OnMediaMarkerReached = function(sender, args)
	{
		this.Debug('_OnMediaMarkerReached()');

		var scriptType = args['marker']['type'];
		var scriptParam = args['marker']['text'];

		this.Debug("ScriptType: " + scriptType + ", ScriptParam: " + scriptParam);

		this.ScriptParser.ParseScriptFromStream(scriptType, scriptParam);
	}
	
	this._PostMediaLengthObtainedEvent = function()
	{
		MainHelper.EventPlayerMediaLengthObtained.Post({Left:0, Right:this._pci.GetMediaDuration()});
	}

	this._AddEventHandlers = function()
	{
 		this.ScriptEventHandler = new SfEventHandler(this.ID);
		this.ScriptEventHandler.MethodName = "_ScriptEventHandler";
		this.ScriptEventHandler.Container = this.Container;
		MainHelper.EventScript.AddHandler(this.ScriptEventHandler);

		this.SliderNotifyEventHandler = new SfEventHandler(this.ID);
		this.SliderNotifyEventHandler.Container = this.Container;
		this.SliderNotifyEventHandler.MethodName = "_SliderNotifyEventHandler";
		MainHelper.EventSliderNotify.AddHandler(this.SliderNotifyEventHandler);

 		this.CommandEventHandler = new SfEventHandler(this.ID);
		this.CommandEventHandler.MethodName = "_CommandEventHandler";
		this.CommandEventHandler.Container = this.Container;
		MainHelper.EventCommand.AddHandler(this.CommandEventHandler);
	}
	
	this._CommandEventHandler = function(args)
	{
		switch(args.Command)
		{
			case SfCommandType.NavigateToSlide:
				var slideNumber = args.SlideNumber;
				if (!slideNumber)
				{
					SfDebug.DPF(SfDebug.ErrMsgCritical, "Navigate to Slide no SlideNumber present");
					return;
				}
				this._NavigateToSlide(Number(slideNumber));
				break;
			case SfCommandType.Play:
				this._Play();
				break;
			case SfCommandType.Pause:
				this._Pause();
				break;
			case SfCommandType.Stop:
				this._Stop();
				break;
			case SfCommandType.Mute:
				this._Mute();
				break;
			case SfCommandType.SetVolume:
				this._SetVolume(args.Volume);
				break;
			case SfCommandType.NavigateToChapter:
				this._NavigateToChapter(Number(args.Number), Number(args.Time));
				break;
		}
	}

	this._ScriptEventHandler = function(args)
	{
		switch(args.Command)
		{
			case SfScriptCommandType.EndPresentation:
				this.Debug("ScriptEventHandler(): OnEndPresentation");
				this._pci.Stop();
				MainHelper.PresentationEnded = true;
				break;
		}
	}

	this._SliderNotifyEventHandler = function(objNotify)
	{
		switch(objNotify.NotifyType)
		{
			case SfSliderNotifyType.NewPosition:
				this.Debug("OnSliderNotify(): " + objNotify.Position);
				this._pci.SetPosition(objNotify.Position);
				this._HandleSlideChangeWhenPositionChanges(objNotify.Position);
				break;
		}
	}
	
	this._Mute = function()
	{
		this._volume.ToggleMute();
	}
	
	this._SetVolume = function(vol)
	{
		this._volume.SetVolume(vol);
	}
	
	this._HandleSlideChangeWhenPositionChanges = function(pos)
	{
		// fire event to change the slide being shown now.
		var slideNumber = this.CalculateSlideNumberToShow(pos);
		
		if (slideNumber == 0)
		{
			MainHelper.CurrentSlideNumber = -1;
			MainHelper.EventPlayBegin.Post(new Object());
			return;
		}
		
		this.Debug("switching to slide: " + slideNumber);
		var args =  MainHelper.CreateShowSlideEventArgs(slideNumber);
		MainHelper.CurrentSlideNumber = slideNumber;
		MainHelper.EventScript.Post(args);	
	}
	
	this._NavigateToChapter = function(number, timeInMilliSeconds)
	{
		this.Debug("_NavigateToChapter(): " + number);
		this._NavigateToTime(timeInMilliSeconds);
	}

	this._NavigateToTime = function(timeInMilliSeconds)
	{
		this.Debug("_NavigateToTime(): " + timeInMilliSeconds);
		this._SetStartTime(timeInMilliSeconds);
		
		MainHelper.EventCommand.Post(new CommandArgs(SfCommandType.Play));
	}

	this._SetStartTime = function(timeInMilliSeconds)
	{
		var timeCode = timeInMilliSeconds/1000;
		this._pci.SetPosition(timeCode);
		this._HandleSlideChangeWhenPositionChanges(timeCode);
		this._timerManager.PostTimerUpdatedEvent(timeCode);
	}
	
	this._NavigateToSlide = function(slideNumber)
	{
		this.Debug("_NavigateToSlide(): " + slideNumber);
		if (MainHelper.Presentation.Status != PresentationStatus.ReplayReady)
		{
			this.Debug("can not navigate when presentation is not on demand");
			return;
		}
		
		if (slideNumber < 0)
		{
			this.Debug("SlideNumber is less than 0");
			return;
		}
		if (MainHelper.MaxSlideTimings < slideNumber)
		{
			SfDebug.DPF(SfDebug.ErrMsgCritical, "slidetimings not known for slideNumber: " + slideNumber);
			return;
		}
		
		var timeCode = (slideNumber == 0) ? 0.00 : MainHelper.Presentation.SlideTimings[slideNumber-1].Time;
		this.Debug("Navigating to timeCode: " + timeCode);
		
		this._NavigateToTime(timeCode*1000);
	}

	this._Play = function()
	{
		var pos = this._pci.GetPosition();
		if (pos == 0)
		{
			MainHelper.CurrentSlideNumber = -1;
			MainHelper.EventPlayBegin.Post(new Object());
		}

		MainHelper.PresentationEnded = false;
		this._pci.Play();
		this._timerManager.Start();
	}
	
	this._Pause = function()
	{
		this._pci.Pause();
		this._timerManager.Stop();
	}

	this._Stop = function()
	{
		this._pci.Stop();
		this._timerManager.Stop();
	}

	this.ShowPlayerDivWhenReady = function()
	{
		var embeddedPlayer = this.GetDivToHideWhenNotReady();
		if (embeddedPlayer)
		{
			embeddedPlayer.style.display = '';
		}
		else
		{
			this.Debug("!EmbeddedPlayer not found");
		}
	}
	
	this.HidePlayerDivWhenNotReady = function()
	{
		var embeddedPlayer = this.GetDivToHideWhenNotReady();
		if (embeddedPlayer)
		{
			embeddedPlayer.style.display = 'none';
		}
		else
		{
			this.Debug("!EmbeddedPlayer not found");
		}
	}
	
	this.GetDivToHideWhenNotReady = function()
	{
		return $('EmbeddedPlayer');
	}
	
}

// BEGINFILE PlayerControlWM7.js ------------------------------------------------------------------------->
SL1_PlayerControl = function(media)
{
	this._media = media;
	
	this.Play = function()
	{
		this._media.play();
	}
	
	this.Stop = function()
	{
		this._media.stop();
	}
	
	this.Pause = function()
	{
		this._media.pause();
	}

	this.GetPlayState = function()
	{
		var state = this._media['currentState'];
		if (typeof(state) == 'undefined')
		{
			return PlayState.Undefined;
		}
		return this._ConvertSL1StateToPlayState(state);
	}
	
	this.SetMedia = function(loc)
	{
		this._media['source'] = loc;
	}
	
	this.GetPosition = function()
	{
		return this._media['position']['seconds'];
	}
	
	this._ParseTime = function(timeInSeconds)
	{
		var hh = Math.floor(timeInSeconds/3600);
		
		var remainingSeconds = timeInSeconds - hh*3600;
		var mm = Math.floor(remainingSeconds/60);
		
		remainingSeconds = remainingSeconds - mm*60;
		var ss = Math.floor(remainingSeconds);
		
		var fraction = remainingSeconds - ss;
		var ff = Math.floor(fraction*1000);

		return {HH:hh, MM:mm, SS:ss, FF:ff};		
	}
	
	this.SetPosition = function(posInSeconds)
	{
		var parsed = this._ParseTime(posInSeconds);
		var strPos = parsed.HH + ":" + parsed.MM + ":" + parsed.SS + "." + parsed.FF;
		this._media['position']= strPos;
	}
	
	this.GetMediaDuration = function()
	{
		return this._media['naturalDuration']['seconds'];
	}

	this.SetVolume = function(val)
	{
		this._media['volume'] = val/100;
	}
	
	this.GetVolume = function()
	{
		return this._media['volume'] * 100;
	}
	
	this.SetMute = function(val)
	{
		this._media['isMuted'] = val;
	}
	
	this.GetMute = function()
	{
		return this._media['mute'];
	}
		
	this._ConvertSL1StateToPlayState = function(state)
	{
		switch (state.toLowerCase())
		{
			case 'buffering':
				return PlayState.Buffering;
			case 'closed':
				return PlayState.Closed;
			case 'error':
				return PlayState.Error;
			case 'opening':
				return PlayState.Opening;
			case 'paused':
				return PlayState.Paused;
			case 'playing':
				return PlayState.Playing;
			case 'stopped':
				return PlayState.Stopped;
			default:
				return PlayState.Undefined;
		}
	}

	this.PlayNormal = function()
	{
		throw Error.notImplemented();
	}
	
	this.FastForward = function()
	{
		throw Error.notImplemented();
	}
	
	this.SlowForward = function()
	{
		throw Error.notImplemented();
	}

	this.SetPlaybackSpeed = function(speed)
	{
		throw Error.notImplemented();
	}
}

SL1_TimerManager = function(playerArea, pci)
{
	this._player = playerArea;
	this._pci = pci;
	this._positionTimer = null;
	this._slideNumberUpdateTimer = null;
	this._shouldCheckSlide = false;
	this._shouldUpdateSlideNumber = false;
	this._Initialize();
}

SL1_TimerManager.prototype =
{
	_Initialize : function()
	{
		if (MainHelper.PlayerDetect.IsIntel())
		{
			this._shouldCheckSlide = false;
			this._shouldUpdateSlideNumber = false;
			return;
		}
		
		//powerpc
		if (MainHelper.Presentation.Status == PresentationStatus.ReplayReady)
		{
			this._shouldCheckSlide = false;//!! never check slide
			this._shouldUpdateSlideNumber = false;
		}
		else
		{
			this._shouldCheckSlide = false;
			this._shouldUpdateSlideNumber = true;
		}
	},
	
	Start : function()
	{
		clearTimeout(this._positionTimer);
		clearTimeout(this._slideNumberUpdateTimer);
		
		this._PositionUpdate();
		
		if (this._shouldUpdateSlideNumber)
		{
			this._SlideNumberUpdate();
		}
	},
	
	Stop : function()
	{
		clearTimeout(this._positionTimer);
		clearTimeout(this._slideNumberUpdateTimer);
	},
	
	PostTimerUpdatedEvent : function(pos)
	{
		MainHelper.EventPlayerTimerUpdated.Post(pos);
	},

	_CheckSlide : function(pos)
	{
		var toShow = this._player.CalculateSlideNumberToShow(pos);
		if (toShow == 0)
		{
			MainHelper.CurrentSlideNumber = -1;
			return;
		}
		else if (toShow != MainHelper.CurrentSlideNumber)
		{
			var args =  MainHelper.CreateShowSlideEventArgs(toShow);
			MainHelper.CurrentSlideNumber = toShow;
			MainHelper.EventScript.Post(args);	
		}
	},
	
	_PositionUpdate : function()
	{
		var pos = this._pci.GetPosition();

		this.PostTimerUpdatedEvent(pos);

		if (this._shouldCheckSlide)
		{
			this._CheckSlide(pos);
			
			if (pos >= this._pci.GetMediaDuration() - 1.0)
			{
				this._player.ScriptParser.HE('E');
				return;
			}
		}

		this._positionTimer = setTimeout(this._PositionUpdate.bind(this), 500);
	},

	_SlideNumberUpdate : function()
	{
		var ajax = new Ajax.Request(
			MainHelper.ViewerAppBaseURL + '/StatusChange/MaxSlide.aspx',
			{
				method : 'get',
				parameters : { 'pid' : MainHelper.Presentation.PresentationID },
				onSuccess : this._SlideNumberOnSuccess.bind(this),
				onFailure : this._SlideNumberOnFailure.bind(this)
			})		
	},
	
	_SlideNumberOnSuccess : function(transport)
	{
		var slideNum = 0;
		
		try
		{
			slideNum = Number(transport.responseXML.childNodes[0].childNodes[0].childNodes[0].nodeValue);
		}
		catch(ex)
		{
			return;
		}
		
		if (slideNum == -1)
		{
			// presentation ended
			this._player.ScriptParser.HE('E');
			return;
		}
		
		if (slideNum != 0 && slideNum != MainHelper.CurrentSlideNumber)
		{
			this._player.ScriptParser.HE('S', slideNum);
		}
		
		this._slideNumberUpdateTimer = setTimeout(this._SlideNumberUpdate.bind(this), this._player.SlideCheckInterval);
	},
	
	_SlideNumberOnFailure : function(args)
	{
	}
}

