/*

gute funcs von prototype.js:

array.uniq(); //macht das mit array, was unique mit objekten macht
anything.inspect(); //liefert debug string zurück



INFO: mod für in original-jquery:

  // Get width or height on the element
	//(this.length ? jQuery.css( this[0], type ) : null) :

	//FLO MOD: add padding to width/height
	(this.length ? jQuery.css(this[0],type)+ (type=="height"?parseInt(this.css("padding-top"))+parseInt(this.css("padding-bottom")):parseInt(this.css("padding-left"))+parseInt(this.css("padding-right"))) : null) :

*/

//+++ General ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//General Object Extension 
Object.extend = function(destination, source){
  for (var property in source)
    destination[property] = source[property];
  return destination;
};

//Name Space
var JQXT = {}; //globale var wg. namespace. "JQXT = JQuery Extension"
//TODO: geht nicht $ zu benutzen, d.h. z.B. $.createDiv();?



//+++ $-Funcs  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//RegEx in verbindung von classnames handling
//wie $() func, aber man ruft auf $RE("*teilstring"). eralubte params sind
// ^needle: starts with
// $needle: ends with
// *needle: contains
//2do: evtl. erweiter auch für hasClass("*teilstring") und removeClass("*teilstring")
function $RE(regClass,context){
	var classStr = regClass.substr(1,regClass.length-1);
	context =  context || document;

	if      (regClass.indexOf("^")!=-1) return $("*[@class^='"+classStr+"'],*[@class*=' "+classStr+"']",context);
	else if (regClass.indexOf("$")!=-1) return $("*[@class$='"+classStr+"'],*[@class*='"+classStr+" ']",context);
	else if (regClass.indexOf("*")!=-1) return $("*[@class*='"+classStr+"']",context);

}

//wie $, findet aber selector angewendet auf -scope childs und -scope selbst
function $Self(selector,scope){
	return $(selector,scope).add(scope.filter(selector));
	//return scope.find("*").andSelf().filter(selector); //alternativ, gleiches ergebnis
}


//+++ Div Handling ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//erzeugt div am ende von body
JQXT.createDiv = function(id,html,optCSS){
  html = html || "";

  var defaultCSS = { 
  	display:"none",
  	position:"absolute"
  };
  var css = $.extend({}, defaultCSS, optCSS || {});
  
  var div = $("<div />").appendTo("body").attr({id:id}).css(css).html(html);
  return div;
}

//returnt index des siblings, VOR/ÜBER dem die maus ist (wenn maus NACH letztem: index=siblingsLength)
JQXT.mouseOverObj = function(x,y,siblings){
	var mouseBeforeId = 0;
	var siblingsLength = siblings.length;

	//maus NACH letztem?
	var obj = $(siblings).filter(":last");
	if ( (x>obj.left()+obj.width() && y>=obj.top()) || (y>obj.top()+obj.height() && x>=obj.left()) ) mouseBeforeId = siblingsLength;

	for(var i = 0;i<siblingsLength;i++){
		obj = $(siblings[i]);

  	//maus ÜBER diesem
  	if(x>=obj.left() && x<=obj.left()+obj.width() && y>=obj.top() && y <=obj.top()+obj.height()){
  		mouseBeforeId = i;
  		break;
  	}
  	//maus NACH diesem
    else if( (x>obj.left()+obj.width() && y>=obj.top()) || (y>obj.top()+obj.height() && x>obj.left())){
    	mouseBeforeId = i+1;
    }
	}

  return mouseBeforeId;
}


