/**
 * Global of Green object
 */
var green;

/**
 Total reducing of CO2
 @class Green
 @constructor
 @param {Map} map object
 */
function Green(map) {
  
  /** 
   * Hash of general entry
   * entries: Array of entries
   * max:  the number of max display to general list
   * display: display or not to put maker on map
   * perPage: the number of plot per Page
   */
  var _general = {};
  _general.entries = [];
  _general.max = 20;
  _general.display = true;
  _general.perPage = 100;

  /** 
   * Hash of guest entry
   * alignment of entries
   * display or not to put maker on map
   */
  var _guest = {};
  _guest.entries = [];
  _guest.display = true;

  var _first = true;

  function _init() {
    _logged_in();
  }

  function _logged_in() {
    var url = Green.API + 'logged_in';;
    var json = new JSON();
    json.load(url, _logged_in_callback);
  }

  function _logged_in_callback(logged_in) {
    Green.login = logged_in;
    map.init();
    if (document.getElementById('loginNav')) {
      var login = document.getElementById('loginNav');
      var html = new HTML();
      login.innerHTML = html.login();
    }
    _get_campaign_info();
  }

  function _get_campaign_info() {
    var url = Green.API + 'get_campaign_info';
    var json = new JSON();
    json.load(url, _get_campaign_info_callback);
  }

  function _get_campaign_info_callback(info) {
    if (document.getElementById('progressReport')) {
      var campaign = document.getElementById('progressReport');
      var html = new HTML();
      campaign.innerHTML = html.campaignInfo(info);
    }
    _get_guest_points();
  }

  function _get_points() {
    var url = Green.API + 'get_recent_actions';
    var json = new JSON();
    var params = {
      timedelta: Green.TIMEDELTA,
      num: _general.perPage
    };
    json.load(url, _get_points_callback, params);
  }

  function _get_points_callback(info) {
    _general.entries = [];
    for (var i = 0; i < info.points.length; i++) {
      var point = info.points[i];
      if (point.type === 0 || point.type == 1) {
        _general.entries.push(point);
      }
    }
    _plotMarkers();
    _listGeneralEntries();
    if (document.getElementById('pageNav')) {
      var pageNav = document.getElementById('pageNav');
      var html = new HTML();
      pageNav.innerHTML = html.pageNav(info.pages);
    }
    if (document.getElementById('backMyBalloon')) {
      var backMyBalloon = document.getElementById('backMyBalloon');
      var html = new HTML();
      backMyBalloon.innerHTML = html.backMyBalloon();
    }
  }

  function _get_guest_points() {
    var url = Green.API + 'get_guests_points';
    var json = new JSON();
    json.load(url, _get_guest_points_callback, {timedelta: Green.TIMEDELTA});
  }

  function _get_guest_points_callback(points) {
    for (var i = 0; i < points.length; i++) {
      var point = points[i];
      _guest.entries.push(point);
    }
    _get_points();
  }

  function _plotMarkers(userId) {
    map.removeMarkers();
    if (_general.display) {
      _plotMarkersGeneral(userId);
    }
    if (_guest.display) {
      _plotMarkersGuest(userId);
    }
    if (Green.login.logged_in) {
      var userId = Green.login.user_id;
      if (userId && userId != -1) {
        if (_first) {
          map.plotLoginUser(userId, true);
          _first = false;
        } else {
          map.plotLoginUser(userId);
        }
      }
    }
  }

  function _plotMarkersGeneral(userId) {
    var entries = _general.entries.concat();
    map.plot(entries, userId);
  }

  function _plotMarkersGuest(userId) {
    var entries = _guest.entries.concat();
    map.plot(entries, userId);
  }

  function _listGeneralEntries() {
    if (document.getElementById('latest')) {
      var ol = document.getElementById('latest').getElementsByTagName('ul')[0];
      var html = new HTML();
      var entries = _general.entries.concat();
      if (entries.length > _general.max) {
        entries = entries.slice(0, _general.max);
      }
      ol.innerHTML = html.generalEntries(entries);
    }
  }

  /**
   * Open the userId's InfoWindow
   * @param {number} userId
   */
  this.openGeneral = function(userId) {
    map.openInfo(userId);
  }

  /**
   * same as openGeneral
   * @param {number} userId
   */
  this.openGuest = function(userId) {
    map.openInfo(userId);
  }

  /**
   * same as openGeneral
   * @param {number} userId
   */
  this.openApproved = function(userId) {
    map.openInfo(userId);
  }

  /**
   * change the display of guest maker
   * @param {boolean} display or not guest maker
   */
  this.switchGuest = function(display) {
    _guest.display = display;
    _plotMarkers();
    map.fitZoom();
  }

  /**
   * change the display of general maker
   * @param {boolean} display or not general maker
   */
  this.switchGeneral = function(display) {
    _general.display = display;
    _plotMarkers();
    map.fitZoom();
  }

  /**
   * display layer
   * @param {string} name
   */
  this.loadLayer = function(name) {
    map.loadLayer(name);
  }

  /**
   * display GroundOverlay
   * @param {string} name
   */
  this.loadGroundLayer = function(name) {
    map.loadGroundLayer(name);
  }

  /**
   * hide layer inc GroundOverlay
   * @param {string} name
   */
  this.removeLayer = function(name) {
    map.removeLayer(name);
  }

  /**
   * Agree with userId
   * Call api:do_approval
   * @param {number} userId
   */
  this.do_approval = function(userId) {
    var url = Green.API + 'do_approval';
    var params = {user_id: userId};
    var json = new JSON();

    /**
     * Call back api:do_approval
     * Define as Closure to check userId
     * @param {boolean} approval do_approval
     */
    function do_approval_callback(approval) {
      if (approval) {
        map.reopenInfo(userId);
      } else {
        map.reopenInfo(userId, true);
      }
    }
    json.load(url, do_approval_callback, params);
  }

  /**
   * Load Page
   * @param {string} url API URL with parameters
   */
  this.loadPage = function(url) {
    var json = new JSON();
    json.load(url, _get_points_callback);
  }

  /**
   * Swtich ScrollWheelZoom enable
   * @param {boolean} enable Enable or not
   */
  this.switchScrollWheelZoom = function(enable) {
    map.switchScrollWheelZoom(enable);
  }

  _init();
}
/**
 * base point of API
 */
