﻿// RM3S Player Class
RM3SPlayer = function(varName, id, preferredType, videoWidth, videoHeight, autoStart, nativeControls, videoURL, startSecs) 
{
	this.varName = varName;
	this.id = id;
	this.type = "";
	this.preferredType = preferredType;
	this.videoWidth = (isNaN(videoWidth) ? 400 : videoWidth);
	this.videoHeight = (isNaN(videoHeight) ? 225 : videoHeight);
	this.autoStart = (autoStart == true || autoStart == "true" ? true : false);
	this.nativeControls = (nativeControls == true || nativeControls == "true" ? true : false);;
	this.videoURL = videoURL;
	this.startSecs = (isNaN(startSecs) ? 0 : startSecs);
	this.timer = null;
	this.timerTimeout = 200; // ms
	this.onTimeChange = null;
	this.onPositionChange = null;
	this.state = {time:null, totaltime:null, loadedtime:null, state:0, stateStr:'', volume:50, muted:false, savedvolume:50};
	this.container = null;
	this.controlsContainer = null;
	this.skipProgressClick = false;
}

RM3SPlayer.prototype = {
	getAppropriateTypes: function() {
		var browser = rm3s_getBrowser();
		var ext = "";
    var isLocal = false;
    if(this.videoURL != null) {
        var i = this.videoURL.lastIndexOf('.');
        if(i > 0) ext = this.videoURL.substring(i + 1);
        ext = ext.replace(/(\s+)/g, ""); // trim
        isLocal = (this.videoURL.indexOf("file://") >= 0);
    }
		var list = [];
		if(browser.type == "ie" && (ext == "wmv" || ext == "mpg" || ext == "avi" || ext == "mp3")) list.push("wmp");
		if(!isLocal && (ext == "wmv" || ext == "mpg" || ext == "mp3")) list.push("slp");
		if(ext == "mov" || ext == "mp4" ) list.push("qtp");
		if(ext == "flv") list.push("flp");
		
		if(list.length == 0) list.push(browser.type == "ie" ? "wmp" : (isLocal ? "qtp" : "slp"));
		
		return list;
	},

	createInstance: function(container, controlsContainer) {
		this.container = container;
		this.controlsContainer = controlsContainer;
		if(container == null) return;
		if(container.innerHTML == null) container = document.getElementById(container);
		if(container.innerHTML == null) return;
		
		container.innerHTML = "";
		
		if(this.type == null || this.type == "") {
			var appTypes = this.getAppropriateTypes();
			if(appTypes != null && appTypes.length > 0) {
				this.type = appTypes[0];
				if(this.preferredType != null && this.preferredType != "") {
					for(var i = 0, n = appTypes.length; i < n; i++) {
						if(appTypes[i] == this.preferredType) { 
							this.type = this.preferredType;
							i = n;
						}
					}
				}
			}
		}
		var innerHTML = null;
		var wndWidth = this.videoWidth;
		var wndHeight = this.videoHeight;
		if(this.nativeControls) {
			wndWidth += 0;
			wndHeight += (this.type == "wmp" ? 65 : (this.type == "qtp" ? 16 : 37));
		}
		
		if(this.type == "wmp") {
			// Windows MediaPlayer
			innerHTML = '<object id="' + this.id + '" name="' + this.id + '" width="' + wndWidth + '" height="' + wndHeight + '" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" onPositionChange="player_onPositionChange(dblOldPosition, dblNewPosition);">' +
										'<param name="URL" value="' + this.videoURL + '" />' +
										'<param name="AutoStart" value="' + (this.autoStart ? 1 : 0) + '" />' +
										'<param name="uiMode" value="' + (this.nativeControls ? "full" : "none") + '" />' +
										'<param name="volume" value="100" />' +
										'<param name="rate" value="1" />' +
										'<param name="currentPosition" value="' + this.startSecs + '" />' + 
										'<param name="StretchtoFit" value="-1" />' +
										'<param name="playCount" value="1" />' +
										'<param name="invokeURLs" value="-1" />' +
										'<param name="enabled" value="-1" />' +
										'<param name="enableContextMenu" value="-1" />' +
										'<param name="fullScreen" value="0" />' +
									'</object>';
		} else if(this.type == "slp") {
			// Silverlight based player
      var cmd = '({"URL" : "' + this.videoURL + '", ' +
								'"AutoPlay" : ' + (this.autoStart ? "true" : "false") + ', ' + 
								'"Width" : ' + this.videoWidth + ', ' +
								'"Height" : ' + this.videoHeight + ', ' +
								'"HideControlBox" : ' + (this.nativeControls ? "false" : "true") + ', ' +
								'"onPositionChange" : player_onPositionChange})';
			container.mediaInfo = cmd;			

      var scene = new sPlayer.sPlayer();
      Silverlight.createObjectEx({
        source: "sPlayer2/sPlayer.xaml", //"sPlayer/sPlayer.xaml.aspx?w=" + this.videoWidth + "&h=" + this.videoHeight + "&c=" + (this.nativeControls ? "true" : "false"),
        parentElement: container,
        id: this.id,
        properties: {
					background: "#000000",
					width: "" + wndWidth,
          height: "" + wndHeight,
          version: "1.0"
        },
        events: {
          onLoad: Silverlight.createDelegate(scene, scene.handleLoad),
          onError: function(sender, args) {
              var errorText = args.errorType + " - " + args.errorMessage;
    							
              if (args.ErrorType == "ParserError") {
                errorText += "<br>File: " + args.xamlFile;
                errorText += ", line " + args.lineNumber;
                errorText += " character " + args.charPosition;
              } else if (args.ErrorType == "RuntimeError") {
                errorText += "<br>line " + args.lineNumber;
                errorText += " character " +  args.charPosition;
              }
              //alert(errorText);
            }	
        }
      });
		} else if(this.type == "qtp") {
			// QuickTime player
			innerHTML = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" ' +
											'width="' + wndWidth + '" height="' + wndHeight + '" id="' + this.id + '">' +
										'<param name="autoplay" value="' + (this.autoStart ? "true" : "false") + '" />' +
										'<param name="controller" value="' + (this.nativeControls ? "true" : "false") + '" />' +
										'<param name="type" value="video/quicktime" />' +
										'<param name="scale" value="Aspect" />' +
										'<param name="enablejavascript" value="true" />' +
//										'<param name="' + (this.videoURL.indexOf("rtsp://") == 0 || this.videoURL.indexOf("rtp://") == 0 ? "qt" : "") + 'src" value="' + this.videoURL + '" />' +
										//'<param name="' + (this.videoURL.indexOf("rtsp://") == 0 || this.videoURL.indexOf("rtp://") == 0 ? "qt" : "") + 'src" value="' + this.videoURL + '" />' +
										//'<param name="qtsrc" value="' + this.videoURL + '" />' +
										'<param name="src" value="video/empty.mov" />' +
										'<param name="qtsrc" value="' + this.videoURL + '" />' +
										'<param name="bgcolor" value="#000000" />' +
										'<param name="starttime" value="' + rm3s_formatTime(this.startSecs, false, true) + ':00" />' +
										'<embed ' +
														//(this.videoURL.indexOf("rtsp://") == 0 || this.videoURL.indexOf("rtp://") == 0 ? "qt" : "") + 'src="' + this.videoURL + '" ' +
														'src="video/empty.mov" ' +
														'qtsrc="' + this.videoURL + '" ' +
														'width="' + wndWidth + '" ' +
														'height="' + wndHeight + '" ' +
														'type="video/quicktime" ' +
														'controller="' + (this.nativeControls ? "true" : "false") + '" ' +
														'pluginspage="www.apple.com/quicktime/download" ' +
														'name="' + this.id + '" enablejavascript="true" ' +
														'autoplay="' + (this.autoStart ? "true" : "false") + '" ' +
														'starttime="' + rm3s_formatTime(this.startSecs, false, true) + ':00" ' +
														'scale="Aspect" bgcolor="#000000">' +
										'</embed>' +
									'</object>';			
		}
		if(innerHTML != null) {
			container.innerHTML = innerHTML;
			container.style.width = wndWidth + "px";
			container.style.height = wndHeight + "px";
		}
		if(this.nativeControls == false && controlsContainer != null) {
			if(controlsContainer.innerHTML == null) controlsContainer = document.getElementById(controlsContainer);
			if(controlsContainer.innerHTML == null) return;
			controlsContainer.innerHTML = '<table border="0" cellpadding="0" cellspacing="0" style="width:100%; table-layout:fixed;" class="playerProgressBar" id="' + this.id + '_progressBar" onclick="playerEvent(\''+ this.varName + '\', \'onProgressBarClick\', event)">' +
																			'<tr>' +
																				'<td style="width:0px;" class="playerProgressDone" id="' + this.id + '_progressDone"><div class="playerProgressBullet" id="' + this.id + '_progressBullet" onmousedown="playerEvent(\''+ this.varName + '\', \'onProgressBulletDown\', event)" onclick="return false;"><div id="' + this.id + '_progressBulletHint" class="playerProgressBulletHint"></div></div></td>' +
																				'<td class="playerProgressEmpty" ></td>' +
																			'</tr>' +
																		'</table>' + 
																		'<table border="0" cellpadding="0" cellspacing="0" style="width:100%; table-layout:fixed;" class="playerControlsPanel">' +
																			'<tr>' +
																				'<td class="playerMuteButtonOn" onclick="playerCall(\''+ this.varName + '.mute()\')" id="' + this.id + '_muteButton" onmouseover="playerButtonHL(this, true)" onmouseout="playerButtonHL(this, false)"></td>' +
																				'<td class="playerVolumeBarCell">' + 
																					'<table border="0" cellpadding="0" cellspacing="0" class="playerVolumeBar" id="' + this.id + '_volumeBar" onclick="playerEvent(\''+ this.varName + '\', \'onVolumeBarClick\', event)">' +
																						'<tr>' +
																							'<td class="playerVolumeOn" id="' + this.id + '_volumeOn"></td>' +
																							'<td style="" class="playerVolumeOff"></td>' +
																						'</tr>' +
																					'</table>' +
																				'</td>' +
																				'<td class="playerBackButton" onclick="playerCall(\''+ this.varName + '.back()\')" id="' + this.id + '_backButton" onmouseover="playerButtonHL(this, true)" onmouseout="playerButtonHL(this, false)"></td>' +
																				'<td class="playerPlayButton" onclick="playerCall(\''+ this.varName + '.playpause()\')" id="' + this.id + '_playpauseButton" onmouseover="playerButtonHL(this, true)" onmouseout="playerButtonHL(this, false)"></td>' +
																				'<td id="' + this.id + '_time" class="playerTime">--:--:--/--:--:--</td>' +
																				'<td id="' + this.id + '_text" class="playerText">' + this.state.stateStr + '</td>' +
																				(this.type == "wmp" ? '<td  class="playerFullScreenButton" onclick="playerCall(\''+ this.varName + '.fullscreen()\')" id="' + this.id + '_fullscreenButton" onmouseover="playerButtonHL(this, true)" onmouseout="playerButtonHL(this, false)"></td>' : '<td style="playerEmptyButton"></td>') +
																			'</tr>' +
																		'</table>';
			controlsContainer.style.display = "block";
			//rm3s_registerEvent(document.getElementById(this.id + "_progressBullet"), "mousedown", function(event) { playerDragStart(event, this); });

			//var _volumeBar = document.getElementById(this.id + '_volumeBar');
			//if(_volumeBar != null) registerEvent(_volumeBar, "mousedown", playerVolumeClick);
			//else alert("ddd");

		} else if(this.nativeControls == true && controlsContainer != null) {
			controlsContainer.style.display = "none";
		}
		
	},
	
	changeVideoURL: function(videoURL, container, controlsContainer) {
		this.videoURL = videoURL;
		this.type = "";
		this.state = {time:null, totaltime:null, loadedtime:null, state:0, stateStr:'', volume:50, muted:false, savedvolume:50};
		if(container != null) this.createInstance(container, controlsContainer);	
	},

	resize: function(width, height) {
		this.videoWidth = width;
		this.videoHeight = height;
		
		var instance = this.getInstance();
		if(instance != null) {
			instance.width = width;
			instance.height = height;
		}
	},

	getInstance: function() {
		var instance = null;
		if(this.type == "slp") {
			var v_Host = document.getElementById(this.id);
			if(v_Host != null && v_Host.content != null) instance = v_Host.content.findName("Media");							
		}
		else if(this.type == "wmp" || this.type == "qtp") instance = rm3s_getEmbedObjectById(this.id);
		else instance = rm3s_getEmbedObjectById(this.id);
		return instance;
	},
	
	startTimer: function(timeout) {
		if(timeout != null && !isNaN(timeout) && timeout > 0) this.timerTimeout = timeout;
		if(this.timer != null) window.clearTimeout(this.timer);
		// update control panel
		try { this.updateControls(); } catch(e) { }
		this.timer = window.setTimeout("playerCall('" + this.varName + ".startTimer()');", this.timerTimeout);
	},
	
	updateControls: function(updateAll) {
		if(this.nativeControls == true) return;
		var _progressBar = document.getElementById(this.id + '_progressBar');
    var time = this.getCurrentTime();
    var totaltime = this.getTotalTime();
    if(this.state.time != time || this.state.totaltime != totaltime || updateAll) {
			this.state.time = time;				    
			this.state.totaltime = totaltime;				    
			var _time = document.getElementById(this.id + '_time');
			if(_time != null) _time.innerHTML = rm3s_formatTime(time, false, true) + "/" + rm3s_formatTime(totaltime, false, true);
			
			var _progressBullet = document.getElementById(this.id + '_progressBullet');
			if(_progressBar != null && _progressBullet != null) {
				var w = (totaltime > 0 ? Math.round(((_progressBar.offsetWidth - _progressBullet.offsetWidth) * time)/totaltime) : 0);
				_progressBullet.style.left = w + "px";
/*				var w = (totaltime > 0 ? Math.round(((_progressBar.offsetWidth - _progressBullet.offsetWidth) * time)/totaltime) : 0);
				_progressBullet.style.left = w + "px";*/
			}
			
		}
		if(this.onTimeChange != null) {
			try { this.onTimeChange(); } catch(e) { }
		}
		
		var loadedtime = this.getLoadedTime();
		if(this.state.loadedtime != loadedtime || updateAll) {
			this.state.loadedtime = loadedtime;
			var _progressDone = document.getElementById(this.id + '_progressDone');
			if(_progressDone != null && _progressDone != null) {
				//var w = (totaltime > 0 ? Math.round((_progressBar.offsetWidth * loadedtime)/totaltime) : 0);
				//_progressDone.style.width = w + "px";
				var w = (totaltime > 0 ? ((100 * loadedtime)/totaltime) : 0);
				_progressDone.style.width = w + "%";
			}
		}
		
		var state = this.getState();
		if(state != null) { // && this.state.state != state.state || this.state.stateStr !=  state.stateStr || this.type == "slp" || this.type == "qtp") {
			this.state.state = state.state;
			this.state.stateStr = state.stateStr;
			var _text = document.getElementById(this.id + '_text');
			if(_text != null) _text.innerHTML = this.state.stateStr;// + " (" + this.state.state + ")";
			
			var _playpauseButton = document.getElementById(this.id + '_playpauseButton');
			if(_playpauseButton != null) {
				var newClass = (this.state.state == 3 ? "playerPauseButton" : "playerPlayButton");
				if(_playpauseButton.className.substr(_playpauseButton.className.length - 2) == "HL") newClass += "HL";
				if(_playpauseButton.className != newClass) _playpauseButton.className = newClass;
			}
		}
		
		var volume = this.getVolume();
		if(this.state.volume != volume || updateAll) {
			this.state.volume = volume;
			var _volumeBar = document.getElementById(this.id + '_volumeBar');
			var _volumeOn = document.getElementById(this.id + '_volumeOn');
			if(_volumeOn != null && _volumeBar != null) {
				var w = Math.round((_volumeBar.offsetWidth * volume)/100);
				_volumeOn.style.width = w + "px";
			}
		}
		
		var _muteButton = document.getElementById(this.id + '_muteButton');
		if(_muteButton != null) {
			var newClass = (this.state.muted ? "playerMuteButtonOff" : "playerMuteButtonOn");
			if(_muteButton.className.substr(_muteButton.className.length - 2) == "HL") newClass += "HL";
			if(_muteButton.className != newClass) _muteButton.className = newClass;
		}
		
	},
	
	playpause: function() {
		//debug("playpause");
		if(this.state.state == 3) {
			this.exec("pause");
			//this.state.state = 2;
			//this.state.stateStr = "Paused";
		} else {
			this.exec("play");
			//this.state.state = 3;
			//this.state.stateStr = "Playing";
		}
		this.updateControls();
	},
	
	back: function() {
		this.exec("goto", 0);
		window.setTimeout('playerCall(\''+ this.varName + '.exec("pause")\')', 200);
		this.state.state = 2;
		this.state.stateStr = "Paused";
		this.updateControls();
	},
	
	mute: function() {
		if(this.state.muted) {
			this.exec("volume", this.state.savedvolume);
		} else {
			this.state.savedvolume = this.state.volume;
			this.exec("volume", 0);
		}
		this.state.muted = !this.state.muted;
		this.updateControls();
	},
	
	fullscreen: function() {
		var playerObj = this.getInstance();
		if(playerObj == null) return null;
		try {
			switch(this.type) {
				case "wmp": playerObj.fullScreen = !playerObj.fullScreen; break;
				case "slp": document.getElementById(this.id).content.fullScreen = true; /*document.getElementById(this.id).sPlayer.switchFullScreen(true);*/ break;
				case "qtp": break;
			}
		} catch(e) {}		
		return null;
	},
	
	handleEvent: function(eventName, event) {
		//alert("handleEvent : " + eventName + " - " + event);
		if(!event) event = window.event;
		switch(eventName) {
			case "onVolumeBarClick":
				var _volumeBar = document.getElementById(this.id + '_volumeBar');
				var mouseOffset = coordinateFactory.mouseOffset(event);
				var clickOffset = mouseOffset.minus(coordinateFactory.topLeftOffset(_volumeBar));

				if(rm3s_getBrowser().type == "ie") clickOffset.x -= 4;
				var v = (_volumeBar == null ? 50 : Math.round(clickOffset.x * 100 / _volumeBar.offsetWidth));
				if(v < 0) v = 0;
				if(v > 100) v = 100;
				this.exec("volume", v);
				
				this.updateControls();
				break;
			case "onProgressBarClick":
				if(this.skipProgressClick) {
					this.skipProgressClick = false;
					break;
				}
				var _progressBar = document.getElementById(this.id + '_progressBar');
				var mouseOffset = coordinateFactory.mouseOffset(event);
				var clickOffset = mouseOffset.minus(coordinateFactory.topLeftOffset(_progressBar));
				var totaltime = this.getTotalTime();
				if(rm3s_getBrowser().type == "ie") clickOffset.x -= 4;
				var p = (_progressBar == null ? 0 : clickOffset.x * totaltime / _progressBar.offsetWidth);
				if(p < 0) p = 0;
				if(p > totaltime) p = totaltime;
				this.exec("goto", p);
				
				this.updateControls();
				break;
			case "onProgressBulletDown":
				playerDragStart(event, this);
				break;
		}
	},

	exec: function(cmd, args) {
		//debug("exec." + cmd + "(" + args + ")");
		var playerObj = this.getInstance();
		if(playerObj == null) return;
		if(cmd == "open") this.changeVideoURL(args, this.container, this.controlsContainer);
		var time = this.getCurrentTime();
		try {
			switch(this.type) {
				case "wmp":
					switch(cmd) {
						//case "open": playerObj.URL = args; break;
						case "play": playerObj.controls.play(); break;
						case "pause": playerObj.controls.pause(); break;
						case "goto": playerObj.controls.currentPosition = parseFloat(args); playerObj.controls.play(); break;
						case "volume": playerObj.settings.volume =parseInt(args); break;
					}
					break;
				case "slp":
					switch(cmd) {
						//case "open": playerObj.source = args; break;
						case "play": playerObj.play(); break;
						case "pause": playerObj.pause(); break;
						case "goto": try { playerObj.Position = f_GetCurrentPosition(args, "str"); } catch(e) {} playerObj.play(); break;
						case "volume": playerObj.volume = parseInt(args) / 100; break;
					}
					break;
				case "qtp":
					switch(cmd) {
						//case "open": playerObj.SetURL(args); break;
						case "play": playerObj.Play(); break;
						case "pause": playerObj.Stop(); break;
						case "goto": playerObj.Stop(); playerObj.SetTime(parseFloat(args) * parseFloat(playerObj.GetTimeScale()));// playerObj.Stop(); playerObj.Play(); 
							//debug("qtp.goto");
							this.state.state = 6;
							this.state.stateStr = "Buffering";
							window.setTimeout('playerCall(\'' + this.varName + '.exec("play", "")\')', 2000);
							break;
						case "setStartTime": playerObj.SetStartTime(parseInt(args)); break;
						case "volume": playerObj.SetVolume(Math.round(parseInt(args) * 255 / 100)); break;
					}
					break;
			}
		} catch(e) {}		
		switch(cmd) {
			case "goto": if(this.onPositionChange != null) { try { this.onPositionChange(time, parseFloat(args)); } catch(e) {} } 
				if(this.type == "qtp") break;
			case "play": this.state.state = 3; this.state.stateStr = "Playing"; break;
			case "pause": this.state.state = 2; this.state.stateStr = "Paused";  break;
		}
		
	},
	
	getCurrentTime: function() {
		var playerObj = this.getInstance();
		if(playerObj == null) return null;
		try {
			switch(this.type) {
				case "wmp": return playerObj.controls.currentPosition;//.toFixed(0);
				case "slp": return playerObj.Position.Seconds;
				case "qtp": var time = playerObj.GetTime(); var scale = playerObj.GetTimeScale();	return (scale <= 0 ? 0 : time/scale);
			}
		} catch(e) {}		
		return null;
	},
	
	getTotalTime: function() {
		var playerObj = this.getInstance();
		if(playerObj == null) return null;
		try {
			switch(this.type) {
				case "wmp": return playerObj.controls.currentItem.duration;//.toFixed(0);
				case "slp": return playerObj.NaturalDuration.Seconds;
				case "qtp": var duration = playerObj.GetDuration(); if(duration == 2147483647) return null; var scale = playerObj.GetTimeScale(); return (scale <= 0 ? 0 : duration/scale);
			}
		} catch(e) {}		
		return null;
	},
	
	getLoadedTime: function() {
		var playerObj = this.getInstance();
		if(playerObj == null) return null;
		try {
			switch(this.type) {
				case "wmp": return playerObj.controls.currentItem.duration * playerObj.network.downloadProgress / 100;//.toFixed(0);
				case "slp": return playerObj.NaturalDuration.Seconds * playerObj.downloadProgress;
				case "qtp": var timeLoaded = playerObj.GetMaxTimeLoaded(); var scale = playerObj.GetTimeScale(); return (scale <= 0 ? 0 : timeLoaded/scale);
			}
		} catch(e) {}		
		return null;
	},
	
	getState: function() {
		var playerObj = this.getInstance();
		if(playerObj == null) return null;
		try {
			switch(this.type) {
				case "wmp": 
					var st = playerObj.object.playState;
					return {state: st, stateStr: (st == 3 ? "Playing" : playerObj.object.Status)};
				case "slp": 
					var st = playerObj.currentState;
					var c = 0;
					switch(st) {
						case "Closed": c = 0; break;
						case "Stopped": c = 1; break;
						case "Paused": c = 2; break;
						case "Playing": c = 3; break;
						case "Opening": c = 4; break;
						case "Buffering": c = 6; break;
					}
					return {state: c, stateStr: st};
				case "qtp":  
					var st = playerObj.GetPluginStatus();
					var c = 0;
					if(((this.state.state > 0 && this.state.state < 4) || this.state.state == 6) && st.indexOf("Error") < 0) {
						c = this.state.state;
						st = this.state.stateStr;
					} else {
						switch(st) {
							case "Waiting": c = 4; break;
							case "Loading": c = 6; break;
							case "Playable": c = 5; break;
							case "Complete": c = 7; break;
							default: 
								if(st.indexOf("Error") >= 0) c = -1;
								else {
									c = this.state.state;
									st = this.state.stateStr;
								}		
						}
					}
					return {state: c, stateStr: st};
			}
		} catch(e) {}		
		return {state:0, stateStr:""};
	},
	
	getVolume: function() {
		var player = this.getInstance();
		if(player == null) return;
		switch(this.type) {
			case "wmp": return player.settings.volume;
			case "slp": return Math.round(player.volume * 100);
			case "qtp": return Math.round(player.GetVolume() * 100 / 255);
		}
		return 0;
	}
}

