function nPackageCalc(obj) {
	
	if (typeof obj == 'string') {
		obj = $(obj);
	}
	
	obj.build = function() {
		var i, wrappersObj, wrapperHtml;
		obj.barWrappers = new Array;
		
		obj.className += ' packageCalc';
		
		obj.innerHTML =
			'<div class="barWrappers"></div>' +
			'<div class="arrow"></div>' +
			'<div class="result">...</div>' +
			'<div class="clear"></div>';
			
		obj.barAbstractHtml =
			'<div class="barLabel">' +
			'	%barLabel%' +
			'	<div class="barDigitalValue"></div>' +
			'</div>' +
			'<div class="bar">' +
			'	<div class="barGraphicValue"></div>' +
			'</div>';
			
		obj.resultObj = $$('result', 'div', obj)[0];
		obj.barWrappersObj = $$('barWrappers', 'div', obj)[0];
	}
	
	obj.newBar = function(config) {
		var i = obj.barWrappers.length;
		
		obj.barWrappers[i] = document.createElement('div');
		obj.barWrappers[i].className = 'barWrapper';
		
		obj.barWrappersObj.appendChild(obj.barWrappers[i]);
		
		obj.barWrappers[i].innerHTML += obj.barAbstractHtml.replace('%barLabel%', config.label);
		obj.barWrappers[i].bar = $$('bar', 'div', obj.barWrappers[i])[0];
		nPackageCalcBar(obj.barWrappers[i].bar, config, obj);
	}
	
	obj.compute = function() {
		var i;
		var values = new Array;
		for (i in obj.barWrappers) {
			values.push(obj.barWrappers[i].bar.getValue());
		}
		
		obj.resultObj.innerHTML = obj.computeCallback(values);
	}
	
	obj.computeCallback = function(values) {
		var i, result = 0;
		for (i in values) {
			result += values[i];
		}
		result = Math.round(result / values.length * 100) / 100;
		return result;
	}
	
	obj.setComputeCallback = function(callback) {
		if (typeof callback == 'function') {
			obj.computeCallback = callback;
		}
	}
	
	obj.build();
	
	return obj;
}


function nPackageCalcBar(obj, config, packageCalcObj) {
	nDynamic(obj);
	obj.nName = 'nPackageCalcBar';
	obj.packageCalcObj = packageCalcObj;
	
	obj.configure({
		label: 'Etykieta paska:',
		defaultValue: 50,
		valueCallback:function(value) {
			return Math.round(value);
		},
		valueRecallback:function(value) {
			return value;
		},
		barJump: 1
	});
	
	obj.configure(config);
	
	obj.config.defaultValue = obj.config.valueRecallback(obj.config.defaultValue);
	obj.value = obj.config.defaultValue;
	
	obj.build = function() {
		obj.graphicValue = $$('barGraphicValue', 'div', obj)[0];
		obj.digitalValue = $$('barDigitalValue', 'div', obj.parentNode)[0];
		
		nConfig.addEvent(obj, 'mousedown', obj.drag);
		obj.resizing.onUpdate();
	}
	
	obj.resizing = obj.point({
		n: {x: obj.value * 2},
		onLoop:function() {
			this.n.x = this.limit(this.relativeX(), 0, 200);
		},
		onUpdate:function() {
			this.obj.value = this.n.x / 2;
			this.obj.graphicValue.style.width = this.obj.correctGraphicValue(this.n.x) + 'px';
			this.obj.digitalValue.innerHTML = this.obj.config.valueCallback(this.obj.value);
		},
		onActivate:function() {
			this.start = this.offset();
			this.n = this.offset();
			this.onUpdate();
		},
		onDeactivate:function() {
			this.obj.packageCalcObj.compute();
		}
	});

	obj.drag = function(e) {
		obj.resizing.run(e);
		obj.resizing.activate();
		nConfig.addEvent(document, 'mouseup', obj.drop);
	}

	obj.drop = function() {
		obj.resizing.deactivate();
		nConfig.dropEvent(document, 'mouseup', obj.drop);
	}

	obj.getValue = function() {
		return obj.config.valueCallback(obj.value);
	}
	
	obj.correctGraphicValue = function(value) {
//		return value - (value % obj.config.barJump);
		return Math.round(Math.round(value / obj.config.barJump) * obj.config.barJump);
	}
	
	obj.build(config);
}


// -------------------------------- construowanie instancji:

