$.fn.animatoFormsInputNapoveda=function(text,trida,pozice) {
	if (this.length>1) {
		alert("animatoFormsInputNapoveda jde volat jen na jediný element!");
		return this;
	}
	
	if (!text) text=this.attr("title");
	if (!text) return this;

	if (!trida) trida="";

	var $div=$("<div class='"+trida+"'></div>");
	$div.html(text+"<span class='forms-napoveda-zobacek'></span>");

	if (!pozice) pozice={};
	pozice=$.extend({"my":"left top", "at":"left bottom", "offset":"0px 5px", "of":this,"collision":"fit"},pozice);

	$div.insertAfter(this);
	$div.hide();

	this.focus(function() {
		$div.stop(true,true).css("position","absolute").show().position(pozice).hide().fadeIn(300);
	}).blur(function() {
		$div.stop(true,true).fadeOut(300);
	});

	return this;
};

$.fn.animatoFormsMultiSetNapoveda=function(trida,pozice) {
	if (this.length>1) {
		alert("animatoFormsInputNapoveda jde volat jen na jediný element!");
		return this;
	}

	var napoveda="";
	var select;
	var poziceMoje;
	if (this.is("select")) {
		napoveda=this.attr("title");
		select=true;
	} else {
		select=false;
		napoveda=this.find(".forms-napoveda-html").html();
	}

	if (!napoveda) return this;

	if (!trida) trida="";

	var $div=$("<div class='"+trida+"'></div>");
	$div.html(napoveda+"<span class='forms-napoveda-zobacek'></span>");

	if (!pozice) pozice={};
	pozice=$.extend({"my":"left bottom", "at":"left top", "offset":"0px -5px", "of":this,"collision":"fit"},pozice);
	poziceMoje=pozice;

	$(document.body).append($div);
	$div.css("position","absolute").position(poziceMoje);
	$div.hide();

	var $kousky=this;
	if (!select) {
		$kousky=$kousky.find(":checkbox, :radio");
	}
	$kousky.focus(function() {
		var pozice=poziceMoje;
		pozice.of=$(this);
		$div.stop(true,true).show().position(pozice).hide().fadeIn(300);
	}).blur(function() {
		$div.stop(true,true).fadeOut(300);
	});

	return this;
};

$.fn.animatoAntiSpam=function() {
	var $form=$(this);
	if (!$form.is("form")) {
		$form=$form.closest("form");
	}
	if (!$form.is("form")) {
		return this;
	}
	if ($form.data("ani.isAntispamed")) return this;
	$form.data("ani.isAntispamed",true);
	$form.append($("<input type='hidden' name='cust_name' value='nejsem"+" "+"spammer' />"));
	return this;
};

$.fn.animatoIndikatorOdesilani=function(trida,html,submitSelector) {
	if (!submitSelector) submitSelector=":submit";
	var $form=$(this);
	var $submits=$form.find(submitSelector);
	$(this).submit(function() {
		if ($form.is(".spatne-vyplneny-formular")) return;
		$submits.each(function() {
			var $th=$(this);
			$th.addClass(trida);
			if ($th.is("button")) $th.data("aniOriginalHtml",$(this).html()).html(html);
				else $th.data("aniOriginalVal",$th.val()).val(html);
		});
	});
};

$.fn.animatoIsValid=function(vratitKomplexniVysledek) {
	var $th=$(this);
	var $subelements=$th.find(".validable");
	var ok=true;
	var nevalidni=[];
	var validni=[];
	$.each($subelements,function(i) {
		var $validuj=$(this);
		var fn=$validuj.data("ani.validable.fn");
		var valid=fn.call($validuj);
		if (!valid) {
			ok=false;
			nevalidni.push($validuj);
		} else {
			validni.push($validuj);
		}
	});
	if (!vratitKomplexniVysledek) {
		return ok;
	} else {
		return {"stav":ok,"nevalidni":nevalidni,"validni":validni};
	}
};

$.fn.animatoFormsInputValidace=function(params) {

	//data("ani.validable.stav"): -1 = chybné, 0 = nezobrazeno, 1 = validováno

	function keyDownCheck() {
		var validni=validate.call(this);
		var $th=$(this);
		var params=$th.data("ani.validable");
		if (!params) return;
		var bylo=$th.data("ani.validable.stav");
		if (validni) {
			if (bylo!=1) {
				if (params.trida) $th.removeClass(params.trida);
				if (params.indikator) {
					var $ind=$(params.indikator);
					$ind.html("<img src='"+params.stavy[0]+params.stavy[3]+"' alt='OK' />");
				}
				$th.data("ani.validable.stav",1);
			}
			var $warn=$th.data("ani.validable.warner");
			if ($warn) {
				$warn.fadeOut(300,function() {
					$(this).remove();
					$th.data("ani.validable.warner",false);
				});
			}
		} else {
			if (bylo==1) {
				if (params.trida) $th.removeClass(params.trida);
				if (params.indikator) {
					var $ind=$(params.indikator);
					$ind.html("");
				}
				$th.data("ani.validable.stav",0);
			}
			var $warn=$th.data("ani.validable.warner");
			if ($warn) {
				$warn.fadeOut(300,function() {
					$(this).remove();
					$th.data("ani.validable.warner",false);
				});
			}
		}
	}

	function changeCheck() {
		var validni=validate.call(this);
		var params=$(this).data("ani.validable");
		if (!params) return;
		var $th=$(this);
		if (validni) {
			if (params.trida) $th.removeClass(params.trida);
			if (params.indikator) {
				var $ind=$(params.indikator);
				$ind.html("<img src='"+params.stavy[0]+params.stavy[3]+"' alt='OK' />");
			}
			var $warn=$th.data("ani.validable.warner");
			if ($warn) {
				$warn.fadeOut(300,function() {
					$(this).remove();
					$th.data("ani.validable.warner",false);
				});
			}
			$th.data("ani.validable.stav",1);
		} else {
			if (params.trida) $th.addClass(params.trida);
			if (params.indikator) {
				var $ind=$(params.indikator);
				$ind.html(
					params.povinne?
					"<img src='"+params.stavy[0]+params.stavy[1]+"' alt='X' />":
					"<img src='"+params.stavy[0]+params.stavy[2]+"' alt='!' />"
				);
			}
			var $warn=$th.data("ani.validable.warner");
			if (params.text && !$warn) {
				$warn=$("<div></div>");
				if (params.textTrida) $warn.addClass(params.textTrida);
				$warn.html(params.text+"<span class='forms-popup-zobacek'></span>");
				$warn.css("position","absolute");
				$warn.click(function() {
					$(this).fadeOut(300,function() {
						$(this).remove();
						$th.data("ani.validable.warner",false);				
					});
				});
				$warn.insertAfter($th);
				if (params.textPozice) {
					if (!params.textPoziceRel && params.indikator && $(params.indikator).length) {
						params.textPozice.of=$(params.indikator);
					} else {
						params.textPozice.of=$th;
					}
					//fix kvůli moc úzkým bublinám při posunu mimo parent element
					$warn.width($warn.width()+10);
					$warn.height($warn.height());
					$warn.position(params.textPozice);
				} else {
					$warn.css("left",$th.position().left+"px");
					$warn.css("top",$th.position().top+"px");
				}
				$warn.hide().fadeIn(300);
				$th.data("ani.validable.warner",$warn);
			}
			$th.data("ani.validable.stav",-1);
		}
	}

	function validate(soft) {
		var params=$(this).data("ani.validable");
		if (!params) return true;
		if (params.re) {
			var val=new String($(this).val());
			if (val.match(params.re)) return true;
				return false;
		}
		if (params.fnName) {
			var val=new String($(this).val());
			return params.fnName(this,val);
		}
		return true;
	}

	function validateForm() {
		var vrat=validate.call(this);
		if (vrat) return true;
		changeCheck.call($(this));
		var params=$(this).data("ani.validable");
		if (!params.povinne) return true;
		return vrat;
	}


	//Hlavní kód

	if (this.length>1) {
		alert("animatoFormsInputValidace jde volat jen na jediný element!");
		return this;
	}

	var defaults={
		"regExp":"",
		"regExpModifikatory":"",
		"text":"",
		"textTrida":"forms-popup-warning",
		"textPozice":"",
		"textPoziceRel":true, //True = k indikátoru, je-li
		"fnName":"",
		"indikator":"",
		"trida":"",
		"stavyPrefix":"",
		"stavy":["","","",""],
		"povinne":false, //Říká, že je nutné být validní pro odeslání, ne že validita = vyplněná hodnota
		"priPsani":true
	};

	if (!params.textPozice) params.textPozice={};
	params.textPozice=$.extend({"my":"left center", "at":"right center", "offset":"5px 0px","collision":"fit"},params.textPozice);  //of se přidá později

	params=$.extend(defaults,params);

	if (params.regExp) {
		var re=new RegExp(params.regExp,params.regExpModifikatory);
		params.re=re;
	} else {
		params.re="";
	}

	if (params.fnName) {
		params.fnName=eval(params.fnName);
	}


	this.addClass("validable");
	this.data("ani.validable",params);
	this.data("ani.validable.fn",validateForm);

	if (params.priPsani) {
		this.keyup(keyDownCheck);
	}
	this.change(changeCheck);


	return this;
};

