var api_url = '/api/v2/';
var login_url = '/login';
var logout_url = '/logout';

var templates = [];

var mouseWheelOffset = 10;

var templateCachingDisabled = false;

var reportSets = {};

var blueReport = {
  tags: []
};
  
function blueReportCommon(modules) {
  this.__construct = function () {
    this.setNamespace('bluereport');
    this.modules = modules;
    var that = this;
    _(modules).each(function (module) {
      that[module.toUpperCase()] = true;
    });
    $('html').addClass(this.BETA ? 'beta' : 'no-beta');
    this.templates = ['clip', 'comment', 'tags', 'sourceCategory', 'sourceGroup'];
    this.loadTemplates();
  };

  this.init = function () {
    $("#progressbar").hide().progressbar({
      value: 0
    }).fadeIn('slow', function () {
      loadUsers();
      loadTags();
      loadAgents();
      loadSourceCategories();
      loadSourceGroups();
    });
  };
  
  this.basicsLoaded = function () {
    $("#progressbar").progressbar({
      value: $("#progressbar").progressbar('value') + 20
    });
    // FIXME: this switch is strange, I don’t get it
    switch ('undefined') {
     case typeof (users):
      return false;
     case typeof (agentTags):
      return false;
     case typeof (groupAgents):
      return false;
     case typeof (sourceCategories):
      return false;
     case typeof (sourceGroups):
      return false;
    }
    $("#progressbar").fadeOut('slow', function () {
      blueReportCommon.launch();
    });
  };

  this.launch = function () {
    this.initEvents();
    setHighchartsDefaults();
    setDatepickerDefaults();

    resizeContent();
    window.onresize = function () {
      resizeContent();
    };
    sourceCategoriesBlock = $.jqote(templates.bluereport.sourceCategory, sourceCategories);
    sourceGroupsBlock = $.jqote(templates.bluereport.sourceGroup, sourceGroups);

    _(this.modules).chain().without('group_admin', 'beta').each(function (module) {
      $.getScript('/js/' + module + '.js');
    });
  };

  this.initEvents = function () {
    // Tell main navigation buttons to activate / deactivate
    $('#container-navigation').delegate('li.loaded:not([class*=active])', 'click', function () {
      if ($('#container-navigation li.loaded.active').length !== 0) {
        $('#container-navigation li.loaded.active').data('object').deactivate();
      }
      $(this).data('object').activate();
    });

    // Checkbox behavior
    $('body').delegate('div.checkbox', 'click', function () {
      $(this).toggleClass('checked');
    });
    $('body').delegate('span.checkbox', 'click', function () {
      $(this).toggleClass('checked');
      if ($(this).hasClass('group')) {
        if ($(this).hasClass('checked')) {
          $(this).siblings().addClass('checked');
        } else {
          $(this).siblings().removeClass('checked');
        }
      }
    });

    $('#logout').click(function () {
      window.location.href = logout_url;
    });
  };

  this.__construct();
}
blueReportCommon.prototype = new baseBlueReport();
blueReportCommon.prototype.constructor = blueReportCommon;

var limits = {},
    socialMediaTracker = [];
/**
 * blueReport functions
 */
function loadSession(){
  $.ajax({
    url: api_url + 'session',
    dataType: 'json',
    async: false,
    cache: false,
    success: function (data, textStatus, XMLHttpRequest) {
      application_version = data.application_version;
      userId = data.user.id;

      if (application_version !== getStorage('application_version') || userId !== getStorage('userId')) {
        $.jStorage.flush();
        setStorage('application_version', application_version);
        setStorage('userId', userId);
      }
      log('Current Storage Size: '+ $.jStorage.storageSize() / 1024.0 +'kB.', 'info');
  
      user = data.user;
      limits = data.limits;
      checkAgentLimit(data.counts.agents);
      checkUserLimit(data.counts.users);
      checkSocialMediaTrackerLimit(data.counts.social_media_trackers);
      blueReportCommon = new blueReportCommon(data.modules);
      $('#container-main').fadeIn('slow');
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
      window.location.href = login_url;
    }
  });
}

function checkAgentLimit(count) {
  if (limits.agents <= count) {
    $('html').addClass('agent-limit-exceeded');
  }
  else {
    $('html').removeClass('agent-limit-exceeded');
  }
}

function checkUserLimit(count) {
  if (limits.users <= count) {
    $('html').addClass('user-limit-exceeded');
  }
  else {
    $('html').removeClass('user-limit-exceeded');
  }
}

function checkSocialMediaTrackerLimit(count) {
  if (limits.social_media_trackers <= count) {
    $('html').addClass('social-media-tracker-limit-exceeded');
  }
  else {
    $('html').removeClass('social-media-tracker-limit-exceeded');
  }
}