//+++ String ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Object.extend(String.prototype, {

  stripScripts: function(){
    return this.replace(new RegExp('<\s*script[^>]*>([\\S\\s]*?)<\/\s*script[^>]*>', 'img'), '');
  },

  stripTags: function(){
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  truncate: function(length, truncation){
    length = length || 30;
    truncation = truncation === undefined ? '...' : truncation;
    return this.length > length ? this.slice(0, length - truncation.length) + truncation : String(this);
  },

  nl2br: function(){
  	//wandel input-zeilenumbruch in html zeilenumbruch
  	//wandel <br><br> in <br>&nbsp;<br> damit leere zeile im html angezeigt wird
    return this.replace(/(\r\n)|(\n\r)|\r|\n/g,"<br />").replace(/<br \/><br \/>/g,"<br />&nbsp;<br />");
  },

  nl2space: function(){
  	//wandel input-zeilenumbruch in leerzeichen (für single line inputs)
    return this.replace(/(\r\n)|(\n\r)|\r|\n/g," ");
  },

  br2nl: function(){
    return this.replace(/<br \/>/g,"\n").replace(/<br>/g,"\n");
  },
  
  space2Nbsp: function(){
  	//wandel doppel-space in zwei &nbsp;
    return this.repl("  ","&nbsp;&nbsp;");
  },

  nbsp2Space: function(){
    return this.repl("&nbsp;"," ");
  },

  //wie replace, aber es wird string übergeben statt regEx
  //2do: wenn oldVal = "[wort]" ist, dann gibts fehler, weil [ und ] als regex interpretiert wird
  repl: function(oldVal,newVal){
  	return this.replace(new RegExp(oldVal,"g"), newVal);
  },
  
  //wandlung von eingaben aus textfeld für html darstellung
  inputToHtml: function(){
  	return escapeHtml(this.nl2br().space2Nbsp());
  },

  //wandlung von html für textfeld eingabe
  htmlToInput: function(){
    return unescapeHtml(this.br2nl().nbsp2Space());
  }
  
});

//TODO: diese funktion geht NICHT, wenn sie im string.prototype sitzt (wg. kontext?)
function escapeHtml(str){
  	return $("<div></div>").text(str).text();
}

function unescapeHtml(str){
  	return str;
  	//TODO!
}

//diese handelt scrollTop/ScrollLeft für die seite (wegenunterschiede $("body").scrollTop(), $("html").scrollTop(), $(document).scrollTop(), $(window).scrollTop
function windowScrollTop(val){
	if(val)	return $("html,body").scrollTop(val);
	else {
		var doc = document.documentElement
		var body = document.body;
  	return doc && doc.scrollTop || body && body.scrollTop || 0;
	}
}

function windowScrollLeft(val){
	if(val)	return $("html,body").scrollLeft(val);
	else {
		var doc = document.documentElement
		var body = document.body;
  	return doc && doc.scrollLeft || body && body.scrollLeft || 0;
	}
}

