package
{
	import ispring.as2player.*;
	
	import flash.display.Sprite;
	import fl.controls.Button;
	import fl.controls.Label;
	import fl.controls.Slider;
	import fl.controls.TextArea;
	import fl.events.SliderEvent;
	import flash.events.MouseEvent;
	import flash.text.TextFieldAutoSize;
	import flash.display.DisplayObjectContainer;
	import flash.net.URLRequest;
	
	public class AS2PlayerSample
	{
		private const PRESENTATION1_URL:String = "presentation1.swf";
		private const PRESENTATION2_URL:String = "presentation2.swf";
		
		private var m_presentation:Sprite;
		private var m_presentationLoader:PresentationLoader;
		
		private var m_playbackController:IPresentationPlaybackController;
		private var m_soundController:ISoundController;
		private var m_presentationInfo:IPresentationInfo;
		
		private var m_buttonPrevious:Button;
		private var m_buttonNext:Button;
		private var m_buttonPlay:Button;
		private var m_buttonPause:Button;
		private var m_buttonPres1:Button;
		private var m_buttonPres2:Button;
		private var m_lSlideIndex:Label;
		private var m_lPos:Label;
		private var m_lVolume:Label;
		private var m_posSlider:Slider;
		private var m_volumeSlider:Slider;
		
		private var m_volumeSliderPressed:Boolean = false;
		private var m_posSliderPressed:Boolean = false;
		
		private var m_seeking:Boolean = false;
		private var m_volumeChanging:Boolean = false;

		public function AS2PlayerSample(target:DisplayObjectContainer)
		{			
			m_presentation = createSprite(target, 37, 10);
			initPresentationLoader();
			initControls(target);
		}
		
		private function loadPresentation(presentationURL:String):void
		{
			prepareForLoad();
			m_presentationLoader.load(new URLRequest(presentationURL));
		}
		
		private function slidePositionChanged(e:PlaybackPositionEvent):void
		{
			if ((!m_posSliderPressed) && (!m_seeking))
			{
				m_posSlider.value = getPresentationPos(e.position);
			}
		}
		
		private function getPresentationPos(slidePosition:Number):Number // 0..1
		{
			var currentSlideInfo:ISlideInfo = m_presentationInfo.slides.getSlideInfo(m_playbackController.currentSlideIndex);
			if (!currentSlideInfo)
				return 0;
				
			var presentationDuration:Number = m_presentationInfo.duration;
			var currentSlideCurrentTime:Number = slidePosition * currentSlideInfo.duration;
			var currentSlideStartTime:Number = currentSlideInfo.startTime;
			return (currentSlideStartTime + currentSlideCurrentTime) / presentationDuration;
		}
		
		private function seek(sliderValue:Number, autoStart:Boolean):void
		{
			var slidesCount:Number = m_presentationInfo.slides.slidesCount;
			var currentPresentationTime:Number = m_presentationInfo.duration * sliderValue;
			var i:Number;
			
			for (i = 0; i < slidesCount; i++)
			{
				var slideInfo:ISlideInfo;
				var slideStartTime:Number;
				var slideEndTime:Number;
				
				slideInfo = m_presentationInfo.slides.getSlideInfo(i);
				slideStartTime = slideInfo.startTime;
				slideEndTime = slideInfo.endTime;
				if ((currentPresentationTime >= slideStartTime) && (currentPresentationTime <= slideEndTime))
				{
					break;
				}
			}
		
			var slidePosition:Number;
		
			slidePosition = (currentPresentationTime - slideStartTime) / (slideEndTime - slideStartTime);
			m_playbackController.gotoSlide(i, false);
			m_playbackController.seek(slidePosition);
		}
		
		private function onPosSliderChange(e:SliderEvent):void
		{
			if (m_posSliderPressed)
			{
				seek(e.value, false);
			}
		}
		
		private function onPosSliderThumbPress(e:SliderEvent):void
		{
			m_seeking = true;
			m_posSliderPressed = true;
		}
		
		private function onPosSliderThumbRelease(e:SliderEvent):void
		{
			m_posSliderPressed = false;
			if (m_playbackController)
			{
				m_seeking = false;
				m_playbackController.endSeek(true);
			}
		}

		private function soundVolumeChanged(e:SoundEvent):void
		{
			trace("volume changed " + e.volume);
			if (!m_volumeSliderPressed)
			{
				m_volumeSlider.value = e.volume;
			}
		}
		
		private function onVolumeSliderThumbPress(e:SliderEvent):void
		{
			m_volumeSliderPressed = true;
		}
		
		private function onVolumeSliderThumbRelease(e:SliderEvent):void
		{
			m_volumeSliderPressed = false;
		}
		
		private function onVolumeSliderChange(e:SliderEvent):void
		{
			if (m_volumeSliderPressed)
			{
				if (m_soundController)
				{
					trace("change volume " + e.value);
					//m_soundController.volume = e.value;
					m_soundController.volume = e.value;
				}
			}
		}

		private function initPresentationLoader():void
		{
			m_presentationLoader = new PresentationLoader();
			m_presentation.addChild(m_presentationLoader);
			m_presentationLoader.addEventListener(PlayerEvent.PLAYER_INIT, playerInit);
			loadPresentation(PRESENTATION1_URL);
		}
		
		private function playerInit(e:PlayerEvent):void
		{
			var player:IPlayer = m_presentationLoader.player;
			m_playbackController = player.playbackController;
			m_soundController = player.soundController;
			m_presentationInfo = player.presentationInfo;
			initEventHandlers();
			updatePlayPauseButton(!m_playbackController.playing);
		}
		
		private function prepareForLoad():void
		{
			removeEventHandlers();
			m_playbackController = null;
			m_soundController = null;
			m_presentationInfo = null;
		}
		
		private function initEventHandlers():void
		{
			m_playbackController.addEventListener(SlidePlaybackEvent.CURRENT_SLIDE_INDEX_CHANGED, currentSlideIndexChanged);
			m_playbackController.addEventListener(PlaybackEvent.START_PLAYBACK, startPlayback);
			m_playbackController.addEventListener(PlaybackEvent.PAUSE_PLAYBACK, pausePlayback);
			m_playbackController.addEventListener(PlaybackPositionEvent.SLIDE_POSITION_CHANGED, slidePositionChanged);
			m_soundController.addEventListener(SoundEvent.SOUND_VOLUME_CHANGED, soundVolumeChanged);
		}
		
		private function removeEventHandlers():void
		{
			if (m_playbackController)
			{
				m_playbackController.removeEventListener(SlidePlaybackEvent.CURRENT_SLIDE_INDEX_CHANGED, currentSlideIndexChanged);
				m_playbackController.removeEventListener(PlaybackEvent.START_PLAYBACK, startPlayback);
				m_playbackController.removeEventListener(PlaybackEvent.PAUSE_PLAYBACK, pausePlayback);
				m_playbackController.removeEventListener(PlaybackPositionEvent.SLIDE_POSITION_CHANGED, slidePositionChanged);
			}
			if (m_soundController)
			{
				m_soundController.removeEventListener(SoundEvent.SOUND_VOLUME_CHANGED, soundVolumeChanged);
			}
		}

		private function currentSlideIndexChanged(e:SlidePlaybackEvent):void
		{
			m_lSlideIndex.text = "Current slide index: " + e.slideIndex;	
		}
		
		private function startPlayback(e:PlaybackEvent):void
		{
			updatePlayPauseButton(false);
		}
		
		private function pausePlayback(e:PlaybackEvent):void
		{
			updatePlayPauseButton(true);
		}
		
		private function updatePlayPauseButton(play:Boolean):void
		{
			m_buttonPlay.visible = play;
			m_buttonPause.visible = !play;
		}
		
		private function onBtnNextClick(e:MouseEvent):void
		{
			if (m_playbackController != null)
				m_playbackController.gotoNextSlide(true);
		}
		
		private function onBtnPrevClick(e:MouseEvent):void
		{
			if (m_playbackController != null)
				m_playbackController.gotoPreviousSlide(true);
		}
		
		private function onBtnPlayClick(e:MouseEvent):void
		{
			if (m_playbackController != null)
				m_playbackController.play();
		}
		
		private function onBtnPauseClick(e:MouseEvent):void
		{
			if (m_playbackController != null)
				m_playbackController.pause();
		}
		
		private function onBtnPres1Click(e:MouseEvent):void
		{
			loadPresentation(PRESENTATION1_URL);
		}
		
		private function onBtnPres2Click(e:MouseEvent):void
		{
			loadPresentation(PRESENTATION2_URL);
		}
		
		private function initControls(container:DisplayObjectContainer):void
		{
			m_buttonPrevious	= createButton(container, "Previous Slide", 50, 565, onBtnPrevClick);
			m_buttonNext		= createButton(container, "Next Slide", 170, 565, onBtnNextClick);
			m_buttonPlay		= createButton(container, "Play", 290, 565, onBtnPlayClick);
			m_buttonPause		= createButton(container, "Pause", 290, 565, onBtnPauseClick);
			m_buttonPres1		= createButton(container, "presentation1", 400, 630, onBtnPres1Click);
			m_buttonPres2		= createButton(container, "presentation2", 520, 630, onBtnPres2Click);
			m_lSlideIndex		= createLabel(container, "Current slide index: ", 530, 567);
			m_lPos				= createLabel(container, "Position:", 37, 603);
			m_lVolume			= createLabel(container, "Volume:", 37, 633);
			m_posSlider			= createSlider(container, 140, 610, 570, 30, true);
			m_volumeSlider		= createSlider(container, 140, 640, 150, 30, true);
			
			m_buttonPause.visible = false;
			
			m_volumeSlider.value = m_volumeSlider.maximum;
			
			m_volumeSlider.addEventListener(SliderEvent.THUMB_PRESS,	onVolumeSliderThumbPress);
			m_volumeSlider.addEventListener(SliderEvent.THUMB_RELEASE,	onVolumeSliderThumbRelease);
			m_volumeSlider.addEventListener(SliderEvent.CHANGE,			onVolumeSliderChange);
			
			m_posSlider.addEventListener(SliderEvent.THUMB_PRESS,	onPosSliderThumbPress);
			m_posSlider.addEventListener(SliderEvent.THUMB_RELEASE,	onPosSliderThumbRelease);
			m_posSlider.addEventListener(SliderEvent.CHANGE,		onPosSliderChange);

		}

		////////////////////////////////////////////////////////////
		// Components creation methods
		////////////////////////////////////////////////////////////
		
		private static function createSprite(container:DisplayObjectContainer, x0:Number, y0:Number):Sprite
		{
			var s:Sprite = new Sprite();
			s.x = x0;
			s.y = y0;
			container.addChild(s);
			return s;
		}
		
		private static function createButton(container:DisplayObjectContainer, labelText:String, x0:Number, y0:Number, clickHandler:Function):Button
		{
			var btn:Button = new Button();
			btn.label = labelText;
			btn.move(x0, y0);
			btn.addEventListener(MouseEvent.CLICK, clickHandler);
			container.addChild(btn);
			return btn;
		}

		private static function createLabel(container:DisplayObjectContainer, labelText:String, x0:Number, y0:Number):Label
		{
			var lbl:Label = new Label();
			lbl.autoSize = TextFieldAutoSize.CENTER;
			lbl.move(x0, y0);
			lbl.text = labelText;
			container.addChild(lbl);
			return lbl;
		}

		private static function createSlider(container:DisplayObjectContainer, x0:Number, y0:Number, width:Number, height:Number, liveDragging:Boolean):Slider
		{
			var s:Slider = new Slider();
			s.move(x0, y0);
			s.setSize(width, height);
			s.maximum = 1;
			s.snapInterval = 0.001;
			s.liveDragging = liveDragging;
			container.addChild(s);
			return s;
		}
	}
}