var Video_API = function(dom, config) {
	this.obj = dom;
	this.config = config;
}
	
Video_API.prototype = { 
	enum_ReadyState: {
		HAVE_NOTHING: 0,
		HAVE_METADATA: 1,
		HAVE_CURRENT_DATA: 2,
		HAVE_FUTURE_DATA: 3,
		HAVE_ENOUGH_DATA: 4
	},
	enum_MediaError: {
		MEDIA_ERR_ABORTED: 1,
		MEDIA_ERR_NETWORK: 2,
		MEDIA_ERR_DECODE: 3,
		MEDIA_ERR_SRC_NOT_SUPPORTED: 4
	},
	enum_NetworkState: {
		NETWORK_EMPTY: 0,
		NETWORK_IDLE: 1,
		NETWORK_LOADING : 2,
		NEWORK_LOADED: 3,
		NETWORK_NO_SOURCE: 4
	},
	load: function(src) {
	   that = this;
	   div = document.createElement('div');
	   this.obj.appendChild(div);
	   this.interval = null;
	   this.obj.src = src;
	   this.obj.currentSrc = src;
	   this.player = $f(div, this.config.swf, {  
			playlist: [{url: this.obj.src}],
			onLoad: function() { that.onLoad(); }, 
			onError: function(errorCode, errorMessage) { that.onError(errorCode, errorMessage); }, 
            onBegin: function() { that.onBegin(); }, 
			onStart: function() { that.onStart(); }, 
			onFinish: function() { that.onFinish(); }, 
			onPause: function() { that.onPause(); }, 
			onResume: function() { that.onResume(); },
			onSeek: function() { that.onSeek(); },
            onMetaData: function() { that.onMetaData(); }
		});
		this.init();
		tmp = this.player;
	},
	
	init: function() {
	    self = this;
		Object.extend(this.obj, {
	        //error state
	        error: false,
	    
	        //network state
	        src: '',
	        currentSrc: '',
	        networkState: 0,
	        autobuffer: 0,
	        error: null,
	        load: function() { },
	        canPlayType: function() { return 'maybe'; },
	        
	        //ready state
	        _readyState: self.enum_ReadyState.HAVE_NOTHING,
	        _arrReadyStates: [self.enum_ReadyState.HAVE_NOTHING],
	        seeking: false,
	        
	        _networkState: self.enum_NetworkState.NETWORK_EMPTY,
	        
	        //playback state
	        startTime: 0,
	        duration: Number.NaN,
	        paused: true,
	        defaultPlaybackRate: 1,
	        _playbackRate: 0,
	        ended: false,
	        autoplay: false,
	        loop: false,
	        play: function() { self.play();  }, 
	        pause: function() { self.pause(); },
	        
	        width: 0,
	        height: 0,
	        videoWidth: 0,
	        videoHeight: 0,
	
	        _volume: 0.5,
	        _muted: false,
	        
	        arrCueRange: {},
	        addCueRange: function(className, id, start, end, pauseOnExit, enterCallback, exitCallback) { self.addCueRange(className, id, start, end, pauseOnExit, enterCallback, exitCallback); },
	        removeCueRange: function(className) { self.removeCueRange(className); }
	        
	    });
		
	    this.obj.__defineGetter__("currentTime", function() { return self.seek(); });
	    this.obj.__defineSetter__("currentTime", function(t) { self.seek(t); });
	    
	    this.obj.__defineGetter__("playbackRate", function() { return self.obj._playbackRate; });
	    this.obj.__defineSetter__("playbackRate", function(t) { self.obj._playbackRate = t; });
	    
	    this.obj.__defineGetter__("readyState", function() { return self.obj._readyState; });
	    this.obj.__defineSetter__("readyState", function(t) { self.obj._readyState = t;  self.obj._arrReadyStates.push(t); });
	    
	    this.obj.__defineGetter__("networkState", function() { return self.obj._networkState; });
	    this.obj.__defineSetter__("networkState", function(t) { self.obj._networkState = t;  });
	    
	    this.obj.__defineGetter__("volume", function() { return self.volume(); });
	    this.obj.__defineSetter__("volume", function(t) { self.obj._volume = t; self.volume(t);  });
	    
	    this.obj.__defineGetter__("muted", function() { return self.mute(); });
	    this.obj.__defineSetter__("muted", function(t) { self.obj._muted = t; self.mute(t); });
	    
	    isIE = false;
	    if(isIE) {
	    	Object.extend(this.obj, {
	    		currentTime: 0,
		        _time: 0,
	    		playbackRate: 0,
	    		readyState: 0,
	    		networkState: 0,
	    		volume: 0,
	    		muted: 0
	    	});
	    	this.delta = 250;
	    	setInterval(function() { self.tick(); }, this.delta);
	    }
	},
	//for IE
	tick: function() {
		t = this.player.GetTime();		
		if(Math.abs(t - this.obj.currentTime) > (this.delta * 2)) {
			this.seek(this.obj.currentTime);
			return;
		}
		this.obj.currentTime = t;
		
		if(this.obj.volume != this.obj._volume) {
			this.volume(this.obj._volume);
			this.obj._volume = this.obj.volume;
		}
		
		if(this.obj.muted != this.obj._muted) {
			this.mute(this.obj.muted);
			this.obj._muted = this.obj.muted;
		}
	},
	play: function() {
		this.player.play();
	},
	pause: function() {
		this.player.pause();
	},
	seek: function(t) {
		if(arguments.length > 0) {
			this.player.seek(t);
		}
		return this.player.getTime();  
	},
	mute: function(t) {
		if(arguments.length > 0) {
			if(t == false) {
				this.player.unmute();
			} else {
				this.player.mute();
			}
		}
		return this.player.getStatus().muted;
	},
	volume: function(t) {
		if(arguments.length > 0) {
			this.player.setVolume(t/100);
		}
		return this.player.getVolume()/100;
	},
	updateDuration: function() {
		this.obj.duration = this.player.getClip().fullDuration;
        $(this.obj).fire('video:durationchange');
	},
	updateMetadata: function() {
		var clip = this.player.getClip();
		var metadata = clip.metaData;
		
		if(metadata == undefined) {
			var self = this;
	        setTimeout(function() { self.updateMetadata(); }, 250);			
		}
        this.obj.readyState = this.enum_ReadyState.HAVE_METADATA;
		
		this.updateDuration();
		this.obj.width = clip.width;
		this.obj.height = clip.height;
		this.obj.videoHeight = metadata.height;
		this.obj.videoWidth = metadata.width;
	},
	onLoad: function() {
	},
	onMetaData: function() {
		var self = this;
        this.obj.readyState = 1;
        setTimeout(function() { self.updateMetadata(); }, 250);
	},
	onBegin: function() {
	},
    onBeforeSeek: function() {
        this.obj.seeking = true;
    },
	onSeek: function() {
        this.obj.seeking = false;
	},
	onError: function(errorCode, errorMessage) {
		switch(errorCode) {
			case 100:
				//init failed
				break;
			case 200:
				//stream not found
				break;
			case 201:
				//unable to load stream
				break;
			case 300:
				//player init failed
				break;
			case 303:
				//failed to load resource
				break;
		}
	},
	onStart: function() {
		var self = this;
        $(this.obj).fire('video:play');
	},
	onFinish: function() {
        $(this.obj).fire('video:ended');
	},
	onPause: function() {
        $(this.obj).fire('video:pause');
	},
	onResume: function() {
        var self = this;
        $(this.obj).fire('video:play');
	},
	onCuepoint: function(className, cbk) {
		if(this.obj.arrCueRange[className] == undefined) { return; }
		cbk();
	},
	addCueRange: function(className, id, start, end, pauseOnExit, enterCallback, exitCallback) {
		self = this;
		if(this.obj.arrCueRange[className] == undefined) { this.obj.arrCueRange[className] = []; }
		this.player.onCuepoint(start*1000, function() { self.onCuepoint(className, enterCallback); });
		this.player.onCuepoint(end*1000, function() { self.onCuepoint(className, exitCallback); });
		this.obj.arrCueRange[className].push(id);
	},
	removeCueRange: function(className) {
		if(this.obj.arrCueRange[className] == undefined) { return; }
		delete this.obj.arrCueRange[className];
	}
};

