var Interface = {

	set:function(o,p,v) {
		this._set(o,p,v);
	}

};

(function($){

var IntRates = {
	
	public:['filepath','content','products'],
	
	currencies:{
		sterling:	{file:'sterling.js', 	name:'Sterling',								symbol:'&pound;'	},
		usdollar:	{file:'usdollar.js', 	name:'US Dollar',								symbol:'$'			},
		euro:		{file:'euro.js', 		name:'Euro',									symbol:'&euro;'		},
		ausdollar:	{file:'ausdollar.js', 	name:'Australian Dollar',						symbol:'$'			},
		candollar:	{file:'candollar.js', 	name:'Canadian Dollar',							symbol:'$'			},
		hkdollar:	{file:'hkdollar.js', 	name:'Hong Kong Dollar',						symbol:'$'			},
		swissfranc:	{file:'swissfranc.js',	name:'Swiss Franc &ndash; Thousands',			symbol:'CHF'		},
		yen:		{file:'yen.js', 		name:'Japanese Yen &ndash; Millions',			symbol:'&yen;'		}
	},
	
	inputs:{},
	inithighlight:5,
	highlighted:null,
	animating:false,
	filepath:null,
	content:null,
	products:{},
	
	// fire on page load
	init:function() {
		if(!this.content) {throw new Error('Content path has not been defined.');return;}
		// load the application content dynamically to reduce footprint for non-js users
		$('#irt_table').load(this.content,function(){IntRates.loaded();$('a.tooltip').tooltip();});
		
		var _scroll = function(){
			var scr = $(document).scrollTop() - $('#CompareRates').parent().offset().top,
				h = $('#CompareRates').parent().parent().height() - $('#CompareRates').parent().height();
			
			$('#CompareRates').animate({top:Math.min(h,Math.max(scr,0))+'px'});
		}
		
		$(window).scroll(function(){
			clearTimeout(IntRates.scrollTimer);
			IntRates.scrollTimer = setTimeout(_scroll,500);
		})
		
	},
	
	scroll:function() {
		
		var scr = $(document).scrollTop() - $('#CompareRates').parent().offset().top,
			h = $('#CompareRates').parent().parent().height() - $('#CompareRates').parent().height();
		var p = Math.min(h,Math.max(scr,0));
		if(p != $('#CompareRates').position().top) {
			$('#CompareRates').css({top:p+'px'});
		}
		
	},
	
	// fire once content loaded
	loaded:function() {
		
		// populate currency drop-down and bind events
		for(var cur in this.currencies) {
			$('#currency_select').append('<option value="'+cur+'">'+this.currencies[cur]['name']+'</option>');
		}
		$('#currency_select').change(function(){
			IntRates.load_currency($(this).val());
		}).change();
		
		$('#slider').slider({range:[0,5],snap:5})
						.bind('slider.stop',function(e,i){IntRates.highlight(i);})
						.bind('slider.move',function(e,i){
							var cur = IntRates.currencies[IntRates.currency];
							if(cur) {
								var str = cur.symbol + cur.data.range[i].format();
								str += cur.data.range[i+1]?' - ' + cur.symbol + (cur.data.range[i+1]-1).format():'+';
								$('#slider_output').html(str);
							}
						});
		
		$('input[type="radio"]').click(function(){IntRates.update_radios(this);}).each(function(){
			if(this.checked) {
				IntRates.inputs[$(this).attr('name')] = $(this).val();
			}
		});
		
	},
	
	// fire when currency is selected
	load_currency:function(cur) {
		if(this.blocked === true) {
			var obj = this;
			var args = arguments;
			setTimeout(function(){args.callee.apply(obj,args);},50);
			return;
		}
		if(!this.filepath) {throw new Error('Data path has not been defined.');return;}
		if(this.currency != cur) {
			this.currency = cur;
			// if currency data has not been loaded before, fetch it from the server
			if(!this.currencies[cur].data) {
				$.getJSON(this.filepath+this.currencies[cur]['file'],null,function(data,status){IntRates.load_currency_json(cur,data,status);});
				this.blocked = true;
			}
			else {
				this.update();
			}
		}
	
	},
	
	// handle loading of currency data from server
	load_currency_json:function(cur,data,status) {
		this.blocked = false;
		
		for(var i=0;i<data.products.length;i++) {
			
			data.products[i] = $.extend(data.products[i],this.products[data.products[i]['id']]);
			data.products[i].bestrate = {aer:0,gross:0};
			
			for(var j=0;j<data.products[i].rates.length;j++) {
				var rates = this.get_rates(data.products[i].rates[j],data.products[i].code);
				
				for(var k in rates) {
					for(var m=0;m<rates[k].length;m++) {
						data.products[i].bestrate[k] = Math.max(data.products[i].bestrate[k],rates[k][m]);
					}
				}
				
				data.products[i].rates[j] = rates;
			}
		}
		
		this.currencies[cur]['data'] = data;
		
		this.update();
		
	},
	
	get_rates:function(rate,code) {
		var rates = {aer:[],gross:[]};
		
		if(rate && rate.constructor == Array) {
			for(var i=0,j=rate.length;i<j;i++) {
				var r = this.get_rate(rate[i],code[i]);
				rates.aer.push(r.aer);
				rates.gross.push(r.gross);
			}
			return rates;
		}
		else if(rate && rate.constructor == Number) {
			var r = this.get_rate(rate,code);
			rates.aer.push(r.aer);
			rates.gross.push(r.gross);
			return rates;
		}
		else if(rate === null) {
			return rates;
		}
		else {
			return rate;
		}
	},
	
	get_rate:function(index,code) {
		var rates = {aer:0,gross:0};
		try{
			rates.aer = parseFloat(window['AER_'+code][index]);
			rates.gross = parseFloat(window[code][index]);
		}catch(e){}
		return rates;
	},
	
	// handle a radio button being clicked
	update_radios:function(r) {
		
		this.inputs[$(r).attr('name')] = $(r).val();
		this.update();
		
	},
	
	// take all the data and use it to render the table
	update:function() {
		
		var currency	 	= this.currency,
			sort			= this.inputs.sort,
			filter			= this.inputs.filter,
			rates			= this.inputs.rates,
			availability	= this.inputs.availability,
			products		= this.currencies[currency].data.products,
			ranges			= this.currencies[currency].data.range;
			
		
		$('span.currency_title').html(this.currencies[currency].symbol + ' ' + this.currencies[currency].name);
		$('#IRT_Table thead th div.IRT_Row01').each(function(i){
			$(this).html('<a href="#">'+IntRates.currencies[currency].symbol + IntRates.currencies[currency].data.range[i].format()+'+</a>').click(function(){IntRates.highlight(i);return false;});
		});
		
		if(filter != 'all') {
			products = this.filter(products, 'premier', filter=='premier');
		}
		products = this.filter(products, 'on_sale', availability=='available');
		
		if(sort == 'access') {
			products = products.sort(function(a,b){return a.access - b.access;});
		}
		else {
			products = products.sort(function(a,b){return b.bestrate[IntRates.inputs.rates] - a.bestrate[IntRates.inputs.rates];});
		}
		
		this.draw(products);
		
		this.highlight();
		$('#slider').trigger('slider.move',this.highlighted);
		
	},
	
	filter:function(arr, prop, value) {
		var a = [];
		for(var i=0,j=arr.length;i<j;i++) {
			if(arr[i][prop] == value) {
				a.push(arr[i]);	
			}
		}
		return a;
	},
	
	sort:function(arr, prop) {
		var a = arr.sort(function(a,b){return b[prop] - a[prop];});
		return a;
	},
	
	draw:function(products) {
		
		this.empty(function(){IntRates.fill(0,products);});

	},
	
	empty:function(f) {
		$('#IRT_Table tbody tr:last').remove();
		if($('#IRT_Table tbody tr').length) {
			$('#IRT_Table tbody tr:last').hide();
			setTimeout(function(){IntRates.empty(f);},25)
		}
		else {
			f();
		}
		
		this.scroll();
		
		$('#HighlightCol .HiglightColRepeat').css('height',$('#IRT_Table tbody').height()-20+'px');
	},
	
	fill:function(n,products) {
		
		$('#HighlightCol').show();
			$('#slider').trigger('slider.enable');
		
		if(n < products.length) {
			$('#IRT_Table tbody').append(this.row(products[n],n));
			setTimeout(function(){IntRates.fill(n+1,products);},25);
		}
		else if (products.length == 0) {
			$('#IRT_Table tbody').append(this.null_row());
			$('#HighlightCol').hide();
			$('#slider').trigger('slider.disable');
		}
		
		this.scroll();
		
		$('#HighlightCol .HiglightColRepeat').css('height',$('#IRT_Table tbody').height()-20+'px');
		
	},
	
	row:function(product,i) {
		var str = '';
		str += '<tr class="'+((i%2)?'':'IRT_TableStyle03')+'">';
		str += '	<td class="IRT_TableStyle04">';
		str += '		<div class="OfferBox '+(product.premier?'PremierBox':'StandBox')+'">';
		if(product.offer || product.new_product) {
			str += '			<div class="IRT_Boxhead">';
			str += '				<span>'+(product.offer?'Special Offer':'New Product')+'</span>';
			str += '			</div>';
		}
		str += '			<div class="Box_Inner">';
		str += '				<h3><a href="'+product.url+'">'+product.name+'</a></h3>';
		str += '				<p>'+product.description+'</p>';
		if(product.on_sale) {
			str += '				<p class="IRT_buttonStyle01"><a href="'+product.url+'">Find out more</a></p>';
			str += '				<p class="IRT_buttonStyle01"><a href="'+product.url2+'">Apply now</a></p>';
		}
		str += '			</div>';
		str += '		</div>';
		str += '	</td>';
		
		for(var j=0;j<6;j++) {
			str += '<td class="'+(this.highlighted==j?'IRT_Highlight':'')+'">';
			str += '<div class="IRT_RowInner">';
			str += '	<div class="IRT_Row01">';
			if(typeof product.rates[j][this.inputs.rates][0] == 'undefined') {
				str += '	<p><span>n/a</span></p>';
			}
			else {
				str += '	<p class="IRT_RowP01"><span>'+parseFloat(product.rates[j][this.inputs.rates][0]).format(2)+'%</span><br />'+(this.inputs.rates=='aer'?'AER':'Gross')+'</p>';
			}
			if(typeof product.rates[j][this.inputs.rates][1] != 'undefined') {
				str += '	<p class="IRT_RowP02"><span>'+parseFloat(product.rates[j][this.inputs.rates][1]).format(2)+'%</span><br />With bonus<br />'+(this.inputs.rates=='aer'?'AER':'Gross')+'</p>';
			}
			str += '	</div>';
			str += '</div>';
			str += '</td>';
			
		}
			
		str += '</tr>';
		
		return str;
	},
	
	null_row:function() {
		var str = '';
		str += '<tr class="IRT_TableStyle03">';
		str += '	<td class="IRT_TableStyle04" colspan="7">';
		str += '		<h3>No products found</h3>';
		str += '	</td>';
		str += '</tr>';
		
		return str;
	},
	
	highlight:function(n) {
		
		if(typeof n == 'undefined') {n = this.highlighted===null?this.inithighlight:this.highlighted;}
		n = n?n:0;
		
		if(n != this.highlighted) {
			this.highlighted = n;
			$('#slider').trigger('slider.set',n);
			
			$('#IRT_Table td.IRT_Highlight').removeClass('IRT_Highlight');
			try {
				var $td = $('#IRT_Table tbody tr td:nth-child('+(n+2)+')'),
					l = $td.position().left,
					w = $td.outerWidth() - $('#HighlightCol').width();
				$('#HighlightCol').animate({left:(l + (w/2))},function(){
					$('#IRT_Table tbody tr td:nth-child('+(IntRates.highlighted+2)+')').addClass('IRT_Highlight');
				});
			}catch(e){}
		}
		
	}
	
}

$.extend(Interface,{
	_set:function(o,p,v) {
		var obj = eval(o);
		try{
			if(this._isPublic(obj,p)) {
				obj[p] = v;
			}
		}
		catch(e){throw new Error('Attempt to set private property ' + p);}
	},
	_isPublic:function(o,p) {
		for(var i=0,j=o.public.length;i<j;i++) {
			if(o.public[i] == p) {
				return true;
			}
		}
		return false;
	}
});

$(document).ready(function(){
	IntRates.init();
});

})(jQuery);

if(!Number.prototype.format) {
	Number.prototype.format = function(n){
		var that=this,str='',a,l;
		n = n?n:0;
		that = (Math.floor(that*Math.pow(10,n)))/Math.pow(10,n);
		a = that.toString().split('.');
		a[1] = a[1]?a[1]:'';
		while(a[1].length < n) {
			a[1] = a[1]+'0';
		}
		l = a[0].length;
		for(var i=0;i<l;i++) {
			str = a[0].charAt(l-i-1)+str;
			if((i+1)%3 == 0 && i<l-1) {
				str = ','+str;
			}
		}
		a[0] = str;
		return n>0?a.join('.'):a[0];
	}
}