var MEASURE = {};


MEASURE.Converter = function () {
	return this;
};
/**
 * @param type {string} type of converter (from $customselect)
 * @return {function} wich in specialFnName || calculate()
 */
MEASURE.Converter.prototype = {
	convert: function (type, i_format, o_format, value) {
		
		var f = this.data[type]; 

		if ((!value || isNaN(value)) && !f.special) { return; }
		
		if (f.special) {
			return this[f.specialFnName](f, i_format, o_format, value);
		} else {
			
			return this.calculate(f, i_format, o_format, value);
		}

	},

	calculate: function (f, i_index, o_index, value) {
		var t = this, val;

		if (value == 0) {
			val = parseInt(value);
		} else {
			val = value * (1 / (f[o_index] / f[i_index]));
		}
		
		return val;
	},

	calculateTemperature: function (f, i_index, o_index, value) {
		var aF = ['c', 'f', 'k', 'r', 'de', 'ne', 're', 'ro'];
		var t = this;

		var val = i_index == o_index ? parseFloat(value, 10) : f.data[i_index].f(value, aF[o_index]);

		return val;
	},
	
	rates: {
	},

	calculateMoney: function (f, ii, oi, value) {
		var src = $('#bank-src');
		
		if (ii != oi) {
			var iCode = f.list.RUB.rates[ii].code;
			var oCode = f.list.RUB.rates[oi].code;
			
			if (this.rates[iCode] && this.rates[iCode][oCode]) {
				setSrcBanks(src, this.rates[iCode][oCode]);
				return value * this.rates[iCode][oCode].value;
			} else {
				var self = this;
				var url = '/money/api/' + iCode + '/' + oCode;
				var result = value;
				$.ajax({
					async: false,
					url: url,
					success: function(data){
						var cur = $(data).children();
						var rates = cur.children();
						
						if (rates.length) {
							var freshest = 0;
							
							var firstRate = rates.eq(0);
							var freshestDate = new Date(firstRate.attr('year'), firstRate.attr('month') - 1, firstRate.attr('day'));
							var min = 1000000;
							
							// min(abs(day - today) + 2 * length)
							rates.each(function(i){
								var $this = $(this);
								
								var rateDate = new Date($this.attr('year'), $this.attr('month') - 1, $this.attr('day'));
								var freshness = Math.abs(rateDate - new Date())/1000/60/60/24 + 2 * $this.children('path').length;
								
								if (freshness < min) {
									freshest = i;
									freshestDate = rateDate;
									min = freshness;
								}
							});
							
							var rate = rates.eq(freshest);
							
							if (!self.rates[iCode]) {
								self.rates[iCode] = {};
							}
							
							self.rates[iCode][oCode] = {
								banks: [],
								date: freshestDate,
								value: rate.find('value').text()
							};
							
							if (rate.find('path').length) {
								self.rates[iCode][oCode].cross = true;
								var prevBank = '';
								rate.find('path').each(function(){
									var $this = $(this);
									if ($this.attr('bank') != prevBank) {
										self.rates[iCode][oCode].banks.push($this.attr('bank'));
										prevBank = $this.attr('bank');
									}
								})
							} else {
								if(rate.attr('reverse') == 1) {
									self.rates[iCode][oCode].banks.push(iCode);
								} else {
									self.rates[iCode][oCode].banks.push(oCode);
								}
							}
							
							setSrcBanks(src, self.rates[iCode][oCode]);
							result = value * self.rates[iCode][oCode].value;
						}
					},
					dataType: 'xml'
				});
				
				return result;
			}
		} else {
			// same currency
			src.text(' ');
			return value;
		}
		
		function setSrcBanks(src, rate) {
			if(rate.cross) {
				// cross
				var text = s('on cross-rate')+' ';
				for(var i=0; i<rate.banks.length; i++) {
					if(i == rate.banks.length - 1 && i != 0) {
						text += ' '+s('and')+' ';
					} else if(i != 0) {
						text += ', ';
					}
					text += localeBanks[rate.banks[i]];
				}
				src.text(text);
			} else {
				// native
				src.text(s('on rate', localeBanks[rate.banks[0]], ordinal_number(rate.date.getDate()), locale_months_full[rate.date.getMonth()])).removeClass('hidden');
			}
		}
			
		//Utils
		function direct_rate(ii, oi, cross) {
			var result = {bank: 0};
			var _in  = _.RUB.rates[ii]; 	
			var _out = _.RUB.rates[oi];
			var cif = 999;	//current ii-freshness
			var cof = 999;	//current oi-freshness
			
			if ( Number(_in.rate) && Number(_out.rate) ) {
				cif = _in.fresh; 
				cof = _out.fresh;
				result.value = value * (1 / (_out.rate / _in.rate) );
				result.bank = _.RUB.bank;
				result.fresh = Math.max(cif, cof);
			}
			
			if (cross) {
				if (_in.code == 'RUB') return result; // if native bank
				cof = 999;							  // hope, USD-rate is always fresh in any bank
			}

			if (cif > 2 || cof > 2) // if RUB rate is older then 2 days or not founded
				for (code in _) {
					_in  = _[code].rates[ii];
					_out = _[code].rates[oi];  
					if (Number(_in.rate) && Number(_out.rate)) 
						if ( (Math.max(_in.fresh, _out.fresh) < 3) && (_in.code == code || _out.code == code)) {
							cif = _in.fresh;
							cof = _out.fresh;
							result.value = value * (1 / (_out.rate / _in.rate) );
							result.bank = _[code].bank;
							result.fresh = Math.max(cif, cof);
							break;
						} 
						else if ((Math.max(_in.fresh, _out.fresh) < Math.max(cif, cof)) ) {
							cif = _in.fresh;
							cof = _out.fresh;
							result.value = value * (1 / (_out.rate / _in.rate) );
							result.bank = _[code].bank;
							result.fresh = Math.max(cif, cof);
						}
				}	
				
			if (!cross)
				return (result.bank /*&& result.fresh < 3*/) 
					? result
					: false;
			else 
				return result;
		}//func
		
		function get_date(dayLeft) {
			var date = new Date();
			date.setDate(date.getDate() - dayLeft);
			return date.getDate() + ' ' + locale_months_full[date.getMonth()];
		}

	}

};