nConfig.addEvent(window, 'load', function() {
	// Kalkulator powstaje w trzech krokach.
	// 1. Tworzymy obiekt kalkulatora.
	// 2. Definiujemy funkcje wyliczajaca wartosc wynikowa.
	// 3. Definiujemy suwaki.
	
	// Przyklad tworzenia instancji:
	
	// 1. Tworzymy obiekt kalkulatora podajac mu jako argument id jakiegos DIVa.
	var calc = nPackageCalc('packageCalc');
	
	// 2. Definiujemy w jaki sposob wylicza sie wartosc wynikowa.
	// Do metody nalezy podac jako argument funkcje, przyjmujaca jeden parametr - tablice wartosci zczytanych z suwakow.
	// Funkcja ta powinna zwracac wyliczona wartosc, przeznaczona do wyswietlenia na stronie.
	//	Wartosc ta nie bedzie uzywana do kolejnych obliczen, wiec moze byc lancuchem znakowym zawierajacym dodakowy komentarz lub jednostke (np. "130 PLN", "2,1 kg", "87 cm<sup>2</sup>" etc.).
	calc.setComputeCallback(function(values) {
		var baza, i, skok, result = 0, uslugi = values[0], freq = values[1], czujki = values[2], koszt_czujek, koszt_czestotliwosci, koszt_uslug, per;
	
	if (freq == 1 ) {
			baza = 120;
			skok = 100;
			if (uslugi > 10) {
				baza = 300;
				skok = 100;
			}
			if (uslugi > 20) {
				baza = 300;
				skok = 90;
			}
	}
	if (freq == 2) {
		baza = 100;
		skok = 90;
			if (uslugi > 10) {
				baza = 200;
				skok = 80;
			}
			if (uslugi > 20) {
				baza = 200;
				skok = 70;
			}
	}
	if (freq == 5) {
		baza = 72;
		skok = 85;
			if (uslugi > 10) {
				baza = 150;
				skok = 75;
			}
			if (uslugi > 20) {
				baza = 150;
				skok = 70;
			}
	}
	if (freq == 10) {
		baza = 68;
		skok = 75;
			if (uslugi > 10) {
				baza = 120;
				skok = 70;
			}
			if (uslugi > 20) {
				baza = 110;
				skok = 65;
			}
	}
	if (freq == 15) {
		baza = 65;
		skok = 60;
			if (uslugi > 10) {
				baza = 100;
				skok = 55;
			}
			if (uslugi > 20) {
				baza = 95;
				skok = 50;
			}
	}
	if (freq == 20) {
		baza = 60;
		skok = 50;
			if (uslugi > 10) {
				baza = 80;
				skok = 40;
			}
			if (uslugi > 20) {
				baza = 70;
				skok = 35;
			}
	}
	if (freq == 30) {
		baza = 50;
		skok = 45;
			if (uslugi > 10) {
				baza = 80;
				skok = 40;
			}
			if (uslugi > 20) {
				baza = 70;
				skok = 30;
			}
	}
		result = baza + (uslugi - 1)*skok + (czujki*(czujki/(freq*10)) - 2)*uslugi*10 + czujki * 5;

/*		if (uslugi > 10) {
			result = baza + (uslugi - 11) * skok + (czujki - 2)*uslugi*10;
		}
		if (uslugi > 20) {
			result = baza + (uslugi - 21) * skok + (czujki - 2)*uslugi*10;
		}
*/		
		
		per = Math.round(result / uslugi);
		
		$('servicesAmount').value = values[0];
		$('minimalTestInterval').value = values[1];
		$('sensorsAmount').value = values[2];
		$('resultPrice').value = Math.round(result) + ' PLN';// (średnio ' + per + ' PLN/usługę)';
		$('prpVl').value = Math.round(result);
		
		return Math.round(result) + ' PLN<div class=\"result2\">(średnio: ' + per + ' PLN netto za usługę/mc)</div>';
	});
	
	// 3. Definiujemy nowy suwak.
	// Argumentem metody jest obiekt zawierajacy opisane nizej wlasciwosci.
	// Wszystkie wlasciwosci sa opcjonalne.
	calc.newBar({
		// Nazwa suwaka.
		label: 'Ilość usług:',
		// Wartosc poczatkowa na suwaku (wartosc rozumiana, jako liczba rowna szerokosci suwaka w pikseach).
		defaultValue: $('servicesAmount').value/3,
		// Ilosc pikseli o ktore przeskakuje poruszany suwak (domyslnie = 1)
		barJump: 200/8,
		// Funkcja konwertujaca wartosc zczytana z suwaka na wartosc wyswietlana w etykiecie.
		// Funkcja powinna przyjmowac jeden argument, bedacy oryginalna wartoscia zczytana z suwaka.
		//	Wartosc ta nie miesci sie w przedziale <0, 200> (gdzie 200 jest aktualna szerokoscia suwaka mierzona w pikselach).
		// Funkcja powinna zwracac wartosc do wyswietlenia w etykiecie suwaka.
		//	Dodatkowo, zwrocona wartosc zostanie przekazana do funkcji computeCallback, wiec musi byc liczba lub obiektem dajacym sie przekonwertowac na liczbe.
		valueCallback:function(value) {
			return Math.round((value / 100) * 9) + 1;
		},
		// Funkcja dzialajaca odwrotnie do valueCallback - konwertuje wartosc wyswietlana w etykiecie na szerokosc pikselowa suwaka.
		valueRecallback:function(value) {
			return Math.round((value - 1) / 9 * 100);
		}
	});
	
	// Definiujemy kolejne suwaki w ten sam sposob...
	calc.newBar({
		label: 'Ilość minut pomiędzy testami:',
		defaultValue: $('minimalTestInterval').value*3,
		barJump: 200/6,
		valueCallback:function(value) {
			var delays = [30,20,15,10,5,2,1];
			return delays[Math.round(value / (100/6))];
		},
		valueRecallback:function(value) {
			var key = 0;
			var delays = [30,20,15,10,5,2,1];
			while (value != delays[key] && key <= delays.length) {
				key++;
			}
			
			if (key < delays.length) {
				return Math.round(key * (100/6));
			} else {
				return false;
			}
		}
	});
	
	calc.newBar({
		label: 'Ilość stacji monitorujących:',
		defaultValue: $('sensorsAmount').value,
		barJump: 200/8,
		valueCallback:function(value) {
			return Math.round(value / 200 * 16) + 2;
		},
		valueRecallback:function(value) {
			return Math.round((value * 25) / 2 - 25);
		}
	});
	
	calc.compute(); 
});

