/* global SB, APP_CONFIG */

/**
 * Tizen platform
 */
SB.createPlatform('tizen', {
  platformUserAgent: 'tizen',
});

SB.readyForPlatform('tizen', function () {
  var App = window.App;
  var AppNetwork = window.AppNetwork;
  var Player = window.Player;

  var tizen = window.tizen;
  var webapis = window.webapis;

  var $ = window.$;
  var $$log = window.$$log;
  var $$error = window.$$error;

	$(document.body).addClass('tizen');

  registerTizenDeviceKeys();
  onAppRestartOpenInitScene();
  onNetworkStateChanged();
  onTizenHardwareKey();

  Player.extend({
		videoObj: null,	// tag video
		STATES: {
	        STOPPED: 'stop',
	        PLAYING: 'play',
	        PAUSED: 'pause',
	        PREPARED: 'prepared'
	    },
	    // state: 0,

		_init: function () {
			$('body').append('<object type="application/avplayer" id="pluginPlayer" style="z-index: 0; position: absolute; left: 0; top: 0; width:100%; height:100%"></object>');

			console.log("Main.onLoad()");

			// setup video player
			var id = "pluginPlayer";

			console.log("Player.init("+id+")");
			console.log("AVPlay version: " + webapis.avplay.getVersion());

			this.state = this.STATES.STOPPED;

			if (!this.videoObj && id) {
				this.videoObj = document.getElementById(id);
			}
    },

		_play: function (options) {
  		var url = options.url;

      this.options = options;

      this._repeat = APP_CONFIG.VIDEO_PREPARE_ATTEMPTS_BEFORE_ERROR_COUNT;
      this._onPrepareError = options.onerror;
      this._isIPTV = options.iptv;

  		if (!this.videoObj) {
  			return 0;
  		}

      var listeners = {};

      $.extend(listeners, this.bufferingEvents());
      $.extend(listeners, this.finishEvents());
      $.extend(listeners, this.updateEvents());

      webapis.avplay.open(url);
      webapis.avplay.setListener(listeners);
      webapis.avplay.setDisplayRect(0, 0, APP_CONFIG.VIDEO_DISPLAY_RECT_WIDTH, APP_CONFIG.VIDEO_DISPLAY_RECT_HEIGHT);

      Player._setBuffer();
      Player._prepare();

			Player.state = Player.STATES.PREPARED;
			Player.state = Player.STATES.PLAYING;

			if (url) {
				Player.videoObj.src = url;
			}
    },

    _prepare: function () {
      Player.trigger('prepare')

      clearTimeout(App.errorPrepareTimer);

      App.errorPrepareTimer = setTimeout(function() {
        Player._prepareError({code: 'Timeout.errorPrepareTimer'})
      }, APP_CONFIG.VIDEO_PREPARE_TIMEOUT_ERROR_MS);

      if (APP_CONFIG.VIDEO_PREPARE_MEDIA_ASYNC) {
        Player._prepareAsync();
      } else {
        Player._prepareSync();
      }
    },

    _prepareSync: function () {
      try {
        webapis.avplay.stop();
        webapis.avplay.prepare();
        Player._prepareSuccess();
      }
      catch (e)
      {
        Player._prepareError(e);
      }
    },

    _prepareAsync: function () {
      webapis.avplay.stop();
      webapis.avplay.prepareAsync(Player._prepareSuccess, Player._prepareError);
    },

    _prepareSuccess: function () {
      clearTimeout(App.errorPrepareTimer);

      webapis.avplay.play();

      Player.trigger('ready');
    },

    _prepareError: function (e) {
      $$error('The media has failed to prepare.. ' + Player._repeat);

      if (Player._repeat > 0) {
        $$error('WebAPIError: ' + JSON.stringify(e));

        Player._repeat--;
        Player._prepare();
        return;
      }

      if (Player._onPrepareError) {
        Player._onPrepareError();
      }
    },

    _setBuffer: function () {
      if (APP_CONFIG.VIDEO_BEFFER_CONFIG_ENABLED) {
        webapis.avplay.setTimeoutForBuffering(APP_CONFIG.VIDEO_BUFFER_TIMEOUT_IN_SECOND);
        webapis.avplay.setBufferingParam("PLAYER_BUFFER_FOR_PLAY", "PLAYER_BUFFER_SIZE_IN_SECOND", parseInt(App.scenes.settings.options.buffering));
        webapis.avplay.setBufferingParam("PLAYER_BUFFER_FOR_RESUME","PLAYER_BUFFER_SIZE_IN_SECOND", APP_CONFIG.VIDEO_BUFFER_FOR_RESUME_SIZE_IN_SECOND);
      }
    },

    _stop: function () {
      this.state = this.STATES.STOPPED;
      clearTimeout(App.errorPrepareTimer);
			webapis.avplay.stop();
    },

    pause: function () {
			webapis.avplay.pause();
      this.state = "pause";
      this.trigger('pause');
    },

    resume: function () {
      webapis.avplay.play();
      this.state = "play";
      this.trigger('resume');
    },

		bufferingEvents: function () {
      var bufferedPercent = 0;
      var bufferingTimes = 0;
      var clearBufferAfterRestorePlay = this._isIPTV && APP_CONFIG.VIDEO_BUFFER_CLEAR_AFTER_RESTORE_PLAY_FOR_IPTV;
      var clearBufferLastTimeAt = Date.now();

      return {
				onbufferingstart: function() {
          var lastClearBufferMinutesAgo = getMinutesDiffFrom(clearBufferLastTimeAt);

          bufferedPercent = 0;

          Player.trigger('bufferingBegin');

          $$log("Buffering times #" + bufferingTimes + '; lastClearBufferMinutesAgo: ' + lastClearBufferMinutesAgo);

          if (
            clearBufferAfterRestorePlay &&
            lastClearBufferMinutesAgo >= APP_CONFIG.VIDEO_BUFFER_CLEAR_ONCE_PER_MINUTES
          ) {
            $$log("Clear Buffer!");

            Player.clearBuffer();
            Player.play(Player.options);
          }

          bufferingTimes++;
				},

				onbufferingprogress: function(percent) {
          if (percent > bufferedPercent + APP_CONFIG.LOG_BUFFERING_ONCE_PER_PERCENT) {
            $$log("Buffering..." + percent);
            bufferedPercent = percent;
          }

          Player.trigger('buffering', [percent]);
				},

				onbufferingcomplete: function() {
          Player._bufferingEnd();
				}
			}
		},

    _bufferingEnd: function() {
      if (this._isIPTV) {
        Player.trigger('bufferingEnd');
        return;
      }

      this._waitDurationAndEndBuffering();
    },

    _waitDurationAndEndBuffering: function () {
      var intervalId = setInterval(function () {
        var duration = webapis.avplay.getDuration();

        if (!duration) {
          return;
        }

        $$log("Duration: " + duration);

        clearInterval(intervalId);

        Player.videoInfo.duration = Math.ceil(duration / 1000);
        Player.trigger('bufferingEnd');
      }, 0);
    },

    finishEvents: function () {
      return {
				ondrmevent: function(drmEvent, drmData) {
					$$log("DRM callback: " + drmEvent + ", data: " + drmData);
				},
				onerror : function(type, data) {
					$$log("OnError: " + data);
				}
      }
    },

    updateEvents: function () {
      return {
        oncurrentplaytime: function(currentTime) {
          Player.videoInfo.currentTime = Math.ceil(currentTime / 1000); // webapis.avplay.getCurrentTime();
					Player.trigger('update');
				}
      }
    },

    forward: function(seconds) {
      try {
        webapis.avplay.jumpForward(seconds * 1000);
      } catch (e) {
        $$error(e.message);
      }
    },

    backward: function(seconds) {
      try {
        webapis.avplay.jumpBackward(seconds * 1000);
      } catch (e) {
        $$error(e.message);
      }
    },

    close: function () {
      webapis.avplay.stop();
      webapis.avplay.close();
    },

    clearBuffer: function () {
      this.close();
    },

    exit: function () {
      this._stop();
      try {
          tizen.application.getCurrentApplication().exit();
      } catch (error) {
          console.error('Application exit failed.', error);
      }
    }

	});

  function onNetworkStateChanged() {
    webapis.network.addNetworkStateChangeListener(function(value) {
      if (value === webapis.network.NetworkState.GATEWAY_DISCONNECTED) {
        AppNetwork.onInternetFail();
      } else if (value === webapis.network.NetworkState.GATEWAY_CONNECTED) {
        AppNetwork.onInternetSuccess();
      }
    });
  }

  function registerTizenDeviceKeys () {
    if (window.tizen && window.tizen.tvinputdevice) {
      tizen.tvinputdevice.getSupportedKeys()
        .forEach(function (k){
            if ([
                'MediaFastForward',
                'MediaRewind',
                'MediaTrackPrevious',
                'MediaTrackNext',
                'MediaPause',
                'MediaPlay',
                'MediaPlayPause',
                'MediaStop',
                'ChannelUp',
                'ChannelDown',
                'Info'
            ].indexOf(k.name) > -1) {
                tizen.tvinputdevice.registerKey(k.name);
            }
        });

      document.body.addEventListener('keydown', function (event) {
        switch (event.keyCode) {
          case tizen.tvinputdevice.getKey('Info').code: {
            $$log('[Info]');
            $(document.body).trigger($.Event("nav_key:info"));
            break;
          }

          case tizen.tvinputdevice.getKey('MediaPlayPause').code: {
            $$log('[MediaPlayPause]');
            $(document.body).trigger($.Event("nav_key:pause"));
            break;
          }

          case tizen.tvinputdevice.getKey('MediaPlay').code: {
            $$log('[MediaPlay]');
            $(document.body).trigger($.Event("nav_key:pause"));
            break;
          }

          case tizen.tvinputdevice.getKey('MediaPause').code: {
            $$log('[MediaPause]');
            $(document.body).trigger($.Event("nav_key:pause"));
            break;
          }

          case tizen.tvinputdevice.getKey('ChannelUp').code: {
            $$log('[ChannelUp]');
            $(document.body).trigger($.Event("nav_key:ch_up"));
            break;
          }

          case tizen.tvinputdevice.getKey('ChannelDown').code: {
            $$log('[ChannelDown]');
            $(document.body).trigger($.Event("nav_key:ch_down"));
            break;
          }

          case tizen.tvinputdevice.getKey('MediaFastForward').code: {
            $$log('[MediaFastForward]');
            $(document.body).trigger($.Event("nav_key:forward"));
            break;
          }

          case tizen.tvinputdevice.getKey('MediaRewind').code: {
            $$log('[MediaRewind]');
            $(document.body).trigger($.Event("nav_key:backward"));
            break;
          }

          case tizen.tvinputdevice.getKey('MediaTrackPrevious').code: {
            $$log('[MediaTrackPrevious]');
            $(document.body).trigger($.Event("nav_key:previous"));
            break;
          }

          case tizen.tvinputdevice.getKey('MediaTrackNext').code: {
            $$log('[MediaTrackNext]');
            $(document.body).trigger($.Event("nav_key:next"));
            break;
          }

          default:
            break;
        }
      });
    } else {
      $$error('tizen.tvinputdevice Not Defined. Miss privelegy?')
    }
  }

  function onAppRestartOpenInitScene() {
    document.addEventListener('visibilitychange', function() {
      $$log('Visibility Change: ' + (document.hidden ? 'hide' : 'show'));

      if (document.hidden) {
        Player.stop();
      }

      if (!document.hidden) {
        App.reopenScene('iptv');
      }
    });
  }

  // Системные нажатия клавиш для приложения tizen
  // Необходимо что-бы отловить back
  function onTizenHardwareKey() {
    document.addEventListener('tizenhwkey', function (event) {
      var key = event.keyName,
          $event = $.Event("nav_key:" + key);

      $(document.body).trigger($event);

      $$log('HardwareKey:' + key);
    });
  }

  function getMinutesDiffFrom(clearBufferLastTimeAt) {
    return (Date.now() - clearBufferLastTimeAt) / 1000 / 60;
  }

});
