function mergeObj(o, a) {
	for (var i in a) {
		if (typeof(a[i]) == 'object' && typeof(o[i]) == 'object') mergeObj(o[i], a[i]);
		else o[i] = a[i];
	}
	return o;
}

function getDim(h) {
	var x = {left:0,top:0,width:h.offsetWidth,height:h.offsetHeight};
	do {
		x.left += h.offsetLeft;
		x.top += h.offsetTop;
	} while (h = h.offsetParent);
	return x;
}

function $(id) {
	return document.getElementById(id);
}

function appNodes(handle, nodes) {
	var i;
	for (i in nodes) {
		handle.appendChild(nodes[i]);
	}
	return handle;
}

function clearNode(node) {
	while (node.firstChild) node.removeChild(node.firstChild);
	return node;
}

function createNode(type, opt) {
	return mergeObj(document.createElement(type), opt);
}

function setText(handle, text) {
	if (handle.firstChild) handle.firstChild.nodeValue = text;
	else handle.appendChild(document.createTextNode(text));
	return handle;
}

function addNewNode(handle, type, opt, text) {
	handle = handle.appendChild(createNode(type, opt));
	return text ? setText(handle, text) : handle;
}

var Dom = {
	mo: function(o, a) {for (var i in a) { if (typeof(a[i]) == 'object' && typeof(o[i]) == 'object') this.mo(o[i], a[i]); else o[i] = a[i];} return o;},
	clear: function(n) {while (n.firstChild) n.removeChild(n.firstChild); return n;},
	create: function(type, opt, t) {var h = this.mo(document.createElement(type), opt); return t ? this.setText(h, t) : h;},
	add: function(h, n) {return h.appendChild(n);},
	addMulti: function(h, n) {
		for (var i in n) h.appendChild(n[i].nodeType ? n[i]: this.create(n[i][0], n[i][1], n[i][2])); return h;
	},
	addNew: function(h, type, opt, t) {h = h.appendChild(createNode(type, opt)); return t ? setText(h, t) : h;},
	setText: function(h, t) {if (h.firstChild) h.firstChild.nodeValue = t; else h.appendChild(document.createTextNode(t)); return h;}
};

function intToHex(i) {
	i = parseInt(i).toString(16);
	while (i.length < 6) i = '0' + i;
	return i;
}

function arrayIndex(s, a) {
	var i;
	for (i in a) if (s == a[i]) return i;
	return false;
}

function testAlert(s) {alert(s);};

function hsvToRgb(h, s, v) {
	var r, g, b, t1, t2, t3, i;
	if (s == 0) {
		return Array(Math.round(v * 255), Math.round(v * 255), Math.round(v * 255));
	}
	else {
		h = h * 6
		if (h == 6) h = 0;
		i = Math.floor(h);
		t1 = v * (1 - s);
		t2 = v * (1 - s * (h - i));
		t3 = v * (1 - s * (1 - (h - i)));
		
		switch (i) {
			case 0: r = v; g = t3; b = t1; break;
			case 1: r = t2; g = v; b = t1; break;
			case 2: r = t1; g = v; b = t3; break;
			case 3: r = t1; g = t2; b = v; break;
			case 4: r = t3; g = t1; b = v; break;
			default: r = v; g = t1; b = t2; break;
		}
		
		r = Math.round(r * 255);
		g = Math.round(g * 255);
		b = Math.round(b * 255);
		return Array(r, g, b);
	}
}

