/**
 * this module contains the bitmovin player wrapper that will be used to handle all the player functionality
 * @author Aamir khan
 * @param {Object} options all the player options
 * @return {Object} the player wrapper object
 * @note every function must be define on the prototype of the player wrapper
 * @module Bitmovin
 */


import { unImplemented } from "../../utils/common";
import State from "../../utils/events/State";
import invokeNative from "../../utils/invokeNative";
import BitmovinEvents from "./BitmovinEvents";
import destroy from "./functions/destroy";
import disableSubtitles from "./functions/disableSubtitles";
import getAudio from "./functions/getAudio";
import getAudioQuality from "./functions/getAudioQuality";
import getAvailableAudio from "./functions/getAvailableAudio";
import getAvailableAudioQualities from "./functions/getAvailableAudioQualities";
import getAvailableSubtitles from "./functions/getAvailableSubtitles";
import getAvailableVideoQualities from "./functions/getAvailableVideoQualities";
import getBufferedRanges from "./functions/getBufferedRanges";
import getConfig from "./functions/getConfig";
import getCurrentTime from "./functions/getCurrentTime";
import getDuration from "./functions/getDuration";
import getManifest from "./functions/getManifest";
import getMaxTimeShift from "./functions/getMaxTimeShift";
import getPlaybackAudioData from "./functions/getPlaybackAudioData";
import getPlaybackVideoData from "./functions/getPlaybackVideoData";
import getSeekableRange from "./functions/getSeekableRange";
import getSource from "./functions/getSource";
import getTimeShift from "./functions/getTimeshift";
import getVideoQuality from "./functions/getVideoQuality";
import init from "./functions/init";
import isPaused from "./functions/isPaused";
import isPlaying from "./functions/isPlaying";
import isStalled from "./functions/isStalled";
import load from "./functions/load";
import loadSDK from "./functions/loadSDK";
import pause from "./functions/pause";
import play from "./functions/play";
import seek from "./functions/seek";
import setAudio from "./functions/setAudio";
import setAudioQuality from "./functions/setAudioQuality";
import setSubtitle from "./functions/setSubtitle";
import setVideoQuality from "./functions/setVideoQuality";
import timeShift from "./functions/timeShift";
import watchAgain from "./functions/watchAgain";




/** @constructor */
function Bitmovin(options) {
    this.options = options
    this.config = this.options.bitmovinConfig;
    this.activePlayer = null;
    this.reportError = unImplemented('reportError') // TODO: implement error reporting
    this.state = new State();
    this.events = BitmovinEvents;
    this.log("Creating Bitmovin Player", this.options);
}

/**
 * load the player SDK from the url and call the callback
 * @param {Function} onSDKloaded to be called after the SDK is loaded
 * @note this can be a promise based function but we will have to consider the old devices that do not support promises
 */
Bitmovin.prototype.loadSDK = loadSDK;
Bitmovin.prototype.init = init;


Bitmovin.prototype.load = load;
Bitmovin.prototype.play = play;
Bitmovin.prototype.pause = pause;
Bitmovin.prototype.watchAgain = watchAgain;
Bitmovin.prototype.seek = seek;
Bitmovin.prototype.isPlaying = isPlaying;
Bitmovin.prototype.isPaused = isPaused;
Bitmovin.prototype.isStalled = isStalled;

Bitmovin.prototype.getDuration = getDuration;
Bitmovin.prototype.getBufferedRanges = getBufferedRanges;
Bitmovin.prototype.getCurrentTime = getCurrentTime
Bitmovin.prototype.setCurrentTime = seek;

Bitmovin.prototype.getAvailableSubtitles = getAvailableSubtitles;
Bitmovin.prototype.getCurrentSubtitle = unImplemented("getCurrentSubtitle");
Bitmovin.prototype.setSubtitle = unImplemented("setSubtitle");


// Audio
Bitmovin.prototype.getAvailableAudioQualities = getAvailableAudioQualities;
Bitmovin.prototype.getAudioQuality = getAudioQuality;
Bitmovin.prototype.setAudioQuality = setAudioQuality;
Bitmovin.prototype.setAudio = setAudio;
Bitmovin.prototype.getAudio = getAudio;
Bitmovin.prototype.getAvailableAudio = getAvailableAudio;


// Video
Bitmovin.prototype.getAvailableVideoQualities = getAvailableVideoQualities;
Bitmovin.prototype.getVideoQuality = getVideoQuality;
Bitmovin.prototype.setVideoQuality = setVideoQuality;

Bitmovin.prototype.getManifest = getManifest;
Bitmovin.prototype.getConfig = getConfig;


Bitmovin.prototype.setSubtitle = setSubtitle
Bitmovin.prototype.disableSubtitles = disableSubtitles
Bitmovin.prototype.timeShift = timeShift
Bitmovin.prototype.getMaxTimeShift = getMaxTimeShift
Bitmovin.prototype.getTimeShift = getTimeShift
Bitmovin.prototype.getSeekableRange = getSeekableRange;
Bitmovin.prototype.getSource = getSource;
Bitmovin.prototype.getPlaybackVideoData = getPlaybackVideoData;
Bitmovin.prototype.getPlaybackAudioData = getPlaybackAudioData;





Bitmovin.prototype.getVideoElement = function getVideoElement() {
    return this.activePlayer.getVideoElement();
}

Bitmovin.prototype.unload = invokeNative('unload');


Bitmovin.prototype.destroy = destroy;

export default Bitmovin;