// Includes code that should be run on every single page of the site
// !!!! Keep white space after last require !!!!
//
//= require fakeJamClient
//= require fakeJamClientMessages
//= require fakeJamClientRecordings
//= require backend_alerts
//= require stun
//= require influxdb-latest
//= require jam_track_utils
//= require bridge
//= require bridge_api


(function (context, $) {

  "use strict";

  context.JK = context.JK || {};

  var ALERT_NAMES = context.JK.ALERT_NAMES;
  var logger = context.JK.logger;
  var stun = null;
  var rest = context.JK.Rest();

  if(gon.global.web_performance_timing_enabled) {
    $(window).on('load', sendTimingResults)
    $(window).on('pagehide', setNavigationStart)
  }


  $(document).on('JAMKAZAM_CONSTRUCTED', function(e, data) {

    var app = data.app;
    if(!app) throw "app not found";

    // makes window.jamClient / context.jamClient set to something non-null very early on
    context.JK.initJamClient(app);

    updateScoringIntervals();

    initializeInfluxDB();

    trackNewUser();

    trackScreenChanges();

    setTimezone()
  })

  function setTimezone() {
      $.cookie("browser.timezone", window.jstz.determine().name(), { expires: 365, path: '/' });
  }

  $(document).on('JAMKAZAM_READY', function() {
    // this event is fired when context.app is initialized

    var app = context.JK.app;

    if(!app) throw "app not found"

    initializeDialogs(app);

    checkAudioStopped();

    checkMacOSXInstalledCorrectly();

    watchPreferencesEvent(app);

    watchNetworkTestEvent(app);

    initializeStun(app);

    operationalEvents(app);

    handleGettingStarted(app);

    initShoppingCart(app);
  });

  function watchPreferencesEvent(app) {
    context.JK.onBackendEvent(ALERT_NAMES.SHOW_PREFERENCES, 'everywhere', function() {
      app.layout.showDialog('client-preferences-dialog')
    });
  }

  function watchNetworkTestEvent(app) {
      context.JK.onBackendEvent(ALERT_NAMES.SHOW_NETWORK_TEST, 'everywhere', function() {
          app.layout.showDialog('network-test')
      });
  }

  function checkMacOSXInstalledCorrectly() {
    var os = context.jamClient.GetOSAsString();
    // check if method exists at all for migration purposes
    if(context.jamClient.IsAppInWritableVolume && os == "MacOSX" && !context.jamClient.IsAppInWritableVolume()) {
      context.JK.Banner.showAlert(
        { title: "Drag JamKazam to the Applications Folder!",
          buttons: [{name: 'SHUTDOWN APPLICATION', click: function() {context.jamClient.ShutdownApplication()}} ],
          html: $('#template-app-in-read-only-volume').html()});
      return;
    }
  }

  function initializeDialogs(app) {

    if(!JK.Banner) {
      // we don't use dialogs everywhere (yes, ugly)
      return
    }
    var backendAlerts = new JK.BackendAlerts(app);
    backendAlerts.initialize();

    JK.Banner.initialize();

    var shutdownDialog = new JK.ShutdownDialog(app);
    shutdownDialog.initialize();

    var googleHelper = new JK.GoogleHelper(app);
    JK.GoogleHelperInstance = googleHelper;
    googleHelper.initialize();

    var twitterHelper = new JK.TwitterHelper(app);
    JK.TwitterHelperInstance = twitterHelper;
    twitterHelper.initialize(gon.global.twitter_public_account);

    var facebookHelper = new JK.FacebookHelper(app);
    JK.FacebookHelperInstance = facebookHelper;
    facebookHelper.initialize(gon.global.facebook_app_id);

    var invitationDialog = new JK.InvitationDialog(app);
    JK.InvitationDialogInstance = invitationDialog;
    invitationDialog.initialize(facebookHelper);

    var textMessageDialog = new JK.TextMessageDialog(app);
    JK.TextMessageDialogInstance = textMessageDialog;
    textMessageDialog.initialize();

    var friendSelectorDialog = new JK.FriendSelectorDialog(app);
    JK.FriendSelectorDialogInstance = friendSelectorDialog;
    friendSelectorDialog.initialize();

    var launchAppDialog = new JK.LaunchAppDialog(app);
    launchAppDialog.initialize();

    var userDropdown = new JK.UserDropdown(app);
    JK.UserDropdown = userDropdown;
    userDropdown.initialize(invitationDialog);

    var gettingStartedDialog = new JK.GettingStartedDialog(app);
    gettingStartedDialog.initialize(invitationDialog);

    var joinTestSessionDialog = new JK.JoinTestSessionDialog(app);
    joinTestSessionDialog.initialize();

    var videoDialog = new JK.VideoDialog(app);
    videoDialog.initialize();

    var clientPreferencesDialog = new JK.ClientPreferencesDialog(app);
    clientPreferencesDialog.initialize();

    var loginRequiredDialog = new JK.LoginRequiredDialog(app);
    loginRequiredDialog.initialize();
  }

  // wait 10 seconds
  function checkAudioStopped() {

    if(context.jamClient.ResetPageCounters) {
      // upgrade concern
      context.jamClient.ResetPageCounters();

      context.JK.AudioStopTimeout = setTimeout(function() {

        if(context.jamClient.IsAudioStarted()) {
          logger.debug("checkAudioStopped: stopping audio ...")
          context.jamClient.StopAudio();
        }
      }, 10000);
    }
  }

  function updateScoringIntervals() {
    if(context.jamClient.SetLatencyTestBlocked) {
      // make sure latency testing is still going on, in case a refresh occurred during network test
      context.jamClient.SetLatencyTestBlocked(false)
    }

    // set scoring intervals
    if(context.jamClient.SetScoreWorkTimingInterval){
      var success = context.jamClient.SetScoreWorkTimingInterval(
        {
          interval: gon.global.scoring_get_work_interval,
          backoff:  gon.global.scoring_get_work_backoff_interval
        })
      if(!success) logger.warning("unable to set scoring intervals")
    }
  }

  function initializeInfluxDB() {
    /**
    context.stats = new InfluxDB({
      "host" : gon.global.influxdb_host,
      "port" : gon.global.influxdb_port,
      "username" : gon.global.influxdb_username,
      "password" : gon.global.influxdb_password,
      "database" : gon.global.influxdb_database
    });

    context.stats.write = context.stats.writePoint;
     */
    context.stats = {write:function() {}}
  }

  function initializeStun(app) {
    stun = new context.JK.Stun(app);
    context.JK.StunInstance = stun;
    stun.initialize();
  }

  function operationalEvents(app) {

    if(!JK.JamServer || !JK.JamServer.registerMessageCallback) {return;} //no websocket means no events

    JK.JamServer.registerMessageCallback(JK.MessageType.RELOAD, function(header, payload) {
      window.location.reload();
    });

    JK.JamServer.registerMessageCallback(JK.MessageType.RESTART_APPLICATION, function(header, payload) {
      context.jamClient.RestartApplication();
    });

    JK.JamServer.registerMessageCallback(JK.MessageType.STOP_APPLICATION, function(header, payload) {
      context.jamClient.ShutdownApplication();
    });

  }

  function handleGettingStarted(app) {
    /**
    var user = app.user()
    if(user) {
      user.done(function(userProfile) {
        if (!userProfile.show_jamtrack_guide && userProfile.show_whats_next && userProfile.show_whats_next_count < 10 &&
          window.location.pathname.indexOf(gon.client_path) == 0 &&
          window.location.hash.indexOf('/checkout') == -1 &&
          window.location.hash.indexOf('/redeem') == -1 &&
          window.location.hash.indexOf('/teachers/setup') == -1 &&
          !app.layout.isDialogShowing('getting-started'))
        {
          app.layout.showDialog('getting-started');
        }
      })
    }*/
  }

  function initShoppingCart(app) {
    context.JK.JamTrackUtils.checkShoppingCart();
  }

  function trackNewUser() {
    var cookie = $.cookie('new_user')

    if(cookie) {
      try {
        cookie = JSON.parse(cookie)

        context.JK.signupData = {}
        context.JK.signupData = cookie

        $(function() {
          // ga() object isn't ready until the page is loaded
          $.removeCookie('new_user')
          context.JK.GA.trackRegister(cookie.musician, cookie.registrationType);
        });
      }
      catch(e) {
        logger.error("unable to deserialize new_user cookie")
      }
    }
  }

  function trackScreenChanges() {

    if (!window.olark) {
      return;
    }

    var activate = ["jamtrack/search", "jamtrack/filter",
      "shoppingCart", "checkoutPayment", "checkoutOrder", "redeemComplete", "checkoutComplete",
      "teachers/setup/introduction", "teachers/setup/basics", "teachers/setup/experience", "teachers/setup/pricing",
      "account/profile", "account/profile/experience", "account/profile/interests", "account/profile/samples",
      "jamclass", "jamclass/searchOptions", "teachers/search", "profile/teacher", "jamclass/test-drive-selection", "jamclass/book-lesson"]
    $(document).on(context.JK.EVENTS.SCREEN_CHANGED, function(e, data) {

      var show = false;

      if (data.newScreen && activate.indexOf(data.newScreen) > -1) {
          show = true;
      }

      if (show) {
        if(window.olark) olark('api.box.show');
      }
      else {
        if(window.olark) olark('api.box.hide');
      }


    });
  }

  function setNavigationStart() {
    if(!window.performance || !window.performance.timing) {
      try {
        window.sessionStorage.setItem('navigationStart', Date.now())
      }
      catch(e) {
        logger.debug("unable to accesss sessionStorage")
      }
    }

  }


  // http://githubengineering.com/browser-monitoring-for-github-com/
  function sendTimingResults() {

    setTimeout(function() {
      var timing;
      var hasTimingApi;

      if(window.performance && window.performance.timing) {
        timing = window.performance.timing
        hasTimingApi = true;
      }
      else {
        timing = {}
        hasTimingApi = false;
      }

      //  Merge in simulated cross-browser load event
      timing['crossBrowserLoadEvent'] = Date.now()

      var chromeFirstPaintTime;
      if(window.chrome && window.chrome.loadTimes) {
        var loadTimes  = window.chrome.loadTimes()
        if(loadTimes) {
          chromeFirstPaintTime = true;
        }
      }

      // firstPaintTime is in seconds; convert to milliseconds to match performance.timing.
      timing['chromeFirstPaintTime'] = Math.round(chromeFirstPaintTime * 1000);

      // Merge in simulated navigation start, if no navigation timing
      if (!hasTimingApi) {
        try {
          var navStart = window.sessionStorage.getItem('navigationStart')
          if(navStart) {
            timing['navigationStart'] = parseInt(navStart, 10)
          }
        }
        catch(e) { }
      }

      context.JK.GA.trackTiming(timing);
    }, 0)

  }

})(window, jQuery);
