function Rates(elementRetail, elementDime, elementBulk, elementLastMod){
	this.elementRetail = $(elementRetail);
	this.elementDime = $(elementDime);
	this.elementBulk = $(elementBulk);
	this.elementLastMod = $(elementLastMod);
};

Rates.prototype = {
	elementRetail: null,
	elementBulk: null,
	elementDime: null,
	elementLastMod: null,
	elementHeader: '<tr class="header"><th>Waluta</th><th>Kupno</th><th>Sprzedaż</th></tr>',

	symbolsRetail: null,
	symbolsDime: null,
	symbolsBulk: null,
	
	symbolsRetailFound: null,
	symbolsBulkFound: null,
	symbolsDimeFound: null,

	ratesRetail: [],
	ratesBulk: [],
	ratesDime: [],

	response: null,
	refresh: 5,
	errorRefresh: 3,
	timeout: 60,
	url: '/RATE.TXT',
	
	start: function() {
		this.update();
	},
	
	update: function() {
		var self = this;
		$.ajax({
			url: self.url,
			timeout: self.timeout * 1000,
			dataType: 'text',
			cache: true,
			ifModified: true,
			
			success: function(data, status, req) {
				if (!self.response || status == 'success') {
					self.response = data;
					self.detectSymbols();
					self.ratesDime = []; self.ratesRetail = [] ; self.ratesBulk = [];
					self.updateElement(self.elementRetail, self.symbolsRetailFound, self.ratesRetail, req, false);
					self.updateElement(self.elementDime, self.symbolsDimeFound, self.ratesDime, req, false);
					self.updateElement(self.elementBulk, self.symbolsBulkFound, self.ratesBulk, req, true);
				}
				window.setTimeout(function(){ self.update(); }, self.refresh * 1000);
			},
			
			error: function(req, msg, ex) {
				window.setTimeout(function() { self.update(); }, self.errorRefresh * self.refresh * 1000);
			}
		});
	},
	
	detectSymbols: function() {
		var self = this;
		if (!self.response)
			return;

		var responseSymbols = [];
		$.each(self.response.split('\n'), function(i, line) {
			var rates = line.split('#');
			if (rates.length == 4)
				responseSymbols.push(rates[0]);
		});

		self.symbolsRetailFound = [];
		self.symbolsBulkFound = [];
		self.symbolsDimeFound = [];
		
		$.each(responseSymbols, function(i, symbol) {
			// wszystkie detaliczne -- dużymi literami
			if ((!self.symbolsRetail || $.inArray(symbol, self.symbolsRetail) != -1)
					&& $.inArray(symbol, self.symbolsRetailFound) == -1
					&& symbol.toUpperCase() == symbol)
					self.symbolsRetailFound.push(symbol);
			// hurtowe -- tylko występujące > 1 raz			
			else if ((!self.symbolsBulk || $.inArray(symbol, self.symbolsBulk) != -1)
					&& $.inArray(symbol, self.symbolsBulkFound) == -1
					&& responseSymbols.countMatched(symbol) > 1
					&& symbol.toUpperCase() == symbol)
				self.symbolsBulkFound.push(symbol);
			// monety -- małymi literami
			else if ((!self.symbolsDime || $.inArray(symbol, self.symbolsDime) != -1)
				&& $.inArray(symbol, self.symbolsDimeFound) == -1
				&& symbol.toLowerCase() == symbol)
				self.symbolsDimeFound.push(symbol);
		});
	},
	
	updateElement: function(el, symbols, rates, req, overwrite) {
		if (req && el && symbols) {
			var self = this;
			var mod = req.getResponseHeader("Last-Modified");
			mod = new Date(Date.parse(mod)).pretty();
	
			var html = '<div class="currencies"><table>' + self.elementHeader;
			$.each(symbols, function(i, val) {
				var rate = self.getRate(val, rates, overwrite);
				if (rate)
					html += '<tr class="' + (i%2 ? 'even' : 'odd')  + '">'
						+ '<td class="cur">' + rate[0] + ' ' + val.toUpperCase() + '</td>'
						+ '<td class="buy">' + rate[1].rate() + '</td>'
						+ '<td class="sell">' + rate[2].rate() + '</td></tr>';
			});
			html += '</table></div>';
			if (self.elementLastMod)
				self.elementLastMod.html('Aktualizacja: ' + mod);
			el.html(html);
		}
	},
	
	getRate: function(id, rates, overwrite) {
		var self = this;
		if (!self.response)
			return;
		if (!rates)
			rates = [];
		if (rates.length == 0) {
			$.each(self.response.split('\n'), function(i, line) {
				var rate = line.split('#');
				if (rate.length == 4) {
					var cur = rate[0];
					var amount = rate[1];
					if (overwrite || !rates[cur])
						rates[cur] = [amount, rate[2], rate[3]];
				}
			})
		}
		return rates[id];
	}
}

Number.prototype.lpad = function(padString, length) {
    var str = this + '';
    while (str.length < length)
        str = padString + str;
    return str;
}

Number.prototype.npad = function() {
	return this.lpad('0', 2);
}

String.prototype.rate = function() {
	return parseFloat(this) == 0 ? '<span class="missing">brak</span>' : this;
}

Date.prototype.pretty = function() {
	return this.getHours().npad() + ':' + this.getMinutes().npad() + ', '
		+ this.getDate().npad() + '-' + (this.getMonth()+1).npad() + '-' + this.getFullYear().npad();
}

Array.prototype.countMatched = function(match) {
	var count = 0;
	$.each(this, function(i, val) {
		if (val == match)
			count++;
	});
	return count;
}