function playerCall(cmd) {
	try { eval(cmd); }
	catch(e) { alert("playerCall - " + cmd + ": " + e.message); } 
} 

function playerEvent(playerVarName, eventName, event) {
	if(!event) event = window.event;
	//alert("playerEvent : " + playerVarName + "." + eventName + ":" + event);
	try { 
		var p = eval(playerVarName);
		p.handleEvent(eventName, event);
	}	catch(e) { alert("playerEvent - " + playerVarName + "." + eventName + ": " + e.message); } 
}

function playerButtonHL(el, flag) {
	if(el == null || el.className == null) return;
	var s = el.className;
	var h = (s.substr(s.length - 2) == "HL");
	if(h != flag) el.className = (flag ? s + "HL" : s.substr(0, s.length - 2));
}

var playerDragOffset = null;
var playerDragPosition = null;

function playerDragStart(event, player) {
  if(!event) event = window.event;
  var el = (event.srcElement ? event.srcElement : event.target);
  player.exec("pause");
  
  var mouseOffset = coordinateFactory.mouseOffset(event);
  playerDragOffset = mouseOffset.minus(coordinateFactory.topLeftOffset(el));
  playerDragPosition = mouseOffset.minus(playerDragOffset);
  
  var _hint = document.getElementById((player == null ? "" : player.id) + "_progressBulletHint");
	if(_hint != null) {
		var t = (player == null ? "" : player.getCurrentTime());
		_hint.innerHTML = rm3s_formatTime(t);
		_hint.style.display = "block";
	}
  player.onDragMove = function(event) { playerDragMove(event, player); };
  player.onDragEnd = function(event) { playerDragEnd(event, player); };
  rm3s_registerEvent(document, 'mousemove', player.onDragMove);
  document.onmousemove = function() {return false;};
  rm3s_registerEvent(document, 'mouseup', player.onDragEnd);
}