function loadUsers() {
  var path = 'users';
  $.ajax({
    url: api_url + path,
    type: 'GET',
    cache: true,
    dataType: 'json',
    context: this,
    success: function (data, textStatus, XMLHttpRequest) {
      var i,user;
      users = {};
      for (i=0 ; i<data.collection.length ; i+=1) {
        user = data.collection[i];
        users[user.id.toString()] = user;
      }
    },
    complete: function (XMLHttpRequest, textStatus) {
      blueReportCommon.basicsLoaded();
    }
  });
}
function loadTags(reload) {
  var path = 'tags'; 
  $.ajax({
    url: api_url + path,
    type: 'GET',
    cache: true,
    dataType: 'json',
    reload: reload,
    success: function (data, textStatus, XMLHttpRequest) {
      agentTags = blueReport.tags = [];
      $(data.collection).each(function (){
        agentTags.push(this.name);
        blueReport.tags.push(this);
      });
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    },
    complete: function (XMLHttpRequest, textStatus) {
      if (this.reload === true) {
        return;
      }
      blueReportCommon.basicsLoaded();
    }
  });
}
function loadAgents() {
  var path = 'agents';
  $.ajax({
    url: api_url + path,
    type: 'GET',
    cache: true,
    dataType: 'json',
    context: this,
    success: function (data, textStatus, XMLHttpRequest) {
      groupAgents = {};
      $(data.collection).each(function (){
        groupAgents[this.id] = this;
      });
    },
    complete: function (XMLHttpRequest, textStatus) {
      blueReportCommon.basicsLoaded();
    }
  });
}
function loadSourceCategories() {
  var path = 'sources/source_categories';
  $.ajax({
    url: api_url + path,
    type: 'GET',
    cache: true,
    dataType: 'json',
    success: function (data, textStatus, XMLHttpRequest) {
      sourceCategories = data.collection;

    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    },
    complete: function (XMLHttpRequest, textStatus) {
      blueReportCommon.basicsLoaded();
    }
  });
}
function loadSourceGroups() {
  var path = 'sources/source_groups';
  $.ajax({
    url: api_url + path,
    type: 'GET',
    cache: true,
    dataType: 'json',
    context: this,
    success: function (data, textStatus, XMLHttpRequest) {
      sourceGroups = data.collection;
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    },
    complete: function (XMLHttpRequest, textStatus) {
      blueReportCommon.basicsLoaded();
    }
  });
}
function baseBlueReport() {

  this.getNamespace = function () {
    return this.namespace;
  };
  this.setNamespace = function (data) {
    this.namespace = data;
  };

  this.getTitle = function () {
    if (typeof (this.title) !== 'string') {
      return this.getNamespace();
    } else {
      return this.title;
    }
  };
  this.setTitle = function (data) {
    this.title = data;
  };

  this.bindObject = function (){
    $('#container-navigation li[rel="'+ this.getNamespace() +'"]').data('object', this);
  };

  this.loadTemplates = function (cache) {
    var i,template, path, data;
    if (templateCachingDisabled) {
      cache = false;
    }
    
    this.markAsLoading();
    templates[this.getNamespace()] = [];

    for (i=0 ; i < this.templates.length ; i+=1) {
      template = this.templates[i];
      path = 'templates/'+ this.getNamespace() +'/'+ template;
      data = getStorage(path);
      cache = cache !== false;
      
      if (null === data || !cache) {
        $.ajax({
          url: '/js/'+ path +'.tpl',
          type: 'GET',
          dataType: 'html',
          cache: cache,
          data: template,
          obj: this,
          template: template,
          path: path,
          // FIXME: potential cause for trouble because of closures created inside loops
          success: function (returnedData, textStatus, XMLHttpRequest) {
            templates[this.obj.getNamespace()][this.template] = $.jqotec(returnedData);
            setStorage(this.path, returnedData);
            if (true === this.obj.templatesLoaded()) {
              this.obj.init();
            }
          }
        });

      } else {
        templates[this.getNamespace()][template] = $.jqotec(data);
        if (true === this.templatesLoaded()) {
          this.init();
        }
      }

    }
  };
  this.templatesLoaded = function () {
    var i;
    for (i=0 ; i < this.templates.length ; i+=1) {
      if (! templates[this.getNamespace()][this.templates[i]]) {
        return false;
      }
    }
    $('#container-content').append(templates[this.getNamespace()].grid);
    return true;
  };

  this.activateLayer = function () {
    document.title = 'blueReport '+ this.getTitle();
    $('#container-header span').text(this.getTitle());
    $('#container-navigation li[rel="'+ this.getNamespace() +'"]').addClass('active');
    $('#container-'+ this.getNamespace()).addClass('active');
  };
  this.deactivateLayer = function () {
    $('#container-navigation li[rel="'+ this.getNamespace() +'"]').removeClass('active');
    $('#container-'+ this.getNamespace()).removeClass('active');
    document.title = 'blueReport';
  };

  this.markAsLoading = function () {
    $('#container-navigation li[rel="'+ this.getNamespace() +'"]').addClass('loading');
  };

  this.markAsLoaded = function () {
    $('#container-navigation li[rel="'+ this.getNamespace() +'"]')
    .removeClass('loading')
    .addClass('loaded',1500,'jswing');
  };

  this.checkScrollingLeft = function () {
    var containerLeft, distanceToBottom;
    containerLeft = $('div.content-left', this.container);
    distanceToBottom = $('>ul', containerLeft).outerHeight() - $(containerLeft).outerHeight() - $(containerLeft).scrollTop();

    if ($(containerLeft).scrollTop() === 0) {
      $('div.scroll.up', containerLeft).hide();
    } else {
      $('div.scroll.up', containerLeft).show();
    }

    if (distanceToBottom <= 0 ) {
      $('div.scroll.down', containerLeft).hide();
    } else {
      $('div.scroll.down', containerLeft).show();
    }
  };
  this.scrollLeft = function (distance) {
    var containerLeft = $('div.content-left', this.container);
    $(containerLeft).scrollTop($(containerLeft).scrollTop() + distance);
  };
}

