# Source: ui/base/abstract-video.js

    /*global require, exports*/

    /**
     * @module montage/ui/base/abstract-video.reel
     */
    var Component = require("../component").Component,
        MediaController = require("../../core/media-controller").MediaController;

    /**
     * @class AbstractVideo
     * @extends Component
     */
    var AbstractVideo = exports.AbstractVideo = Component.specialize(/** @lends AbstractVideo# */ {

        /**
         * @private
         */
        constructor: {
            value: function AbstractVideo() {
                if (this.constructor === AbstractVideo) {
                    throw new Error("AbstractVideo cannot be instantiated.");
                }
            }
        },

        _mediaElement: {
            value: null
        },

        mediaElement: {
            get: function () {
                return this._mediaElement;
            },
            set: function (element) {
                this._mediaElement = element;

                if (this.videoController) {
                    this.videoController.mediaElement = this.mediaElement;
                }
            }
        },

        _videoController: {
            value: null
        },

        /**
         * The MediaController instance used by the video component.
         * @type {module:montage/core/media-controller.MediaController}
         * @default null
         */
        videoController: {
            get: function () {
                return this._videoController;
            },
            set: function (controller) {
                if (controller) {
                    this._videoController = controller;

                    if (this.mediaElement) {
                        this.videoController.mediaElement = this.mediaElement;
                    }
                }
            }
        },

        _src: {
            value: null
        },

        /**
         * @type {string}
         * @default null
         */
        src: {
            get: function () {
                return this._src;
            },
            set: function (src) {
                this._src = src;
            }
        },

        /**
         * @private
         */
        _sources: {
            value: []
        },
        /**
         * @type {Array}
         * @default null
         */
        sources: {
            get: function () {
                return this._sources;
            },
            set: function (sources) {
                if (sources && sources.length) {
                    var mediaElement = this.element.ownerDocument.createElement("video");
                    for (var i = 0; i < sources.length; i++) {
                        var mediaSrc = sources[i].src,
                            mediaType = sources[i].type;
                        if (mediaType && mediaElement.canPlayType(mediaType)) {
                            this.src = mediaSrc;
                            break;
                        }
                    }
                    this._sources = sources;
                }
            }
        },

        /**
         * @function
         */
        loadMedia: {
            value: function () {
                this.mediaElement.src = this.src;
                this.mediaElement.load();
            }
        },

        _repeat: {
            value: false
        },

        /**
         * @type {Function}
         * @default {boolean} false
         */
        repeat: {
            get: function () {
                return this._repeat;
            },

            set: function (repeat) {
                if (repeat !== this._repeat) {
                    this._repeat = repeat;
                    if (repeat) {
                        this.mediaElement.setAttribute("loop", "true");
                    } else {
                        this.mediaElement.removeAttribute("loop");
                    }
                    this.needsDraw = true;
                }
            }
        },

        /**
         * @function
         */
        toggleRepeat: {
            value: function () {
                this.repeat = !this.repeat;
            }
        },

        _posterSrc: {
            value: null
        },

        /**
         * @type {string}
         * @default null
         */
        posterSrc: {
            get: function () {
                return this._posterSrc;
            },
            set: function (posterSrc) {
                this._posterSrc = posterSrc;
            }
        },

        /**
         * @function
         */
        showPoster: {
            value: function () {
                if (this.posterSrc && this.mediaElement) {
                    this.mediaElement.poster = this.posterSrc;
                }
            }
        },

        /**
         * Specifies whether the full screen video is supported.
         * @type {boolean}
         * @default true
         */
        supportsFullScreen: {
            value: true
        },

        _isFullScreen: {
            value: false
        },

        /**
         * @type {boolean}
         */
        isFullScreen: {
            get: function () {
                return this._isFullScreen;
            }
        },

        /**
         * Toggles full-screen playback mode.
         * @function
         */
        toggleFullScreen: {
            value: function () {
                if (this.supportsFullScreen) {
                    this._isFullScreen = !this._isFullScreen;
                    if (!this._isFullScreen) {
                        if (this.element.webkitExitFullscreen) {
                            this.element.webkitExitFullscreen();
                        } else if (this.element.webkitCancelFullScreen) {
                            this.element.webkitCancelFullScreen();
                        } else if (this.element.ownerDocument.webkitCancelFullScreen && this.element.ownerDocument.webkitCurrentFullScreenElement === this.element) {
                            this.element.ownerDocument.webkitCancelFullScreen();
                        }
                    } else {
                        if (this.element.webkitEnterFullScreen) {
                            this.element.webkitEnterFullScreen();
                        } else if (this.element.webkitRequestFullScreen) {
                            this.element.webkitRequestFullScreen();
                        }
                    }
                    this.needsDraw = true;
                }
            }
        },

        handleControllerStatusChange: {
            value: function () {
                this.needsDraw = true;
            }
        },

        handleControllerVolumeChange: {
            value: function () {
                this.needsDraw = true;
            }
        },

        enterDocument: {
            value: function (firstTime) {
                if (firstTime) {
                    // look for src attribute on original element
                    if (this.originalElement.hasAttribute("src") && this.originalElement.getAttribute("src")) {
                        this.src = this.originalElement.getAttribute("src");
                    } else {
                        // try to grab <source> child elements from original element
                        var sources = this.originalElement.getElementsByTagName("source"),
                            mediaSrc, mediaType;
                        for (var sourceIdx = 0; sourceIdx < sources.length; sourceIdx++) {
                            mediaSrc = sources[sourceIdx].getAttribute("src");
                            mediaType = sources[sourceIdx].getAttribute("type");
                            if (mediaType && !this.mediaElement.canPlayType(mediaType)) {
                                continue;
                            }
                            this.src = mediaSrc;
                            break;
                        }
                    }

                    // try to grab <track> child elements from original element
                    var tracks = this.originalElement.getElementsByTagName("track");
                    for (var trackIdx = 0; trackIdx < tracks.length; trackIdx++) {
                        var trackKind = tracks[trackIdx].getAttribute("kind");
                        if (trackKind === "captions" || trackKind === "subtitles") {
                            var track = document.createElement("track");
                            track.kind = trackKind;
                            track.label = tracks[trackIdx].getAttribute("label");
                            track.src = tracks[trackIdx].getAttribute("src");
                            track.srclang = tracks[trackIdx].getAttribute("srclang");
                            track.default = tracks[trackIdx].hasAttribute("default");
                            this.mediaElement.appendChild(track);
                            this.mediaElement.textTracks[this.mediaElement.textTracks.length - 1].mode = "showing";
                        }
                    }

                    this.addPathChangeListener("videoController.status", this, "handleControllerStatusChange");
                    this.addPathChangeListener("videoController.volume", this, "handleControllerVolumeChange");

                    if (!this.videoController) {
                        this.videoController = new MediaController();
                    }

                    this.videoController.mediaElement = this.mediaElement;
                }
            }
        }

    });