function iFlyPlayer() {
	this.loadAudio = function(url) {
		this.__proxy__.loadAudio(url)
	};
	this.play = function() {
		this.__proxy__.play()
	};
	this.playRange = function(beginPos, endPos) {
		this.__proxy__.playRange(beginPos, endPos)
	};
	this.pause = function() {
		this.__proxy__.pause()
	};
	this.stop = function() {
		this.__proxy__.stop()
	};
	this.getVolume = function() {
		return this.__proxy__.getVolume()
	};
	this.setVolume = function(volume) {
		this.__proxy__.setVolume(volume)
	};
	this.setMute = function(isMute) {};
	this.onReady = function() {
		this.__proxy__.addEventListener("onReady", arguments[0])
	};
	this.onError = function() {
		this.__proxy__.addEventListener("onError", arguments[0])
	};
	this.onPlayBegin = function() {
		this.__proxy__.addEventListener("onPlayBegin", arguments[0])
	};
	this.onPlaying = function() {
		this.__proxy__.addEventListener("onPlaying", arguments[0])
	};
	this.onBuffering = function() {
		this.__proxy__.addEventListener("onBuffering", arguments[0])
	};
	this.onPause = function() {
		this.__proxy__.addEventListener("onPause", arguments[0])
	};
	this.onStop = function() {
		this.__proxy__.addEventListener("onStop", arguments[0])
	}
}(function(win) {
	if (!win.JWPlayerSettings) {
		win.JWPlayerSettings = {
			PlayerSWF: "js/iFlyPlayer/jwplayer/player.swf"
		}
	}
	function JWPlayer(option) {
		option = option || {};
		option.events = option.events || {};
		this.__proxy__ = {};
		var _this = this;
		var _events;
		var _isPlayRange;
		var _rangeET;
		var _state = "IDLE";
		var _audioLoading;
		var _bufferPercent;
		var _pendingPlayRnage = [];
		var _pendingPlay;
		var _audioUrl;
		if (option.events) {
			_events = option.events;
			delete option.events
		}
		option.width = option.width || 1;
		option.height = option.height || 1;
		option.players = [{
			type: "flash",
			src: JWPlayerSettings.PlayerSWF
		}];
		option.id = option.id || "jwplayer-" + new Date().getTime();
		if (document.getElementById(option.id) === null) {
			var playerPanel = document.createElement("div");
			playerPanel.id = option.id;
			document.body.appendChild(playerPanel)
		}
		var _jw = jwplayer(option.id).setup(option);
		this.__proxy__.addEventListener = function(fnName, handler) {};
		_jw.onReady(function(e) {
			_jw.setVolume(100);
			var callback = _events.onReady;
			if (callback) {
				callback.call(_this, e)
			}
		});
		_jw.onError(function(e) {
			_audioLoading = false;
			var callback = _events.onError;
			if (callback) {
				callback.call(_this, e)
			}
		});
		_jw.onTime(function(e) {
			debug("onTime, _audioLoading:" + _audioLoading + ", _state:" + _state + ", _bufferPercent:" + _bufferPercent);
			if (_audioLoading && _bufferPercent === 100) {
				_jw.stop();
				_jw.setMute(false);
				setTimeout(function() {
					_audioLoading = false;
					if (_pendingPlay) {
						debug("onTime, pending play trigger");
						_jw.play(true);
						_pendingPlay = false
					}
					while (_pendingPlayRnage.length > 0) {
						var rangeInfo = _pendingPlayRnage.shift();
						debug("onTime, pending _pendingPlayRnage trigger:" + rangeInfo.begPos + "," + rangeInfo.endPos);
						_this.__proxy__.playRange(rangeInfo.begPos, rangeInfo.endPos)
					}
				}, 0)
			}
			if (!_audioLoading && _isPlayRange && e.position >= _rangeET) {
				_isPlayRange = false;
				_rangeET = undefined;
				_jw.stop()
			}
			if (!_audioLoading && (_state === "BUFFERING" || _state === "PLAYING")) {
				var callback = _events.onPlaying;
				if (callback) {
					callback.call(_this, e)
				}
			}
		});
		_jw.onBufferChange(function(e) {
			_bufferPercent = e.bufferPercent
		});
		_jw.onBeforePlay(function(e) {});
		_jw.onPlay(function(e) {
			_state = e.newstate;
			var callback = _events.onPlayBegin;
			if (!_audioLoading && callback) {
				e.duration = _jw.getDuration();
				callback.call(_this, e)
			}
		});
		_jw.onPause(function(e) {
			_state = e.newstate;
			var callback = _events.onPause;
			if (!_audioLoading && callback) {
				callback.call(_this)
			}
		});
		_jw.onBuffer(function(e) {
			_state = e.newstate;
			var callback = _events.onBuffering;
			if (!_audioLoading && callback) {
				callback.call(_this, e)
			}
		});
		_jw.onIdle(function(e) {
			_state = e.newstate;
			if (_isPlayRange) {
				_isPlayRange = false;
				_rangeET = undefined
			}
			var callback = _events.onStop;
			if (!_audioLoading && callback) {
				setTimeout(function() {
					callback.call(_this)
				}, 0)
			}
		});
		this.__proxy__.loadAudio = function(url) {
			if (_audioUrl === url) {
				return
			}
			_audioUrl = url;
			_state = "IDLE";
			_audioLoading = true;
			_jw.setMute(true);
			_jw.load(url);
			_jw.play(true)
		};
		this.__proxy__.play = function() {
			if (_audioLoading) {
				debug("_pendingPlay:");
				_pendingPlay = true
			} else {
				debug("play:");
				_jw.play(true)
			}
		};
		this.__proxy__.playRange = function(begPos, endPos) {
			if (_audioLoading) {
				debug("_pendingPlayRnage push:" + begPos + "," + endPos);
				_pendingPlayRnage.push({
					begPos: begPos,
					endPos: endPos
				})
			} else {
				debug("playRange:" + begPos + "," + endPos);
				_isPlayRange = true;
				_rangeET = endPos / 1000;
				_jw.seek(begPos / 1000);
				_jw.play(true)
			}
		};
		this.__proxy__.pause = function() {
			_jw.pause(true)
		};
		this.__proxy__.stop = function() {
			_pendingPlay = false;
			while (_pendingPlayRnage.length > 0) {
				_pendingPlayRnage.pop()
			}
			_jw.stop()
		};
		this.__proxy__.getVolume = function() {
			return _jw.getVolume()
		};
		this.__proxy__.setVolume = function(volume) {
			if (!isNaN(volume)) {
				if (volume < 0) {
					volume = 0
				} else if (volume > 100) {
					volume = 100
				}
				_jw.setVolume(volume)
			}
		};
		this.getDuration = function() {
			return _jw.getDuration()
		}
	};
	JWPlayer.prototype = new iFlyPlayer();
	JWPlayer.prototype.constructor = JWPlayer;

	function debug(msg) {};
	win.JWPlayer = JWPlayer
})(window);