Green.API = 'http://teamm6.appspot.com/api/';

/**
 * difference in time from GMT for using as parameter to call API
 */
Green.TIMEDELTA = (new Date).getTimezoneOffset() / 60;

/**
 * login info
 */
Green.login = {'logged_in': false};


/**
 * attach a.onclick of general list
 * @param {number} userId
 */
function openLatest(userId) {
  green.openGeneral(userId);
}

/**
 * attach a.onclick of guest list
 * @param {number} userId
 */
function openGuest(userId) {
  green.openGuest(userId);
}

/**
 * attach checkbox.onclick of guest's green action
 * @param {checkbox} checkbox object
 */
function switchGuest(checkbox) {
  green.switchGuest(checkbox.checked);
}

/**
 * attach checkbox.onclick of all green action
 * @param {checkbox} checkbox object
 */
function switchGeneral(checkbox) {
  green.switchGeneral(checkbox.checked);
}

/**
 * attach each checkbox.onclick of Green layer
 * @param {checkbox} checkbox object
 */
function loadLayer(checkbox) {
  if (checkbox.checked) {
    green.loadLayer(checkbox.value);
  } else {
    green.removeLayer(checkbox.value);
  }
}

/**
 * only call from loadLayers for GroundLayer
 * private
 * @param {checkbox} checkbox object
 */
function loadGroundLayer(checkbox) {
  if (checkbox.checked) {
    green.loadGroundLayer(checkbox.value);
  } else {
    green.removeLayer(checkbox.value);
  }
}

/**
 * attach each checkbox.onclick of Green layer
 * the deference for loadLayer is just read GroundOverlay or not
 * @param {checkbox} checkbox object
 */
function loadLayers(checkbox) {
  loadGroundLayer(checkbox);
  loadLayer(checkbox);
}

/**
 * attach a.onclick to the agree button on InfoWindow
 * @param {number} userId
 */
function doApproval(userId) {
  green.do_approval(userId);
}

/**
 * attach a.onclick to the PageNav
 * @param {string} url API URL with parameters
 */
function loadPage(url) {
  green.loadPage(url);
}

/**
 * attach checkbox.onclick to the ScrollWheelZoom
 * @param {boolean} checked Enable or not
 */
function switchScrollWheelZoom(checked) {
  green.switchScrollWheelZoom(checked);
}

/**
 * attach a.onclick to the Approved User on InfoWindow
 * @param {number} userId user_id
 */
function openApproved(userId) {
  green.openApproved(userId);
}

google.setOnLoadCallback(function(){
  var map = new Map();
  green = new Green(map);
});
google.load('maps', '2');

