
	var CElement = function (nodeName, parent) {
		if (nodeName) {
			this.element = n(nodeName);
			this.style = this.element.style;
		} else {
			this.element;
			this.style;
		}
		
		this.parent = parent;
		this.event = {};
		
		if (parent) {
			parent.appendChild(this.element);
		}
	};
	
	CElement.prototype.setElement = function (element, parent) {
		this.element = element;
		this.style = this.element.style;
		
		this.parent = parent;
		this.event = {};
		
		if (parent) {
			parent.appendChild(this.element);
		} else {
			this.parent = this.element.parentNode;
		}
	};
	
	CElement.prototype.getElement = function () {
		return this.element;
	};
	
	CElement.prototype.setName = function (name) {
		this.element.name = name;
	};
	
	CElement.prototype.setId = function (name) {
		this.element.id = name;
	};
	
	CElement.prototype.setHtml = function (value) {
		this.innerHTML = value;
	};
	
	CElement.prototype.getParent = function () {
		return this.parent;
	};
	
	CElement.prototype.setXY = function (x, y) {
		this.style.position = 'absolute';
		this.style.top = x + 'px';
		this.style.left = y + 'px';
	};
	
	CElement.prototype.applyStyles = function (styles_arr) {
		for (var k in styles_arr) {
			this.style[k] = styles_arr[k];
		}
	};
	
	CElement.prototype.setAttribute = function (name, value) {
		this.element.setAttribute(name, value);
	};
	
	CElement.prototype.appendChild = function () {
		for (var k = 0; k < arguments.length; k ++) {
			this.element.appendChild(arguments[k] instanceof CElement ? arguments[k].element : arguments[k]);
		}
	};
	
	CElement.prototype.removeChild = function () {
		for (var k in attributes) {
			this.element.removeChild(attributes[k]);
		}
	};
	
	CElement.prototype.attachEvent = function (event_name, callback, element_context) {
		if (element_context === true) {
			callback = createMethodReference(this, callback);
		} else if (element_context) {
			callback = createMethodReference(element_context, callback);
		}
		
		if (!this.event[event_name]) {
			this.event[event_name] = [];
		}
		
		this.event[event_name].push(callback);
	};
	
	CElement.prototype.callEvent = function (event_name, arg, arg1, arg2) {
		if (this.event[event_name]) {
			for (var k = 0; k < this.event[event_name].length; k ++) {
				if (this.event[event_name][k](arg, arg1, arg2) === false)
					return false;
			}
		}
		return true;
	};
	
	CElement.prototype.setSize = function (width, height) {
		this.style.width = width + 'px';
		this.style.height = height + 'px';
	};
	
	CElement.prototype.setHeight = function (height) {
		this.style.height = height + 'px';
	};
	
	CElement.prototype.setWidth = function (width) {
		this.style.width = width + 'px';
	};
	
	CElement.prototype.setVerticalAlign = function (align) {
		this.style.verticalAlign = align;
	};
	
	CElement.prototype.setOpacity = function (value) {
		this.style.opacity = value;
		
		if (isIe()) {
			if (!this.element.currentStyle || !this.element.currentStyle.hasLayout) {
				this.style.display = 'inline-block';
			}
			
			this.element.className = ('opacity' + Math.round(value*100));
			this.style.filter = (value === '' ? '' : "alpha(opacity=" + (value * 100) + ")");
		} else {
			this.style['-moz-opacity'] = this.style['-khtml-opacity'] = value || '';
		}
	};
	
	CElement.prototype.setBackgroundColor = function (value) {
		this.style.backgroundColor = value;
	};
	
	CElement.prototype.setBackground = function (url, position, repeat) {
		if (url) {
			this.style.backgroundImage = 'url("' + url + '")';
		}
		
		if (get_type(position) == 'object') {
			if (get_type(position[0]) == 'number') {
				position[0] += 'px';
			}
			if (typeof(position[1]) == 'number') {
				position[1] += 'px';
			}
			
			this.style.backgroundPosition = position[0] + ' ' + position[1];
		}
		
		if (!repeat) {
			this.style.backgroundRepeat = 'no-repeat';
		} else if (repeat == 'x') {
			this.style.backgroundRepeat = 'repeat-x';
		} else if (repeat == 'y') {
			this.style.backgroundRepeat = 'repeat-y';
		}
	};
	
	CElement.prototype.setMargin = function (margin_arr) {
		for (var k in margin_arr) {
			this.style['margin' + ucfirst(k)] = get_type(margin_arr[k]) == 'number' ? margin_arr[k] + 'px' : margin_arr[k];
		}
	};
	
	CElement.prototype.getMargin = function () {
		var res = {
			top: parseInt(this.style.marginTop, 10),
			right: parseInt(this.style.marginRight, 10),
			bottom: parseInt(this.style.marginBottom, 10),
			left: parseInt(this.style.marginLeft, 10)
		};
		
		for (var k in res) {
			if (isNaN(res[k])) {
				res[k] = 0;
			}
		}
		
		return res;
	};
	
	CElement.prototype.getClientWidth = function () {
		return parseInt(this.element.clientWidth, 10);
	};
	
	CElement.prototype.getSize = function () {
		return [this.getWidth(), this.getHeight()];
	};
	
	CElement.prototype.getWidth = function () {
		return parseInt(this.element.offsetWidth, 10);
	};
	
	CElement.prototype.getHeight = function () {
		return parseInt(this.element.offsetHeight, 10);
	};
	
	CElement.prototype.setClass = function (value) {
		this.element.className = value;
	};
	
	CElement.prototype.isHide = function () {
		return (this.style.display != 'none');
	};
	
	CElement.prototype.switchDisplay = function () {
		return (this.style.display = (this.style.display == 'none' ? 'block' : 'none'));
	};
	
	CElement.prototype.getLocalTop = function () {
		return this.element.offsetTop + (isIe() ? this.getParent().getMargin().top : 0);
	};
	
	CElement.prototype.getLocalLeft = function () {
		return this.element.offsetLeft + (isIe() ? this.getParent().getMargin().left : 0);
	};
	
	CElement.prototype.getLocalRight = function () {
		return this.getLocalLeft() + this.getWidth();
	};
	
	CElement.prototype.getLocalPosition = function () {
		return {top: this.getLocalTop(), left: this.getLocalLeft()};
	};
	
	CElement.prototype.getAbsoluteTop = function () {
		var res = this.element.offsetTop;
		if (this.element.offsetParent) {
			var e = new CElement;
			e.setElement(this.element.offsetParent);
			res += e.getAbsoluteTop();
		}
		return res;
	};
	
	CElement.prototype.getAbsoluteBottom = function () {
		return this.getAbsoluteTop() + this.getHeight();
	};
	
	CElement.prototype.getAbsoluteLeft = function () {
		var res = this.element.offsetLeft;
		if (this.element.offsetParent) {
			var e = new CElement;
			e.setElement(this.element.offsetParent);
			res += e.getAbsoluteLeft();
		}
		return res;
	};
	
	CElement.prototype.getAbsoluteRight = function () {
		return this.getAbsoluteLeft() + this.getWidth();
	};
	
	CElement.prototype.getAbsolutePosition = function () {
		return {top: this.getAbsoluteTop(), left: this.getAbsoluteLeft()};
	};
	
	CElement.prototype.getMouseXY = function () {
		if (!this.isMouseOver()) {
			return null;
		}
		
		return {x: this.getMouseX(), y: this.getMouseY()};
	};
	
	CElement.prototype.isMouseOver = function (child) {
		var mouse = getMouseXY();
		var res = true;
		
		if (mouse.x < this.getAbsoluteLeft() || mouse.x > this.getAbsoluteRight()) {
			res = false;
		}
		
		if (mouse.y < this.getAbsoluteTop() || mouse.y > this.getAbsoluteBottom()) {
			res = false;
		}
		
		if (!res && child) {
			var recursive_check = function (node) {
				for (var k = 0; k < node.childNodes.length; k ++) {
					if (node.childNodes[k].nodeName.toLowerCase() == 'div') {
						var e = new CElement;
						e.setElement(node.childNodes[k]);
						
						if (e.isMouseOver(true)) {
							return true;
						}
					}
				}
				return false;
			};
			
			res = recursive_check(this.element);
		}
		
		return res;
	};
	
	CElement.prototype.getMouseX = function () {
		if (!this.isMouseOver()) {
			return null;
		}
		var mouse = getMouseXY();
		
		return mouse.x - this.getAbsoluteLeft();
	};
	
	CElement.prototype.getMouseY = function () {
		if (!this.isMouseOver()) {
			return null;
		}
		var mouse = getMouseXY();
		
		return mouse.y - this.getAbsoluteTop();
	};
	
	var CTable = function (parent) {
		createMethodReference(this, CElement)('table', parent);
		
		this.row = [];
		this.body = n('tbody');
		
		this.element.appendChild(this.body);
	};
	CTable.prototype = clone(CElement.prototype);
	
	CTable.prototype.createRow = function (cols_num) {
		var tr = n('tr');
		this.body.appendChild(tr);
		
		var td = n('td', null, cols_num);
		for (var i = 0; i < cols_num; i ++) {
			tr.appendChild(td[i]);
		}
		
		this.row.push({
			element: tr,
			td: td
		});
		
		return td;
	};
	
	
	var CDiv = function (parent) {
		createMethodReference(this, CElement)('div', parent);
	};
	CDiv.prototype = clone(CElement.prototype);
	
	
	var CImg = function (parent) {
		createMethodReference(this, CElement)('img', parent);
	};
	CImg.prototype = clone(CElement.prototype);
	
	CImg.prototype.setSrc = function (src) {
		this.setAttribute('src', src);
		this.element.src = src;
	};
	
	
	var CDebug = function (message) {
		//~ console.info(message);
		//~ console.trace();
	};
	
	
	CInput = function (type, parent) {
		createMethodReference(this, CElement)('input', parent);
		this.setType(type);
		
		this.attachEvent('focus', function () {
			if (this.default_value) {
				if (this.getValue() == this.default_value) {
					this.setValue('');
				}
			}
		}, true);
		
		this.attachEvent('blur', function () {
			if (this.default_value) {
				if (this.getValue() == '') {
					this.setValue(this.default_value);
				}
			}
		}, true);
	};
	CInput.prototype = clone(CElement.prototype);
	
	CInput.prototype.setValue = function (value) {
		this.element.value = value;
	};
	
	CInput.prototype.getValue = function () {
		return this.element.value;
	};
	
	CInput.prototype.setType = function (value) {
		try {
			this.element.setAttribute('type', value);
		} catch (E) {
		}
	};
	
	CInput.prototype.getType = function () {
		return this.element.type;
	};
	
	CInput.prototype.setDefaultValue = function (value) {
		this.default_value = value;
	};
	
	CInput.prototype.getDefaultValue = function () {
		return this.default_value;
	};
	
	
	var CTextInput = function (parent) {
		createMethodReference(this, CInput)('text', parent);
	};
	CTextInput.prototype = clone(CInput.prototype);
	
	CTextInput.prototype.setMaxLength = function (value) {
		this.element.setAttribute('maxlength', value);
	};
	
	
	var CPasswordInput = function (parent) {
		createMethodReference(this, CTextInput)(parent);
		this.setType('password');
	};
	CPasswordInput.prototype = clone(CTextInput.prototype);
	
	
	CRadio = function (parent) {
		createMethodReference(this, CInput)('radio', parent);
	};
	CRadio.prototype = clone(CInput.prototype);
	
	
	CCheckbox = function (parent) {
		createMethodReference(this, CInput)('checkbox', parent);
	};
	CCheckbox.prototype = clone(CInput.prototype);
	
	
	/*
	 * "Potencjometr" - np. ocena z gwiazdek
	 * */
	var CPot = function (parent, size, control) {
		createMethodReference(this, CElement)('div', parent);
		
		this.size = size || 5;
		this.item_control = control || 'CRadio';
		this.item = [];
		this.value = 0;
		this.over_value = null;
		
		this.redraw();
		this.style.cursor = 'pointer';
		this.attachEvent('mouseout', createMethodReference(this, function () {
			//~ this.over_value = null;
		}));
	};
	CPot.prototype = clone(CElement.prototype);
	
	CPot.prototype.getItems = function () {
		return this.item;
	};
	
	CPot.prototype.getValue = function () {
		return this.value;
	};
	
	CPot.prototype.getOverValue = function () {
		return this.over_value;
	};
	
	CPot.prototype.redraw = function () {
		this.cleanUp();
		
		for (var k = 0; k < this.size; k ++) {
			eval('this.item[k] = new ' + this.item_control + '(this);');
			
			this.item[k].attachEvent('click', createMethodReference({pot:this, value:k}, function () {
				if (this.pot.item[this.value].isMouseOver()) {
					this.pot.setValue(this.value);
				}
			}));
			
			this.item[k].attachEvent('mouseover', createMethodReference({pot:this, value:k}, function () {
				if (this.pot.item[this.value].isMouseOver()) {
					this.pot.over_value = this.value;
				}
			}));
			
			delete on_change;
		}
	};
	
	CPot.prototype.cleanUp = function () {
		for (var k = 0; k < this.item.length; k ++) {
			this.removeChild(this.item[k]);
		}
		
		this.setHtml('');
	};
	
	CPot.prototype.setName = function (name) {
		for (var k = 0; k < this.item.length; k ++) {
			this.item[k].setName(name);
		}
		this.item = [];
	};
	
	CPot.prototype.setValue = function (value) {
		this.value = value;
		this.callEvent('change');
	};
	
	
	var CImgPot = function (parent, size, img1, img2) {
		createMethodReference(this, CPot)(parent, size, 'CImg');
		
		this.img = [img1, img2];
		
		for (var k = 0; k < this.getItems().length; k ++) {
			this.getItems()[k].setSrc(this.img[0]);
		}
		this.getItems()[0].setSrc(this.img[1]);
		
		this.attachEvent('change', function () {
			for (var k = this.getValue(); k < this.getItems().length; k ++) {
				this.getItems()[k].setSrc(this.img[0]);
			}
			
			for (var k = 0; k <= this.getValue(); k ++) {
				this.getItems()[k].setSrc(this.img[1]);
			}
		}, true);
		
		this.attachEvent('mousemove', function () {
			this.over_value = null;
			
			for (var k = 0; k < this.getItems().length; k ++) {
				if (this.item[k].isMouseOver()) {
					this.over_value = k;
				}
			}
			
			if (this.getOverValue() === null) {
				return;
			}
			
			for (var k = 0; k < this.getItems().length; k ++) {
				this.getItems()[k].setSrc(this.img[0]);
			}
			
			for (var k = 0; k <= this.getOverValue(); k ++) {
				this.getItems()[k].setSrc(this.img[1]);
			}
		}, true);
		
		this.attachEvent('mouseout', function () {
			this.over_value = null;
			
			for (var k = 0; k < this.getItems().length; k ++) {
				if (this.item[k].isMouseOver()) {
					this.over_value = k;
				}
			}
			
			for (var k = this.getValue(); k < this.getItems().length; k ++) {
				this.getItems()[k].setSrc(this.img[0]);
			}
			
			for (var k = 0; k <= this.getValue(); k ++) {
				this.getItems()[k].setSrc(this.img[1]);
			}
		}, true);
	};
	CImgPot.prototype = clone(CPot.prototype);
	
	
	var CReplacement = function (sourceitem, newitem) {
		//~ sourceitem.parentNode.replaceChild(sourceitem, newitem.element);
	};