$.fn.animatoFormsCheckboxValidace=function(params) {

	//data("ani.validable.stav"): -1 = chybné, 0 = nezobrazeno, 1 = validováno

	function check(validni) {
		var $th=$(this);
		if (validni===undefined) {
			validni=validate.call($th);
		}
		var params=$th.data("ani.validable");
		if (!params) return;

		if (validni) {
			if (params.trida) $th.removeClass(params.trida);
			if (params.indikator) {
				var $ind=$(params.indikator);
				$ind.html("<img src='"+params.stavy[0]+params.stavy[3]+"' alt='OK' />");
			}
			var $warn=$th.data("ani.validable.warner");
			if ($warn) {
				$warn.fadeOut(300,function() {
					$(this).remove();
				});
				$th.data("ani.validable.warner",false);
			}
			$th.data("ani.validable.stav",1);
		} else {
			if (params.trida) $th.addClass(params.trida);
			if (params.indikator) {
				var $ind=$(params.indikator);
				$ind.html(
					params.povinne?
					"<img src='"+params.stavy[0]+params.stavy[1]+"' alt='X' />":
					"<img src='"+params.stavy[0]+params.stavy[2]+"' alt='!' />"
				);
			}
			var $warn=$th.data("ani.validable.warner");
			if (params.text && !$warn) {
				$warn=$("<div></div>");
				if (params.textTrida) $warn.addClass(params.textTrida);
				$warn.html(params.text+"<span class='forms-popup-zobacek'></span>");
				$warn.css("position","absolute");
				$warn.click(function() {
					$(this).remove();
					$th.data("ani.validable.warner",false);				
				});				
				$warn.insertAfter($th);
				if (params.textPozice) {
					if (!params.textPoziceRel && params.indikator) {
						params.textPozice.of=$(params.indikator);
					} else {
						params.textPozice.of=$th;
					}
					$warn.width($warn.width()+10);
					$warn.height($warn.height());					
					$warn.position(params.textPozice);
				} else {
					$warn.css("left",$th.position().left+"px");
					$warn.css("top",$th.position().top+"px");
				}
				$warn.hide().fadeIn(300);
				$th.data("ani.validable.warner",$warn);
			}
			$th.data("ani.validable.stav",-1);
		}
	}

	function validate() {
		var params=$(this).data("ani.validable");
		if (!params) return true;
		var pocet=$(this).find(":checked:not(.invalidable), :selected:not(.invalidable)").length;
		if (params.min || params.max) {
			if (params.min && pocet<params.min) return false;
			if (params.max && pocet>params.max) return false;
		}
		if (params.fnName) {
			return params.fnName(this,pocet);
		}
		return true;
	}

	function validateForm() {
		var vrat=validate.call(this);
		check.call($(this),vrat);
		var params=$(this).data("ani.validable");
		if (!params.povinne) return true;
		return vrat;
	}


	//Hlavní kód

	if (this.length>1) {
		alert("animatoFormsCheckboxValidace jde volat jen na jediný element!");
		return this;
	}

	var defaults={
		"min":false,
		"max":false,
		"text":"",
		"textTrida":"",
		"textPozice":"",
		"textPoziceRel":true, //True = k indikátoru, je-li
		"fnName":"",
		"indikator":"",
		"trida":"",
		"stavyPrefix":"",
		"stavy":["","","",""],
		"select":false,
		"povinne":false //Říká, že je nutné být validní pro odeslání, ne že validita = vyplněná hodnota
	};

	if (!params.textPozice) params.textPozice={};
	params.textPozice=$.extend({"my":"left center", "at":"right center", "offset":"5px 0px"},params.textPozice); //of se přidá později
	params=$.extend(defaults,params);

	if (params.fnName) {
		params.fnName=eval(params.fnName);
	}

	this.addClass("validable");
	this.data("ani.validable",params);
	this.data("ani.validable.fn",validateForm);
	var pole=this;

	if (params.select) {
		this.change(function() {check.call(pole);});
	} else {
		this.find("input").click(function() {
			window.setTimeout(function() {
				check.call(pole);
			},40);
		});
	}

	return this;
};



function animatoFormsSliderChange() {
	var $slider=$(this);
	var $container=$slider.parent("div");
	var rozsah=$slider.data("formsSliderRozsah");
	var id=$container.attr("id");
	var dataCislo=$slider.data("formsSliderCislo");
	var dataPattern=$slider.data("formsSliderPattern");
	var dataDesetinna=$slider.data("formsSliderDesetinna");

	var val1=$slider.slider("values",0);
	$container.find("#"+id+"_i1").val(val1);
	$container.find("#"+id+"_v1").html(animatoSliderFormatCisla(val1,dataCislo,dataPattern,dataDesetinna));

	if (rozsah) {
		var val2=$slider.slider("values",1);
		$container.find("#"+id+"_i2").val(val2);
		$container.find("#"+id+"_v2").html(animatoSliderFormatCisla(val2,dataCislo,dataPattern,dataDesetinna));
	}
};

function animatoSliderFormatCisla(source,cislo,pattern,desetinna) {
	var text=source;
	if (cislo) {
		text=animatoSliderNumberFormat(text,desetinna,",","&nbsp;");
	}
	if (pattern) {
		text=pattern.replace("%%",text);
	}
	return text;
};

