
	function fav_item_class(parent, container) {
		this.parent = parent;
		this.container = container;
		this.href = null;
		this.flag = null;
		this.code = 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);
		}
		
		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);
		}
	}
	
	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_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_img = 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_img = document.createElement("IMG");
		this.el_img.src = "/gfx/border_star.gif";
		
		this.el_href = document.createElement("A");
		
		this.border_inner.appendChild(this.el_img);
		this.border_inner.appendChild(this.el_href);
		
		this.motions_container = context.createElement("DIV");
		this.motions_container.className = "item_list";
		
		var ref = document.getElementById("fav_link");
		this.motions_area = context.createElement("DIV");
		this.motions_area.style.position = "absolute";
		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) {
			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 msg = this.show_msg(result_flag ? "<span>POZOR!</span><br/>Položka byla přidána do oblíbených" : "<span>POZOR!</span><br/>Položka byla odebrána z oblíbených");
				if (msg != null && this.reload_flag && !result_flag) {
					msg.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 (flag) {
			this.el_href.innerHTML = "odebrat z oblíbených";
		} else {
			this.el_href.innerHTML = "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) {
			this.active = ref;
			var f, br;
			
			var size = 4;
			var px = context.get_elementX(ref.container);
			var py = context.get_elementY(ref.container);
			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 ? "#C07C88" : "#a7bbcf";
			
				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 + "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 "table" :
					this.border_inner.className = "item_border_table";
					this.border_inner.style.left = (px + pw - 150 - size) + "px"
					this.border_inner.style.top = (py + size) + "px";
					this.border_inner.style.width = (150) + "px";
					break;
					
				default :
					this.border_inner.className = "item_border_default";
					this.border_inner.style.left = (px + size) + "px"
					this.border_inner.style.top = (py + ph - 37 - size) + "px";
					this.border_inner.style.width = (pw - size - size) + "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) {
			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";
		}
	}