//+++ jQuery Obj Extension ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
jQuery.fn.extend({


  // prüft, ob obj in containerObj sitzt (oder selbst containerObj ist).
  // dabei kann containerObj mehrere objekte sein
  isChildOf: function(parentObj,isSelf){ 
  	isSelf = isSelf===undefined? true : isSelf;
  	var parentObjs = isSelf? this.parents().andSelf() : this.parents();
  	parentObj = $(parentObj);
  	
  	return parentObjs.filter(function(){
  	  var isParent = false;
  	  var iteratedParentObj = this;
  	  parentObj.each(function(){
  	    if(this==iteratedParentObj) isParent=true;
  	  });
  	  return isParent;
  	}).length != 0;
  },

	/*
  // prüft, ob obj in parentObj sitzt 
  // zus. flag "isSelf"(default=true): oder ob obj selbst parentObj ist
  // dabei kann parentObj mehrere objekte sein
  
  //TODO: diese func geht nicht, wenn parentObj jQuery Obj sind, da der vergleich filter(JObj)/parents(jObj) nicht funzt)
  isChildOf: function(parentObj,isSelf){
  	isSelf = isSelf===undefined? true : isSelf;
  	
  	if (isSelf) 	return this.parents(parentObj).length!=0 || this.filter(parentObj).length!=0;
  	else 					return this.parents(parentObj).length!=0;

  },
  */

	unwrap: function(expr){
  	return this.each(function(){
    	$(this).parents(expr).eq(0).after(this).remove();
  	});
	},

  //sleep function: waits x millisecs. works as animation (with queue). wenn andere function ausgeführt werden soll benutze den callback
  sleep: function(speed,callback){
  	//make blank animation, animation of rare used param without any changes
  	return this.animate({"line-height":this.css("line-height")},speed,callback);
  },

	//lies teilstirng aus class, die mit prefix beginnt(prefix enthält)
	//beispiel: findet MEINEID per getIdFromClass($(),"needle") aus <div class="text gross needleMEINEID">
	getIdFromClass: function(prefix){
		//2do: wie begrenze ich, dass nur vom ersten returnt wird (falls objekte.length>1 übergeben: da string returnt macht mehr als ein string keinen sinn)
  	var ret = "";
   	if(this.attr("className")){ //error handling
    	$.each(this.attr("className").split(/\s+/), function(){
   	  	var regex = new RegExp(prefix,"g");
       	if(this.indexOf(prefix)!=-1) ret = this.replace(regex, "");
     	});
   	}
   	return ret;
	},

	//hängt obj in body (append) und macht display:none (soz. ausgelagert)
	storeDiv: function(){
	  return this.appendTo("body").css({display:"none"});
	},

  //hide div und danach stored es unsichtbar
  removeOpticalAni: function(speed,callback){
  	var obj = this;
  	this.slideUp(speed,function(){
  		obj.storeDiv();
  		if(callback) callback.call();
  	});
  	return obj;
  },

  //hide div und entfernt es dann komplett
  removeAni: function(speed,callback){
  	var obj = this;
  	this.slideUp(speed,function(){
  		obj.remove();
  		if(callback) callback.call();
  	});
  	return obj;
  },

  //ersetzt class durch andere class (neue class bekommt nur der, der alte class hatte!)
	//"switchClass" gibt es in UI, deswegen anderes naming
	switchClassF: function(oldClass,newClass){
		this.filter("."+oldClass).removeClass(oldClass).addClass(newClass);
		return this;
  },

  //ersetzt einen teil aus src="..." mit neuem string (für img-rollover)
  //val kann string oder regExp sein.
  //2do: wenn val=string -> behandel als string, sonst als regExp
  switchSrc: function(val,newVal){
  	if(typeof val == "string") val = new RegExp(val);
    return this.attr("src", function(){return this.src.replace(val, newVal);} );
	},

  //ersetzt einen teil aus href="..." mit neuem string
  //val kann string oder regExp sein.
  //2do: wenn val=string -> behandel als string, sonst als regExp
  switchHref: function(val,newVal){
  	if(typeof val == "string") val = new RegExp(val);
    return this.attr("href", function(){return this.href.replace(val, newVal);} );
	},

	//wie stop, aber danach wird NICHTS ausgeführt (schreibt man kommentar in die nächste zeile, gibt es fehler im IE!!!!)????
  stopp: function(){
    return(this.queue([]).stop());
  },

  outerHtml: function(){
    return $( $('<div></div>').html(this.clone())).html();
  } ,

  //wie fadeIn, aber geeignet für fade Toggling (z.b. item faded-out und während fading soll er wieder einfaden)
  toggleFadeIn: function(speed, callback){
  	//methode 1: faded von 0-100
  	return this.stopp().hide().opacity(1).fadeIn(speed,callback); //opacity = ziel-opacity!

  	//methode 2: faded von IST-100
  	//return this.stopp().show().fadeTo(speed,1,callback);
  },
  
  toggleFadeOut: function(speed, callback){
  	//methode 1: faded von 100-0
  	return this.stopp().show().opacity(1).fadeOut(speed,callback); //opacity = ziel-opacity!

  	//methode 2: faded von IST-0
  	//return this.stopp().show().fadeTo(speed,0,callback);
  },

  //wie slideDown, aber geeignet für fade Toggling (z.b. item slide down und während sliding soll er wieder einfaden)
  //TODO: diese func ist noch billig umgesetzt. die origHeight sollte aus objekt gelesen werden (beim ersten aml wo slide passiert)
  //TODO: ausserdem sollten alle animations-arten als eine func umgesetzt werden (toggleFadeIn, toggleSlidedown usw. als toggleFXIn("slide",speed,callback) und toggleFXOut(...))
  toggleSlideDown: function(speed, origHeight, callback){
  	//methode 1: slided von 0-100
  	return this.stopp().hide().css("height",origHeight).slideDown(speed,callback);

  	//methode 2: faded von IST-100
  	//return this.stopp().show().fadeTo(speed,1,callback);
  },
  
  //TODO: diese func ist noch billig umgesetzt. die origHeight sollte aus objekt gelesen werden (beim ersten aml wo slide passiert)
  toggleSlideUp: function(speed, origHeight, callback){
  	//methode 1: slided von 100-0
  	return this.stopp().show().css("height",origHeight).slideUp(speed,callback); 

  	//methode 2: faded von IST-0
  	//return this.stopp().show().fadeTo(speed,0,callback);
  },

  
  /*
  2do: besser lösen als:
  
  call als:
  toggleFadeIn(300)
  toggleFadeIn(300,callback)
  toggleFadeIn(300,{start:true,sleep:300},callback)
  
  toggleFadeIn(speed,par1,par2)
    if(typeof par1=="function") var callback = par1;
    else var opt = par1;
    
    var sleep = 0;
    if(opt){
      if(opt.sleep) sleep = opt.sleep;
      if(opt.start) var startFromCurrent = opt.start;
    }
    
    if(startFromCurrent) this.stopp().sleep(sleep).show().fadeTo(speed,1,callback);
    else return this.stopp().hide().opacity(1).sleep(sleep).fadeIn(speed,callback);
  
    //fadeOut analog:
    //if(startFromCurrent) return this.stopp().sleep(sleep).show().fadeTo(speed,0,callback);
    //else return this.stopp().sleep(sleep).fadeOut(speed,callback);
    
  */
  //fadeIn/Out mit sleep davor  
  toggleFadeInS: function(speed, callback){
  	//methode 1: faded von 0-100
  	return this.stopp().hide().opacity(1).sleep(100).fadeIn(speed,callback); //opacity = ziel-opacity!

  	//methode 2: faded von IST-100
  	//return this.stopp().show().fadeTo(speed,1,callback);
  },
  
  toggleFadeOutS: function(speed, callback){
  	//methode 1: faded von 100-0
  	return this.stopp().sleep(100).fadeOut(speed,callback); //opacity = ziel-opacity!

  	//methode 2: faded von IST-0
  	//return this.stopp().show().fadeTo(speed,0,callback);
  },

  opacity: function(val){
  	if(val || val===0){return this.css({"opacity":val});}
    else return this.css("opacity");
  },

  cloneAsForm: function(obj,opt){
  	opt = opt || {};
    this.clonePos(obj).css({
      fontSize:obj.css("fontSize"),
      color:obj.css("color"),
      fontWeight:obj.css("font-weight"),
      fontFamily:obj.css("font-family"),
      textAlign:obj.css("text-align"),
      lineHeight:obj.css("line-height"),
      fontStyle:obj.css("font-style"),
      textDecoration:obj.css("text-decoration"),
      width:obj.innerWidth()+parseInt(obj.css("padding-left"))+parseInt(obj.css("padding-right")),
      height:obj.innerHeight()+parseInt(obj.css("padding-top"))+parseInt(obj.css("padding-bottom"))+(this.get(0).tagName=="TEXTAREA"?15:0),
      padding:obj.css("padding")
    });

  	return this;
  },

  //windowFixed (default: false): objekt wird im fenster an der position angezeigt (für css:fixed)
  clonePos: function(obj,opts){
  	opts = opts || {};
  	var windowFixed = opts.windowFixed===undefined? false : opts.windowFixed;
  	var xOff = opts.xOff || 0;
  	var yOff = opts.yOff || 0;

  	if(windowFixed) {
    	this.css({
      	left:obj.offset().left-$(window).scrollLeft()+xOff,
      	top:obj.offset().top-$(window).scrollTop()+yOff
    	});
  	} else {
    	this.css({
      	left:obj.offset().left+xOff,
      	top:obj.offset().top+yOff
    	});
    }
    return this;
  },

  cloneDim: function(obj,opts){
  	opts = opts || {};
  	var offWidth = opts.offWidth || 0;
  	var offHeight = opts.offHeight || 0;
    this.css({
      width:obj.totalWidth()+offWidth, //war innerHeight
      height:obj.totalHeight()+offHeight
    });
    return this;
  },

  left: function(xPos){
    if(xPos==undefined) return this.offset().left;
    else {
      this.css({left:xPos+"px"});
      return this;
    }
  },

  top: function(yPos){
    if(yPos==undefined) return this.offset().top;
    else {
      this.css({top:yPos+"px"});
      return this;
    }
  },

  moveLeft: function(x){
    return this.css({left:this.left()+x});
  },

  moveTop: function(y){
    return this.css({top:this.top()+y});
  },


  //geht auch für display:none objekte
  // set: macht, dass height + padding + border = wert
  // get: return height incl. padding + border
  totalHeight: function(newHeight){
  	var padTop = parseInt(this.css("padding-top"));
  	var padBot = parseInt(this.css("padding-bottom"));
  	var borTop = parseInt(this.css("borderTopWidth")); //schreibweise wichtig (einzig richtige!)
  	var borBot = parseInt(this.css("borderBottomWidth")); //schreibweise wichtig (einzig richtige!)

    if (newHeight==undefined) return this.height() + padTop + padBot + borTop + borBot;
    else return this.height(newHeight - padTop - padBot - borTop - borBot);
  },

  totalWidth: function(newWidth){
  	var padLeft = parseInt(this.css("padding-left"));
  	var padRight = parseInt(this.css("padding-right"));
  	var borLeft = parseInt(this.css("borderLeftWidth")); //schreibweise wichtig (einzig richtige!)
  	var borRight = parseInt(this.css("borderRightWidth")); //schreibweise wichtig (einzig richtige!)

    if(newWidth==undefined) return this.width() + padLeft + padRight + borLeft + borRight;
    else return this.width(newWidth - padLeft - padRight - borLeft - borRight);
  },


  cloneWidth: function(obj,xOff){
  	xOff = xOff || 0;
    return this.totalWidth(obj.totalWidth() + xOff);
  },

  cloneHeight: function(obj,yOff){
  	yOff = yOff || 0;
    return this.totalHeight(obj.totalHeight() + yOff);
  },

  //call like:
  //  setPosTo($(obj), "CENTERX");
  //  setPosTo($(obj), "CENTERX", ["BOTTOMI",-200]);
  //  setPosTo($(obj), ["CENTERX",150], "BOTTOMI");
  //  setPosTo($(obj), ["CENTER",150,200]); //order: xOffset,yOffset
  
  // wenn man called:
  //  setPosTo($(window), "CENTER"); wird es zentriert auf viewport, sichtbar in der mitte egal wo gecrollt ist
  //  setPosTo($(document), "CENTER"); wird es zentriert auf document, in der mitte, also evtl. ausserhalb des viewports
  setPosTo: function(obj, mode1, mode2){
  	isWindowOrDocument = (obj.get(0)==window || obj.get(0)==document);
  	
    var xOffset=0;
    var yOffset=0;

    var xScrollOff = 0;
    var yScrollOff = 0;

    var thisHeight = this.totalHeight();
    var thisWidth = this.totalWidth();

		// wegen relativem positionieren: offset des parents von this berechnen
		var bckpOpac = this.css("opacity");
		var bckpDisplay = this.css("display");
		if(bckpDisplay=="none") this.css({opacity:0,display:"block"}); //show (invisble)
    var thisParentOffsetX = this.left() - parseFloat(this.css("left"));
    var thisParentOffsetY = this.top() - parseFloat(this.css("top"));
    if(bckpDisplay=="none") this.css({opacity:bckpOpac,display:bckpDisplay});

    if(isWindowOrDocument){
	    var objLeft = 0; //2do: kann bei document auch anders sein.
  	  var objTop = 0;
    	var objHeight = obj.height();
    	var objWidth = obj.width();
			
	    xScrollOff = obj.scrollLeft();
  	  yScrollOff = obj.scrollTop();
			
  	} else {
	    var objLeft = obj.left();
  	  var objTop = obj.top();
    	var objHeight = obj.totalHeight();
    	var objWidth = obj.totalWidth();
  	}
  	
    for(var i=1;i<=(mode2?2:1);i++){
      param = eval("mode"+i);
      if(typeof param=="object"){
        mode = param[0];
        if(param.length==2){
        	if(mode=="LEFT"||mode=="LEFTI"||mode=="RIGHT"||mode=="RIGHTI"||mode=="CENTERX"||mode=="CENTER"){
        		xOffset = param[1] - thisParentOffsetX + xScrollOff; 
        	} else if(mode=="TOP"||mode=="TOPI"||mode=="BOTTOM"||mode=="BOTTOMI"||mode=="CENTERY"){
        		yOffset = param[1] - thisParentOffsetY + yScrollOff;
        	}
        } else if(param.length>2 && mode=="CENTER"){
       		xOffset = param[1] - thisParentOffsetX + xScrollOff;
       		yOffset = param[2] - thisParentOffsetY + yScrollOff;
        }
      }
      else if(typeof param=="string"){
      	mode = param;
     		xOffset = -thisParentOffsetX + xScrollOff;
     		yOffset = -thisParentOffsetY + yScrollOff;
      }

      mode = mode || "CENTER";
      //positionieren
      if(mode=="CENTER"){
      	this.left(objLeft + Math.round((objWidth - thisWidth)/2) + xOffset);
        this.top(objTop + Math.round((objHeight - thisHeight)/2) + yOffset);
      }
      else if(mode=="CENTERVISIBLE"){

      	//wenn obj ein div ist und größer als viewport: setze "this" an optisches center im obj innerhalb des viewports
      	if(!isWindowOrDocument){
	    		var objHeightOff = 0;
	    		var objWidthOff = 0;
	    		var win = $(window);
	    		var leftScroll = win.scrollLeft();
  	  		var topScroll = win.scrollTop();
      		var viewportHeight = win.height();
      		var viewportWidth = win.width();
      		
      		//obj ende ausserhalb viewport
      		if(objTop+objHeight > topScroll+viewportHeight) objHeightOff += (topScroll+viewportHeight)-(objTop+objHeight);
					
					//obj anfang ausserhalb viewport
      		if(objTop < topScroll) objHeightOff += objTop-topScroll;
      		
      		//obj rechts ausserhalb viewport
      		if(objLeft+objWidth > leftScroll+viewportWidth) objWidthOff += (leftScroll+viewportWidth)-(objLeft+objWidth);
					
					//obj links ausserhalb viewport
      		if(objLeft < leftScroll) objWidthOff += objLeft-leftScroll;

					//breite/höhe wird entsprechend viewport korrigiert
      		objWidth += objWidthOff; 
      		objHeight += objHeightOff;
				}

      	this.left(objLeft + Math.round((objWidth - thisWidth)/2) + xOffset);
        this.top(objTop + Math.round((objHeight - thisHeight)/2) + yOffset);
      }
      else if(mode=="CENTERX") 	this.left(objLeft + Math.round((objWidth - thisWidth)/2) + xOffset);
      else if(mode=="CENTERY") 	this.top(objTop + Math.round((objHeight - thisHeight)/2) + yOffset);
      else if(mode=="LEFT") 		this.left(objLeft - thisWidth + xOffset); //OUTER
      else if(mode=="LEFTI") 		this.left(objLeft + xOffset); //INNER
      else if(mode=="TOP") 			this.top(objTop - thisHeight + yOffset);
      else if(mode=="TOPI") 		this.top(objTop + yOffset);
      else if(mode=="RIGHT") 		this.left(objLeft + objWidth + xOffset);
      else if(mode=="RIGHTI") 	this.left(objLeft + objWidth - thisWidth + xOffset);
      else if(mode=="BOTTOM") 	this.top(objTop + objHeight + yOffset);
      else if(mode=="BOTTOMI") 	this.top(objTop + objHeight - thisHeight + yOffset);
    }
    
    return this;
  },

	isInViewport: function(){
 		var win = $(window);
 		var leftScroll = win.scrollLeft();
 		var topScroll = win.scrollTop();
 		var viewportHeight = win.height();
 		var viewportWidth = win.width();
 		
 		var objLeft = this.left();
 		var objRight = objLeft + this.totalWidth();
 		var objTop = this.top();
 		var objBot = objTop + this.totalHeight();
		
		//flags: -1: kleiner als viewport, 0:im viewport, 1: größer	als viewport
		var leftXFlag = objLeft<leftScroll ? -1 : objLeft>=leftScroll+viewportWidth ? 1 : 0;
		var rightXFlag = objRight<leftScroll ? -1 : objRight>=leftScroll+viewportWidth ? 1 : 0;
		var topYFlag = objTop<topScroll ? -1 : objTop>=topScroll+viewportHeight ? 1 : 0;
		var botYFlag = objBot<topScroll ? -1 : objBot>=topScroll+viewportHeight ? 1 : 0;
		
		//es werden 4 flags returnt (für jede seite des zu prüfenden objekts. 
		//(ausserdem wird noch die viewport breite/höhe returnt, da man diese oft braucht in verbindung mit isInViewport)
 		return {xLeft:leftXFlag,xRight:rightXFlag,yTop:topYFlag,yBot:botYFlag,viewportHeight:viewportHeight,viewportWidth:viewportWidth};
	}


});


/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};
