
	// --- fav_item_class ---

	function fav_item_class(parent, container) {
		this.parent = parent;
		this.container = container;
		this.cls = null;
		this.href = null;
		this.flag = null;
		this.code = null;
		
		this.table_a = null;
		this.table_b = null;
		
		this.left_top = null;
		this.right_top = null;
	}
	
	fav_item_class.prototype.construct = function() {
		var self = this;
		
		this.container.onmouseover = function(trgEvent) {
			self.evt_over(trgEvent == null ? event : trgEvent);
		}
		this.container.onmouseout = function(trgEvent) {
			self.evt_out(trgEvent == null ? event : trgEvent);
		}
		this.cls = this.container.className;
		
		var founded = null;
		var pos = 0;
		
		while (pos < this.container.childNodes.length && founded == null) {
			if (this.container.childNodes[pos].nodeType == 1 && this.container.childNodes[pos].tagName.toUpperCase() == "INPUT" && this.container.childNodes[pos].type == "hidden") founded = this.container.childNodes[pos];
			else pos++;
		}
		
		if (founded != null) {
			this.flag = parseInt(founded.value.substr(0, 1));
			this.href = founded.value.substr(1, founded.value.length - 1);
			
			founded = founded.nextSibling;
			while (founded != null && !(
				founded.nodeType == 1 && founded.tagName.toUpperCase() == "INPUT" && founded.type == "hidden"
			)) founded = founded.nextSibling;
			
			if (founded != null) this.code = parseInt(founded.value);
		}
		
		var pct = this.container.parentNode;
		founded = null;
		pos = 0;
		
		while (pos < pct.childNodes.length && founded == null)
			if (pct.childNodes[pos].nodeType == 1 && pct.childNodes[pos].tagName == "SPAN" && pct.childNodes[pos].className == "left_top") founded = pct.childNodes[pos];
			else pos++;
			
		if (founded != null) this.left_top = founded;
		founded = null;
		pos = 0;
			
		while (pos < pct.childNodes.length && founded == null)
			if (pct.childNodes[pos].nodeType == 1 && pct.childNodes[pos].tagName == "SPAN" && pct.childNodes[pos].className == "right_top") founded = pct.childNodes[pos];
			else pos++;
			
		if (founded != null) this.right_top = founded;
			
		var current, stack = new Array();
		stack[0] = this.container;
		
		while (stack.length > 0 && (this.table_a == null || this.table_b == null)) {
			current = stack.pop();
			
			if (current.tagName.toUpperCase() == "TABLE") {
				if (this.table_a == null) this.table_a = current;
				else this.table_b = current;
			}
			
			if (current.childNodes.length > 0)
				for (pos = 0; pos < current.childNodes.length; pos++)
					if (current.childNodes[pos].nodeType == 1) stack[stack.length] = current.childNodes[pos];
		}
	}
	
	fav_item_class.prototype.evt_over = function(trgEvent) {
		this.parent.touch(this);
	}
	
	fav_item_class.prototype.evt_out = function(trgEvent) {
		if (!this.parent.locked) {
			var target = trgEvent.relatedTarget == null ? trgEvent.toElement : trgEvent.relatedTarget;
			var f, pass = true;
			
			do {
				if (target == null) pass = false;
				else if (target == this.container) pass = false;
				else if (target == this.parent.border_inner) pass = false;
				else {
					for (f = 0; pass && f < this.parent.border.length; f++)
						if (target == this.parent.border[f]) pass = false;
				}
				
				if (pass) target = target.parentNode;
			} while (pass);
			
			if (target == null) this.parent.release(this);
		}
	}
	
	fav_item_class.prototype.activate = function() {
		this.container.className = this.cls + " item_list_node_big_active";
		this.table_b.style.display = "none";
		this.table_a.style.display = document.all ? "block" : "table";
		
		var pos = 0;
		var loop = this.container;
		while (loop != null) {
			if (loop.nodeType == 1 && loop.tagName.toUpperCase() == "DIV" && loop.className != "") pos++;
			loop = loop.previousSibling;
		}
		
		if (pos == 1) this.left_top.className = "left_top left_top_high";
		else this.left_top.className = "left_top";
		
		if (pos == 4) this.right_top.className = "right_top right_top_high";
		else this.right_top.className = "right_top";
		
		//this.table_b.style.visibility = "hidden";
		//this.table_a.style.visibility = "visible";
	}
	
	fav_item_class.prototype.deactivate = function() {
		this.container.className = this.cls;
		this.table_b.style.display = document.all ? "block" : "table";
		this.table_a.style.display = "none";
		
		this.left_top.className = "left_top";
		this.right_top.className = "right_top";
		
		//this.table_b.style.visibility = "visible";
		//this.table_a.style.visibility = "hidden";
	}

	// --- fav_motion ---
	
	function fav_motion(parent, base_container, result_flag) {
	
		this.inheritFrom = shadow_block_class;
		this.inheritFrom();
	
		this.parent = parent;
		this.base_container = base_container;
		this.container = null;
		this.target_container = null;
		this.result_flag = result_flag;
		
		this.cx = 0;
		this.cy = 0;
		
		this.tx = 0;
		this.ty = 0;
		
		this.base_step = 45;
		this.min_step = 5;
		this.base_len = null;
		
		this.step = this.base_step;
		this.docked = false;
		this.dock_step = 60;
		this.ondone = null;
		
		this.construct();
	}
	
	clone_add(fav_motion.prototype, shadow_block_class.prototype);
	
	fav_motion.prototype.construct = function() {
		this.container = context.createElement("DIV");
		this.container.innerHTML = this.base_container.innerHTML;
		this.container.className = this.base_container.className;
		this.container.style.zIndex = 10;
		this.container.style.backgroundColor = "white";
		this.container.style.width = (context.get_elementWidth(this.base_container) - 2) + "px";
		this.container.style.height = (context.get_elementHeight(this.base_container) - 2) + "px";
		this.container.style.position = "absolute";
		
		var tmp = document.createElement("DIV");
		if (this.result_flag) {
			tmp.className = "fav_info";
			tmp.innerHTML = "<span>přidáno do oblíbených</span>";
		} else {
			tmp.className = "fav_info fav_info_active";
			tmp.innerHTML = "<span>odebráno z oblíbených</span>";
		}
		
		this.container.appendChild(tmp);
		
		this.target_container = context.createElement("DIV");
		this.target_container.style.width = context.get_elementWidth(this.base_container) + "px";
		this.target_container.style.height = context.get_elementHeight(this.base_container) + "px";
		this.target_container.style.backgroundColor = "silver";
		this.update_opacity(0);
		
		this.parent.motions_container.appendChild(this.container);
		this.parent.motions_area.appendChild(this.target_container);
		
		if (this.result_flag) {
			this.cx = context.get_elementX(this.base_container);
			this.cy = context.get_elementY(this.base_container);
		} else {
			this.cx = context.get_elementX(this.target_container);
			this.cy = context.get_elementY(this.target_container);
		}
		this.update();
		
		this.shadows_build();
	}
	
	fav_motion.prototype.destroy = function() {
		this.shadows_destroy();
	
		context.structure_destroy(this.container);
		context.structure_destroy(this.target_container);
		context.object_destroy(this);
	}
	
	fav_motion.prototype.shadow_width = function() { return context.get_elementWidth(this.container) - 1; }
	fav_motion.prototype.shadow_height = function() { return context.get_elementHeight(this.container) - 1; }
	
	fav_motion.prototype.update_opacity = function(value, both) {
		this.target_container.style.opacity = value / 100;
		this.target_container.style.filter = "Alpha(opacity=" + Math.round(value) + ")";
		
		if (both) {
			this.container.style.opacity = value / 100;
			this.container.style.filter = "Alpha(opacity=" + Math.round(value) + ")";
		}
	}
	
	fav_motion.prototype.update_target = function() {
		this.tx = context.get_elementX(this.target_container);
		this.ty = context.get_elementY(this.target_container);
	}
	
	fav_motion.prototype.update = function() {
		if (this.docked) {
			if (this.result_flag) {
				this.tx = context.get_elementX(this.target_container);
				this.ty = context.get_elementY(this.target_container);
			} else {
				this.tx = context.get_elementX(this.base_container);
				this.ty = context.get_elementY(this.base_container);
			}
			
			this.cx = this.tx;
			this.cy = this.ty;
		}
	
		this.container.style.left = Math.round(this.cx) + "px";
		this.container.style.top = Math.round(this.cy) + "px";
	}
	
	fav_motion.prototype.do_motion = function() {
		if (this.docked) {
			if (this.result_flag) {
				this.dock_step--;
				if (this.dock_step == 0) {
					if (this.ondone != null) this.ondone();
					this.parent.motion_rem(this);
					
				} else if (this.dock_step < 20) {
					this.update_opacity(this.dock_step * 5, true);
				}
				
			} else {
				this.docked = false;
			}
		
		} else {
			// update cile (muze se menit)
			if (this.result_flag) {
				this.tx = context.get_elementX(this.target_container);
				this.ty = context.get_elementY(this.target_container);
			} else {
				this.tx = context.get_elementX(this.base_container);
				this.ty = context.get_elementY(this.base_container);
			}
		
			// update prirustku (muze se menit)
			var diff_x = this.tx - this.cx;
			var diff_y = this.ty - this.cy;
			var len = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
			
			if (this.base_len == null) this.base_len = len;
			
			if (this.result_flag) {
				if (len <= 100) this.update_opacity(100 - len);
			} else {
				if (this.base_len - len <= 100) this.update_opacity(100 - this.base_len + len);
				else {
					context.structure_destroy(this.target_container);
					this.parent.motion_update();
				}
			}
			
			if (len > this.step) {
				var koef = this.step / len;
				this.step = this.base_step * (len / this.base_len);
				if (this.step < this.min_step) this.step = this.min_step;
				
				this.cx += diff_x * koef;
				this.cy += diff_y * koef;
				
				this.update();
			} else {
				if (this.result_flag) {
					this.docked = true;
					this.update();
					
				} else {
					if (this.ondone != null) this.ondone();
					this.parent.motion_rem(this);
				}
			}
		}
	}
	
	// --- fav_class ---

	function fav_class() {
		this.containers = new Array();
		this.border = null;
		this.border_inner = null;
		this.el_href = null;
		this.items = new Array();
		this.active = null;
		this.locked = false;
		this.reload_flag = false;
		this.display = null;
		
		this.msg_cont = null;
		this.msg = null;
		
		this.motions_container = null;
		this.motions_area = null;
		this.motions = new Array();
		
		this.construct();
	}
	
	fav_class.prototype.construct = function() {
		
		this.display = "default";
		this.active = null;
		var self = this;
		
		this.border = new Array();
		var f, ref;
		for (f = 0; f < 4; f++) {
			ref = document.createElement("DIV");
			ref.style.fontSize = "1px";
			ref.style.position = "absolute";
			ref.style.zIndex = 1;
			ref.onmouseout = function(trgEvent) {
				//self.evt_out(trgEvent == null ? event : trgEvent);
			}
			
			this.border[this.border.length] = ref;
			document.body.appendChild(ref);
		}
		
		this.border_inner = document.createElement("DIV");
		this.border_inner.style.display = "none";
		this.border_inner.style.zIndex = 1;
		
		//this.el_href = document.createElement("A");
		//this.border_inner.appendChild(this.el_href);
		
		this.motions_container = context.createElement("DIV");
		this.motions_container.className = "item_list_big";
		this.motions_container.style.border = "0";
		this.motions_container.style.position = "absolute";
		this.motions_container.style.left = "0";
		this.motions_container.style.top = "0";
		
		//var ref = document.getElementById("fav_link");
		this.motions_area = context.createElement("DIV");
		this.motions_area.style.position = "absolute";
		this.motions_area.style.left = "0";
		this.motions_area.style.top = "0";
		//this.motions_area.style.left = context.get_elementX(ref) + "px";
		//this.motions_area.style.top = (context.get_elementY(ref) + 39) + "px";
		
		//document.body.appendChild(this.border_inner);
		document.body.appendChild(this.motions_container);
		document.body.appendChild(this.motions_area);
	}
	
	fav_class.prototype.do_motion = function() {
		var pos = 0;
		while (pos < this.motions.length) {
			this.motions[pos].do_motion();
			pos++;
		}
	}
	
	fav_class.prototype.motion_add = function(base_container, result_flag) {
		var ref = new fav_motion(this, base_container, result_flag);
		this.motions[this.motions.length] = ref;
		return ref;
	}
	
	fav_class.prototype.motion_rem = function(ref) {
		var founded = null;
		var pos = 0;
		
		while (founded == null && pos < this.motions.length)
			if (this.motions[pos] == ref) founded = this.motions[pos];
			else pos++;
			
		if (founded != null) {
			var f;
			for (f = pos; f < this.motions.length - 1; f++)
				this.motions[f] = this.motions[f + 1];
			this.motions.pop();
			
			founded.destroy();
			this.motion_update();
		}
	}
	
	fav_class.prototype.motion_update = function() {
		var f;
		for (f = 0; f < this.motions.length; f++)
			this.motions[f].update();
	}
	
	fav_class.prototype.show_msg = function(caption) {
		this.msg_cont = context.createElement("DIV");
		document.body.appendChild(this.msg_cont);
	
		this.msg = new error_wnd();
		this.msg.construct(this.msg_cont, "ano, jsem si toho vědom(a)", caption, "error_box_mega");
		return this.msg;
	}
	
	fav_class.prototype.trigger = function() {
		if (!this.locked && this.active != null) {
			// !! DOCASNE !!
			
			var result_flag = 1;
			var tmp = this.active;
			this.active = null;
			this.touch(tmp);
			
			var ref = this.motion_add(tmp.container, result_flag);
			if (this.reload_flag && !result_flag) {
				ref.ondone = function() {
					var tmp = document.location.href;
					document.location.href = tmp;
				}
			}
			
		
			/*
			this.locked = true;
		
			query_struct = new structure_class();
			query_struct.map("head/major", "add_fav");
			query_struct.map("head/web_group_code", this.active.code);
			
			var self = this;
			context.request("add_fav", null, function(data, request) {
				if (self != null) self.evt_trigger(data, request);
			}, query_struct);
			*/
		}
	}
	
	fav_class.prototype.evt_trigger = function(data, request) {
		var res;
		if ((res = request.get_response()) != null) {
			
			var head = res[0];
			var body = res[1];
			
			var el = body.getElementsByTagName("fav_flag");
			if (el.length > 0) {
				var f, result_flag = parseInt(context.element_value(el[0]));
				
				for (f = 0; f < this.items.length; f++) {
					if (this.items[f].code == this.active.code) 
						this.items[f].flag = result_flag;
				}
				
				this.locked = false;
				var tmp = this.active;
				this.active = null;
				this.touch(tmp);
				
				var ref = this.motion_add(tmp.container, result_flag);
				if (this.reload_flag && !result_flag) {
					ref.ondone = function() {
						var tmp = document.location.href;
						document.location.href = tmp;
					}
				}
			}
			
			var el = body.getElementsByTagName("fav_count");
			if (el.length > 0) {
				var count = context.element_value(el[0]);
				var link = document.getElementById("fav_link");
				
				if (link != null) {
					link.innerHTML = "Oblíbené (" + count + ")";
				}
			}
		}
	}
	
	fav_class.prototype.set_href = function(href, flag) {
		if (this.el_href != null) {
			if (flag) {
				this.el_href.innerHTML = "&gt; odebrat z oblíbených";
			} else {
				this.el_href.innerHTML = "&gt; Přidat do oblíbených";
			}
			
			if (typeof href == "string") {
				this.el_href.href = href;
			} else {
				this.el_href.href = "javascript:blank()";
				this.el_href.onclick = href;
			}
		}
	}
	
	fav_class.prototype.add_container = function(container) {
		var f, cur, item;
		for (f = 0; f < container.childNodes.length; f++) {
			cur = container.childNodes[f];
			
			if (cur.nodeType == 1 && (
				(cur.className.length >= 4 && cur.className.substr(0, 4) == "item") || 
				(cur.className.length >= 5 && cur.className.substr(0, 5) == "uitem")
			)) {
				item = new fav_item_class(this, cur);
				this.items[this.items.length] = item;
				item.construct();
			}
		}
		
		this.containers[this.containers.length] = container;
	}
	
	fav_class.prototype.evt_out = function(trgEvent) {
		if (!this.locked) {
			var target = trgEvent.relatedTarget == null ? trgEvent.toElement : trgEvent.relatedTarget;
			var f, pass = true;
			
			do {
				if (target == null) pass = false;
				else if (target == this.border_inner) pass = false;
				else {
					for (f = 0; pass && f < this.border.length; f++)
						if (target == this.border[f]) pass = false;
				}
				
				if (pass) target = target.parentNode;
			} while (pass);
			
			if (target == null) {
				this.release();
			}
		}
	}
	
	fav_class.prototype.touch = function(ref) {
		if (!this.locked && this.active != ref) {
			if (this.active != null) this.active.deactivate();
			
			this.active = ref;
			this.active.activate();
			
			var f, br;
			
			var size = 2;
			var px = context.get_elementX(ref.container) + (document.all ? 0 : 1);
			var py = context.get_elementY(ref.container) + (document.all ? -1 : 0);
			var pw = context.get_elementWidth(ref.container);
			var ph = context.get_elementHeight(ref.container);
			
			for (f = 0; f < this.border.length; f++) {
				br = this.border[f];
				br.style.backgroundColor = ref.flag ? "#FB6B00" : "#FB6B00";
			
				switch (f) {
					case 0 : // top
						br.style.left = px + "px";
						br.style.top = py + "px";
						br.style.width = pw + "px";
						br.style.height = size + "px";
						break;
						
					case 1 : // right
						br.style.left = (px + (pw - size)) + "px";
						br.style.top = py + "px";
						br.style.width = size + "px";
						br.style.height = ph + "px";
						break;
						
					case 2 : // bottom
						br.style.left = px + "px";
						br.style.top = (py + (ph - size)) + "px";
						br.style.width = pw + "px";
						br.style.height = size + "px";
						break;
						
					case 3 : // left
						br.style.left = (px - 1) + "px";
						br.style.top = py + "px";
						br.style.width = size + "px";
						br.style.height = ph + "px";
						break;
				}
				
				br.style.display = "block";
			}

			//this.set_href(ref.href, ref.flag);
			
			var self = this;
			this.set_href(function() {
				self.trigger();
			}, ref.flag);
			
			switch (this.display) {
				case "default" :
					this.border_inner.className = "item_border_default";
					this.border_inner.style.left = (px + pw - 177 - size) + "px"
					this.border_inner.style.top = (py + size) + "px";
					this.border_inner.style.width = (177) + "px";
					break;
			}
			
			if (ref.flag) this.border_inner.className = this.border_inner.className + " item_border_active";
			this.border_inner.style.display = "block";
		}
	}
	
	fav_class.prototype.release = function(ref) {
		if (!this.locked && this.active == ref) {
			if (this.active != null) this.active.deactivate();
			
			this.active = null;
			
			var f;
			for (f = 0; f < this.border.length; f++)
				this.border[f].style.display = "none";
			this.border_inner.style.display = "none";
		}
	}
