var webm =
  'data:video/webm;base64,GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA='
var mp4 =
  'data:video/mp4;base64,[encoded data, 6456 characters]'

var _createClass = (function () {
  function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i]
      descriptor.enumerable = descriptor.enumerable || false
      descriptor.configurable = true
      if ('value' in descriptor) descriptor.writable = true
      Object.defineProperty(target, descriptor.key, descriptor)
    }
  }
  return function (Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps)
    if (staticProps) defineProperties(Constructor, staticProps)
    return Constructor
  }
})()

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError('Cannot call a class as a function')
  }
}

// Detect iOS browsers < version 10
var oldIOS =
  typeof navigator !== 'undefined' &&
  parseFloat(
    (
      '' +
      (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(
        navigator.userAgent
      ) || [0, ''])[1]
    )
      .replace('undefined', '3_2')
      .replace('_', '.')
      .replace('_', '')
  ) < 10 &&
  !window.MSStream

// Detect native Wake Lock API support
var nativeWakeLock = 'wakeLock' in navigator

var NoSleep = (function () {
  var _releasedNative = true
  var _nativeRequestInProgress = false

  function NoSleep() {
    var _this = this

    _classCallCheck(this, NoSleep)

    if (nativeWakeLock) {
      this._wakeLock = null
      var handleVisibilityChange = function handleVisibilityChange() {
        if (
          _this._wakeLock !== null &&
          document.visibilityState === 'visible'
        ) {
          _this.enable()
        }
      }
      document.addEventListener('visibilitychange', handleVisibilityChange)
      document.addEventListener('fullscreenchange', handleVisibilityChange)
    } else if (oldIOS) {
      this.noSleepTimer = null
    } else {
      // Set up no sleep video element
      this.noSleepVideo = document.createElement('video')

      this.noSleepVideo.setAttribute('title', 'No Sleep')
      this.noSleepVideo.setAttribute('playsinline', '')

      this._addSourceToVideo(this.noSleepVideo, 'webm', webm)
      this._addSourceToVideo(this.noSleepVideo, 'mp4', mp4)

      this.noSleepVideo.addEventListener('loadedmetadata', function () {
        if (_this.noSleepVideo.duration <= 1) {
          // webm source
          _this.noSleepVideo.setAttribute('loop', '')
        } else {
          // mp4 source
          _this.noSleepVideo.addEventListener('timeupdate', function () {
            if (_this.noSleepVideo.currentTime > 0.5) {
              _this.noSleepVideo.currentTime = Math.random()
            }
          })
        }
      })
    }
  }

  _createClass(NoSleep, [
    {
      key: '_addSourceToVideo',
      value: function _addSourceToVideo(element, type, dataURI) {
        var source = document.createElement('source')
        source.src = dataURI
        source.type = 'video/' + type
        element.appendChild(source)
      },
    },
    {
      key: 'enable',
      value: function enable() {
        var _this2 = this

        if (nativeWakeLock) {
          _nativeRequestInProgress = true
          navigator.wakeLock
            .request('screen')
            .then(function (wakeLock) {
              _releasedNative = false
              _nativeRequestInProgress = false

              _this2._wakeLock = wakeLock
              _this2._wakeLock.addEventListener('release', function () {
                _releasedNative = true
                _this2._wakeLock = null
              })
            })
            .catch(function (err) {
              _nativeRequestInProgress = false
              console.error(err.name + ', ' + err.message)
            })
        } else if (oldIOS) {
          this.disable()
          console.warn(
            '\n        NoSleep enabled for older iOS devices. This can interrupt\n        active or long-running network requests from completing successfully.\n        See https://github.com/richtr/NoSleep.js/issues/15 for more details.\n      '
          )
          this.noSleepTimer = window.setInterval(function () {
            if (!document.hidden) {
              window.location.href = window.location.href.split('#')[0]
              window.setTimeout(window.stop, 0)
            }
          }, 15000)
        } else {
          this.noSleepVideo.play()
        }
      },
    },
    {
      key: 'disable',
      value: function disable() {
        if (nativeWakeLock) {
          if (this._wakeLock != null) {
            _releasedNative = true
            this._wakeLock.release()
          }

          this._wakeLock = null
        } else if (oldIOS) {
          if (this.noSleepTimer) {
            console.warn(
              '\n          NoSleep now disabled for older iOS devices.\n        '
            )
            window.clearInterval(this.noSleepTimer)
            this.noSleepTimer = null
          }
        } else {
          this.noSleepVideo.pause()
        }
      },
    },
    {
      key: 'enabled',
      value: async function enabled() {
        if (nativeWakeLock) {
          if (_nativeRequestInProgress == true) {
            // Wait until the request is done.
            while (true) {
              // Wait for 42 milliseconds.
              await new Promise((resolve, reject) => setTimeout(resolve, 42))
              if (_nativeRequestInProgress == false) {
                break
              }
            }
          }

          // todo: use WakeLockSentinel.released when that is available (https://developer.mozilla.org/en-US/docs/Web/API/WakeLockSentinel/released)
          if (_releasedNative != false) {
            return false
          }

          return true
        } else if (oldIOS) {
          return this.noSleepTimer != null
        } else {
          if (this.noSleepVideo == undefined) {
            return false
          }

          return !this.noSleepVideo.paused
        }
      },
    },
  ])

  return NoSleep
})()

var noSleep = new NoSleep()

var Wakelock = {
  enabled: async function () {
    try {
      return noSleep.enabled()
    } catch (e) {
      return false
    }
  },
  toggle: async function (enable) {
    if (enable) {
      noSleep.enable()
    } else {
      noSleep.disable()
    }
  },
}

if (nativeWakeLock != true) {
  // The first non-native call sometimes throws an error, however,
  // the error does not leak the try-catch above. Therefore, this
  // is an easy fix that realiably works.
  Wakelock.enabled()
}
