'use strict';

var Backbone = require('backbone');
var Marionette = require('backbone.marionette');
var NUSMods = require('./nusmods');
var NavigationCollection = require('./common/collections/NavigationCollection');
var NavigationView = require('./common/views/NavigationView');
var Promise = require('bluebird'); // jshint ignore:line
var SelectedModulesController = require('./common/controllers/SelectedModulesController');
var TimetableModuleCollection = require('./common/collections/TimetableModuleCollection');
var _ = require('underscore');
var config = require('./common/config');
var localforage = require('localforage');
require('qTip2');

// Set Backbone.History.initialRoute to allow route handlers to find out if they
// were called from the initial route.
var loadUrl = Backbone.History.prototype.loadUrl;
Backbone.History.prototype.loadUrl = function() {
  if (!Backbone.History.initialRoute) {
    Backbone.History.initialRoute = true;
  } else {
    Backbone.History.initialRoute = false;
    // No longer initial route, restore original loadUrl.
    Backbone.History.prototype.loadUrl = loadUrl;
  }
  return loadUrl.apply(this, arguments);
};

var App = new Marionette.Application();

App.addRegions({
  mainRegion: '.content',
  navigationRegion: '#nav',
  selectRegion: '.navbar-form',
  bookmarksRegion: '.nm-bookmarks'
});

var navigationCollection = new NavigationCollection();
var navigationView = new NavigationView({collection: navigationCollection});
App.navigationRegion.show(navigationView);

App.reqres.setHandler('addNavigationItem', function (navigationItem) {
  return navigationCollection.add(navigationItem);
});

NUSMods.setConfig(config);

var selectedModulesControllers = [];

for (var i = 0; i < 5; i++) {
  selectedModulesControllers[i] = new SelectedModulesController({
    semester: i + 1
  });
}

App.reqres.setHandler('selectedModules', function (sem) {
  return selectedModulesControllers[sem - 1].selectedModules;
});
App.reqres.setHandler('addModule', function (sem, id, options) {
  return selectedModulesControllers[sem - 1].selectedModules.add({
    ModuleCode: id,
    Semester: sem
  }, options);
});
App.reqres.setHandler('removeModule', function (sem, id) {
  var selectedModules = selectedModulesControllers[sem - 1].selectedModules;
  return selectedModules.remove(selectedModules.get(id));
});
App.reqres.setHandler('isModuleSelected', function (sem, id) {
  return !!selectedModulesControllers[sem - 1].selectedModules.get(id);
});
App.reqres.setHandler('displayLessons', function (sem, id, display) {
  _.each(selectedModulesControllers[sem - 1].timetable.where({
    ModuleCode: id
  }), function (lesson) {
    lesson.set('display', display);
  });
});

var bookmarkedModulesNamespace = config.namespaces.bookmarkedModules + ':';

App.reqres.setHandler('getBookmarks', function (callback) {
  if (!callback) { 
    return; 
  }
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    callback(modules);
  });
});
App.reqres.setHandler('addBookmark', function (id) {
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    if (!_.contains(modules, id)) {
      modules.push(id);
    }
    localforage.setItem(bookmarkedModulesNamespace, modules);
  });
});
App.reqres.setHandler('deleteBookmark', function (id) {
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    var index = modules.indexOf(id);
    if (index > -1) {
      modules.splice(index, 1);
      localforage.setItem(bookmarkedModulesNamespace, modules);
    }
  });
});

App.on('start', function () {
  var AppView = require('./common/views/AppView');

  new Marionette.AppRouter({
    routes: {
      '*default': function () {
        Backbone.history.navigate('timetable', {trigger: true, replace: true});
      }
    }
  });

  // header modules
  require('./timetable');
  require('./modules');
  // require('ivle');
  require('./apps');
  require('./barenus');
  require('./friends');
  require('./venues');
  require('./preferences');
  require('./blog');

  // footer modules
  require('./about');
  require('./contribute');
  require('./help');
  require('./support');

  Promise.all(_.map(_.range(1, 5), function(semester) {
    var semTimetableFragment = config.semTimetableFragment(semester);
    return localforage.getItem(semTimetableFragment + ':queryString')
      .then(function (savedQueryString) {
      if ('/' + semTimetableFragment === window.location.pathname) {
        var queryString = window.location.search.slice(1);
        if (queryString) {
          if (savedQueryString !== queryString) {
            // If initial query string does not match saved query string,
            // timetable is shared.
            App.request('selectedModules', semester).shared = true;
          }
          // If there is a query string for timetable, return so that it will
          // be used instead of saved query string.
          return;
        }
      }
      var selectedModules = TimetableModuleCollection.fromQueryStringToJSON(savedQueryString);
      return Promise.all(_.map(selectedModules, function (module) {
        return App.request('addModule', semester, module.ModuleCode, module);
      }));
    });
  }).concat([NUSMods.generateModuleCodes()])).then(function () {
    new AppView();

    Backbone.history.start({pushState: true});
  });

  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    if (!modules) {
      localforage.setItem(bookmarkedModulesNamespace, []);
    }
  });
});

module.exports = App;

@@ -3817,14 +3817,23 @@
  // 
-header
+navigation menu
  mod
@@ -3888,19 +3888,16 @@
 les');%0A 
- //
  require
@@ -3902,12 +3902,16 @@
 re('
-ivle
+./venues
 ');%0A
@@ -3928,24 +3928,27 @@
 './apps');%0A 
+ //
  require('./
@@ -3951,14 +3951,14 @@
 ('./
-barenu
+friend
 s');
@@ -3963,38 +3963,38 @@
 );%0A  require('./
-friend
+barenu
 s');%0A  require('
@@ -3987,36 +3987,41 @@
 );%0A  require('./
-venu
+preferenc
 es');%0A  require(
@@ -4023,32 +4023,28 @@
 uire('./
-preferences
+blog
 ');%0A 
+ //
  require
@@ -4041,30 +4041,28 @@
 // require('
-./blog
+ivle
 ');%0A%0A  // fo

Reorder navigation menu