
	function $(id) {return document.getElementById(id);}
	
	function n(type, id, count) {
		if (count > 0) {
			var res = [];
			for (var i = 0; i < count; i ++) {
				res.push(n(type, id?id+i:null));
			}
			return res;
		} else {
			var o = document.createElement(type);
			if (!id) 
				id = 'object' + (new Date()).getTime();
			o.setAttribute('id', id);
			
			return o;
		}
	}
	
	function createMethodReference(object, method) {
		if (!(method instanceof Function)) {
			method = object[method];
		}
		
		return function () {
			method.apply(object, arguments);
		};
	}
	
	function attachEvent(o, sEventName, oCallback) {
		if (typeof o.addEventListener != 'undefined') {
		  o.addEventListener(
			sEventName,
			oCallback,
			false
		  );
		} else if (typeof o.attachEvent != 'undefined') {
		  o.attachEvent(
			'on' + sEventName,
			oCallback
		  );
		}
	}
	
	function write_list_for(id, fid, title, s_options) {
		var list = $(id);
		
		var nlist = n('div');
		nlist.className = 'select-imitation';
		
		var noptions = n('div');
		noptions.style.position = 'absolute';
		noptions.style.display = 'none';
		noptions.className = 'select-imitation-options';
		
		$(fid).appendChild(nlist);
		$(fid).appendChild(noptions);
		$(fid).className = 'select-imitation-container';
		$(fid).style.display = '';
		
		if (s_options) {
			for (var k in s_options) {
				var val = s_options[k];
				switch (k) {
					case 'options-width':
						noptions.style.width = val + 'px';
						break;
						
					case 'select-width':
						nlist.style.width = val + 'px';
						break;
				}
			}
		}
		
		if (!title) title = "Wybrano";
		var ndata = {num: 0, title: title, nlist: nlist, noptions: noptions, no: [], focus: false, opened: false, selected: 0, "default": "", list:list};
		
		var first = -1;
		var o = list.childNodes;
		for (var i = 1; i < o.length; i ++) {
			if ((new String(o[i].nodeName)).toLowerCase() == 'option') {
				var first = i;
				break;
			}
		}
		
		if (first >= 0) {
			nlist.innerHTML = o[first].innerHTML;
			ndata["default"] = o[first].innerHTML;
		}
		
		list_parse_options(o, first+1, ndata);
		
		if ((ndata.num) * 26 < 250) {
			noptions.style.overflow = '';
			noptions.style.height = 'auto';
		}
		
		attachEvent(nlist, 'click', createMethodReference(ndata, function () {
			if (this.opened) {
				this.noptions.style.display = 'none';
			} else {
				this.noptions.style.display = '';
			}
			
			this.focus = true;
			this.opened = !this.opened;
		}));
		
		attachEvent(document.body, 'click', createMethodReference(ndata, function () {
			if (!this.focus) {
				this.noptions.style.display = 'none';
				this.opened = false;
			}
		}));
		
		var set_focus = createMethodReference(ndata, function () {
			this.focus = true;
		});
		var unset_focus = createMethodReference(ndata, function () {
			this.focus = false;
		});
		
		attachEvent(nlist, 'mouseover', set_focus);
		attachEvent(nlist, 'mousemove', set_focus);
		attachEvent(nlist, 'mouseout', unset_focus);
		attachEvent(noptions, 'mouseover', set_focus);
		attachEvent(noptions, 'mousemove', set_focus);
		attachEvent(noptions, 'mouseout', unset_focus);
		
		list.style.display = 'none';
		list.name = '';
	}
	
	function list_parse_options(o, first, ndata) {
		for (var i = first; i < o.length; i ++) {
			var no = n('div');
			var span = n('span');
			var check = n('input');
			
			no.className = 'select-imitation-option';
			
			if (o[i].nodeName.toLowerCase() == 'optgroup') {
				no.className = 'select-imitation-group';
				no.innerHTML = o[i].getAttribute('label');
				ndata.noptions.appendChild(no);
				ndata.num ++;
				list_parse_options(o[i].getElementsByTagName('option'), 0, ndata);
				continue;
			}
			
			if (o[i].nodeName.toLowerCase() != 'option') {
				continue;
			}
			ndata.noptions.appendChild(no);
			
			var table = new CTable(no);
			table.style.width = '90%';
			var no_side = table.createRow(2);
			
			no_side[0].style.width = '28px';
			no_side[0].className = 'select-imitation-option-left';
			//~ if (ndata.noptions.style.width) {
				//~ no_side[1].style.width = new String((parseInt(ndata.noptions.style.width) - parseInt(no_side[0].style.width) - 10) + 'px');
				//~ no_side[1].style.width = new String((parseInt(ndata.noptions.offsetWidth) - parseInt(no_side[0].offsetWidth) - 10) + 'px');
			//~ }
			no_side[1].className = 'select-imitation-option-right';
			
			check.type = 'checkbox';
			check.name = ndata.list.name;
			check.value = o[i].value;
			no_side[0].appendChild(check);
			check.readonly = true;
			check.className = 'no-replace';
			check.style.padding = '0';
			check.style.margin = '0';
			check.style.border = '0';
			check.style.background = 'transparent';
			
			var nod = {selected: false, element: no, side: no_side, value: o[i].value, name: o[i].innerHTML, last:0};
			if (o[i].getAttribute('selected') == "1") {
				check.checked = true;
				no.className = 'select-imitation-option select-imitation-option-active';
				
				nod.selected = true;
				ndata.selected ++;
				
				if (ndata.selected == 0) {
					ndata.nlist.innerHTML = ndata['default'];
					ndata.nlist.style.fontWeight = 'normal';
				} else if (ndata.selected == 1) {
					ndata.nlist.innerHTML = ' ' + o[i].innerHTML;
					ndata.nlist.style.fontWeight = 'bold';
				} else {
					ndata.nlist.innerHTML = ' '+ndata.title+': ' + ndata.selected;
					ndata.nlist.style.fontWeight = 'bold';
				}
			}
			
			span.innerHTML = ' ' + o[i].innerHTML;
			no_side[1].appendChild(span);
			
			ndata.no.push(nod);
			ndata.num ++;
			
			var clicked = createMethodReference({ndata:ndata, no:no, check:check, span:span, nod:nod}, function () {
				var t = (new Date).getTime();
				if ((t - this.nod.last) < 200) {
					return;
				}
				this.nod.last = t;
				
				this.nod.selected = !this.nod.selected;
				this.check.checked = this.nod.selected;
				
				if (this.check.checked) {
					this.ndata.selected ++;
					this.no.className = 'select-imitation-option select-imitation-option-active';
				} else {
					this.ndata.selected --;
					this.no.className = 'select-imitation-option';
				}
				
				if (this.ndata.selected == 0) {
					this.ndata.nlist.innerHTML = this.ndata['default'];
					this.ndata.nlist.style.fontWeight = 'normal';
				} else if (this.ndata.selected == 1) {
					for (var i = 0; i < this.ndata.no.length; i ++) {
						if (this.ndata.no[i].selected) {
							this.ndata.nlist.innerHTML = ' ' + this.ndata.no[i].name;
							break;
						}
					}
					this.ndata.nlist.style.fontWeight = 'bold';
				} else {
					this.ndata.nlist.innerHTML = ' '+ndata.title+': ' + this.ndata.selected;
					this.ndata.nlist.style.fontWeight = 'bold';
				}
			});
			
			attachEvent(no, 'click', clicked);
			attachEvent(check, 'click', clicked);
		}
	}
	
	var TConnection = function (sUrl, fOnData) {
		this.onData = null;
		this.oConn = getAC();
		this.sMethod = 'GET';
		this.sUrl = '';
		
		this.oConn.onreadystatechange = createMethodReference(this, function () {
			if (this.oConn.readyState == 4) {
				if (this.onData) {
					this.onData(this.oConn);
				}
			}
		});
		
		//fast call
		if (sUrl) {
			this.sUrl = sUrl;
			this.onData = fOnData;
			this.open();
		}
	};
	TConnection.prototype.onData = null;
	TConnection.prototype.sMethod = 'GET';
	TConnection.prototype.sUrl = '';
	TConnection.prototype.bCacheProtection = true;

	TConnection.prototype.open = function () {
		this.oConn.open(this.sMethod, this.sUrl + (this.bCacheProtection ? '&_t='+(new Date()).getTime() : ''));
		this.oConn.send('');
	};
	
	function getAC() {
		var res;
		if (window.XMLHttpRequest) {
			try {
				res = new XMLHttpRequest();
		   } catch(e) {
				res = false;
		   }
		} else if (window.ActiveXObject) {
		   try {
			res = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				try {
					res =  new ActiveXObject("Msxml2.XMLHTTP");
				} catch(e) {
					res = false;
				}
			}
		}

		return res;
	}
	
	var CTable = function (parent) {
		this.row = [];
		this.body = n('tbody');
		this.table = n('table');
		
		this.table.appendChild(this.body);
		
		if (parent) {
			parent.appendChild(this.table);
		}
		
		this.style = this.table.style;
	};
	
	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;
	};
	
	function getElementsByClass(searchClass,node,tag) {
		var classElements = new Array();
		if ( node == null )
			node = document;
		if ( tag == null )
			tag = '*';
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		//var pattern = new RegExp("(^|[ 	]*)"+searchClass+"([ 	]*|$)");
		for (i = 0, j = 0; i < elsLen; i++) {
			//if ( pattern.test(els[i].className) ) {
			if (is_subclass_of(els[i], searchClass)) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	}

	function is_subclass_of(element, className) {
		className = new String(className);
		className = className.replace(/-/, '\\-');
		
		var pattern = new RegExp("(^|[ 	]+)"+className+"([ 	]+|$)");
		return pattern.test(element.className);
		
		return (new String(element.className)).match("/(^|[ 	]*)" + className + "([ 	]*|$)/");
	}
	
	var change_selection = function () {
		if (this.check.checked) {
			this.item.style.backgroundPosition = '-14px 0';
		} else {
			this.item.style.backgroundPosition = '0 0';
		}
	};
	
	function replace_checkboxes() {
		var change = function () {
			this.check.checked = !this.check.checked;
			
			createMethodReference(this, change_selection)();
		};
		
		var ec = [];
		var e = document.getElementsByTagName('input');
		for (var i = 0; i < e.length; i ++) {
			if (e[i].type == 'checkbox') {
				ec.push(e[i]);
			}
		}
		
		for (var i = 0; i < ec.length; i ++) {
			var check = ec[i];
			
			if (check.type == 'checkbox' && !is_subclass_of(check, 'no-replace')) {
				var item = n('div');
				var check2 = n('input');
				var span = n('span');
				
				var obj = {item: item, check: check2};
				
				check2.type = 'checkbox';
				check2.name = check.name;
				check2.value = check.value;
				check2.id = check.id;
				check.id = '';
				
				item.className = 'checkbox-replacement';
				item.style.width = '14px';
				item.style.height = '14px';
				item.style.border = '0';
				item.style.padding = '0';
				item.style.margin = '4px 0 3px 0';
				item.style.cursor = 'pointer';
				item.style.position = 'absolute';
				
				check2.style.visibility = 'hidden';
				
				span.appendChild(item);
				span.appendChild(check2);
				
				check.parentNode.replaceChild(span, check);
				check2.checked = check.checked;
				if (check.checked) {
					check2.setAttribute("checked", "1");
				}
				
				createMethodReference(obj, change_selection)();
				
				attachEvent(item, 'click', createMethodReference(obj, change));
				attachEvent(check2, 'click', createMethodReference(obj, change_selection));
				attachEvent(check2, 'change', createMethodReference(obj, change_selection));
			}
		}
	}
	
	var clone = function(obj) {
		var n = {};
		for (p in obj) {
			n[p] = obj[p];
		}
		return n;
	};
	
	if (/msie/i.test (navigator.userAgent)) //only override IE
	{
		document.nativeGetElementById = document.getElementById;
		document.getElementById = function(id)
		{
			var elem = document.nativeGetElementById(id);
			if(elem)
			{
				//make sure that it is a valid match on id
				if(elem.id == id)
				{
					return elem;
				}
				else
				{
					//otherwise find the correct element
					for(var i=1;i<document.all[id].length;i++)
					{
						if(document.all[id][i].id == id)
						{
							return document.all[id][i];
						}
					}
				}
			}
			return null;
		};
	}
	
	function on_window_load(func) {
		if (isIe()) {
			attachEvent(document, 'readystatechange', createMethodReference({func:func}, function () {
				if (document.readyState == 'complete') {
					this.func();
				}
			}));
		} else {
			attachEvent(window, 'load', createMethodReference({func:func}, function () {
				this.func();
			}));
		}
	}

