Wego = typeof Wego == 'undefined' || !Wego ? {} : Wego;

function prettyFormatNumber(number){
	var number = '' + Math.round(number);
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(number)) {
    number = number.replace(rgx, '$1,$2'); // Add commas.
  }
  return number;
}

Wego.CurrencyConverter = function(rates) {
  this.rates = rates;
};

Wego.CurrencyConverter.prototype.from = function() {
  return this.rates['from'];
};

// Returns exchange rate, or null if the rate is not known.
// E.g. exchange_rate('USD', 'SGD') # => 1.38
Wego.CurrencyConverter.prototype.exchange_rate = function(from, to) {
  if (this.from() == from) {
    return this.rates[to];
  }
  if (this.from() == to) {
    return 1.0 / this.rates[from];
  }

  var from_rate = this.rates[from];
  var to_rate = this.rates[to];
  if (from_rate && to_rate) {
    return to_rate / from_rate;
  }

  return null;
};

Wego.CurrencyConverter.prototype.convert = function(amount, from, to) {
  rate = this.exchange_rate(from, to);
  return rate ? amount * rate : null;
};

function Navigation(pageID, pageSize, tablesorterOptions){
	this.previousPage = 0;
	this.pageSize = pageSize;
	this.currentPage = pageID;
	this.totalRows = $('#results table tbody tr').size();
	this.tablesorterOptions = tablesorterOptions;
	this.sorter = null;
}

Navigation.providerParser = function(){
	return {
		id: 'provider',
		is: function(s){ return false; },
		format: function(s){
			var provider = $(s).find('.provider a').text();
			return provider;
		},
		type: 'text'
	};
};

Navigation.priceParser = function(){
	return {
		id: 'price',
		is: function(s){ return false; },
		format: function(s){
			return new Number($(s).text().replace(/[\D]/g, '')); // Different stuff returned by FF/IE
		},
		type: 'numeric'
	};
};

Navigation.dateParser = function(){
	return {
		id: 'timestamp',
		is: function(s){ return false; },
		format: function(s){
			return s.replace(/[\D]/ig, '');
		},
		type: 'numeric'
	};
};

Navigation.stayDurationParser = function(){
	var mapping = {
		four: 4,
		five: 5
	};
	
	return {
		id: 'stayduration',
		is: function(s){ return false; },
		format: function(s){
			var number = null;
			var blurb = s.replace(/(day|night)(s?)/i, '').replace(/^\s*|\s*$/g, '');
			if(blurb.match(/[a-z]+/i)){
				number = mapping[blurb.toLowerCase()];
			}
			else{
				number = blurb;
			}

			return number;
		},
		type: 'numeric'
	};
}

Navigation.featuredRowsWidget = function(){
	return {
		id: 'featuredRows',
		format: function(table){
			$('tr.featured', table.tBodies[0]).prependTo(table.tBodies[0]);
		}
	};
};

Navigation.prototype.embed = function() {
	this.configure();
	this.updatePage();
};

Navigation.prototype.updatePage = function() {	
	var range = this.calculatePageRange(this.currentPage);
	var start = range.start;
	var end = range.end;

	this.applyTableSorter();
	this.buildPaginator(start, end);
	this.displayRows(start, end);
	this.updateStatus(start, end, this.totalRows);
};

Navigation.prototype.displayRows = function(start, end) {
	$('#results table tbody tr').each(function(i){
		var row = $(this);
		i++;
		if(i >= start && i <= end){
			row.css('display', '');
		}
		else
			row.css('display', 'none');
	});
};

Navigation.prototype.buildPaginator = function() {
	var self = this;
	$(".pagination").pagination(this.totalRows, {
		items_per_page: this.pageSize,
		current_page: this.currentPage,
		prev_text: '<< ',
		next_text: ' >>',
		ellipse_text: '...',
		num_edge_entries: 1,
		num_display_entries: 4,
		callback: function(newPageID){
			self.previousPage = self.currentPage;
			self.currentPage = newPageID;
			self.updatePage();
			return false;
		}
	});
};

Navigation.prototype.applyTableSorter = function() {
	if(this.totalRows == 0)
		return;
		
	var options = {
		cssHeader: 'table-header',
		headers: this.tablesorterOptions.headerOptions,
		widgets: ['zebra', 'featuredRows']
	};
	
	if(this.sorter == null){
		options.sortList = this.tablesorterOptions.sortList;
	}
	
	this.sorter = $("#results table").tablesorter(options);
};

Navigation.prototype.calculatePageRange = function(pageID) {
	var start = pageID * this.pageSize + 1;
	var end = start + this.pageSize - 1;
	return {start: start, end: Math.min(end, this.totalRows)};
};

Navigation.prototype.updateStatus = function(start, end, total) {
	$('#status span#start').text(start);
	$('#status span#end').text(Math.min(end, total));
	$('#status span#total').text(total);
};

Navigation.prototype.configure = function() {
	var self = this;
	var total_items = $('#results table tbody tr').size();

	$('#status a').bind('click', function(e){
		$('#results table tbody tr').each(function(i){
			var row = $(this);
			row.css('display', '');
		});

		self.updateStatus(1, total_items, total_items);
		return false;
	});
	
	$("#results table").bind('sortEnd', function(){
		var range = self.calculatePageRange(self.currentPage);
		self.displayRows(range.start, range.end);
	});
	
	$('#paging-chooser a').bind('click', function(){
		var setting = $(this);
		self.pageSize = Number(setting.text());
		self.updatePage();

		$('#paging-chooser a.current').removeClass('current');
		setting.addClass('current');
		return false;
	});
};