/**
 * @fileoverview
 * to show user timezone and firstname, lastname profile and logout links if we
 * think they are logged in.
 *
 * btUser depends on btTimezone but btTimezone is independant.
 *
 * Also provides the logout handler as it is closely related to the writing of
 * user status area.
 */

/**
 * The cookie name for user info.
 * @todo PS - refactor to proper jquery plugin with tests etc. see btfeed plugin as example
 * @todo PS - set these from config somehow
 * @todo PS - make these options on the plugin and not globals.
 * @todo PS - could use jquery json plugin to eval the output securely http://code.google.com/p/jquery-json/ which is a better pattern in general
 */
var cookie_name = 'BTSESSION';
var cookie_domain = 'brighttalk.com';
var cookie_delim = ':';
var sessionIdIndex = 0;
var first_name_index = 1;
var last_name_index = 2;
var timezone_index = 4;
var manager_index = 5;
var max_cookie_items = manager_index;
var zones_mapping_json = "http://www.brighttalk.com/js/5/tz/zones.js";
var default_timezone = 'America/Los_Angeles';

// uncomment this line to get debug to firebug console or bottom of page (if not firebug)
var DEBUG = false;

/**
 * Function for flash to call after a successful login.
 */
function flashAfterLogin() {
  $.btUser.initialise();
  $.btUser.writeUserStatusBar();
}


/**
 * when the document is ready initialise the user status area, including timezone.
 */
jQuery(document).ready(function($) {
  $('#startDate.datapairs-element-value abbr').removeClass('dtstart');
  $('#startDate.datapairs-element-value span').removeClass('hcalendar-dtstart');

  // @todo now that we do current user call on user we don't really need to guess timezone
  $().btUser();
  $().btTimeZone();

  // add clear cookie_name cookie on logout
  $('#logout-status').live('click', function() {
    $(document).trigger('logout');
    return false;
  });

  // Expose the ability to localise a date element via this event
  $(document).bind('localiseDate', function(e) {
    $.btTimeZone.updateDateItem(0, e.target);
  });

  /**
   * Logout event
   */
  $(document).bind('logout', function(event) {
    $.ajax({
      url: 'http://www.brighttalk.com/service/user/xml/logout/',
      dataType: 'xml',
      success: function(xml, textStatus, XMLHttpRequest) {
        $.cookie(cookie_name, '', {expires: -1, path: "/", domain: cookie_domain});
        var timezone = $(xml).find('timeZone').text();
        $.btTimeZone.changeTimeZone(timezone);
        window.location = 'http://www.brighttalk.com/';
      }
    });
    return false;
  });

});