function toJson(data) {
	switch (typeof(data)) {
		case 'number': return data; break;
		case 'boolean': return data ? 'true' : 'false'; break;
		case 'undefined': return 'false'; break;
		case 'string': return '"' + jsonStringEscape(data) + '"'; break;
		case 'object':
			if (data.constructor == (new Array).constructor) {
				var i, t = [];
				for (i in data) t.push(toJson(data[i]));
				return '[' + t.join(',') + ']';
			}
			else {
				var i, t = [];
				for (i in data) t.push('"' + i + '":' + toJson(data[i]));
				return '{' + t.join(',') + '}';
			}
			break;
	}
}
function jsonStringEscape(str) {
	return str.replace(/"/g, '\"').replace(/\r\n/g, "#NEWLINE#").replace(/[\r\n]/g, "#NEWLINE#");
}
function fromJson(json) {
	var data;
	try {eval("data = " + json + ";")} catch(e) {return e}
	return data;
}


function intval(num) {
	if (typeof(num) == 'string') num = num.replace(/[^0-9\.]/g, '');
	num = parseInt(num);
	return isFinite(num) ? num : 0;
}

function floatval(num) {
	if (typeof(num) == 'string') num = num.replace(/[^0-9\.]/g, '');
	return parseFloat(num);
}


function BzgPriceFieldClass(parent, format, input, defaultInput, drawOnChange) {
	var i, temp;
	
	this.id = parent.fieldList.length;
	this.parent = parent;
	this.input = input;
	this.defaultInput = defaultInput;
	this.drawOnChange = drawOnChange;
	this.aantal = defaultInput;
	this.fixed = false;
	
	// Maak prijslijst
	this.prijzen = [];
	format = format.split(',');
	if (format[0] == 'fixed') this.fixed = true;
	for (i in format) {
		temp = format[i].split(':');
		if (temp.length == 2) {
			this.prijzen.push({
				num: intval(temp[0]),
				prijs: floatval(temp[1])
			});
		}
	}
	
	parent.fieldList[this.id] = this;
	
	this.getPriceInt = function() {
		return this.calcPrice(intval(this.aantal));
	}
	
	this.getPrice = function(aantal) {
		prijs = this.calcPrice(intval(aantal));
		return "\u20AC " + Math.floor(prijs / 100) + ',' + (prijs + 100000000).toString().substr(7);
	}
	
	this.calcPrice = function(num) {
		var i, prijs = this.prijzen[0].prijs;
		for (i in this.prijzen) {
			if (this.prijzen[i].num > num) break;
			else prijs = this.prijzen[i].prijs;
		}
		return prijs * num;
	}
	
	this.setPrice = function(aantal) {
		var handle, inputHandle;
		aantal = Math.max(aantal, 0);
		this.aantal = intval(aantal);
		this.parent.updateTotal();
		if (handle = $('priceField_' + this.id)) {
			Dom.setText(handle, this.getPrice(aantal));
		}
		if (this.drawOnChange) {
			if (handle = $('priceField_doc_' + this.id)) handle.style.display = aantal == this.defaultInput ? 'none' : 'block';
		}
	}
	
	this.draw = function() {
		document.write('<div class="priceField" id="priceField_' + this.id + '">' + this.getPrice(this.defaultInput) + '</div>');
		if (this.drawOnChange) document.write('<div id="priceField_doc_' + this.id + '" style="display: none;">' + this.drawOnChange + '</div>');
	}
	
	this.init = function(tries) {
		var thisHandle = this, handle;
		if (handle = $(this.input)) {
			handle.onkeyup = function() {
				thisHandle.setPrice(this.value);
			}
			handle.onchange = function() {
				thisHandle.setPrice(this.value);
			}
			this.parent.updateTotal();
		}
		else if (!tries) {
			return false;
		}
		else setTimeout(function(){thisHandle.init(tries - 1)}, 100);
	}
}
var BzgPrice = new function() {
	this.fieldList = [];
	this.totalList = [];
	
	this.changeInput = function(id, add) {
		var handle;
		if (handle = $(id)) {
			handle.value = Math.max(0, intval(handle.value) + add);
			if (handle.onkeyup) handle.onkeyup();
		}
	}
	
	this.updateTotal = function() {
		var i, total = 0;
		if (this.totalList.length) {
			for (i in this.fieldList) total += this.fieldList[i].getPriceInt();
			for (i in this.totalList) {
				if (handle = $('bzgPriceTotal_' + this.totalList[i])) {
					Dom.setText(handle, "\u20AC " + Math.floor(total / 100) + ',' + (total + 100000000).toString().substr(7));
				}
			}
		}
	}
	
	this.addTotal = function() {
		var id = this.totalList.length;
		document.write('<span id="bzgPriceTotal_' + id + '">&euro; 0,00</span>');
		this.totalList.push(id);
	}
	
	this.createPriceField = function(format, input, defaultInput, drawOnChange) {
		var priceField = new BzgPriceFieldClass(this, format, input, defaultInput, drawOnChange);
		priceField.draw();
		priceField.init(100);
	}
}
