/*
extension methods to <video> or <audio> object to bring it into parity with PluginMediaElement (see below)
*/
mejs.HtmlMediaElement = {
    pluginType: 'native',
    isFullScreen: false,

    setCurrentTime: function (time) {
        this.currentTime = time;
    },

    setMuted: function (muted) {
        this.muted = muted;
    },

    setVolume: function (volume) {
        this.volume = volume;
    },

    // for parity with the plugin versions
    stop: function () {
        this.pause();
    },

    // This can be a url string
    // or an array [{src:'file.mp4',type:'video/mp4'},{src:'file.webm',type:'video/webm'}]
    setSrc: function (url) {

        // Fix for IE9 which can't set .src when there are <source> elements. Awesome, right?
        var
            existingSources = this.getElementsByTagName('source');
        while (existingSources.length > 0) {
            this.removeChild(existingSources[0]);
        }

        if (typeof url == 'string') {
            this.src = url;
        } else {
            var i, media;

            for (i = 0; i < url.length; i++) {
                media = url[i];
                if (this.canPlayType(media.type)) {
                    this.src = media.src;
                    break;
                }
            }
        }
    },

    setVideoSize: function (width, height) {
        this.width = width;
        this.height = height;
    }
};

/*
Mimics the <video/audio> element by calling Flash's External Interface or Silverlights [ScriptableMember]
*/
mejs.PluginMediaElement = function (pluginid, pluginType, mediaUrl) {
    this.id = pluginid;
    this.pluginType = pluginType;
    this.src = mediaUrl;
    this.events = {};
    this.attributes = {};
};

