/* global console */
/* jshint bitwise:false */

(function (Twitch, $) {

  var HTML5Player = function (options) {
    this.options = options;
    this.$el = $('#' + options.id);
    this.el = this.$el[0];

    this.$contentPlayer = this.$el.find('.js-video_player video');
    this.contentPlayer = this.$contentPlayer[0];
    this.contentPlayer.load();
    this.adContainer = this.$el.find('.js-ad_container').show()[0];
    this.videoPlayerContainer = this.$el.find('.js-video_player')[0];

    this._onlineStatus = 'unknown';
    this.bufferEmpties = 0;
  };

  // https://gist.github.com/4rn0/4174742
  HTML5Player.canPlayHLS = function () {
    var a = navigator.userAgent,
        b = document.createElement('video');
    if (a.match(/iPhone|iPod|iPad/)) {
      return true;
    }
    try {
      return b && b.canPlayType && !!b.canPlayType('application/x-mpegURL; codecs="avc1.42E01E, mp4a.40.2"');
    } catch (c) {
      return false;
    }
  };

  HTML5Player.prototype.init = function (success, error) {
    console.info('HTML5Player.init');

    success = success || function () {};
    error = error || function () {};

    if (this.options.videoId) {
      console.info('HTML5Player.init error');
      error("HTML5 player doesn't support archives");
      return;
    }

    // Android supports a broken-ish version of HLS, but feature detection doesn't return true
    var isAndroid = navigator.userAgent.match(/Android/i);
    if (!HTML5Player.canPlayHLS() && !isAndroid) {
      this.$el.find('.js-message').show().text('Unsupported player.');
      console.info('HTML5Player.init error');
      error("Browser doesn't support HLS");
      return;
    }

    this.$el.show();

    var self = this;
    Twitch.hls.getPlaylist(this.options.channel).then(function (url) {
      self._onlineStatus = 'online';
      $(self).triggerHandler('online');

      var mwcc = URI.parseQuery(window.location.search).mwcc;

      var eventParams = {
        "vid_width": self.$contentPlayer.width(),
        "vid_height": self.$contentPlayer.height(),
        "player": self.options.player,
        "video_renderer": "html5",
        "platform": self.options.platform,

        "adblock": Twitch.storage.get("adblock_enabled", {storage: 'sessionStorage'}) === "true",
        "app_version": "HTML5 0.1",
        "browser": navigator.userAgent,
        "orientation": window.innerHeight >= window.innerWidth ? 'portrait' : 'landscape',
        "live": true,

        // TODO: Can't figure out how to get these values
        "buffer_empty_count": undefined,
        "quality": undefined,
        "fullscreen": undefined
      };

      if (mwcc) {
        eventParams.exp_name = 'mwcc';
        eventParams.exp_grp = mwcc;

      }

      var eventController = self.eventController = new Twitch.player.EventController(self.options.channel, url, eventParams);

      var pingFAN = function (path) {
        $.ajax({
          type: "GET",
          url: "http://fan.twitch.tv/" + path,
          cache: false,
          data: {
            channel: self.options.channel,
            context: "preroll",
            turbo_token: self.options.turboToken,
            chansub_token: self.options.channelSubscriptionToken
          }
        });
      };

      if (self.options.ads === false) {
        pingFAN("ad");
        setTimeout(pingFAN, 30000, "adcompleted");
        self.setSrc(url);
        console.info('HTML5Player.init success (no ads)');
        success();
        return;
      }

      var adController = new Twitch.player.AdsController({
        container: self.adContainer,
        player: self.contentPlayer
      });

      // when the ad controller emits 'start'...
      $(adController).on('start', function (jqEvent) {
        pingFAN("ad");
        eventController.sendVideoAdImpression("preroll", jqEvent.currentTarget.adsLoader.provider);
      });

      // when the ad controller emits 'contentResumeRequested' or 'adError', play content video
      $(adController).on('contentResumeRequested adError', function () {
        pingFAN("adcompleted");
        self.setSrc(url);
        self.preloadContent(function () {
          // wat: this try/catch somehow helps android play the video after the ad
          try {
            self.play();
          } catch (e) { }
        });
      });

      // kick off the ad (This only does prerolls...)
      adController.initialize().then(function () {
        if (~window.location.href.indexOf('errortest') &&
            Twitch.deployFlavor !== 'production' &&
            Twitch.deployFlavor !== 'beta') {
          adController.requestAds('invalid_ad_url');
        }
        else if (~window.location.href.indexOf('twitchtest')) {
          adController.requestAds(Twitch.ads.hls.getAdTagUrl({provider: 'test'}), "test");
          eventController.sendVideoAdOpportunity("preroll", "test");
        } else {
          adController.requestAds(Twitch.ads.hls.getAdTagUrl({
            provider: 'twitch',
            platform: 'html5',
            channel: self.options.channel || '',
            game: self.options.game || '',
            referrer: document.referrer
          }), "twitch");
          eventController.sendVideoAdOpportunity("preroll", "twitch");
        }
      });
      console.info('HTML5Player.init success');
      success();
    }, function () {
      self._onlineStatus = 'offline';
      $('.js-message').show().text('OFFLINE');
      self.$contentPlayer.removeAttr('poster');
      console.info('HTML5Player.init success (offline)');
      success();
    });

  };

  HTML5Player.prototype.destroy = function () {
    // This method exists only to match the interface the flash player exposes
  };

  HTML5Player.prototype.preloadContent = function (contentLoadedAction) {
    if (this.isMobilePlatform()) {
      // trigger load, and continue when loadedmetadata is fired
      this.contentPlayer.addEventListener('loadedmetadata', contentLoadedAction, false);
      this.contentPlayer.load();
    } else {
      // trigger load, and immediately continue
      this.contentPlayer.load();
      contentLoadedAction();
    }
  };

  HTML5Player.prototype.play = function () {
    this.contentPlayer.play();
    this.eventController.trackVideoPlaying(this);
  };

  HTML5Player.prototype.pause = function () {
    this.contentPlayer.pause();
  };

  HTML5Player.prototype.isMobilePlatform = function () {
    return this.contentPlayer.paused &&
      (navigator.userAgent.match(/(iPod|iPhone|iPad)/) ||
       navigator.userAgent.toLowerCase().indexOf('android') > -1);
  };

  HTML5Player.prototype.getVideoPlayer = function () {
    return this.contentPlayer;
  };

  HTML5Player.prototype.registerVideoEndedCallback = function (callback) {
    this.contentPlayer.addEventListener(
      'ended',
      callback,
      false);
  };

  HTML5Player.prototype.unregisterVideoEndedCallback = function (callback) {
    this.contentPlayer.removeEventListener(
      'ended',
      callback,
      false);
  };

  HTML5Player.prototype.onlineStatus = function () {
    return this._onlineStatus;
  };

  HTML5Player.prototype.on = function (event, callback) {
    $(this).on(event, callback);
  };

  HTML5Player.prototype.off = function (event, callback) {
    $(this).off(event, callback);
  };

  HTML5Player.prototype.mute = function () {
    this.$contentPlayer.prop('muted', true);
  };

  HTML5Player.prototype.unmute = function () {
    this.$contentPlayer.prop('muted', false);
  };

  HTML5Player.prototype.setSrc = function (src) {
    this.contentPlayer.src = src;
  };

  Twitch.player.HTML5Player = HTML5Player;

})(Twitch, jQuery);
