docs: function() {
  		
  		var	self = this,
  			$target = self._$origin,
  			originIsArea = self._$origin.is('area');
  		
  		// if this._$origin is a map area, the target we'll need
  		// the dimensions of is actually the image using the map,
  		// not the area itself
  		if (originIsArea) {
  			
  			var mapName = self._$origin.parent().attr('name');
  			
  			$target = $('img[usemap="#'+ mapName +'"]');
  		}
  		
  		var bcr = $target[0].getBoundingClientRect(),
  			$document = $(env.window.document),
  			$window = $(env.window),
  			$parent = $target,
  			// some useful properties of important elements
  			geo = {
  				// available space for the tooltip, see down below
  				available: {
  					document: null,
  					window: null
  				},
  				document: {
  					size: {
  						height: $document.height(),
  						width: $document.width()
  					}
  				},
  				window: {
  					scroll: {
  						// the second ones are for IE compatibility
  						left: env.window.scrollX || env.window.document.documentElement.scrollLeft,
  						top: env.window.scrollY || env.window.document.documentElement.scrollTop
  					},
  					size: {
  						height: $window.height(),
  						width: $window.width()
  					}
  				},
  				origin: {
  					// the origin has a fixed lineage if itself or one of its
  					// ancestors has a fixed position
  					fixedLineage: false,
  					// relative to the document
  					offset: {},
  					size: {
  						height: bcr.bottom - bcr.top,
  						width: bcr.right - bcr.left
  					},
  					usemapImage: originIsArea ? $target[0] : null,
  					// relative to the window
  					windowOffset: {
  						bottom: bcr.bottom,
  						left: bcr.left,
  						right: bcr.right,
  						top: bcr.top
  					}
  				}
  			},
  			geoFixed = false;
  		
  		// if the element is a map area, some properties may need
  		// to be recalculated
  		if (originIsArea) {
  			
  			var shape = self._$origin.attr('shape'),
  				coords = self._$origin.attr('coords');
  			
  			if (coords) {
  				
  				coords = coords.split(',');
  				
  				$.map(coords, function(val, i) {
  					coords[i] = parseInt(val);
  				});
  			}
  			
  			// if the image itself is the area, nothing more to do
  			if (shape != 'default') {
  				
  				switch(shape) {
  					
  					case 'circle':
  						
  						var circleCenterLeft = coords[0],
  							circleCenterTop = coords[1],
  							circleRadius = coords[2],
  							areaTopOffset = circleCenterTop - circleRadius,
  							areaLeftOffset = circleCenterLeft - circleRadius;
  						
  						geo.origin.size.height = circleRadius * 2;
  						geo.origin.size.width = geo.origin.size.height;
  						
  						geo.origin.windowOffset.left += areaLeftOffset;
  						geo.origin.windowOffset.top += areaTopOffset;
  						
  						break;
  					
  					case 'rect':
  						
  						var areaLeft = coords[0],
  							areaTop = coords[1],
  							areaRight = coords[2],
  							areaBottom = coords[3];
  						
  						geo.origin.size.height = areaBottom - areaTop;
  						geo.origin.size.width = areaRight - areaLeft;
  						
  						geo.origin.windowOffset.left += areaLeft;
  						geo.origin.windowOffset.top += areaTop;
  						
  						break;
  					
  					case 'poly':
  						
  						var areaSmallestX = 0,
  							areaSmallestY = 0,
  							areaGreatestX = 0,
  							areaGreatestY = 0,
  							arrayAlternate = 'even';
  						
  						for (var i = 0; i < coords.length; i++) {
  							
  							var areaNumber = coords[i];
  							
  							if (arrayAlternate == 'even') {
  								
  								if (areaNumber > areaGreatestX) {
  									
  									areaGreatestX = areaNumber;
  									
  									if (i === 0) {
  										areaSmallestX = areaGreatestX;
  									}
  								}
  								
  								if (areaNumber < areaSmallestX) {
  									areaSmallestX = areaNumber;
  								}
  								
  								arrayAlternate = 'odd';
  							}
  							else {
  								if (areaNumber > areaGreatestY) {
  									
  									areaGreatestY = areaNumber;
  									
  									if (i == 1) {
  										areaSmallestY = areaGreatestY;
  									}
  								}
  								
  								if (areaNumber < areaSmallestY) {
  									areaSmallestY = areaNumber;
  								}
  								
  								arrayAlternate = 'even';
  							}
  						}
  						
  						geo.origin.size.height = areaGreatestY - areaSmallestY;
  						geo.origin.size.width = areaGreatestX - areaSmallestX;
  						
  						geo.origin.windowOffset.left += areaSmallestX;
  						geo.origin.windowOffset.top += areaSmallestY;
  						
  						break;
  				}
  			}
  		}
  		
  		// user callback through an event
  		var edit = function(r) {
  			geo.origin.size.height = r.height,
  				geo.origin.windowOffset.left = r.left,
  				geo.origin.windowOffset.top = r.top,
  				geo.origin.size.width = r.width
  		};
  		
  		self._trigger({
  			type: 'geometry',
  			edit: edit,
  			geometry: {
  				height: geo.origin.size.height,
  				left: geo.origin.windowOffset.left,
  				top: geo.origin.windowOffset.top,
  				width: geo.origin.size.width
  			}
  		});
  		
  		// calculate the remaining properties with what we got
  		
  		geo.origin.windowOffset.right = geo.origin.windowOffset.left + geo.origin.size.width;
  		geo.origin.windowOffset.bottom = geo.origin.windowOffset.top + geo.origin.size.height;
  		
  		geo.origin.offset.left = geo.origin.windowOffset.left + geo.window.scroll.left;
  		geo.origin.offset.top = geo.origin.windowOffset.top + geo.window.scroll.top;
  		geo.origin.offset.bottom = geo.origin.offset.top + geo.origin.size.height;
  		geo.origin.offset.right = geo.origin.offset.left + geo.origin.size.width;
  		
  		// the space that is available to display the tooltip relatively to the document
  		geo.available.document = {
  			bottom: {
  				height: geo.document.size.height - geo.origin.offset.bottom,
  				width: geo.document.size.width
  			},
  			left: {
  				height: geo.document.size.height,
  				width: geo.origin.offset.left
  			},
  			right: {
  				height: geo.document.size.height,
  				width: geo.document.size.width - geo.origin.offset.right
  			},
  			top: {
  				height: geo.origin.offset.top,
  				width: geo.document.size.width
  			}
  		};
  		
  		// the space that is available to display the tooltip relatively to the viewport
  		// (the resulting values may be negative if the origin overflows the viewport)
  		geo.available.window = {
  			bottom: {
  				// the inner max is here to make sure the available height is no bigger
  				// than the viewport height (when the origin is off screen at the top).
  				// The outer max just makes sure that the height is not negative (when
  				// the origin overflows at the bottom).
  				height: Math.max(geo.window.size.height - Math.max(geo.origin.windowOffset.bottom, 0), 0),
  				width: geo.window.size.width
  			},
  			left: {
  				height: geo.window.size.height,
  				width: Math.max(geo.origin.windowOffset.left, 0)
  			},
  			right: {
  				height: geo.window.size.height,
  				width: Math.max(geo.window.size.width - Math.max(geo.origin.windowOffset.right, 0), 0)
  			},
  			top: {
  				height: Math.max(geo.origin.windowOffset.top, 0),
  				width: geo.window.size.width
  			}
  		};
  		
  		while ($parent[0].tagName.toLowerCase() != 'html') {
  			
  			if ($parent.css('position') == 'fixed') {
  				geo.origin.fixedLineage = true;
  				break;
  			}
  			
  			$parent = $parent.parent();
  		}
  		
  		return geo;
  	}