/**
 * The AVPlayer package
 *
 * @package    AvPlayer
 * @author     AlloVince <allo.vince@gmail.com>
 * @copyright  2008-2009 AVE7.NET
 * @license    GNU General Public License v3
 * @link       http://code.google.com/p/tsostplayer/
 */
package {
	import flash.events.*;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.media.SoundLoaderContext;
	import flash.display.*;
	import flash.errors.*;
	import flash.utils.ByteArray;
	
	//import flash.net.URLRequest;
	import flash.net.*;
	//JS Interface
	import flash.external.ExternalInterface;
	import flash.text.TextField;
	//import com.adobe.serialization.json.*;
	import AvPlayer.*;
	
	/**
	 * The AVPlayer Core Class
	 *
	 * @version    0.09
	 */
	public class AvPlayer extends MovieClip{

		//Player全局设置
		private var _options = {
			debug : true, //Debug Mode
			jsName : 'avp', // Js new Class Name
			autoStart : false, //自动开始播放
			autoNext : false, //自动播放下一首
			shuffle : false, //乱序播放
			loop : false //循环播放
		}

		
		//曲目播放那个状态
		private var _status = {
			hasLoaded:false, //已经将链接读入
			loadComplete:false, //已经读取完毕
			isPlaying:false, //正在播放
			pausePosition:0, //暂停位置
			loadLength:0, //已经读取的长度
			length:0, //曲目全长
			played:0, //已经播放长度
			volume:0.7, //音量
			listIndex:0 //播放列表位置
		}
		
		//UI设置
		private var _UI = {
			initBar: {
				width:140,
				height:14,
				posx:58,
				posy:3.5,
				bg:"0xFFFFFF",
				round:5
			},
			loadedBar:{
				width:140,
				height:14,
				posx:58,
				posy:3.5,
				bg:"0xEFEFEF",
				round:5
			},
			playedBar:{
				width:140,
				height:14,
				posx:58,
				posy:3.5,
				bg:"0xCFE8FF",
				round:5
			},
			pointer:{
				x:58,
				y:5,
				radius:2,
				areaX:60,
				areaY:10,
				areaWidth:140,
				areaHeigth:12,
				blur:6,
				color:"0x677FA5",
				alpha:0
			},
			playerTimer : {
				x:60,
				y:0.5,
				size:9,
				textColor:"0x000000",
				mouseEnabled:false
			}
		};
		
		//当前播放媒体
		private var _melody:Object = {
			title:'',
			artist:'',
			album:'',
			link:'',
			year:'',
			track:'',
			comment:'',
			lyric:''
		};
		

		private var _sound:Sound = new Sound();
		private var _req:URLRequest;
		private var _channel:SoundChannel;
		
		//生成List用
		private var _melodySample:Object;
		
		//播放列表
		private var _playlist:Array = new Array();
		//播放列表URL
		private var _playlistUrl:String = "";
		private var _playlistXML:XML = new XML();
		private var _playlistLoader:URLLoader;
		
		private var _streamPlay:SoundLoaderContext = new SoundLoaderContext(8000, true);
		//声道
		private var _trans:SoundTransform = new SoundTransform(_status.volume, 0);
		
		//Flash vars
		private var _param:Object = LoaderInfo(root.loaderInfo).parameters;
		
		//计时器
		private var _showtimer;
		//计时器的文字栏
		private var _timerText:TextField = new TextField();
		//进度条
		public var _progressBar;
		

		
		public var _error = false;
		
		/** ----------------------------
		 * 
		 * Function Series actionXXX
		 * 对外部公开的函数，可供Js调用
		 * 全部为public
		 * 
		 *  ----------------------------*/
		 
		/**
		 * 播放曲目
		 *
		 * @param  melody String or Object
		 * @return void
		 * @access public
		 */
		public function actionPlay(url = null){
			var same = url ? actionSetMelody(url) : true;
			
			if(!_melody.link) {
				return p('no media input');
			}
			
			//已经开始播放且为同一首歌
			if(_status.isPlaying == true && same == true){
				return p("has played");
			}
			
			//要更改播放曲目，首先停止当前音乐，
			if(same == false) {
				actionStop();
			}
			
			//p(_melody);
			
			//未被读入,重新初始化Sound对象
			if (_status.hasLoaded == false) {
				try{
					_sound = new Sound();
					_req = new URLRequest(_melody.link);
					//Load error hander
					_sound.addEventListener(IOErrorEvent.IO_ERROR, this.ioErrorHandler);
					_sound.load(_req,_streamPlay);
				}
				catch(e:Error){
					p('actionPlay Load Error' + e);
				}
			}
			try{
					//设置状态
					_status.hasLoaded = true;

					//监控读取过程
					_sound.addEventListener(ProgressEvent.PROGRESS, this.onLoadProgress);
					_sound..addEventListener(Event.ID3, this.onGetID3Info);
					//增加读取完毕事件
					_sound.addEventListener(Event.COMPLETE, this.onSoundLoaded);
					
					//播放实时监控
					addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
					
					//开始播放
					_channel = _sound.play(_status.pausePosition,1,_trans);
					
					//音量
					_channel.soundTransform = _trans;
					
					//初始化暂停位置
					_status.pausePosition = 0;
					_status.isPlaying = true;
					
					//游标初始化
					_progressBar.initPointer(this.onDropPointer);
					this.addChild(_progressBar.pointerArea);
					this.addChild(_progressBar.pointer);
					
					//增加完成监听
					_channel.addEventListener(Event.SOUND_COMPLETE, this.onPlayComplete);
					
			}
			catch(e:Error){
				p('startplay error' + e);
			}
		}

		/**
		 * 重置操作，清除曲目状态，解除事件绑定
		 *
		 * @param  void
		 * @return void
		 * @access public
		 */
		public function actionReset(){
			//重置曲目播放状态
			_status.hasLoaded = false;
			_status.isPlaying = false;
			
			//解除时间绑定
			removeEventListener(IOErrorEvent.IO_ERROR, this.ioErrorHandler);
			removeEventListener(ProgressEvent.PROGRESS, this.onLoadProgress);
			removeEventListener(Event.SOUND_COMPLETE, this.onPlayComplete);
			removeEventListener(Event.ENTER_FRAME, this.onEnterFrame);
			removeEventListener(Event.COMPLETE, this.onSoundLoaded);
			
			//读取过程中关闭声音需要配合close来结束sound类
			_sound.close();
			_sound = null;
		}
		
		/**
		 * 暂停操作
		 *
		 * @param  void
		 * @return void
		 * @access public
		 */
		public function actionPause(){
			//如果正在播放，记录曲目位置并停止
			if (_status.pausePosition == 0 && _status.isPlaying == true) {
				this.actionStop(_channel.position);
			}
			//如果未播放且之前有暂停记录，则恢复播放
			else if (_status.pausePosition > 0 && _status.isPlaying == false) {
				this.actionPlay();
			}
			else {
				p("Nothing to Pause");
			}
		}
		
		/**
		 * 停止操作
		 *
		 * @param  position
		 *         position = 0 进行完全停止操作，恢复曲目状态，并解除事件绑定
		 *         position != 0 仅停止声音播放
		 * @return void
		 * @access public
		 */
		public function actionStop(position:Number = 0):void{
			//还没有读入
			if(!_status.hasLoaded) {
				return;
			}
			
			try {
				//停止播放
				_channel.stop();
				//停止计时器
				_showtimer.stopTimer(position);
				//记录停止位置
				_status.pausePosition = position;
				_status.isPlaying = false;
			}
			catch(e:Error) {
				p('actionStop Error' + e);
			}
			
			//完全停止
			if(position == 0){
				
				//在读取过程中中止，需要用close关闭sound
				if(_status.loadComplete == false) {
					removeEventListener(ProgressEvent.PROGRESS, this.onLoadProgress);
					_sound.close();
				}
				
				
				//取消监听
				removeEventListener(Event.SOUND_COMPLETE, this.onPlayComplete);
				removeEventListener(Event.ENTER_FRAME, this.onEnterFrame);
				removeEventListener(Event.COMPLETE, this.onSoundLoaded);
				
				
				//恢复状态
				_status.hasLoaded = false;
				_status.played = 0;
				
				
				//重置进度条
				this.removeChild(_progressBar.loadbar);
				this.removeChild(_progressBar.playbar);
				
				
				//时间显示
				_timerText.text = '';
			}
		}
		
		/**
		 * 取得当前播放状态
		 *
		 * @param  void
		 * @return _status:Object
		 * @access public
		 */
		public function actionStatus(){
			return _status;
		}
		
		/**
		 * 设置当前曲目
		 *
		 * @param  melody:Object
		 * @return void
		 * @access public
		 */
		public function actionSetMelody(melody){
			//p(melody);
			if(!melody) {
				p('Nothing to SetMelody');
				return false;
			}
			else if(melody is String) {
				melody = {link:melody}
			}
			else if(melody is Object) {
				melody = melody;
			}
			else {
				p('SetMelody Error')
				return false;
			}
			var same = melody.link == _melody.link ? true : false;
			_melody = same == true ? _melody : melody;
			return same;
		}
		
		/**
		 * 设置当前曲目列表
		 *
		 * @param  list:Object
		 * @return void
		 * @access public
		 */
		public function actionSetList(url){
			var list_url:URLRequest = new URLRequest(url);
			_playlistLoader = new URLLoader();
			_playlistLoader.addEventListener(IOErrorEvent.IO_ERROR, this.ioErrorHandler);
			_playlistLoader.addEventListener("complete", onListLoad);
			try{
				_playlistLoader.load(list_url);
			}
			catch(e:Error){
				
			}
		}
		

		/**
		 * 播放下一首
		 *
		 * @param  url:String 下一首的Url
		 * @return void
		 * @access public
		 */
		public function actionNext(url = ''){
			
			//未播放状态点击Next是否开始播放
			if(_status.isPlaying == false) {
				//return p("not played yet");
			}
			
			//顺序播放
			if(!_options.shuffle) {
				
				//最后一首
				if(_status.listIndex == _playlist.length - 1) {
					//回到第一首
					_status.listIndex = 0;
					//return p('this is the last one');
				}
				else {
					//下一首
					_status.listIndex < _playlist.length ? _status.listIndex++ : '';
				}
			}
			//乱序播放
			else {
				//产生播放列表范围内的随机数
				_status.listIndex = Math.floor(Math.random()* _playlist.length);
			}


			for(var i in _playlist) {
				if(i == _status.listIndex) {
					actionSetMelody(_playlist[i]);
					actionStop();
					actionPlay(url);
					break;
				}
			}
		}
		
		/**
		 * 播放上一首
		 *
		 * @param  url:String 上一首的Url
		 * @return void
		 * @access public
		 */
		public function actionPrev(url = ''){
			if(_status.isPlaying == false) {
				//return p("not played yet");
			}
			
			//顺序播放
			if(!_options.shuffle) {
				
				//第一首
				if(_status.listIndex == 0) {
					//回到最后一首
					_status.listIndex = _playlist.length - 1;
				}
				else {
					//上一首
					_status.listIndex > 0 ? _status.listIndex-- : '';
				}
			}
			//乱序播放
			else {
				//产生播放列表范围内的随机数
				_status.listIndex = Math.floor(Math.random()* _playlist.length);
			}
			
			for(var i in _playlist) {
				if(i == _status.listIndex) {
					actionSetMelody(_playlist[i]);
					actionStop();
					actionPlay(url);
					break;
				}
			}
		}
		
		
		/** ----------------------------
		 * 
		 * Function Series onXXX
		 * 对事件进行绑定的函数
		 * 
		 *  ----------------------------*/
		 
		/**
		 * 被绑定的播放事件
		 *
		 * @param  event:MouseEvent
		 * @return void
		 * @access private
		 */
		private function onPlay(event:MouseEvent):void {
			this.actionPlay();
		}
		/**
		 * 被绑定的暂停事件
		 *
		 * @param  event:MouseEvent
		 * @return void
		 * @access private
		 */
		private function onPause(event:MouseEvent):void {
			this.actionPause();
		}
		/**
		 * 被绑定的停止事件
		 *
		 * @param  event:MouseEvent
		 * @return void
		 * @access private
		 */
		private function onStop(event:MouseEvent):void {
			this.actionStop();
		}
		/**
		 * 被绑定的下一首事件
		 *
		 * @param  event:MouseEvent
		 * @return void
		 * @access private
		 */
		private function onNext(event:MouseEvent):void {
			this.actionNext();
			ExternalInterface.call(_options.jsName + ".PlayNext");
		}
		/**
		 * 被绑定的上一首事件
		 *
		 * @param  event:MouseEvent
		 * @return void
		 * @access private
		 */
		private function onPrev(event:MouseEvent):void {
			this.actionPrev();
			ExternalInterface.call(_options.jsName + ".PlayPrev");
		}

		
		/**
		 * 被绑定的读取进度事件
		 *
		 * @param  event:Event
		 * @return void
		 * @access private
		 */
		private function onLoadProgress(event:ProgressEvent):void {
			if(_sound.length > 0) {
				try{
					//读取过程中动态计算全长
					_status.length = _sound.length / (_sound.bytesLoaded / _sound.bytesTotal);
					//动态计算已经读取的长度
					_status.loadLength = _status.length * (_sound.bytesLoaded / _sound.bytesTotal);

					//读取进度条
					_progressBar.playProgress(_progressBar.loadbar,_UI.loadedBar,_sound.bytesLoaded / _sound.bytesTotal);
					this.addChild(_progressBar.loadbar);
				}
				catch(e:Error) {
					p("LoadProgress Error" + e);
				}
			}
		}
		
		/**
		 * 被绑定的读取完成事件
		 *
		 * @param  event:Event
		 * @return void
		 * @access private
		 */
		private function onSoundLoaded(event:Event):void {
			//加载完毕后启用实际长度，取消监听,启用游标
			removeEventListener(ProgressEvent.PROGRESS, this.onLoadProgress);
			_status.loadComplete = true;
			_status.length = _sound.length;
		}
		

		/**
		 * 被绑定的播放完成事件
		 *
		 * @param  event:Event
		 * @return void
		 * @access private
		 */
		private function onPlayComplete(event:Event) {
			this.actionStop();
			
			//有播放列表 and 自动连续播放
			if(_playlist.length > 0 && _options.autoNext) {
				
				if(!_options.shuffle && !_options.loop && _status.listIndex == _playlist.length - 1) {
					//顺序播放且不循环,在最后一首停止
				}
				else {
					this.actionNext();
					this.actionPlay();
				}
			}
			
			ExternalInterface.call(_options.jsName + ".PlayComplete");
		}
		
		/**
		 * 被绑定的获取ID3 Tag事件
		 *
		 * @param  event:Event
		 * @return void
		 * @access private
		 */
		private function onGetID3Info(event:Event) {
			var id3 = event.target.id3;
			//p(id3);
		}
		
		/**
		 * 被绑定的播放列表读取事件
		 *
		 * @param  event:Event
		 * @return void
		 * @access private
		 */
		private function onListLoad(event:Event):void {
			
			_playlistXML = XML(_playlistLoader.data);
			
			var tmp:Object = new Object;
			
			//有link,将link作为播放列表的第一条入栈
			if(_param.link) {
				tmp = cloneObj(_melodySample);
				tmp.link = _param.link;
				_playlist.push(tmp);
			}

			for(var i in _playlistXML.channel.item) {
				//每回创建一个新的Obj
				tmp = cloneObj(_melodySample);
				tmp.title = _playlistXML.channel.item[i].title;
				tmp.link = _playlistXML.channel.item[i].link;
				_playlist.push(tmp);
				//p(tmp);
			}
			
			//没有Link参数，将播放列表的第一条作为当前曲目
			if(!_param.link) {
				this.actionSetMelody(_playlist[0]);
				_options.autoStart == true ? this.actionPlay() : '';
			}
		}
		

		/**
		 * 被绑定的监听事件
		 *
		 * @param  event:Event
		 * @return void
		 * @access private
		 */
		private function onEnterFrame(event:Event):void {
			//开始播放
			if(_channel.position > 0) {
				try{
					//开始计时器
					_showtimer.startTimer(_channel.position,_status.length);
				
					//显示计数
					_timerText.text = _showtimer.timeStatus.played;
					_status.played = _channel.position;
				
					//当前播放百分比
					var pesent = _channel.position / _status.length;
					pesent = pesent > 0 ? pesent : 0; //修正参数类型
	
					//进度条
					_progressBar.playProgress(_progressBar.playbar,_UI.playedBar, pesent);
					this.addChild(_progressBar.playbar);
					
					this.addChild(_timerText);
	
					ExternalInterface.call(_options.jsName + ".EnterFrame",_status.played);
				}
				catch(e:Error) {
					p("EnterFrame Error" + e);
				}
			}
		}
		
		/**
		 * 点击游标
		 *
		 * @param  pesent 播放位置的百分比
		 * @return void
		 * @access private
		 */
		private function onDropPointer(pesent) {
			if(_status.isPlaying == true){
				//点击位置超过了当前读取量
				if(_status.pausePosition >= _status.loadLength) {
					p('this Position is not loaded yet');
				}
				_status.pausePosition = _status.length * pesent;
				this.actionStop(_status.pausePosition);
				this.actionPlay();
			}
			else {
				p("Nothing is Playing");
			}

		}

		/**
		 * 读取过程中的出错处理
		 *
		 * @param  e:IOErrorEvent
		 * @return void
		 * @access private
		 */
		private function ioErrorHandler(e:IOErrorEvent)	{
			trace(e);
			_status.isPlaying ? this.actionReset() : '';
			ExternalInterface.call(_options.jsName + ".IoError");
			//ExternalInterface.call('console.log',"[%s]",e); //如果loading过程中退出，此处的参数传递在errorhandler中无法响应,所以不能直接用ExternalInterface.call
		}
		
		/**
		 * 打印信息
		 *
		 * @param  m 所要打印的信息
		 * @return void
		 * @access private
		 */
		private function p(m,level = 0){
			if(!_options.debug) return false;
			var type = typeof(m);
			if(type == 'object') {
				for(var i in m) {
					var s = i + ' : ';
					if(typeof(m[i]) == 'object') {
						trace(s);
						ExternalInterface.call('console.log',"[%s]",s);
						s = '';
						p(m[i],level + 1);
					}
					else {
						s = i + ' : ' + m[i];

					}
					for(var j = 0; j < level; j++) {
						s = "\t" + s;
					}
					if(s) {
						trace(s);
						ExternalInterface.call('console.log',"[%s]",s);
					}
				}
				
			}
			else {
				trace(m);
				ExternalInterface.call('console.log',"[%s]",m);
			}

		}
		
		/**
		 * 根据Flash Vars初始化内部参数
		 *
		 * @param  void
		 * @return void
		 * @access private
		 */
		private function initParam(){
			
			if(_param.autostart) {
				_options.autoStart = _param.autostart;
			}
			
			if(_param.autonext) {
				_options.autoNext = _param.autonext;
			}
			
			if(_param.shuffle) {
				_options.shuffle = _param.shuffle;
			}
			
			if(_param.loop) {
				_options.loop = _param.loop;
			}
			
			if(_param.list) {
				_melodySample = cloneObj(_melody);
				this.actionSetList(_param.list);
			}
			
			if(_param.link) {
				this.actionSetMelody(_param.link);
				//自动开始播放
				_options.autoStart == true ? this.actionPlay() : '';
			}
			

		}
		
		/**
		 * 初始化计时器
		 *
		 * @param  void
		 * @return void
		 * @access private
		 */
		private function initTimer(){
			//时间显示初始化
			_showtimer = new Showtimer();

			_timerText.x = _UI.playerTimer.x;
			_timerText.y = _UI.playerTimer.y;
			//_timerText.size = _UI.playerTimer.size;
			_timerText.mouseEnabled = _UI.playerTimer.mouseEnabled;
			_timerText.textColor = _UI.playerTimer.textColor;
		}
		
		/**
		 * 初始化播放器
		 *
		 * @param  void
		 * @return void
		 * @access private
		 */
		private function initPlayer(){
			//进度条初始化
			_progressBar = new Progress(_UI);
			this.addChild(_progressBar.initProgress());
			
			//计时器初始化
			initTimer();
			
			//如果有参数，初始化参数
			//_param.link = "http://mediaplayer.yahoo.com/example1.mp3";
			//_param.list = "Demos/list.xml";
			initParam();
			
			//对元素绑定事件
			buttPlay.addEventListener(MouseEvent.CLICK,onPlay);			
			buttPause.addEventListener(MouseEvent.CLICK,onPause);
			buttStop.addEventListener(MouseEvent.CLICK,onStop);
			
			buttPrev.addEventListener(MouseEvent.CLICK,onPrev);
			buttNext.addEventListener(MouseEvent.CLICK,onNext);
			
			//公开所有对外函数
			ExternalInterface.addCallback("avStop", actionStop);
			ExternalInterface.addCallback("avPlay", actionPlay);
			ExternalInterface.addCallback("avPause", actionPause);
			ExternalInterface.addCallback("avReset", actionReset);
			ExternalInterface.addCallback("avStatus", actionStatus);
			ExternalInterface.addCallback("avMelody", actionSetMelody);
			ExternalInterface.addCallback("avList", actionSetList);
		}

		/**
		 * 构造函数
		 *
		 * @param  void
		 * @return void
		 * @access public
		 */
		public function AvPlayer() {
			initPlayer();
		}
		
		/**
		 * 复制一个对象而不是引用
		 *
		 * @param source:Object 所要复制的对象
		 * @return Object
		 * @access private
		 */
		private function cloneObj(source:Object):* {
			var copier:ByteArray = new ByteArray();
			copier.writeObject(source);
			copier.position = 0;
			return(copier.readObject());
		}
	}
	
}