/* global console, swfobject, URI, TMI */
/* jshint indent: false */

// = require ./index
// = require chromecast_sender

(function (Twitch, $) {

  // adUnfilledStart, adUnfilledEnd excluded from SWF_EVENTS until sub upsell fixed POC: Thomas Reed
  var SWF_EVENTS = ['streamLoaded', 'online', 'offline', 'adCompanionRendered', 'viewerCount', 'videoLoading', 'videoPlaying',
        'tosViolation', 'popout', 'loginRequest', 'adFeedbackShow', 'mouseScroll',
      'chromecastMediaSet', 'chromecastSessionRequested', 'chromecastVolumeUpdated', 'pauseChromecastSession'],
      SWF_FUNCTIONS = ['playVideo', 'pauseVideo', 'mute', 'unmute', 'loadStream', 'fullscreen', 'adFeedbackDone',
        'setTrackingData', 'getVideoTime', 'videoSeek', 'isPaused', 'playVideo',
      'showChromecast', 'setChromecastConnected', 'togglePlayPause', 'isChatWebSockets'];

  var buildFlashVars = function (options) {
    var flashVars;
    if (options.playerType === 'live') {
      flashVars = {
        id: options.id,
        'hide_chat': true,
        channel: options.channel,
        'host_channel': options.hostChannel,
        embed: options.embed ? "1" : "0",
        'auto_play': true
      };
    } else if (options.playerType === 'highlighter') {
      flashVars = {
        id: options.id,
        videoId: options.archiveId,
        playerType: options.playerType,
        hostname: SiteOptions['twitch_cdn_hostport'],
        'auto_play': true
      };
    } else if (options.playerType === 'archive') {
      flashVars = {
        id: options.id,
        videoId: options.archiveId,
        playerType: options.playerType,
        hostname: SiteOptions['twitch_cdn_hostport'],
        'auto_play': true,
        playOffset: getPlayOffset()
      };
    }
    // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
    flashVars.device_id = Twitch.idsForMixpanel.getOrCreateUniqueId();
    flashVars.session_device_id = Twitch.idsForMixpanel.getOrCreateSessionUniqueId();
    flashVars.localstorage_device_id = Twitch.idsForMixpanel.getOrCreateLocalStorageUniqueId();
    flashVars.test_environment_url = 'http://' + SiteOptions.www_hostport;
    // jscs:enable requireCamelCaseOrUpperCaseIdentifiers

    // flash will send incorrect mixpanel event properties if we don't clear keys with undefined values
    _.each(flashVars, function (v, k) {
      if (v === undefined) delete flashVars[k];
    });
    return flashVars;
  };


  // Converts a time format of 1h2m3s into seconds
  // any on the elements can be omitted
  // Elements do have to appear in order
  var getPlayOffset = function () {
    var paramTime = URI().query(true).t;

    if (!paramTime) { return 0; }

    var segments = paramTime.match(/^(\d+[Hh])?(\d+[Mm])?(\d+[Ss])?$/);

    if (segments) {
      var hours = parseInt(segments[1], 10) || 0;
      var minutes = parseInt(segments[2], 10) || 0;
      var seconds = parseInt(segments[3], 10) || 0;
      return (hours * 60 * 60) + (minutes * 60) + seconds;
    } else if (paramTime.match(/^\d+$/)) {
      return parseInt(paramTime, 10);
    } else {
      return 0;
    }
  };

  var FlashPlayer2 = function (options) {
    var flashVars = buildFlashVars(options);
    flashVars.eventsCallback = swfCallbacks.register(function (events) {
      self._onEvents(events);
    });

    this._readyDeferred = RSVP.defer();
    this._id = flashVars.id;
    this._hostChannel = flashVars.hostChannel;
    if (options.playerType !== 'live') {
      this._videoType = 'hls';
    }

    var self = this,
      embedSwfArgs = [
        "//" + SiteOptions['twitch_cdn_hostport'] + "/swflibs/TwitchPlayer.swf",
        flashVars.id,
        "100%",
        "100%",
        "11",
        null,
        flashVars,
        {
          allowScriptAccess: "always",
          allowFullScreen: true,
          wmode: "opaque",
          bgcolor: "000000"
        },
        null,
        function (e) {
          if (!e.success) self._readyDeferred.reject(self);
        }
      ];

    swfobject.embedSWF.apply(swfobject, embedSwfArgs);
  };

  RSVP.EventTarget.mixin(FlashPlayer2.prototype);

  FlashPlayer2.prototype._onPlayerInit = function () {
    this.adFeedbackMenu = new Twitch.player.AdFeedbackMenu($('.js-ad-feedback-menu').first(), this);
    this.ready(this._id);
  };

  FlashPlayer2.prototype.destroy = function () {
    clearInterval(this.swfTrackingInterval);
  };

  FlashPlayer2.prototype.ready = function (id) {
    var self = this;
    this.ref = document.getElementById(id);
    this.$el = $(this.ref);

    var hostModeData = {
      'host_channel': this._hostChannel
    };
    this.setTrackingData('video-play', hostModeData);
    if (this._videoType) this.setTrackingData('video-type', this._videoType);

    var lastChatMsgRate;
    var knownUsingWebSockets;
    this.swfTrackingInterval = setInterval(function () {
      // Once every second, update the chat_msg_rate and isChatWebSockets property for the appropriate tracking events
      if (TMI) {
        var usingWebSockets = TMI.usingWebSockets();
        if (usingWebSockets !== knownUsingWebSockets) {
          self.isChatWebSockets(usingWebSockets);
          knownUsingWebSockets = usingWebSockets;
        }
        var msgRate = TMI.getMessageRate();
        if (msgRate !== lastChatMsgRate) {
          lastChatMsgRate = msgRate;
          var chatTrackingData = {
            'chat_msg_rate': msgRate
          };
          self.setTrackingData('minute-watched', _.extend(chatTrackingData, hostModeData));
          self.setTrackingData('buffer-empty', chatTrackingData);
        }
      }
    }, 1000);

    Twitch.chromecast.initialize(this);

    this.isReady = true;
    this._readyDeferred.resolve(this);
  };

  FlashPlayer2.prototype.promise = function (resolve, reject) {
    return this._readyDeferred.promise.then(resolve, reject);
  };

  FlashPlayer2.prototype._onEvents = function (events) {
    var event;
    for (var i = 0; i < events.length; i++) {
      event = events[i];
      try {
        this._onEvent(event);
      } catch (err) {
        console.warn("Error handling FlashPlayer2 event " + event.event + ": " + err);
      }
    }
  };

  FlashPlayer2.prototype._onEvent = function (event) {
    switch (event.event) {
    case "playerInit":
      this._onPlayerInit();
      break;
    default:
      this.trigger(event.event, event.data);
      break;
    }
  };

  (function createMethods() {
    _.each(SWF_FUNCTIONS, function (method) {
      FlashPlayer2.prototype[method] = function () {
        if (this.isReady && this.ref[method]) return this.ref[method].apply(this.ref, arguments);
      };
    });
  })();

  Twitch.player.FlashPlayer2 = FlashPlayer2;

  var swfCallbacks = {
    callbackId: 0,
    register: function (callback) {
      Twitch.player.FlashPlayer2.callbacks = Twitch.player.FlashPlayer2.callbacks || {};
      var id = 'callback' + this.callbackId++;
      Twitch.player.FlashPlayer2.callbacks[id] = callback;
      return 'Twitch.player.FlashPlayer2.callbacks.' + id;
    }
  };

})(Twitch, jQuery);