function playerDragMove(event, player) {
  if(!event) event = window.event;
  var mouseOffset = coordinateFactory.mouseOffset(event);
  playerDragPosition = mouseOffset.minus(playerDragOffset);

	var _progressBar = document.getElementById(player.id + '_progressBar');
	var clickOffset = playerDragPosition.minus(coordinateFactory.topLeftOffset(_progressBar));
	var totaltime = player.getTotalTime();
	if(rm3s_getBrowser().type == "ie") clickOffset.x -= 4;
	var p = (_progressBar == null ? 0 : clickOffset.x * totaltime / _progressBar.offsetWidth);
	if(p < 0) p = 0;
	if(p > totaltime) p = totaltime;
  var dragElement = document.getElementById((player == null ? "" : player.id) + "_progressBullet");
  if(dragElement != null) {
		var l = clickOffset.x;
		if(l > _progressBar.offsetWidth - dragElement.offsetWidth) l = _progressBar.offsetWidth - dragElement.offsetWidth;
		if(l < 0) l = 0;
		dragElement.style.left = l + "px";
  }
  var _hint = document.getElementById((player == null ? "" : player.id) + "_progressBulletHint");
	if(_hint != null) _hint.innerHTML = rm3s_formatTime(p);
  return false;
}

function playerDragEnd(event, player) {
  if(!event) event = window.event;
  if(player == null) return false;
  var mouseOffset = coordinateFactory.mouseOffset(event);
  playerDragPosition = mouseOffset.minus(playerDragOffset);

	var _progressBar = document.getElementById(player.id + '_progressBar');
	var clickOffset = playerDragPosition.minus(coordinateFactory.topLeftOffset(_progressBar));
	var totaltime = player.getTotalTime();
	if(rm3s_getBrowser().type == "ie") clickOffset.x -= 4;
	var p = (_progressBar == null ? 0 : clickOffset.x * totaltime / _progressBar.offsetWidth);
	if(p < 0) p = 0;
	if(p > totaltime) p = totaltime;
  var _hint = document.getElementById(player.id + "_progressBulletHint");
	if(_hint != null) _hint.style.display = "none";
	
	player.exec("goto", p);
	
	player.updateControls();
  rm3s_unregisterEvent(document, 'mousemove', player.onDragMove);
  document.onmousemove = null;
  rm3s_unregisterEvent(document, 'mouseup', player.onDragEnd);
  
  player.skipProgressClick = true;
  
  return false;
}