function animatoSliderNumberFormat(number, decimals, dec_point, thousands_sep) {
    // discuss at: http://phpjs.org/functions/number_format
    number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
    var n = !isFinite(+number) ? 0 : +number,
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        s = '',
        toFixedFix = function (n, prec) {
            var k = Math.pow(10, prec);return '' + Math.round(n * k) / k;
        };
    // Fix for IE parseFloat(0.55).toFixed(0) = 0;
    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
    if (s[0].length > 3) {s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');}
    return s.join(dec);
};

function animatoFormsSliderSlide() {
	animatoFormsSliderChange.call(this);
};

$.fn.animatoFormsFileMultipler=function(maxPocet,deleter) {
	var $inp=$(this);
	var $obal=$("#"+$inp.attr("id")+"-obal");
	$obal.data("animatoFormsMultiplerMax",maxPocet);
	$multipler=$("#"+$inp.attr("id")+"-multipler");
	$multipler.css("cursor","pointer").click(function() {
		var $newObal=$obal.clone();
		$newObal.removeAttr("id").removeClass("validable");
		$newObal.find("input").removeAttr("id").val("");
		var $posledni=$obal.siblings(".forms-fileinput-obal").last();
		if (!$posledni.length) $posledni=$obal;
		var $deleter=$("<span class='forms-file-deleter'>"+deleter+"</span>");
		$deleter.css("cursor","pointer").click(function() {
			$(this).parent().remove();
			var maxPocet=$obal.data("animatoFormsMultiplerMax");
			if (maxPocet) {
				if ($obal.parent().children(".forms-fileinput-obal").length<maxPocet) {
					$multipler.show();
				}
			}
		});
		$newObal.append($deleter);
		$posledni.after($newObal);
		var maxPocet=$obal.data("animatoFormsMultiplerMax");
		if (maxPocet) {
			if ($obal.parent().children(".forms-fileinput-obal").length>=maxPocet) {
				$multipler.hide();
			}
		}
	});
	return this;
};

$.fn.animatoFormsFileValidator=function(params) {
	var $inp=$(this);
	var $obal=$("#"+$inp.attr("id")+"-obal");
	$obal.addClass("validable");
	$obal.data("ani.validable.fn",animatoFormsFileValid).data("ani.forms.file",params);
	return this;
};

function animatoFormsFileValid() {
	var $th=$(this);
	var params=$th.data("ani.forms.file");
	var ok=true;
	var $set=$th.siblings(".forms-fileinput-obal").andSelf();
	var zprava=[];
	if (params["povinne"]) {
		var neco=false;
		var spatny=null;
		$set.each(function() {
			if ($(this).find("input[type=file]").val()) {
				neco=true;
				if (params["trida"]) $(this).find("input[type=file]").removeClass(params["trida"]);
			} else {
				if (!spatny) spatny=this;
			}
		});
		if (!neco) {
			ok=false;
			if (params["trida"]) $(spatny).find("input[type=file]").addClass(params["trida"]);
			if (params["povinneText"]) zprava.push($("<div>"+params["povinneText"]+"</div>"));
		}
	}
	if (params["pripony"] && params["pripony"].length) {
		var spatne=false;
		var regexp=new RegExp("\\.("+(params["pripony"].join("|"))+")$","i");
		$set.each(function() {
			var $inp=$(this).find("input[type=file]");
			var val=$inp.val();
			if (val && !val.match(regexp)) {
				spatne=true;
				if (params["trida"]) $inp.addClass(params["trida"]);
			} else {
				if (val) {
					if (params["trida"]) $inp.removeClass(params["trida"]);
				}
			}
		});
		if (spatne) {
			ok=false;
			if (params["priponyText"]) zprava.push($("<div>"+params["priponyText"]+"</div>"));
		}
	}
	if (zprava && zprava.length) {
		var idZpravy=$th.attr("id")+"-zprava";
		var $zpravaCont=$("<div></div>");
		var $staraZprava=$("#"+idZpravy);
		var animovat=true;
		if ($staraZprava.length) {
			$staraZprava.remove();
			animovat=false;
		}
		$zpravaCont.addClass(params["tridaZprava"]);
		$zpravaCont.attr("id",idZpravy);
		$.each(zprava,function(i,z) {
			$zpravaCont.append(z);
		});
		$zpravaCont.insertBefore($th);
		if (animovat) $zpravaCont.hide().slideDown(400);
	}
	return ok;
};

$.fn.animatoPasswordHelper=function(params) {
	
	var $th=$(this);
	if ($th.length!=1) {
		alert("animatoPasswordHelper lze použít jen na jediný element!");
		return this;
	}
	params=$.extend({
		"textNadpis":"Vytvořit heslo",
		"textTyp":"Typ hesla",
		"textDelka":"Délka hesla",
		"textSila":"Síla hesla: ",
		"textSila1":"velmi slabé",
		"textSila2":"slabé",
		"textSila3":"střední",
		"textSila4":"silné",
		"textSila5":"velmi silné",
		"textTyp1":"Čísla",
		"textTyp2":"Písmena",
		"textTyp3":"Velká a malá písmena",
		"textTyp4":"Ne-alfanumerické znaky",
		"textTyp5":"Nepoužívat zaměnitelné znaky",
		"textPouzit":"Použít toto heslo",
		"textVytvorit":"Vygenerovat heslo",
		"textHeslo":"Heslo",
		"trida":"pwgen",
		"pozice":{"my":"left center","at":"right center","offset":"5px 0px"},
		"bind":""
	},params);
	params.pozice.of=$th;
	var $div=$("<div />");
	var origId=$th.attr("id");
	if (!origId) origId="p"+Math.round(Math.rand()*100000);
	$div.addClass(params["trida"]);
	$div.css("position","absolute");
	$div.html("<div class='forms-pwgenerator-nadpis'>"+params.textNadpis+"</div>"
		+"<table style='width:320px; margin:0px;' cellpadding='0' cellspacing='0'>"
		+"<tr><td style='width:80px; vertical-align:top' rowspan='5'>"+params.textTyp+"</td>"
		+"<td><input type='checkbox' checked='checked' name='pwgen-typ[]' id='"+origId+"-v1' value='1' /> <label for='"+origId+"-v1'>"+params.textTyp1+"</label></td></tr>"
		+"<tr><td><input type='checkbox' checked='checked' name='pwgen-typ[]' id='"+origId+"-v2' value='a' /> <label for='"+origId+"-v2'>"+params.textTyp2+"</label></td></tr>"
		+"<tr><td><input type='checkbox' checked='checked' name='pwgen-typ[]' id='"+origId+"-v3' value='A' /> <label for='"+origId+"-v3'>"+params.textTyp3+"</label></td></tr>"
		+"<tr><td><input type='checkbox' name='pwgen-typ[]' id='"+origId+"-v4' value='.' /> <label for='"+origId+"-v4'>"+params.textTyp4+"</label></td></tr>"
		+"<tr><td><input type='checkbox' checked='checked' name='pwgen-typ[]' id='"+origId+"-v5' value='G' /> <label for='"+origId+"-v5'>"+params.textTyp5+"</label></td></tr>"
		+"<tr><td style='vertical-align:top'>"+params.textDelka+"</td><td><input type='number' value='8' name='pwgen-delka' id='"+origId+"-n' style='width:30px;' class='forms-pwgenerator-input-mini' /></td></tr>"
		+"</table>"
		+"<div class='forms-pwgenerator-go'>"
			+"<input type='button' value='"+params.textVytvorit+"' class='forms-pwgenerator-button' id='"+origId+"-gen' />"
		+"</div>"
		+"<div class='forms-pwgenerator-heslo-popis' style='display:none;' id='"+origId+"-popis'>"+params.textHeslo+"</div>"
		+"<div class='forms-pwgenerator-heslo' style='display:none;' id='"+origId+"-heslo'>"
			+"<input type='text' class='forms-pwgenerator-output' id='"+origId+"-output' />"
		+"</div>"
		+"<div class='forms-pwgenerator-sila' style='display:none;' id='"+origId+"-sila'>"
			+"<div class='forms-pwgenerator-sila-typ' id='"+origId+"-sila1' style='display:none'>"+params.textSila+" "+params.textSila1+"</div>"
			+"<div class='forms-pwgenerator-sila-typ' id='"+origId+"-sila2' style='display:none'>"+params.textSila+" "+params.textSila2+"</div>"
			+"<div class='forms-pwgenerator-sila-typ' id='"+origId+"-sila3' style='display:none'>"+params.textSila+" "+params.textSila3+"</div>"
			+"<div class='forms-pwgenerator-sila-typ' id='"+origId+"-sila4' style='display:none'>"+params.textSila+" "+params.textSila4+"</div>"
			+"<div class='forms-pwgenerator-sila-typ' id='"+origId+"-sila5' style='display:none'>"+params.textSila+" "+params.textSila5+"</div>"
		+"</div>"
		+"<div class='forms-pwgenerator-pouzit' style='display:none;' id='"+origId+"-pouzit'>"
			+"<input type='button' value='"+params.textPouzit+"' class='forms-pwgenerator-button' id='"+origId+"-use' />"
		+"</div>"
		+"<div class='forms-pwgenerator-zavrit'></div>"
	);
	$th.after($div);
	$div.data("animatoPasswordHelperOrigId",origId);
	$div.data("animatoPasswordHelperBind",params.bind);
	$div.find(".forms-pwgenerator-zavrit").click(function() {
		$div.fadeOut(400);
	});
	var $buttonGen=$("#"+origId+"-gen");
	$buttonGen.click(function() {
		animatoPasswordHelperGen.call($th,$div);
	});
	var $buttonUse=$("#"+origId+"-use");
	$buttonUse.click(function() {
		animatoPasswordHelperUse.call($th,$div);
	});
	var $output=$("#"+origId+"-output");
	$output.bind("keyup",function() {
		animatoPasswordHelperRefreshSila.call($th,$div);
	});

	$div.position(params.pozice);
	$div.hide();

	$div.click(function() {
		$(this).removeClass("animatoPwgenBlurred");
	});

	$th.focus(function() {
		$div.show().position(params.pozice).hide().fadeIn(400);
	}).blur(function() {
		$div.addClass("animatoPwgenBlurred");
		window.setTimeout(function() {
			if ($div.is(".animatoPwgenBlurred")) $div.fadeOut(400);
		},400);
	});
	return this;
};

function animatoPasswordHelperGen($gen) {
	var origId=$gen.data("animatoPasswordHelperOrigId");
	var delka=$("#"+origId+"-n").val();
	var znaky=[];
	$gen.find("input[name*=pwgen-typ]:checked").each(function() {
		znaky.push($(this).val());
	});
	znaky=znaky.join("");
	var heslo=animatoPasswordHelperMake(delka,znaky);
	$gen.find(".forms-pwgenerator-output").val(heslo);
	animatoPasswordHelperRefreshSila($gen);
	$("#"+origId+"-popis").slideDown();
	$("#"+origId+"-heslo").slideDown();
	$("#"+origId+"-pouzit").slideDown();
};

function animatoPasswordHelperRefreshSila($gen) {
	var origId=$gen.data("animatoPasswordHelperOrigId");
	var heslo=$gen.find(".forms-pwgenerator-output").val();
	var sila=animatoPasswordHelperSila(heslo);
	$("#"+origId+"-sila").show();
	$gen.find(".forms-pwgenerator-sila-typ").hide();
	$("#"+origId+"-sila"+sila).show();
};


function animatoPasswordHelperMake(delka,params) {
	var znaky="";
	if (!(delka>0)) delka=8;
	if (params.indexOf("a")!=-1) znaky+="abcdefghijklmnopqrstuvwxyz";
	if (params.indexOf("A")!=-1) znaky+="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	if (params.indexOf("1")!=-1) znaky+="01234567890123456789";
	if (params.indexOf(".")!=-1) znaky+=",.-?:_!;@#$&*()";
	if (params.indexOf("G")!=-1) {
		znaky=znaky.replace(/[G6I1l0Oo]/g,"");
	}
	if (!znaky) return "";
	var vysledek="";
	var len=znaky.length;
	for (var i=0;i<delka;i++) {
		vysledek+=znaky.charAt(Math.floor(Math.random()*len));
	}
	return vysledek;
};

function animatoPasswordHelperSila(pw) {
	var pocetMoznychZnaku=0;
	if (pw.match(/[a-z]/)) pocetMoznychZnaku+=26;
	if (pw.match(/[A-Z]/)) pocetMoznychZnaku+=26;
	if (pw.match(/[0-9]/)) pocetMoznychZnaku+=10;
	if (pw.match(/[áěščřžýáíéúůňďťž]/i)) pocetMoznychZnaku+=15;
	if (pw.match(/[,.\-?:_!;@#$&*()]/)) pocetMoznychZnaku+=20;
	var komb=Math.pow(pocetMoznychZnaku,pw.length);
	var log=Math.log(komb)/Math.LN10;
	if (log<5) return 1;
	if (log<12) return 2;
	if (log<15) return 3;
	if (log<18) return 4;
	return 5;
};

function animatoPasswordHelperUse($gen) {
	var $pw=$gen.find(".forms-pwgenerator-output");
	var heslo=$pw.val();
	if (heslo) {
		$(this).val(heslo);
		var binds=$gen.data("animatoPasswordHelperBind");
		if (binds) $(binds).val(heslo);
	}
	$gen.fadeOut(400);
};

var animatoFullWidthInputCssLoaded=false;
jQuery.fn.animatoFullWidthInput=function() { //Použitelné jen pro common.css !!
	var origThis=this;
	var proved=function() {
		var $cont=origThis.parent();
		var fullWidth=$cont.width();
		if (origThis.siblings().filter(".formsInputIndicator, .formsTextareaIndicator").length>0) fullWidth-=22;
		origThis.outerWidth(fullWidth);
		return origThis;
	};
	var cykluj=function() {
		if (animatoFullWidthInputCssLoaded) {
			window.setTimeout(proved,300);
		} else {
			var $checker=$("<div></div>").addClass("forms-common-css-loaded");
			$(document.body).append($checker);
			if ($checker.width()==10 || $checker.height()==10) {
				animatoFullWidthInputCssLoaded=true;
			}
			window.setTimeout(cykluj,100);
			$checker.remove();
		}
	};
	cykluj();
	return this;
};

function animatoMoveCalendar($src,$targetParent) {
	$src=$($src);
	$wd=$src.datepicker("widget");
	$wd.appendTo($targetParent);
	$wd
		.show()
		.position({"my":"left top","at":"left bottom","offset":"0px 8px","of":$src})
		.hide();
	$src.datepicker("option","beforeShow",function(i,a) {
		window.setTimeout(function() {
			$wd
				.position({"my":"left top","at":"left bottom","offset":"0px 4px","of":$src})
				.css("z-index",500);
		},50);
		return {};
	});
}

/**
* Vytvoří z klasického &lt;select> pěkný a stylovatelný pseudo-select.
* <br />Každý pseudoselect je tvořen jedním DIVem (main), který obsahuje:
* <br /> - View - div obsahující text vybrané hodnoty (když se pseudoselect zavřený)
* <br /> - Expander - div, na který se dá kliknout, aby se rozbalil Popup
* <br /> - Popup - div, který obsahuje jednotlivé Optiony
* <br /><br />Původnímu Selectu je předávána change() událost, všechny změny v hodnotě Pseudoselectu se předávají původnímu Selectu.
* <br /><br />Lze aplikovat vždy jen na jediný select, jQuery objekt s vícero selecty najednou zatím nefunguje.
* @param opts Objekt s těmito vlastnostmi:
* <dl>
* 	<dt>tridaMain</dt><dd>Třída hlavního DIVu (default 'pseudoselect-main')</dd>
* 	<dt>tridaMainOpen</dt><dd>Třída (přídavná) hlavního DIVu, je-li Popup viditelný a vysunutý. Default 'pseudoselect-open'</dd>
*	<dt>tridaMainMultiple</dt><dd>Třída (přídavná) hlavního DIVu, je-li Pseudoselect typu multiple (tj. umožňuje volbu vícero možností najednou). Default 'pseudoselect-main-multiple'</dd>
* 	<dt>tridaExpander</dt><dd>Třída zavřeného Expanderu (nabízejícího otevření). Default 'pseudoselect-expander'</dd>
* 	<dt>tridaView</dt><dd>Třída View. Default 'pseudoselect-view'</dd>
* 	<dt>tridaPopup</dt><dd>Třída celého Popupu. Default 'pseudoselect-popup'</dd>
* 	<dt>tridaOption</dt><dd>Třída každého Optionu. Default 'pseudoselect-option'</dd>
* 	<dt>tridaOptionChecked</dt><dd>Přídavná třída pro Option, který je vybraný. Default 'pseudoselect-option-checked'</dd>
* 	<dt>tridaOptionDisabled</dt><dd>Přídavná třída pro Option, který je disabled. Default 'pseudoselect-disabled'</dd>
* 	<dt>tridaOptionEnabled</dt><dd>Přídavná třída pro Option, který není disabled. Hover efekty pro Optiony je vhodné dělat jen pro Enabled Default 'pseudoselect-enabled'</dd>
* 	<dt>tridaOptGroup</dt><dd>Třída pro každý Optgroup (je-li). Default 'pseudoselect-optgroup'</dd>
* 	<dt>tridaOptGroupLabel</dt><dd>Třída pro nadpis Oprgroupu. Default 'pseudoselect-optgroup-label'</dd>
* 	<dt>tridaCheckbox</dt><dd>Třída pro checkboxy u multiple selectů. Důležité hlavně pro správné fungování Pseudocheckboxů, jsou-li použity. Default 'pseudoselect-checkbox'.</dd>
*	<dt>optionCheckedMultiple</dt><dd>Pokud jde o multiple select, má se zaškrtlým optionům dávat třída tridaChecked? Default: false</dd>
* 	<dt>viewPattern</dt><dd>Vzoreček pro text, který se má zobrazovat ve View, je-li zvoleno více než viewShowCount položek. Entita %% se nahradí počtem zvolených možností. Lze zadat také array se třemi prvky, první je text použitý pro jednu zvolenou možnost, druhý prvek je text pro 2 až 4 možností, třetí pro 5 a více. Default ["%% vybraná","%% vybrané","%% vybraných"]</dd>
* 	<dt>viewShowCount</dt><dd>Limit, pro kolik zvolených hodnot se již nevypíšou přímo zvolené hodnoty, ale jen shrnutí jejich počtu dle viewPattern. Default 3</dd>
* 	<dt>viewSeparator</dt><dd>Pokud je zvoleno méně než viewShowCount, zobrazí se ve View přímo zvolené možnosti spojené tímto řetězcem. Default ' ,'</dd>
* 	<dt>viewVyzva</dt><dd>Pokud není zvoleno nic (v Multiple selectu) nebo před prvním zvolením a není-li žádný option přímo selected (v non-multiple selectu), zobrazí se ve View tento text... Default 'Nevybráno nic'</dd>
* 	<dt>htmlExpander</dt><dd>HTML obsah zavřeného Expanderu. Default ''</dd>
* 	<dt>htmlExpanderClose</dt><dd>HTML obsah otevřeného expanderu. False = neměnit a nechat obsah dle htmlExpander. Default false</dd>
* 	<dt>multiple</dt><dd>Povolit výběr více možností? True / false = ano / ne. String 'auto' = nastavit podle toho, má-li zdrojový Select atribut 'multiple'. Default 'auto'</dd>
* 	<dt>width</dt><dd>Šířka celého PseudoSelectu. False = nepřizpůsobovat, hodnota se nastaví dle obsahu View nebo dle CSS. String "auto" = přečíst rozměr z CSS a poku dnení (nebo je nulový), nastavit vnější šířku tak, aby byla stejná, jako vnější šířka zdrojového Selectu. Číslo = nastavit tuto vnější šířku. String "+" a nějaké číslo = nastavit vnitřní šířku zvětšenou o toto. Default 'auto'</dd>
* 	<dt>height</dt><dd>Výška Pseudoselectu. Možnosti stejné, jako u width. Default 'auto'</dd>
* 	<dt>clickAll</dt><dd>Boolean určující, zda se má Popup rozbalit/zabalit nejen na kliknutí na Expander, ale i na celý Pseudoselect. Default 'auto'</dd>
* 	<dt>id</dt><dd>ID pro PseudoSelect. String "auto" = použít ID původního Selectu s postfixem "-pseudoselect". Default 'auto'</dd>
* 	<dt>effect</dt><dd>Jméno efektu, s nímž se má zobrazovat a skrývat Popup. Viz JQueryUI efekty. Default 'slide'</dd>
* 	<dt>effectOptions</dt><dd>Další možnosti efektu. Viz dokumentace na webu jQuery. Default {"direction":"up"}</dd>
* 	<dt>effectDuration</dt><dd>Doba, po níž se má animovat Popup, v milisekundách. Default 400</dd>
* 	<dt>position</dt><dd>Pozice Popupu vzhledem k PseudoSelectu (viz JQuery Pozice). Default {"my":"left top","at":"left bottom","offset":"0px 5px"}</dd>
* 	<dt>popupWidth</dt><dd>Boolean, zda zarovnat vnější šířka Popupu s vnější šířkou PseudoCheckboxu? Default true</dd>
* 	<dt>changeViewDuration</dt><dd>False = text ve View okamžitě změnit. Číslo = udělat animovanou změnu s takovou délkou v ms. Default 200</dd>
* 	<dt>maxHeight</dt><dd>Maximální výška Popupu (v px), která když se překročí, zobrazí se posuvník. Default 200</dd>
* 	<dt>checkboxWrap</dt><dd>Mají se jednotlivé checkboxy do něčeho zabalit? HTML snippet viz jQuery funkce wrap(). Default ''</dd>
* 	<dt>pseudoCheckbox</dt><dd>Používat pseudoCheckboxy místo normálních Checkboxů? Zadej objekt s těmito vlastnostmi (viz parametry k PseudoCheckboxu):
*	<ul>
*	<li>tridaNahradu</li><li>tridaChecked</li><li>tridaDisabled</li><li>tridaAnimCheck</li><li>tridaAnimUncheck</li>
*	</ul>
*	trida se doplní automaticky na hodnotu zadanou v tridaCheckbox
* Default null.</dd>
* </dl>
*/

$.fn.pseudoSelect = function(opts) {
	var defaults={
		"tridaExpander":"pseudoselect-expander",
		"tridaMainOpen":"pseudoselect-open",
		"tridaPopup":"pseudoselect-popup",
		"tridaOption":"pseudoselect-option",
		"tridaOptionChecked":"pseudoselect-option-checked",
		"tridaOptionDisabled":"pseudoselect-option-disabled",
		"tridaOptionEnabled":"pseudoselect-option-enabled",
		"tridaMain":"pseudoselect-main",
		"tridaMainMultiple":"pseudoselect-main-multiple",
		"tridaView":"pseudoselect-view",
		"tridaOptGroup":"pseudoselect-optgroup",
		"tridaOptGroupLabel":"pseudoselect-optgroup-label",
		"tridaCheckbox":"pseudoselect-checkbox",
		"optionCheckedMultiple":false,
		"viewPattern":["%% vybraná","%% vybrané","%% vybraných"],
		"viewShowCount":3,
		"viewSeparator":", ",
		"viewVyzva":"Vyberte...",
		"htmlExpander":"",
		"htmlExpanderClose":false,
		"multiple":"auto",
		"width":"auto", //false = nepřizpůsobovat, číslo = nastavit outer, "auto" = změřit originální select, "+číslo" = nastavit inner plus toto číslo
		"height":"auto",
		"clickAll":true, //Reagovat na kliknutí na celý pseudoselect, nejen na Expander?
		"pseudoCheckbox":null, //tridaNahrady, tridaChecked, tridaDisabled, tridaAnimCheck, tridaAnimUncheck
		"checkboxWrap":false,
		"id":"auto",
		"effect":"slide",
		"effectOptions":{"direction":"up"},
		"effectDuration":300,
		"position":{"my":"left top","at":"left bottom","offset":"0px 5px"},
		"popupWidth":true,
		"changeViewDuration":250,
		"maxHeight":200
	};
	opts=$.extend(defaults,opts);

	this.init=function() {
		if (this.length>1) {
			alert("PseudoSelect lze volat jen na jediný element!");
			return;
		}
		if (!this.is("select")) return;
		if (!this.effects || !this.position) {
// 			alert("Pseudoselect nelze vytvořit, chybí jQuery UI - části effects a position");
// 			console.log(this);
// 			return;		
		}
		if (this.data("pseudoSelect.nahrada")) return;
		
		var $el=$("<div></div>");
		var $view=$("<div></div>");
		var $expander=$("<div></div>");
		var $popup=$("<div></div>");
		this.data("pseudoSelect.nahrada",$el);
		
		opts.position.of=$el;
		$el.data("pseudoSelect.opts",opts);

		//Připrav main
		$el.css("display","inline-block");
		$el.addClass(opts.tridaMain);		
		
		//Připrav view
		$view.addClass(opts.tridaView);
		$view.appendTo($el);
		
		//Připrav expander
		$expander.addClass(opts.tridaExpander).html(opts.htmlExpander).appendTo($el);

		//Připrav popup
		$popup.addClass(opts.tridaPopup).appendTo($el).hide();
		
		//Parts
		$el.data("pseudoSelect.parts",{"view":$view,"expander":$expander,"popup":$popup,"orig":this});
		$expander.data("pseudoSelect.main",$el);
		$popup.data("pseudoSelect.main",$el);
		$view.data("pseudoSelect.main",$el);

		//Zruš orig
		this.hide();		

		//id
		if (opts.id=="auto" && this.attr("id")) $el.attr("id",this.attr("id")+"-pseudoselect");
		else if (opts.id && opts.id!="auto") $el.attr("id",opts.id);
		
		//rozměry
		var vratitAttrMultiple=false;
		if ((opts.multiple=="auto" && this.attr("multiple")) || opts.multiple) {
			if (this.attr("multiple")) {
				$el.addClass(opts.tridaMainMultiple);
				this.removeAttr("multiple");
				vratitAttrMultiple=true;
			}
		}		
		
		if (opts.width=="auto") {if (!$el.css("width") || $el.css("width")=="0px") $el.outerWidth(this.outerWidth());}
		else if (opts.width) {
			if (opts.width.substr(0,1)=="+") {
				var w=opts.width.substr(1);
				$el.width(this.width()*1+w*1);
			}
			$el.outerWidth(opts.width);
		}
		if (opts.height=="auto") {if (!$el.css("height") || $el.css("height")=="0px") $el.outerHeight(this.outerHeight());}
		else if (opts.height) {
			if (opts.height.substr(0,1)=="+") {
				var h=opts.height.substr(1);
				$el.height(this.height()*1+h*1);
			}
			$el.outerHeight(opts.height);
		}		
		if (vratitAttrMultiple) {
			this.attr("multiple",true);
		}
		
		var origThis=this;
		//Events
		$expander.click(function(e) {
			origThis.popupSwitch.call(origThis,e);
			e.stopPropagation();
		});
		$view.click(function(e) {
			origThis.popupSwitch.call(origThis,e);
			e.stopPropagation();
		});
		if (opts.clickAll) $el.click(function(e) {
			origThis.popupSwitch.call(origThis,e);
			e.stopPropagation();
		});
		$popup.click(function(e) {
			e.stopPropagation();
		});
		this.change(function(e) {
			origThis.updatePopup.call(origThis,$popup);	
		});

		$el.insertAfter(this);
		
		//Naplň View
		this.fillView($el,true);
		
		//Výzva
		if (opts.viewVyzva && ((opts.multiple=="auto" && this.attr("multiple")) || opts.multiple)) {
			this.prepend($("<option></option>").html(opts.viewVyzva).val("").attr("selected","selected").addClass("invalidable").addClass("forms-select-vyzva"));
		}
	};
	
	this.popupSwitch=function(event) { //Voláno z hlavního kontextu
		var $main=this.data("pseudoSelect.nahrada");
		if (!$main) return;
		var opts=$main.data("pseudoSelect.opts");
		var $popup=$main.data("pseudoSelect.parts").popup;
		var $expander=$main.data("pseudoSelect.parts").expander;
		var origThis=this;
		if ($popup.is(":visible")) {
			$popup.hide(opts.effect,opts.effectOptions,opts.effectDuration);
			$main.removeClass(opts.tridaMainOpen);
			if ($expander.data("pseudoSelect.origHtml")!==false) $expander.html($expander.data("pseudoSelect.origHtml"));
		} else {
			$main.data("pseudoSelect.parts").orig.buildContents.call(this,$main,$popup);
			$popup.show();
			if (opts.popupWidth) {
				$popup.outerWidth($main.outerWidth());
			}
			
			$popup.position(opts.position)
				.hide()
				.show(opts.effect,opts.effectOptions,opts.effectDuration);
				
			$main.addClass(opts.tridaMainOpen);
			if (opts.htmlExpanderClose!==false) {
				$expander.data("pseudoSelect.origHtml",$expander.html())
					.html(opts.htmlExpanderClose);
			}
			
			$(document.body).one("click",function() {
				if ($popup.is(":visible")) {
					origThis.popupSwitch.call(origThis);
				}
			});
		}
	};
	
	this.updatePopup=function($popup) {
		var $th=$(this);
		if (!$th.attr("multiple")) return;
		if (!$popup.is(":visible")) return;
		var vals=$th.val();
		$.each(vals,function(e,r) {
			var $opts=$popup.find("input[type=checkbox]");
			$opts.each(function() {
				var $opt=$(this);
				var val=$opt.val();
				if (vals.indexOf(val)==-1) {
					$opt.removeAttr("checked");
				} else {
					$opt.attr("checked",true);
				}
			});
		});
	};
	
	this.buildContents=function($main,$popup) { //Voláno z hlavního kontextu
		var $orig=$($main.data("pseudoSelect.parts").orig);
		var $children=$orig.children("option:not(.forms-select-vyzva), optgroup");
		var opts=$main.data("pseudoSelect.opts");
		var values=[];
		$popup.html("");
		var firstChecked=null;
		var origThis=this;
		var multiple=(opts.multiple!="auto"?opts.multiple:($orig.attr("multiple")?true:false));
		var selectedNone=(!multiple && ($main.data("pseudoSelect.parts").view.text()==opts.viewVyzva));
		var addValue=function($opt,optgroup) {
			var newObj={"value":$opt.val(),"label":$opt.html()};
			newObj.disabled=$opt.is(":disabled");
			newObj.checked=($opt.is(":selected") && !selectedNone);
			if (optgroup) newObj.optgroup=optgroup;
			values.push(newObj);
		};
		var optgroupsIndex=0;
		$children.each(function() {
			var $th=$(this);
			if ($th.is("option:not(.forms-select-vyzva)")) addValue($th); 
			if ($th.is("optgroup")) {
				var optgroup={"index":optgroupsIndex,"label":$th.attr("label")};
				optgroupsIndex++;
				$th.children("option:not(.forms-select-vyzva)").each(function() {
					addValue($(this),optgroup);
				});
			}
		});
		
		var optgroupElements=[];
		var onlyValues=[];
		var buildOpt=function(val) {
			var $opt=$("<div></div>").addClass(opts.tridaOption);
			if (val.checked && (!multiple || opts.optionCheckedMultiple)) {
				$opt.addClass(opts.tridaOptionChecked);
				if (!firstChecked) firstChecked=$opt;
			}
			if (val.disabled) $opt.addClass(opts.tridaOptionDisabled);
				else $opt.addClass(opts.tridaOptionEnabled);
			$opt.data("pseudoSelect.value",val.value);

			if (multiple) {
				var chkbId="chkb"+Math.floor(Math.random()*8999999+1000000);
				var $chkb=$("<input type='checkbox' id='"+chkbId+"' class='"+opts.tridaCheckbox+"' />");
				$chkb.val(val.value);
				if (val.checked) {
					$chkb.attr("checked",true);
				}
				if (!val.disabled) {
					$chkb.click(function(e) {
						var $th=$(this);
						if ($th.is(":checked") && opts.optionCheckedMultiple) {
							$opt.addClass(opts.tridaOptionChecked);
						} else {
							$opt.removeClass(opts.tridaOptionChecked);
						}
						origThis.clickOptionMultiple.call(origThis,$opt,$main,$popup);
					});
				} else {
					$chkb.attr("disabled",true);
				}
				var $label=$("<label for='"+chkbId+"'></label>").html(val.label);
				$opt.prepend($chkb).append($label);				
				if (opts.checkboxWrap) $chkb.wrap(opts.checkboxWrap);
			} else {
				$opt.html(val.label);			
				if (!val.disabled) {
					$opt.click(function() {
						origThis.clickOption.call(origThis,$(this),$main,$popup);
						return false;
					});
				}			
			}
			return $opt;		
		};
		$.each(values,function(i,val) {
			var $opt=buildOpt(val);
			if (val.optgroup) {
				if (!optgroupElements[val.optgroup.index]) {
					optgroupElements[val.optgroup.index]=$("<div></div>")
						.addClass(opts.tridaOptGroup)
						.append(
							$("<div></div>").addClass(opts.tridaOptGroupLabel).html(val.optgroup.label)
						);
				};
				optgroupElements[val.optgroup.index].append($opt);
			} else {
				onlyValues.push($opt);	
			}
		});
		$.each(optgroupElements,function(i,$el) {
			$popup.append($el);
		});
		$.each(onlyValues,function(i,$opt) {
			$popup.append($opt);	
		});
		
		if (opts.pseudoCheckbox && multiple) {
			window.setTimeout(function() {
				var chkbParams=opts.pseudoCheckbox;
				$popup.find("input[type=checkbox]").pseudoCheckbox(chkbParams);
			},30);
		}
		
		if (opts.maxHeight && $popup.height()>opts.maxHeight) {
			$popup.height(opts.maxHeight).css("overflow","auto");
			//if (firstChecked) $popup.scrollTo(firstChecked); //TODO: scrolling
		}
	};
	
	this.clickOption=function($option,$main,$popup) { //Voláno z hlavního kontextu
		var $orig=$($main.data("pseudoSelect.parts").orig);
		var value=$option.data("pseudoSelect.value");
		this.val(value).change();
		this.fillView($main);
		this.popupSwitch();
	};
	
	this.clickOptionMultiple=function($option,$main,$popup) { //Voláno z hlavního kontextu
		var $orig=$($main.data("pseudoSelect.parts").orig);
		var $checks=$popup.find("input[type=checkbox]:checked");
		var newValues=[];
		$checks.each(function() {
			newValues.push($(this).val());
		});
		this.val(newValues);
		if (newValues.length) this.change();
		this.fillView($main);
	};
	
	this.fillView=function($main,bezAnimace) {
		var $view=$main.data("pseudoSelect.parts").view;
		var $orig=$main.data("pseudoSelect.parts").orig;
		var opts=$main.data("pseudoSelect.opts");
		var text="";
		var multiple=opts.multiple=="auto"?$orig.attr("multiple"):opts.multiple;
		if (!multiple) {			
			var $opt=$orig.find("option:selected:not(.forms-select-vyzva)");
			text=$opt.html();
			if (!$opt.get(0).hasAttribute("selected") && bezAnimace) text=opts.viewVyzva;
		} else {
			var $values=$orig.find("option:selected:not(.forms-select-vyzva)");
			var values=[];
			$values.each(function() {
				values.push($(this).html());
			});
			if (!values) text="";
			else if (values.length && values.length>=opts.viewShowCount) {
				var pattern=opts.viewPattern;
				if (typeof pattern == 'object' && typeof pattern.length != "undefined") {
					if (pattern.length<=2) pattern[2]=pattern[1];
					if (values.length==1) pattern=pattern[0];
					else if (values.length<5) pattern=pattern[1];
					else pattern=pattern[2];
				}
				text=pattern.replace(/%%/g,values.length);
			} else {
				text=values.join(opts.viewSeparator);
			}
			if (!text) text=opts.viewVyzva;
		}
		
		if (text!=$view.html()) {
			var duration=$main.data("pseudoSelect.opts").changeViewDuration;
			if (!bezAnimace && duration) {
				$view.fadeTo(duration,0.01,function() {
					$view.html(text);
				}).fadeTo(duration,1);
			} else {
				$view.html(text);
			}			
		}
	};
	
	this.init();
	return this;
};


/**
* Vytvoří z klasického checkboxu nebo radiobuttonu pseudocheckbox.
* <br />V podstatě jde o &lt;div>, který dostává nějaké třídy.
* <br />Narozdíl od pseudoselect() lze aplikovat i na vícero elementů naráz. Vícenásobná aplikace na jediný element nevadí, proběhne vždy jen jednou.
* <br /><br />Je-li zavoláno na něco jiného, než na checkbox nebo radio, pak se prohledají potomci a pseudocheckbox se aplikuje na ně. Takto lze efektivně proměnit všechny checkboxy v určitém formuláři apod.
* @param opts Objekt s těmito vlastnostmi:
* <dl>
* 	<dt>trida</dt><dd>Třída DIVu nahrazujícího původní checkbox nebo radio (default 'pseudocheckbox')</dd>
* 	<dt>tridaChecked</dt><dd>Třída (přídavná) pro zaškrtnutý pseudocheckbox. Default 'pseudocheckbox-checked'</dd>
* 	<dt>tridaDisabled</dt><dd>Třída (přídavná) pro disabled pseudocheckbox. Default 'pseudocheckbox-disabled'</dd>
* 	<dt>tridaEnabled</dt><dd>Třída (přídavná) pro pseudocheckbox, který není disabled. Vhodné pro nějaké :hover efekty, které by neměly být u disabled prvků. Default 'pseudocheckbox-enabled'</dd>
* 	<dt>tridaAnimCheck</dt><dd>Pole tříd tvořících mezistupně pro animaci při zaškrtnutí. Default []</dd>
* 	<dt>duration</dt><dd>Doba v milisekundách, po kterou se má provádět animace zaškrtnutí/odštrknutí, je-li nějaká. Default 300.</dd>
* 	<dt>width</dt><dd>Rozměry pseudocheckboxu. Možno zadat číslo (= vnější rozměr), false (= nenastavovat a nechat to na CSS) nebo "auto" (= pokud je nastaveno CSS, respektovat to, jinak použít rozměr původního checkboxu). Default "auto"</dd>
* 	<dt>height</dt><dd>Totéž jako width, ale týká se výšky.</dd>
* </dl>
*/
$.fn.pseudoCheckbox=function(opts) {
	var defaults={
		"trida":"pseudocheckbox",
		"tridaChecked":"pseudocheckbox-checked",
		"tridaDisabled":"pseudocheckbox-disabled",
		"tridaEnabled":"pseudocheckbox-enabled",		
		"tridaAnimCheck":[],
		"tridaAnimUncheck":false,
		"duration":300,
		"width":"auto",
		"height":"auto"
	};
		
	opts=$.extend(defaults,opts);
	this.each(function() {
		var $th=$(this);
		
		if (!$th.is("*[type=checkbox], *[type=radio]")) {
			$th.find("input[type=checkbox], input[type=radio]").pseudoCheckbox(opts);
			return this;
		}
		
		if ($th.data("pseudocheckbox")) return;
		
		var $chkb=$("<div></div>").css("display","inline-block").addClass(opts.trida);
		if (opts.width=="auto") {
			if (!$chkb.css("width") || $chkb.css("width")=="0px") $chkb.outerWidth($th.outerWidth());
		}
		else if (opts.width!==false) $chkb.outerWidth(opts.width);
		if (opts.height=="auto") {
			if (!$chkb.css("height") || $chkb.css("height")=="0px") $chkb.outerHeight($th.outerHeight());
		}
		else if (opts.height!==false) $chkb.outerHeight(opts.height);
		
		$chkb.data("pseudocheckbox.stav",$th.is(":checked"));
		$th.data("pseudocheckbox",$chkb);
		
		$th.hide();
		$th.after($chkb);
		
		this.updateDiv=function(bezAnimace,$coUpdatovat) {
			var $orig;
			if (!$coUpdatovat) {
				$orig=$th;
			} else {
				$orig=$coUpdatovat;
			}
			var $chkb=$orig.data("pseudocheckbox");
			
			var disabled=$orig.is(":disabled");
			var checked=$orig.is(":checked");	
			if (disabled) {
				$chkb.addClass(opts.tridaDisabled);
				$chkb.removeClass(opts.tridaEnabled);
				if (checked) $chkb.addClass(opts.tridaDisabled);
			} else {
				$chkb.removeClass(opts.tridaDisabled);
				$chkb.addClass(opts.tridaEnabled);				
				if (opts.tridaAnimCheck && opts.tridaAnimCheck.length && !bezAnimace) {
					var chkbChecked=$chkb.data("pseudocheckbox.stav");				
					var animStates=[];
					if (chkbChecked && !checked) { //animate uncheck
						animStates=opts.tridaAnimUncheck.slice?opts.tridaAnimUncheck.slice():false;
						if (!opts.tridaAnimUncheck) {
							animStates=opts.tridaAnimCheck.slice();
							animStates.reverse();
						}
						animStates=[opts.tridaChecked].concat(animStates);
						animStates.push("");
					}
					if (!chkbChecked && checked) { //animate check
						animStates=[""].concat(opts.tridaAnimCheck.slice());
						animStates.push(opts.tridaChecked);						
					}
					if (animStates.length) {
						var animStep=opts.duration/(animStates.length-1);
						var y=1;
						for (var i=1;i<animStates.length;i++) {
							window.setTimeout(function() {
								$chkb.removeClass(animStates[y-1]);
								$chkb.addClass(animStates[y]);
								y++;
							},(i-1)*animStep);
						}
					}
				} else {
					if (checked) $chkb.addClass(opts.tridaChecked);
					else $chkb.removeClass(opts.tridaChecked);
				}
				$chkb.data("pseudocheckbox.stav",checked);
			}
		};
		
		this.updateDiv(true);
		var $origThis=this;
		
		if ($th.is("*[type=checkbox]")) {
			$th.change(function() {
				$origThis.updateDiv(false);
			});
			$chkb.click(function() {
				$th.click();
			});
		} else {
			$chkb.click(function() {
				$th.click();
			});
// 			$th.change(function() {
// 				$origThis.updateDiv(false);
// 			});
			$th.change(function() {
				var $ostatni=$th.closest("form, body").find("input[type=radio][name="+($th.attr("name"))+"]");
				if ($ostatni.length) $ostatni=$th.closest("form, body").find("input[type=radio]");
				$ostatni.each(function() {
					$origThis.updateDiv(false,$(this));
				});
			});
		}
	});
	
	return this;
};

/*
function animatoFormsInitCheckbox(trida,tridaNahrady,tridaCheck,tridaDisabled,tridaAnimCheck,tridaAnimUncheck) {
	$(function() {
		$("."+trida).each(function() {
			var $th=$(this);
			if ($th.data("animatoCheckboxNahrada")) return;
			var $nahrada=$("<div class='"+tridaNahrady+"' />");
			if ($th.is(":checked")) $nahrada.addClass(tridaCheck);
			if ($th.is(":disabled")) $nahrada.addClass(tridaDisabled);
			$th.addClass("forms-checkbox-orig-overlaid");
			$th.after($nahrada);
			var pos=$th.position();
			$nahrada.css({"position":"absolute","left":pos.left+parseInt($nahrada.css("left")),"top":pos.top+parseInt($nahrada.css("top"))});
			$nahrada.data("animatoCheckbox",$th.is(":checked"));
			$th.data("animatoCheckboxNahrada",$nahrada);
			$nahrada.data("animatoCheckboxOrig",$th);

			$th.click(function() {
				if (!$th.data("animatoCheckboxClicked")) {
					animatoFormsCheckboxClick($th,trida,tridaCheck,tridaAnimCheck,tridaAnimUncheck,true);
				}
			});
			
			$nahrada.click(function() {
				var $th=$(this);
				var $orig=$th.data("animatoCheckboxOrig");
				if ($orig.is(":disabled")) return;
				if (!$orig || !$orig.length) return;
				animatoFormsCheckboxClick($orig,trida,tridaCheck,tridaAnimCheck,tridaAnimUncheck,false);				
			});
		});
	});
}

function animatoFormsCheckboxClick($orig,tridaOrig,tridaCheck,tridaAnimCheck,tridaAnimUncheck,kliknutoNaOrig) {
	var rychlostAnimace=50;
	if (!kliknutoNaOrig) {
		$orig.data("animatoCheckboxClicked",true);
		$orig.click();
		$orig.data("animatoCheckboxClicked",false);
	}
	$("."+tridaOrig).each(function() {
		var $th=$(this);
		var $nahrada=$th.data("animatoCheckboxNahrada");
		if (!$nahrada || !$nahrada.length) return;
		var wasChecked=$nahrada.data("animatoCheckbox");
		var isChecked=$th.is(":checked");
		if (wasChecked!=isChecked) {
			var cisloAnimace=Math.round(Math.random()*1000);
			$nahrada.data("animatoCheckboxAnimace",cisloAnimace);
			if (tridaAnimCheck) $nahrada.removeClass(tridaAnimCheck.join(" "));
			if (tridaAnimUncheck) $nahrada.removeClass(tridaAnimUncheck.join(" "));
			if (isChecked) {
				if (tridaAnimCheck) {
					var serie=[];
					serie=serie.concat(tridaAnimCheck);
					var $chk=$nahrada;
					serie.push(tridaCheck);
					for (var i=0;i<serie.length;i++) {
						var pocitadloI=0;
						window.setTimeout(function() {
							var i=pocitadloI;
							if (cisloAnimace!=$chk.data("animatoCheckboxAnimace")) return;
							if (i) {$chk.removeClass(serie[i-1]);}
							$chk.addClass(serie[i]);
							pocitadloI++;
						},(i+1)*rychlostAnimace);
					}
				} else {
					$nahrada.addClass(tridaCheck);
				}
				$nahrada.data("animatoCheckbox",true);
			} else { // !isChecked
				if (tridaAnimCheck) {
					var serie=[];
					serie.push(tridaCheck);
					serie=serie.concat(tridaAnimUncheck);
					var $chk=$nahrada;
					for (var i=1;i<=serie.length;i++) {
						var pocitadloI=1;
						window.setTimeout(function() {
							var i=pocitadloI;
							if (cisloAnimace!=$chk.data("animatoCheckboxAnimace")) return;
							$chk.removeClass(serie[i-1]);
							if (i!=serie.length) $chk.addClass(serie[i]);
							pocitadloI++;
						},(i)*rychlostAnimace);
					}
				} else {
					$nahrada.removeClass(tridaCheck);
				}
				$nahrada.data("animatoCheckbox",false);
			}
		}
	});
}
*/