// JavaScript values and ExternalInterface methods that match HTML5 video properties methods
// http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/fl/video/FLVPlayback.html
// http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
mejs.PluginMediaElement.prototype = {

    // special
    pluginElement: null,
    pluginType: '',
    isFullScreen: false,

    // not implemented :(
    playbackRate: -1,
    defaultPlaybackRate: -1,
    seekable: [],
    played: [],

    // HTML5 read-only properties
    paused: true,
    ended: false,
    seeking: false,
    duration: 0,
    error: null,
    tagName: '',

    // HTML5 get/set properties, but only set (updated by event handlers)
    muted: false,
    volume: 1,
    currentTime: 0,

    // HTML5 methods
    play: function () {
        if (this.pluginApi != null) {
            if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
                this.pluginApi.playVideo();
            } else {
                this.pluginApi.playMedia();
            }
            this.paused = false;
        }
    },
    load: function () {
        if (this.pluginApi != null) {
            if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
            } else {
                this.pluginApi.loadMedia();
            }

            this.paused = false;
        }
    },
    pause: function () {
        if (this.pluginApi != null) {
            if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
                if (this.pluginApi.getPlayerState() == 1) {
                    this.pluginApi.pauseVideo();
                }
            } else {
                this.pluginApi.pauseMedia();
            }


            this.paused = true;
        }
    },
    stop: function () {
        if (this.pluginApi != null) {
            if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
                this.pluginApi.stopVideo();
            } else {
                this.pluginApi.stopMedia();
            }
            this.paused = true;
        }
    },
    canPlayType: function (type) {
        var i,
            j,
            pluginInfo,
            pluginVersions = mejs.plugins[this.pluginType];

        for (i = 0; i < pluginVersions.length; i++) {
            pluginInfo = pluginVersions[i];

            // test if user has the correct plugin version
            if (mejs.PluginDetector.hasPluginVersion(this.pluginType, pluginInfo.version)) {

                // test for plugin playback types
                for (j = 0; j < pluginInfo.types.length; j++) {
                    // find plugin that can play the type
                    if (type == pluginInfo.types[j]) {
                        return 'probably';
                    }
                }
            }
        }

        return '';
    },

    positionFullscreenButton: function (x, y, visibleAndAbove) {
        if (this.pluginApi != null && this.pluginApi.positionFullscreenButton) {
            this.pluginApi.positionFullscreenButton(Math.floor(x), Math.floor(y), visibleAndAbove);
        }
    },

    hideFullscreenButton: function () {
        if (this.pluginApi != null && this.pluginApi.hideFullscreenButton) {
            this.pluginApi.hideFullscreenButton();
        }
    },


    // custom methods since not all JavaScript implementations support get/set

    // This can be a url string
    // or an array [{src:'file.mp4',type:'video/mp4'},{src:'file.webm',type:'video/webm'}]
    setSrc: function (url) {
        if (typeof url == 'string') {
            this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(url));
            this.src = mejs.Utility.absolutizeUrl(url);
        } else {
            var i, media;

            for (i = 0; i < url.length; i++) {
                media = url[i];
                if (this.canPlayType(media.type)) {
                    this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(media.src));
                    this.src = mejs.Utility.absolutizeUrl(media.src);
                    break;
                }
            }
        }

    },
    setCurrentTime: function (time) {
        if (this.pluginApi != null) {
            if (this.pluginType == 'youtube' || this.pluginType == 'vimeo') {
                this.pluginApi.seekTo(time);
            } else {
                this.pluginApi.setCurrentTime(time);
            }


            this.currentTime = time;
        }
    },
    setVolume: function (volume) {
        if (this.pluginApi != null) {
            // same on YouTube and MEjs
            if (this.pluginType == 'youtube') {
                this.pluginApi.setVolume(volume * 100);
            } else {
                this.pluginApi.setVolume(volume);
            }
            this.volume = volume;
        }
    },
    setMuted: function (muted) {
        if (this.pluginApi != null) {
            if (this.pluginType == 'youtube') {
                if (muted) {
                    this.pluginApi.mute();
                } else {
                    this.pluginApi.unMute();
                }
                this.muted = muted;
                this.dispatchEvent({type: 'volumechange'});
            } else {
                this.pluginApi.setMuted(muted);
            }
            this.muted = muted;
        }
    },

    // additional non-HTML5 methods
    setVideoSize: function (width, height) {

        //if (this.pluginType == 'flash' || this.pluginType == 'silverlight') {
        if (this.pluginElement && this.pluginElement.style) {
            this.pluginElement.style.width = width + 'px';
            this.pluginElement.style.height = height + 'px';
        }
        if (this.pluginApi != null && this.pluginApi.setVideoSize) {
            this.pluginApi.setVideoSize(width, height);
        }
        //}
    },

    setFullscreen: function (fullscreen) {
        if (this.pluginApi != null && this.pluginApi.setFullscreen) {
            this.pluginApi.setFullscreen(fullscreen);
        }
    },

    enterFullScreen: function () {
        if (this.pluginApi != null && this.pluginApi.setFullscreen) {
            this.setFullscreen(true);
        }

    },

    exitFullScreen: function () {
        if (this.pluginApi != null && this.pluginApi.setFullscreen) {
            this.setFullscreen(false);
        }
    },

    // start: fake events
    addEventListener: function (eventName, callback, bubble) {
        this.events[eventName] = this.events[eventName] || [];
        this.events[eventName].push(callback);
    },
    removeEventListener: function (eventName, callback) {
        if (!eventName) {
            this.events = {};
            return true;
        }
        var callbacks = this.events[eventName];
        if (!callbacks) return true;
        if (!callback) {
            this.events[eventName] = [];
            return true;
        }
        for (var i = 0; i < callbacks.length; i++) {
            if (callbacks[i] === callback) {
                this.events[eventName].splice(i, 1);
                return true;
            }
        }
        return false;
    },
    dispatchEvent: function (event) {
        var i,
            args,
            callbacks = this.events[event.type];

        if (callbacks) {
            for (i = 0; i < callbacks.length; i++) {
                callbacks[i].apply(this, [event]);
            }
        }
    },
    // end: fake events

    // fake DOM attribute methods
    hasAttribute: function (name) {
        return (name in this.attributes);
    },
    removeAttribute: function (name) {
        delete this.attributes[name];
    },
    getAttribute: function (name) {
        if (this.hasAttribute(name)) {
            return this.attributes[name];
        }
        return '';
    },
    setAttribute: function (name, value) {
        this.attributes[name] = value;
    },

    remove: function () {
        mejs.Utility.removeSwf(this.pluginElement.id);
    }
};
