	
	/*
	 -------------------------------------------------------------------------------------------------------------
	 
	 *** Scaling the background image to the vieport ***
	 
	 A. Setup
	 
	 To make your background image resize and match the browser window or the page, do the following:
	 
	 (1) Define a background image for the body tag in your CSS, just as you normally would. You can use 
	     'background-image', 'background-position', or combine the statements with 'background'. If you set a
	     background position, do so using percentages or keywords ('right', 'center', etc). Other units, such
	     as px, em or pt, are currently not supported.
	   
	 (2) Reference the jQuery library in your page. This script has been tested with jQuery 1.3.2; if you want
	     to be on the safe side, stick to that version.
	   
	 (3) Reference this file, scaleBg.js.
	 
	 (4) Determine the width and height of the background image, in pixels.
	 
	 (5) Include a Javascript call to the function scaleBackground() in your page. The function must be called
	     after the document-ready event - see the examples below. You need to pass the image width and height to
	     the function, there is no reliable way to determine them automatically. All other parameters are optional.
	     
	     By default, the background image will be resized to fill the window.
	     
	 
	 That's it, basically. The full syntax of the function is
	 
		scaleBackground( originalWidthPx, originalHeightPx, [matchTo = Background.MATCH_TO_WINDOW],
						[matchingMethod = Background.FILL], [coreWidthPx], [coreHeightPx] );
	 
	 
	 B. Options
	 
	 You can fine-tune the resizing by setting the optional parameters:
	 
	 - [matchTo]:
	 
		Background.MATCH_TO_WINDOW
		adjusts the background image to the window size. This is the default behaviour.
		
		Background.MATCH_TO_PAGE
		adjusts the image to the page size. While this might often be more desirable than matching the image to 
		the window, it is not quite as smooth if viewed in IE. Not a big deal, but if MATCH_TO_WINDOW does the 
		job for you, then stick to that.
	 
	 - [matchingMethod]:
		
		Background.FILL
		makes the image fill the browser window or the page completely. Some parts of the image will be outside
		of the viewport and will be clipped.
		
		Background.FIT_INSIDE
		makes the image fit inside the window or page. The image will be fully visible, but parts of the viewport
		will not be covered by it.
		
		Background.PROTECT_CORE_AREA
		is helpful if a core part of the image should always be visible, while other areas of it are less 
		significant and can be allowed to get out of view, without the need to resize. Set this option and define 
		the size of the core area, in pixels, with the parameters [coreWidthPx] and [coreHeightPx]. When that 
		part of the image is about to be clipped, the size of the image is reduced to keep it visible. When, on 
		the other hand, the viewport is enlarged beyond the core area, the image is *not* scaled up, and other 
		parts of it come into view.
		
		If one dimension is insignificant to you, set it to 0. For instance, you might want to keep a part of 
		your original image visible which is 300px wide, but you don't care how much of that stip is visible 
		vertically. Set coreHeightPx to 0 to achieve this.
		
		Note that there may be conflicts: the core area might be clipped so much that the resized image would 
		leave part of the viewport uncovered. In these cases, keeping the viewport covered takes precedence over 
		protecting the visibility of the core area, and part of it may indeed disappear from view. Too complicated? 
		Then just don't worry about it, it will work out fine.
		
	 By default, the image is anchored at the top left corner. If you want to center the image or anchor it 
	 elsewhere, just set the CSS 'background-position' accordingly. (And don't forget to set the height of the html
	 element to 100% if you do that, otherwise Firefox, Chrome etc. might not place the background where you'd
	 expect it to be ... ;-) )
	 
	 
	 C. Usage examples
	  
	   In these examples, we assume that the background image is 800px wide and 600px high.
	
	  ( 1 ) Using the default settings: this will resize the background image to fill the window.
		
		$( document ).ready( function() {
			
			scaleBackground( 800, 600 );
			
			// This is equivalent to: scaleBackground( 800, 600, Background.MATCH_TO_WINDOW, Background.FILL );
			
		});
		
	  ( 2 ) Resize the background image to fit into the window.
		
		$( document ).ready( function() {
			
			scaleBackground( 800, 600, Background.MATCH_TO_WINDOW, Background.FIT_INSIDE );
			
		});
		
	  ( 3 ) Resize the background image to fill the page.
		
		$( document ).ready( function() {
			
			scaleBackground( 800, 600, Background.MATCH_TO_PAGE, Background.FILL );
			
		});
		
	  ( 4 ) Resize the image only if the core area of the image, 400px wide and 300px high, is not fully visible
	        inside the window.
		
		$( document ).ready( function() {
			
			scaleBackground( 800, 600, Background.MATCH_TO_WINDOW, Background.PROTECT_CORE_AREA, 400, 300 );
			
		});
		
	 -------------------------------------------------------------------------------------------------------------
	 
	 Version 0.2.4 - 26/08/2009
	 
	 (c) Michael Heim, http://www.zeilenwechsel.de/
	 
	*/
	
	
	/*
	 Constants
	*/
	// - matchTo:
	Background.MATCH_TO_WINDOW = 0;
	Background.MATCH_TO_PAGE = 1;
	
	// - matchingMethod:
	Background.FILL = 0;
	Background.FIT_INSIDE = 1;
	Background.PROTECT_CORE_AREA = 2;
	
	
	/*
	 Sets up the background resizing. Call after document ready.
	*/
	function scaleBackground ( originalWidthPx, originalHeightPx, matchTo, matchingMethod, coreWidth, coreHeight ) {
		
		var bg = new Background( originalWidthPx, originalHeightPx, matchTo, matchingMethod, coreWidth, coreHeight );
		
	}	
	
	
	/*
	 Constructor for the background resizing object.
	 
	 NB: coreWidth and coreHeight must be specified if PROTECT_CORE_AREA is chosen as the matching method.
	 They are ignored in all other cases.
	*/
	function Background ( originalWidth, originalHeight, matchTo, matchingMethod, coreWidth, coreHeight ) {
		
		// Copy the background image to a div for manipulation.
		//
		// If the background is to be fitted inside the window or document, it will not cover the whole area.
		// Parts of the original background image would come to the surface, so it has to be removed. In fact,
		// it should never be seen unless PROTECT_CORE_AREA is chosen. 
		var removeOriginal = ( matchingMethod != Background.PROTECT_CORE_AREA );
		var success = this.createBgDiv( removeOriginal );
		
		// Activate the resizing.
		if ( success ) {
			
			this.matchTo = matchTo || Background.MATCH_TO_WINDOW;
			this.matchingMethod = matchingMethod || Background.FILL;
			
			if ( this.matchTo == Background.MATCH_TO_WINDOW ) {
				
				this.matchBackground = this.matchBackgroundToWindow;
				
			} else {
				
				this.matchBackground = this.matchBackgroundToDocument;
				
			}
			
			this.treatAsIE = this.assumeIE();
			
			this.lastWindow = new Area();
			this.lastWindow.setSize( 0, 0 );
			
			this.img = new Area( 'img#bgImg', originalWidth, originalHeight, coreWidth, coreHeight );
			this.imgDiv = new Area( 'div#bgDiv' );
			this.window = new Area ( window );
			
			// Read the background position.
			this.imgPosition = this.backgroundPosition( originalWidth, originalHeight );
			
			if ( this.matchTo == Background.MATCH_TO_PAGE ) {
				
				this.document = new Area ( document );
				// The above does not work in IE8: jQuery, as of version 1.3.2, returns an exaggerated document size in IE8.
				// Therefore, we use a workaround and replace calls to $( document ).width() and $( document ).height() with
				// a reliable solution. We don't bother to filter out IE8 in particular and do it for all IE browsers.
				if ( this.treatAsIE ) this.document.obj = 
					( document.documentElement && document.documentElement.scrollWidth ?
						{
							width:  function () { return document.documentElement.scrollWidth; },
							height: function () { return document.documentElement.scrollHeight; }
						}
						:
						{
							width:  function () { return document.body.scrollWidth; },
							height: function () { return document.body.scrollHeight; }
						}
					)
				
				this.lastDocument = new Area();
				this.lastDocument.setSize( 0, 0 );
				
			}
			
			this.dropRepeatCalls = false;
			
			
			// Execute once and bind to resize event.
			this.matchBackground();
			
			// Bind to window resize event.
			$( window ).resize( ( function ( obj ) { return function () { obj.matchBackground(); }; } )(this) );
			
			// In IE, bind to the resize event of a div with width 100%. The method will filter out intentional changes.
			// The remainder is a response to an IE8 page zoom and indeed requires yet another image resize.
			if ( screen.logicalXDPI && screen.logicalYDPI && screen.deviceXDPI && screen.deviceYDPI ) {
				
				this.ieZoomState = screen.deviceXDPI / screen.logicalXDPI;
				
				$( '<div id="ieZoomDetect" style="width: 100%; height: 10px; position: absolute; top: -100px;"></div>' )
					.prependTo( 'body' )
					.resize( ( function ( obj ) { return function () { obj.matchZoomChangeIE(); }; } )(this) );
				
			}
			
		}
		
	}
	
	
	Background.prototype = {
		
		matchZoomChangeIE: function () {
			
			if ( screen.deviceXDPI / screen.logicalXDPI != this.ieZoomState ) {
				
				this.ieZoomState = screen.deviceXDPI / screen.logicalXDPI;
				this.matchBackground();
				
			}
			
		},
		
		matchBackground: function () {},
		
		matchBackgroundToWindow: function ( recursiveCall ) {
			
			this.window.updateData();
			
			// Exit if the window size has not changed since the last call.
			if ( this.equalSize( this.window, this.lastWindow ) ) return;
			
			// Check if the core area is used and, if so, needs to be restored. Quit if it is still fully visible.
			if ( this.matchingMethod == Background.PROTECT_CORE_AREA && this.img.core.fitsInside( this.window ) ) {
				
				// Core area is fully visible; the original background image can be shown.
				this.showBackgroundImage();
				if ( this.imgDiv.obj.css( 'display' ) != 'none' ) this.imgDiv.obj.hide();
				
				this.lastWindow.setSize( this.window.width, this.window.height );
				return;
			
			}
			
			this.imgDiv.setSize( '100%', this.window.height );
			
			var zoomFactor = this.img.zoomFactor( this.window, this.matchingMethod, this.imgPosition );
			this.img.setSize( zoomFactor.width, zoomFactor.height );
			this.img.obj.css( { top: zoomFactor.top, left: zoomFactor.left } );
			
			var canvasCropped = this.window.hasShorterSideThan( this.lastWindow );
			this.lastWindow.setSize( this.window.width, this.window.height );
			
			if ( this.imgDiv.obj.css( 'display' ) == 'none' ) this.imgDiv.obj.show();
			this.hideBackgroundImage();
			
			if ( canvasCropped && ! recursiveCall ) {
				
				// Scrollbars may have appeared before the image was sized down. They have now vanished, leaving
				// an empty fringe. Adjust the image size.
				this.matchBackgroundToWindow( true );
				
			}
			
		},
		
		/*
		 To fit the background image to the window or document size, whichever is larger, the document size has to be
		 determined once the window is resized. This is not as straightforward as it appears to be.
		 
		 First, the image has to be clipped to the window size so that it doesn't artificially expand the document
		 beyond the window. Then, $( document ).height() returns the true height of the document - in FF, Google Chrome
		 and Safari. But not in IE.
		 
		 As it turns out, IE updates the document properties only after the resize event has run its course.
		 The only way to capture them from $( window ).resize(...) is to set a timer.
		 
		 So the adjustment comes in two parts. Part 1, done here, crops the image to fit the resized window and sets
		 the timer. Part 2, called by the timer, checks the true document size and does the adjustment.
		
		*/
		matchBackgroundToDocument: function () {
			
			if ( this.dropRepeatCalls ) return;
			
			this.window.updateData();
			
			// Exit if the window size has not changed since the last call. Only for FF and friends - it would sometimes make IE quit
			// the resizing too early if the window is dragged around fast.(Perhaps some unfortunate interaction with the setTimout()
			// call IE has to use.)
			if ( ! this.treatAsIE && this.equalSize( this.window, this.lastWindow ) ) return;
			
			// Check if the core area is used and, if so, needs to be restored. Quit if it is still fully visible.
			this.document.updateData();
			if ( this.matchingMethod == Background.PROTECT_CORE_AREA && this.img.core.fitsInside( this.document ) ) {
				
				// Core area is fully visible; the original background image can be shown.
				if ( this.imgDiv.obj.css( 'display' ) != 'none' ) this.imgDiv.obj.hide();
				
				this.lastWindow.setSize( this.window.width, this.window.height );
				return;
			
			}
			
			// Clip the image so that it fits into the window. This will make unneccessary scrollbars disappear
			// and reveal if the document is truly larger than the window.
			this.imgDiv.setSize( this.window.width, this.window.height );
			
			this.window.updateData();
			
			if ( this.treatAsIE ) {
				
				// There is a pretty strong indication that we are dealing with IE. Defer further action until the resize event
				// has run its course and IE has refreshed the document properties.
				
				// NB: IE doesn't update the document size properly before the resize event has terminated. Thus, it would be
				// tempting to assume that IE can be detected by checking for a change in document size:
				//
				// 	   suspectIE = this.equalSize( this.document, this.lastDocument )
				// 	   
				// Yet this does not work as intended. IE7 (maybe IE8, too, haven't checked) often adjusts the document size somewhat,
				// but not fully! A change in document size does not help to separate other browsers from IE.
				
				this.lastWindow.setSize( this.window.width, this.window.height );
				
				setTimeout( ( function ( obj ) { return function () { obj.matchBackgroundToDocument2( false ); }; })( this ), 0 );
				/*
				 A more generic way of writing this:
				 
					setTimeout( ( function ( obj, param ) { return function () { obj.matchBackgroundToDocument2( param ); }; })( this, true ), 0 );
				 
				 Another way of doing this, using .call():
				 
					var myContext = this;
					setTimeout( function () { myContext.matchBackgroundToDocument2.call( myContext, false ); }, 0 );
				 
				 Cf. http://www.west-wind.com/Weblog/posts/5033.aspx, comment _michael 17.8.2009
				*/
				
			} else {
				
				// We are most likely dealing with a non-IE browser, and the document properties may be correct. Try to avoid an ugly
				// delayed redraw and and finish the job right away.
				//
				// A timer, set up at the end of part 2, will catch if that was too early, and if necessary correct the result.
				// Such a correction is hardly ever necessary, though.
				this.matchBackgroundToDocument2( false );
				
			}
			
		},
		
		matchBackgroundToDocument2: function ( secondaryCall ) {
			
			// Re-read the document size. If this function has already run, check first if further action is actually necessary,
			// ie if the document size has changed since.
			this.document.updateData();
			if ( secondaryCall && this.equalSize( this.document, this.lastDocument ) ) return;
			
			// Block secondary Resize events which may be triggered by the following layout adjustments. Affects IE8.
			this.dropRepeatCalls = true;
			
			// Make sure the window data is up to date.
			this.window.updateData();
			
			// Make the canvas cover both the document and the window.
			var canvas = this.boundingBox( this.window, this.document );
			var zoomFactor = this.img.zoomFactor( canvas, this.matchingMethod, this.imgPosition );
			
			this.img.setSize( zoomFactor.width, zoomFactor.height );
			this.img.obj.css( { top: zoomFactor.top, left: zoomFactor.left } );
			this.imgDiv.setSize( canvas.width, canvas.height ); // <-- this causes IE8 to run another resize event, no matter what.
			
			this.lastWindow.setSize( this.window.width, this.window.height );
			this.lastDocument.setSize( this.document.width, this.document.height );
			
			if ( this.imgDiv.obj.css( 'display' ) == 'none' ) this.imgDiv.obj.show();
			
			// Let the layout adjustments run their course and finally unblock subsequent resize events. 
			if ( secondaryCall ) {
				
				setTimeout( ( function ( obj ) { return function () { obj.dropRepeatCalls = false; }; } )( this ), 0 );
				
			} else {
				
				// For FF and friends, set up the timer to run a second check, just in case.
				setTimeout( ( function ( obj ) { return function () { obj.dropRepeatCalls = false; obj.matchBackgroundToDocument2( true ); }; } )( this ), 0 );
				
			}
			
		},
		
		assumeIE: function () {
			
			// Use a combination of navigator.appName and object detection to make a fairly safe guess that we are dealing
			// with IE (IE6 or newer). That is accurate enough for the purpose: it catches every IE (that's the important part),
			// while perhaps producing a few false positives (which does not pose a problem). No need to make a fuss and anaylze
			// the referer.
			return ( navigator.appName == 'Microsoft Internet Explorer' && document.compatMode && document.all );
			
		},
		
		hideBackgroundImage: function () {
			if ( $( 'body' ).css( 'background-image' ) != 'none' ) $( 'body' ).css( 'background-image', 'none' );
		},
		
		showBackgroundImage: function () {
			if ( $( 'body' ).css( 'background-image' ) == 'none' ) $( 'body' ).css( 'background-image', 'url( ' + this.imgUrl + ' )' );
		},
	
		createBgDiv: function ( removeOriginal ) {
			
			// Copy background image to div. Remove the original if desired.
			var urlRegex = /url\s*\(\s*(?:[^:]+:\/\/[^\/]+)?(\/?[^"'\)]+)['"]?\s*\)\s*;?/i;
			
			var bgDef = $( 'body' ).css( 'background-image' ).match( urlRegex );
			if ( ! bgDef ) return false;
			
			this.imgUrl = bgDef[1];
			
			if ( removeOriginal ) this.hideBackgroundImage();
			
			$( '<div id="bgDiv"><img src="' + this.imgUrl + '" id= "bgImg" style="position: relative;" /></div>')
				.css( { overflow: 'hidden',
						position: 'absolute',
						top: '0px',
						left: '0px',
						width: '100%',
						display: 'none',
						'z-index': '-1'
						} )
				.height( $( window ).height() )
				.prependTo( 'body' );
			
			return true;
			
		},
		
		/*
		 Return the background position, as defined in the CSS, in relative values between 0 and 1 (in analogy to a positioning in percent).
		*/
		backgroundPosition: function ( originalWidthPx, originalHeightPx ) {
			
			// Querying the CSS property 'background-position' fails in IE with jQuery 1.3.2. In IE, 'background-position-x' and
			// 'background-position-y' must be queried instead. It seems easiest to do that using jQuery:
			//
			// 		$( 'body' ).css( 'background-position-x' )
			//
			// and that does indeed work - most of the time. But it fails if the image is centered and a short notation is used, ie
			// 'background-position: center' instead of 'background-position: center center'. jQuery then reports an imaginary px value
			// for 'background-position-y'.
			//
			// The solution is to access the background-position-x, -y properties directly, bypassing jQuery. We use feature detection
			// (currentStyle vs. getComputedStyle) just in case, in order to be 'future-proof'.
			var posCss = $( 'body' ).css( 'background-position' );
			if ( typeof( posCss ) == 'undefined' ) {
				
				var body = document.getElementsByTagName('body')[0];
				
				if ( body.currentStyle ) {
					
					// The IE way. This will catch all current IE versions up to IE8.
					posCss = body.currentStyle.backgroundPositionX + ' ' + body.currentStyle.backgroundPositionY;
					
				} else if ( window.getComputedStyle ) {
					
					// The W3C way for FF and other compliant browsers. We shouldn't ever get here, but who knows how some
					// future browser will behave ...
					posCss = window.getComputedStyle( body, null ).backgroundPositionX + ' ' + window.getComputedStyle( body, null ).backgroundPositionY;
			
				}
			}
			if ( typeof( posCss ) == 'undefined' ) {
				
				// Extremely unlikely: everything failed. Try jQuery with 'background-position-x' and 'background-position-y'
				// in an act of desperation, betting on improvements in some future release.
				posCss = $( 'body' ).css( 'background-position-x' ) + ' ' + $( 'body' ).css( 'background-position-y' );
				
			}
			
			// If the background position cannot be determined, exit and return the upper left corner as default positioning.
			if ( ! posCss ) return { top: 0, left: 0 };
			
			// Convert the literal CSS background-position into relative values.
			function relativePosition ( value, originalSize ) {
				
				var token = value.toLowerCase();
				
				switch ( token ) {
					
					case 'top':
						return 0;
					case 'left':
						return 0;
					case 'bottom':
						return 1;
					case 'right':
						return 1;
					case 'center':
						return 0.5;
					default:
						if ( token.indexOf( '%' ) != -1 ) {
							return parseInt( token ) / 100;
						} else {
							return token;
						}
						
				}
				
			}
			
			var pos = posCss.split( ' ' );
			var posH = ( pos[0] ? relativePosition( pos[0], originalWidthPx ) : 0 );
			var posV = ( pos[1] ? relativePosition( pos[1], originalHeightPx ) : 0 );
			
			return { posH: posH, posV: posV };
			
		},
		
		equalSize: function ( area1, area2 ) {
			
			return ( ( area1.width == area2.width ) && ( area1.height == area2.height ) );
			
		},
		
		boundingBox: function ( area1, area2 ) {
			
			var boundingBox = new Area();
			boundingBox.setSize( Math.max( area1.width, area2.width ), Math.max( area1.height, area2.height ) );
			
			return boundingBox;
			
		}
		
	}
	
	
	function Area ( selector, originalWidth, originalHeight, coreWidth, coreHeight ) {
		
		if ( selector ) this.obj = $( selector );
		
		if ( originalHeight && originalWidth ) {
			
			this.original = new Area();
			this.original.setSize( originalWidth, originalHeight );
			
			if ( typeof( coreWidth ) != "undefined" && typeof( coreHeight ) != "undefined" ) {
				
				this.core = new Area();
				this.core.setSize( coreWidth, coreHeight );
				
			}
			
		}
		
	}
	
	Area.prototype = {
		
		fitsInside: function ( frameArea ) {
			
			return ( frameArea.width >= this.width && frameArea.height >= this.height );
			
		},
		
		hasShorterSideThan: function ( frameArea ) {
			
			return ( frameArea.width > this.width || frameArea.height > this.height );
			
		},
		
		fit: function ( frameArea ) {
			
			var zoomFactor;
			
			var zoomToHeight = this.aspectRatio < frameArea.aspectRatio;
			
			if ( zoomToHeight ) {
				
				zoomFactor = frameArea.height / this.height;
				
			} else {
				
				zoomFactor = frameArea.width / this.width;
				
			}
			
			var resultArea = new Area();
			resultArea.setSize( Math.round( this.width * zoomFactor) , Math.round( this.height * zoomFactor ) );
			
			return resultArea;
			
		},
		
		fill: function ( frameArea ) {
			
			var zoomFactor;
			
			var zoomToHeight = this.aspectRatio > frameArea.aspectRatio;
			
			if ( zoomToHeight ) {
				
				zoomFactor = frameArea.height / this.height;
				
			} else {
				
				zoomFactor = frameArea.width / this.width;
				
			}
			
			var resultArea = new Area();
			resultArea.setSize( Math.round( this.width * zoomFactor) , Math.round( this.height * zoomFactor ) );
			
			return resultArea;
			
		},
		
		zoomFactor: function ( canvas, matchingMethod, imgPosition ) {
			
			var resultArea;
			var scaling;
			var zoomFactor;
			
			if ( matchingMethod == Background.PROTECT_CORE_AREA ) {
				
				// If a protected core area is defined, that implies a kind of 'fill' mode. If the core area is fully
				// visible, the original background image stays untouched. Only if a core area is partially outside
				// the canvas, a scaled image is used instead.
				
				// When the background image is replaced by a scaled image, a new reference comes into play: The scaling
				// does not refer to the original size of the image but to the canvas (window or document size). So the
				// size of the original image is *not* 100%, the canvas is.  
				
				// (1) Calculate the scaling that would be needed to restore the image to its original pixel size (ie like the
				//     background image). This image would not be fully visible.
				var upscaling = {
					width: this.original.width / canvas.width,
					height: this.original.height / canvas.height				
				};
				
				// (2) Now calculate how much the original image would have to be downscaled so that the core area is
				//     fully visible in the canvas. Calculate the factor separately for width and height and then
				//	   use the one for the more resticting dimension, ie the more agressive downscaling (the smaller factor). 
				var downscaling = {
					width: ( this.core.width > canvas.width ? canvas.width / this.core.width : 1 ),
					height: ( this.core.height > canvas.height ? canvas.height / this.core.height : 1 )
				};
				downscaling = Math.min( downscaling.width, downscaling.height );
				
				// (3) Make sure the downscaling does not go too far. If the downscaled image does not fully cover the
				//     canvas anymore, it has to be limited. The top priority is to prevent ugly fringes from appearing.
				//	   The visibility of the core area comes second. So here is the lower limit for downscaling the
				//     original image:
				var canvasCoverLimit = {
					width: canvas.width / this.original.width,
					height: canvas.height / this.original.height
				};
				canvasCoverLimit = Math.max( canvasCoverLimit.width, canvasCoverLimit.height );
				
				downscaling = Math.max( downscaling, canvasCoverLimit);
				
				// (4) Apply the downscaling to the dimensions of the upscaled image. This results in the scaling
				//     factors for width and height in relation to the canvas size. Done.
				scaling = {
					width: upscaling.width * downscaling,
					height: upscaling.height * downscaling
				}
				
			} else {
				
				// Standard cases, fit or fill.
				if ( matchingMethod == Background.FILL ) {
					
					resultArea = this.original.fill( canvas );
					
				} else {
					
					resultArea = this.original.fit( canvas );
					
				}
				
				scaling = {
					width: resultArea.width /  canvas.width,
					height: resultArea.height / canvas.height
				}
				
			}
			
			zoomFactor = {
				width: Math.round( scaling.width * 100 ) + '%',
				height: Math.round( scaling.height * 100 ) + '%',
				top: Math.round( ( 1 - scaling.height ) * imgPosition.posV * 100 ) + '%',
				left: Math.round( ( 1 - scaling.width ) * imgPosition.posH * 100 ) + '%'
			};
			
			return zoomFactor;
			
		},
		
		updateData: function () {
			
			this.width = this.obj.width();
			this.height = this.obj.height();
			this.aspectRatio = this.width / this.height;
			
		},
		
		setSize: function ( width, height ) {
			
			// Make sure integers are used. Round down if necessary - rounding up would make the area 1px too large,
			// which might cause scrollbars to appear.
			width = ( isNaN( width ) ? width : Math.floor( width ) );
			height = ( isNaN( height ) ? height : Math.floor( height ) );
			
			if ( this.obj ) {
				
				// Limit resize events to the minimum. Compare the current CSS settings with the desired ones and change
				// them only if they differ.
				//
				// NB: We need to look at the actual CSS settings, not at the jQuery functions .width() and .height(). These
				// convert the result to pixel values. We need the exact settings, which may be percentages, to match.
				var targetW = ( isNaN( width ) ? width : width + 'px' );
				var targetH = ( isNaN( height ) ? height : height + 'px' );
				var curW = this.obj.css( 'width' ).toString();
				var curH = this.obj.css( 'height' ).toString();
				if ( curW !== targetW || curH !== targetH ) this.obj.width( width ).height( height );
				
			}
			
			this.width = width;
			this.height = height;
			
			this.aspectRatio = this.width / this.height;
			
		}
		
	}
	
	