/**
 * common functions
 */
function resizeContent() {
  if(navigator.appVersion.indexOf ("MSIE 7.") === -1) {
    $('#container-content').css('height', $('body').height() - $('#container-header').height() - $('#container-navigation').height());
  }
}
function getStorage (id, defaultValue) {
  if (null === defaultValue) {
    defaultValue = false;
  }
  // return false;
  return $.jStorage.get(id,defaultValue);
}
function setStorage (id, value) {
  if (null === value) {
    value = '';
  }
  return $.jStorage.set(id, value);
}
function removeStorage (id) {
  return $.jStorage.deleteKey(id);
}
function log (msg, type) {
  if (typeof console === 'undefined') {
    return false;
  }

  msg = (typeof (msg) !== 'undefined') ? msg : 'Holla' ;

  switch (type) {
    case 'info':
      console.info(msg);
      break;
    case 'warn':
      console.warn(msg);
      break;
    case 'error':
      console.error(msg);
      break;
    case 'debug':
      console.debug(msg);
      break;

    default:
      console.log(msg);
  }
}
function notify (msg, type) {
  switch (type) {
    case 'error':
      $.pnotify({
        pnotify_title: 'Fehler',
        pnotify_text: msg,
        pnotify_type: 'error',
        pnotify_history: false,
        pnotify_opacity: 0.9
      });
      break;

    default:
      $.pnotify({
        pnotify_text: msg,
        pnotify_history: false,
        pnotify_opacity: 0.9
      });
  }
}
function setHighchartsDefaults() {
  Highcharts.setOptions({
    global: {
      useUTC: false
    },
    chart:{
      animation: true
    },
    exporting: {
      enabled: false,
      buttons: {
        exportButton: {
          enabled: false
        },
        printButton: {
          enabled: false
        }
      }
    },
    title: {
      text: null
    },
    lang: {
      months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
      weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
      resetZoom: 'gesamter Zeitraum'
    },
    xAxis: {
      title: {
        text: null
      }
    },
    yAxis: {
      title: {
        text: null
      }
    },
    legend: {
      enabled: false
    },
    credits: {
      enabled: false
    }
  });
}
function setDatepickerDefaults() {
  $.datepicker.setDefaults($.datepicker.regional.de);
  $.datepicker.setDefaults({
    showWeek: true
  });
}

String.prototype.escapeHTML = function (){
  var result = "", i;
  for(i = 0; i < this.length; i+=1){
    if (this.charAt(i) === "&" 
        && this.length - i - 1 >= 4 
        && this.substr(i, 4) !== "&amp;"){
      result = result + "&amp;";
    }
    else if (this.charAt(i) === "<") {
      result = result + "&lt;";
    }
    else if (this.charAt(i) === ">") {
      result = result + "&gt;";
    }
    else if (this.charAt(i) === '"') {
      result = result + "&quot;";
    }
    else {
      result = result + this.charAt(i);
    }
  }
  return result;
};

function setLogoutButtonText(){
  if(typeof (user) !== "undefined"){
    if(user.full_name.length > 0){
      $("#full-name").html(user.full_name);
      $("#logout-text").html(" abmelden");
    }
  }
}

$(document).ready(function () {
  loadSession();
  setLogoutButtonText();
  Highcharts.setOptions({
    chart: {
      style: {
        fontFamily: 'Helvetica, Arial, sans-serif'
      }
    }
  });
});