(function($) { // hide the jquery namespace and make it compatible with other libs

/**
 * A prototype based object to look after the user details
 */
function BTUser () {
  this.debug = 0; // Change this to a positive integer to start debugging
  // set default values
  this.sessionId = '';
  this.first_name = '';
  this.last_name = '';
  this.time_zone = '';
  this.time_zone_display = '';
  this.is_manager = '';
  this.cookie_name = 'btuser';
}

$.extend(BTUser.prototype, {
  templates: {
      'manager': '<li id="manage-link"><a  id="userstatus-manage"href="http://www.brighttalk.com/admin">Manage</a><span class="breakbar">&nbsp;|&nbsp;</span></li>',
      'timezone': '<div id="timezone-status">All times in your timezone:&nbsp;<a id="site-timezone-link" href="http://www.brighttalk.com/mybrighttalk/profile" brightalk:timezone="{timeZone}">{timeZoneDisplay}</a></div>',
      'profile': '<li><a id="userstatus-mybrighttalk" href="http://www.brighttalk.com/mybrighttalk">My BrightTALK</a><span class="breakbar">&nbsp;|&nbsp;</span></li>',
      'logout': '<li><a id="logout-status" href="http://www.brighttalk.com/">Logout</a></li>',
      'name': '<li id="user-name"><a id="userstatus-profile" href="http://www.brighttalk.com/mybrighttalk/profile" title="Go to Profile">{firstName} {lastName}</a><span class="breakbar">&nbsp;|&nbsp;</span></li>'
    },

  /* Debug logging (if debug > 0). */
  log: function (message) {
    if (this.debug > 0) {
      $.log('BTUser: ' + message);
    }
  },

  /* Trace logging (if debug > 1). */
  trace: function (message) {
    if (this.debug > 1) {
      $.log('BTUser: ' + message);
    }
  },
  //URL DECODES
  decode: function (value) {
      value= value.replace(/&/g, "&amp;");
      value= value.replace(/'/g, "&apos;");
      value= value.replace(/"/g, "&quot;");
      value= value.replace(/>/g, "&gt;");
      value= value.replace(/</g, "&lt;");
      value= value.replace(/:/g, "");
      return value.replace(/\+/g,  " ");
   },

  /* wrapper function to get the session data from cookie */
  getSessionDataFromCookie : function() {
    var cookie_str = $.cookie(cookie_name);
    this.trace(cookie_str);
    if (cookie_str === null) {
      return null;
    }
    var user_data = cookie_str.split(cookie_delim);
    for (var i = 0; i < user_data.length; i++) {
      user_data[i] = $.btUser.decode(user_data[i]);
    }
    if (user_data.length >= last_name_index) {
      this.sessionId = user_data[sessionIdIndex];
      this.first_name = user_data[first_name_index];
      this.last_name = user_data[last_name_index];
    }
    if (user_data.length >= timezone_index) {
      this.time_zone = user_data[timezone_index];
    }
    if (user_data.length >= manager_index) {
      this.is_manager = user_data[manager_index];
    }
    if (this.time_zone) {
      this.time_zone_display = $.btTimeZone.getTimeZoneDisplay(this.time_zone);
    }
    return user_data;
  },

  /* Initialise the user values from the cookie */
  initialise : function() {
    this.log('initialise');

    $.btUser.templates.loggedOut = $("#user-status").html();

    $(document).bind('userInfoUpdated', function() {
      var user_data = $.btUser.getSessionDataFromCookie();
      if (user_data !== null) {
        $.btUser.writeUserStatusBar();
      }
      $('.user-timezone').text($.btUser.time_zone_display);
    });

    var user_data = $.btUser.getSessionDataFromCookie();

    if (user_data === null || (user_data.length >= timezone_index) && user_data[timezone_index] === '') {
      $.btTimeZone.guessTimezone();
    } else {
      $(document).trigger('userInfoUpdated');
    }
    this.trace(user_data);
  },

  /* Update currency symbols on the page */
  updateCurrencySymbols : function () {
  	var currsymbols = $('.currencysymbol');
    if ($(currsymbols).size()>0) {
		var parts = this.time_zone.split('/');
		var tz = parts[0].toLowerCase();
		//currency array
		var currencymap = [];
		currencymap['pounds'] = ['europe', 'africa'];
		currencymap['euros'] = [];
		//check the values
    	if (jQuery.inArray(tz,currencymap['pounds'])>=0) {
    		$(currsymbols).text('£');
    	} else if (jQuery.inArray(tz,currencymap['euros'])>=0) {
    		$(currsymbols).text('€');
    	} else {
			//leave as is
    	}
		return true;
    }
  },

  /* Write the user status bar with the current values. */
  writeUserStatusBar : function() {
    this.log('writeUserStatusBar');

    var templates = $.btUser.templates;

    var timeZoneDisplay = this.time_zone_display;
    if (timeZoneDisplay === undefined) {
      timeZoneDisplay = this.time_zone;
    }
    var timezoneHtml = templates.timezone.replace('{timeZone}', this.time_zone).replace('{timeZoneDisplay}', timeZoneDisplay);

    //default to logged out html
    var newUserStatus = $('<div id="user-status">' + templates.loggedOut + '</div>');

    // with timezone replaced
    jQuery('#timezone-status', newUserStatus).replaceWith(timezoneHtml);

    if (this.isUserLoggedIn()) {
      userAccountNav = '';
      if (this.isManager()) {
        userAccountNav += templates.manager;
      }
      userAccountNav += templates.name.replace('{firstName}', this.first_name).replace('{lastName}', this.last_name);
      userAccountNav += templates.profile;
      userAccountNav += templates.logout;
      jQuery('#account-nav', newUserStatus).each(function() {
        $(this).html(userAccountNav);
      });
    }

    $("#user-status").replaceWith(newUserStatus);

  },

  /* Return true if we think the user is logged in. */
  isUserLoggedIn : function() {
    this.log('isUserLoggedIn');

    if (this.sessionId === '' && this.first_name === '' && this.last_name === '') {
      return false;
    } else {
      return true;
    }
  },

  isManager : function() {
    this.log('isManager  = '+ this.is_manager);
    return (this.is_manager === 'true');
  }
});

$.fn.btUser = function(options) {
  $.btUser.initialise();
  return $.btUser;
};

$.btUser = new BTUser(); // singleton instance
// @todo PS - make these into options and set in document.ready function.
$.btUser.cookie_name = cookie_name;

})(jQuery);

(function($) { // hide the jquery namespace and make it compatible with other libs

/**
 * A prototype based object for all things timezone
 */
function BTTimeZone() {
  this.debug = 0; // Change this to a positive integer to start debugging
  this.time_zone = ''; // the timezone value e.g. Europe/London
  this.cookie_name = 'timezone'; // the name for the cookie
  this.initialised = false;
  this.time_zone_offsets = []; // an array of offset arrays one for each continent
  this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; // months used for formatting
  this.time_zone_display = []; // an associative array of timezone to display value
  this.isGuessing = false;
}

$.extend(BTTimeZone.prototype, {
  /* Debug logging (if debug > 0). */
  log: function (message) {
    if (this.debug > 0) {
      $.log('BTTimeZone: ' + message);
    }
  },

  /* Trace logging (if debug > 1). */
  trace: function (message) {
    if (this.debug > 1) {
      $.log('BTTimeZone: ' + message);
    }
  },

  /* Initialise the user values from the cookie */
  initialise : function() {
    this.log('initialise');

    // @todo PS try doing a document.createElement("abbr"); which should work in all browsers
    // and if you do it in IE6 then recognises all abbrs
    // see http://ejohn.org/blog/html5-shiv/
    document.createElement("abbr");

    var user_data = $.btUser.getSessionDataFromCookie();
    if (user_data !== null) {
      if (user_data.length >= timezone_index) {
        this.time_zone = user_data[timezone_index];
      }
    }

    $(document).bind('convertDates', function() {
      $.btTimeZone.convertDates();
    });

    if (this.time_zone === '') {
      $.btTimeZone.guessTimezone();
    } else {
      // change the dates on the page
      $(document).trigger('convertDates');
    }
  },

  guessTimezone : function () {
    if (!$.btTimeZone.isGuessing) {
      $.btTimeZone.isGuessing = true;
      $.ajax({
        url: '/service/user/xml/current/',
        dataType: 'xml',
        success: function(xml, textStatus, XMLHttpRequest) {
          var timezone = $(xml).find('timeZone').text();
          $.btTimeZone.changeTimeZone(timezone);
          $.btTimeZone.isGuessing = false;
        }
      });
    }
  },

  changeTimeZone : function(timezone) {
    // fire user info update event
    // @todo make this work as a proper plugin so that it has a context and can be called multiple times/chained etc.
    $.btTimeZone.time_zone = timezone;
    $.btTimeZone.alias = $.btTimeZone.getTimeZoneDisplay(timezone);
    $.btTimeZone.setCookie(timezone, $.btTimeZone.alias);
    //re-initialise the btUser
    $.btUser.time_zone_display = $.btTimeZone.alias;
    $(document).trigger('userInfoUpdated');
    $(document).trigger('convertDates');
  },

  /* Set the timezone value in the cookie of name = cookie_name */
  setCookie : function(timezone, alias) {
    this.log('setCookie');

    if (alias === undefined) {
      alias = timezone;
    }

    var cookie_str = $.cookie(this.cookie_name);
    if (cookie_str === null) {
      cookie_str = '';
      for(var i = 0; i < max_cookie_items; i++) {
        cookie_str += cookie_delim;
      }
    }
    var data = cookie_str.split(cookie_delim);
    data[timezone_index] = timezone;
    cookie_str = data.join(cookie_delim);
    this.trace('cookie_str='+cookie_str);
    $.cookie(this.cookie_name, '', {expires: -1, path: "/"});
    $.cookie(this.cookie_name, cookie_str, {expires: 365 , path: "/", domain: cookie_domain});
  },

  /* convert the dates on the page based on the value of this.time_zone*/
  convertDates : function() {
    this.log('initOffsetArray');
    $.btTimeZone.convertDatesForGivenTimezone(this.time_zone);
  },

  convertDatesForGivenTimezone : function(time_zone) {
  // get the zone/region/continent for the timezone
    var continent = $.btTimeZone.getContinentForTimezone(time_zone);
    $.btTimeZone.time_zone_offsets[continent] = [];
    $.btTimeZone.tzOffsetArray = [];

    // @todo PS - make this path options config
    $.getJSON("http://www.brighttalk.com/js/5/tz/" + continent + ".js", function(data) {
      for (var i in data) {
        // we want all the values defined so no if here
        $.btTimeZone.time_zone_offsets[continent][i] = data[i];
      }
      $.btTimeZone._setDates(time_zone);
      $.btTimeZone.trace('initOffsetArray ajax and processing complete');
    });
  },

  getContinentForTimezone: function(time_zone) {
  var continent = 'etc';
  if (time_zone !== '') {
    var time_zone_parts = time_zone.split("/");
    if (time_zone_parts.length > 1) {
      continent = time_zone_parts[0];
    }
  }
  return continent.toLowerCase();
  },

  /* Internal function for setting the dates */
  _setDates : function(time_zone) {
    this.log('_setDates');
    //var time_zone = this.time_zone;
    if (time_zone === null) {
      return false;
    }
    $('.hcalendar-dtstart').each(function(i, item) {
      $.btTimeZone.updateDateItem(i, item, time_zone);
    });
    return true;
  },

  updateDateItem : function(i, item, time_zone) {
  if (time_zone === undefined) {
    time_zone = this.time_zone;
  }
    //function to replace the date for a tag surrounding the <abbr tag as IE6
    //doesn't put abbr tags into the DOM properly.
    $.btTimeZone.trace('updateDateItem');

    var dtstart = jQuery(item.innerHTML);
    var dtstart_length = dtstart.length;
    var timePattern = /(am|pm)/;
    var datePattern = /[a-zA-Z]{3}\s\d{2}\s\d{4}/;
    var dateNoYearPattern = /[a-zA-Z]{3}\s\d{2}/;

    var dtstart_str = dtstart.text();
    // use innerText for browsers that support it like IE6 as .text() seems to not work there
    if (item.innerText) {
      dtstart_str = item.innerText;
    }

    $.btTimeZone.trace('dtstart_str='+dtstart_str);
    var hasTime = timePattern.test(dtstart_str);
    var hasDate = datePattern.test(dtstart_str);
    var hasDateNoYear = dateNoYearPattern.test(dtstart_str) && !hasDate;
    if (hasDateNoYear) {
      hasDate = true;
    }
    $.btTimeZone.trace('item.innerHTML=' + item.innerHTML   + ' dtstart_length=' + dtstart_length + ' hasTime=' + hasTime + ' hasDate=' + hasDate);

    var timestamp = parseInt(dtstart.attr('brighttalk:timestamp'), 10);
    $.btTimeZone.trace('timestamp=' + timestamp);
    if (timestamp > 1) {
      var offset = $.btTimeZone._getOffset(timestamp, time_zone);
      var date = new Date((timestamp + offset) * 1000);
      $.btTimeZone.trace('new timestamp='+ (timestamp + offset));
      var date_str = $.btTimeZone._formatDate(date, hasTime, hasDate, hasDateNoYear);
      $.btTimeZone.trace('old=' + dtstart + ' offset=' + offset + '>>>>> timestamp=' + timestamp + ' new=' + date_str);

      item.innerHTML = '<abbr class="dtstart" brighttalk:timestamp="' + timestamp + '">' + date_str + '</abbr>';
    }
  },

  /* get date offset for a timestamp */
  _getOffset : function(timestamp, time_zone) {
    this.log('_getOffset');
    var continent = $.btTimeZone.getContinentForTimezone(time_zone);
    var offsets = this.time_zone_offsets[continent][time_zone];
    if(offsets === undefined){
      return 0;
    }
    if (offsets.length == 1) {
        return offsets[0][1];
    } else if (offsets.length === 0) {
        return 0;
    }

    for (var i = 0; i < (offsets.length - 1); i++) {
      if (timestamp > offsets[i][0] && timestamp < offsets[i+1][0]) {
        return offsets[i][1];
      }
      if (i == (offsets.length - 1)) {
        return offsets[i+1][1];
      }
    }
    // @todo remove if this works
    //return 0;
    return offsets[offsets.length - 1][1];
  },

  /* Format a date as we like it, optionally include the time */
  _formatDate : function(date, disp_time, display_date, sans_year) {
    if (display_date == null) {
      display_date = true;
    }
    if (sans_year == null) {
      sans_year = false;
    }
    this.log('_formatDate date=' + date + ' disp_time=' + disp_time);
    var days = date.getUTCDate();
    if (days < 10) {
      days = '0' + days;
    }
    var date_str = '';
    if (display_date) {
    date_str = this.months[(date.getUTCMonth())] + ' ' + days;
      if (!sans_year) {
        date_str += ' ' +  date.getUTCFullYear();
      }
    }
    if (!disp_time) {
      return date_str;
    }
    var hour = date.getUTCHours();
    var am_pm = 'am';
    if (hour === 0) {
      hour = 12;
    } else if (hour == 12) {
      am_pm = 'pm';
    } else if (hour > 12) {
      hour -= 12;
      am_pm = 'pm';
    }
    var mins = date.getUTCMinutes();
    if (mins < 10) {
      mins = '0' + mins;
    }
    return date_str + ' ' + hour + ':' + mins + ' ' + am_pm;
  },

  /* get the display value for a particular timezone value default to timezone value if we cannot find one */
  getTimeZoneDisplay : function(time_zone) {
    // is time_zone_display loaded??
    if (this.time_zone_display.length <= 0) {
      this._loadTimeZoneDisplay(false);
    }
    var display_value;
    try {
      display_value = this.time_zone_display[time_zone];
    } catch (err) {
      display_value = time_zone;
    }
    if (display_value == 'undefined') {
      display_value = time_zone;
    }
    return display_value;
  },

  /* Load the mapping of timezone to display values */
  _loadTimeZoneDisplay : function(async) {
    if (async === null) {
      async = true;
    }
    $.ajaxSetup({async: async});
    $.getJSON(zones_mapping_json, function(data) {
      $.btTimeZone.time_zone_display = data;
    });
    // reset to
    $.ajaxSetup({async: true});
  }

});

$.fn.btTimeZone = function(options) {
  $.btTimeZone.initialise();
  $.btUser.updateCurrencySymbols();
  return $.btTimeZone.initialised;
};

$.btTimeZone = new BTTimeZone(); // singleton instance
$.btTimeZone.initialised = false;
// @todo PS - make these into options and set in document.ready function.
$.btTimeZone.cookie_name = cookie_name;

})(jQuery);

