window.YouTubePlayer = class YouTubePlayer extends Player
    constructor: (data) ->
        if not (this instanceof YouTubePlayer)
            return new YouTubePlayer(data)

        @setMediaProperties(data)
        @pauseSeekRaceCondition = false

        waitUntilDefined(window, 'YT', =>
            # Even after window.YT is defined, YT.Player may not be, which causes a
            # 'YT.Player is not a constructor' error occasionally
            waitUntilDefined(YT, 'Player', =>
                removeOld()

                @yt = new YT.Player('ytapiplayer',
                    videoId: data.id
                    playerVars:
                        autohide: 1
                        autoplay: 1
                        controls: 1
                        iv_load_policy: 3 # iv_load_policy 3 indicates no annotations
                        rel: 0
                    events:
                        onReady: @onReady.bind(this)
                        onStateChange: @onStateChange.bind(this)
                )
            )
        )

    load: (data) ->
        @setMediaProperties(data)
        if @yt and @yt.ready
            @yt.loadVideoById(data.id, data.currentTime)
        else
            console.error('WTF?  YouTubePlayer::load() called but yt is not ready')

    onReady: ->
        @yt.ready = true
        @setVolume(VOLUME)

    onStateChange: (ev) ->
        # If you pause the video before the first PLAYING
        # event is emitted, weird things happen (or at least that was true
        # whenever this comment was authored in 2015).
        if ev.data == YT.PlayerState.PLAYING and @pauseSeekRaceCondition
            @pause()
            @pauseSeekRaceCondition = false

        if (ev.data == YT.PlayerState.PAUSED and not @paused) or
                (ev.data == YT.PlayerState.PLAYING and @paused)
            @paused = (ev.data == YT.PlayerState.PAUSED)
            if CLIENT.leader
                sendVideoUpdate()

        if ev.data == YT.PlayerState.ENDED and CLIENT.leader
            socket.emit('playNext')

    play: ->
        @paused = false
        if @yt and @yt.ready
            @yt.playVideo()

    pause: ->
        @paused = true
        if @yt and @yt.ready
            @yt.pauseVideo()

    seekTo: (time) ->
        if @yt and @yt.ready
            @yt.seekTo(time, true)

    setVolume: (volume) ->
        if @yt and @yt.ready
            if volume > 0
                # If the player is muted, even if the volume is set,
                # the player remains muted
                @yt.unMute()
            @yt.setVolume(volume * 100)

    setQuality: (quality) ->
        # https://github.com/calzoneman/sync/issues/726

    getTime: (cb) ->
        if @yt and @yt.ready
            cb(@yt.getCurrentTime())
        else
            cb(0)

    getVolume: (cb) ->
        if @yt and @yt.ready
            if @yt.isMuted()
                cb(0)
            else
                cb(@yt.getVolume() / 100)
        else
            cb(VOLUME)
