// Did we include Base first?
if (typeof Mekin == 'undefined') {
	throw('Mekin.Resource library requires Mekin base library.\nInclude Mekin.js first.');
}

//
// Resource manager
//
Mekin.Resource = {

	resourcesRemaining: 0,
	
	totalResources: 0,
	
	resourcesLoaded: 0,
	
	ieImageArea: null,		// Special hack in IE to make images load properly
	
	isReadyToFire: false,	// Set by user calling 'preload'
	
	Scriptname: 'Mekin/Resource.js',
	
	imagePath: '../images/',	// relative to 'Mekin/Resource.js'
	
	options: null,

	// Provides a convienent method for creating an image and adding it to the resource mananger
	// Style and options (hide?) are applied immediately
	// 
	// Also provides a cross-browser method for creating fadable transparent PNGs.
	// Most modern browsers (Safari, Firefox, Opera, Chrome) support transparent PNGs out of the box.
	// IE requries using a div and an IE-specific filter, which loads a transparent PNG as the div's background
	//
	// This should not be called before the page is loaded
	
	createImageRel: function ( src, style, options ) {
	
		// Creates an image but assumes the given src path is relative to 'js/Mekin/../../
	
		var pathToSrc = Mekin.Path.getFilename( this.Scriptname, this.imagePath + src );
		return this.createImage( pathToSrc, style, options );
	},
	
	createImage: function( src, style, options ) {
		
		// default options
		options = Object.extend( {
			hide:              false,
			reflection:        false,
			reflectionHeight:  0.5,
			reflectionOpacity: 0.5,
			preload: true
		}, options || {} );
		
		var isPng = src.toLowerCase().match(/\.png$/i) == ".png";
		
		// Version 8.0 seems to support PNGs properly
		var isIE = Prototype.Browser.IE;// && getInternetExplorerVersion() < 8.0;
		
		var node = null;
		
		// Add one to resource count
		if (options.preload) {
			++this.resourcesRemaining;
			++this.totalResources;
		}
		
		// Create a DOM Image with a few extra goodies
		var imgNode = Object.extend( $(document.createElement('img')), {
		
			isPng: isPng,
		
			originalWidth:  0,
			originalHeight: 0,
						
			isReady:  false,
			hasError: false,
			
			options: options,

			// This function takes an image element
			// In non-IE browsers, this == img, but
			// in IE we use a different image that is
			// secretly added to the page so we can read its width+height
			onLoad: function( img ) {
				this.isReady = true;
				
				this.originalWidth  = img.width;
				this.originalHeight = img.height;
				
				if (this.options.preload) {
					Mekin.Resource.onLoad();
				}
				
				if (this.options && this.options.onLoad) {
					node = this;
					if (isIE && isPng) {
						node = this.parentNode;
					}
					this.options.onLoad.call(this, node);
				}
			},
						
			// Set width/height such that
			// 1. Image fits within width and height
			// 2. Aspect ratio is maintained
			fitWithin: function( maxWidth, maxHeight ) {
				if (this.originalWidth > 0 && this.originalHeight > 0) {
				
					aspectRatio = this.originalWidth / this.originalHeight;
					
					// Ensure new height is less than or equal to restriction
					newHeight = Math.min( this.originalHeight, maxHeight );
					newWidth  = aspectRatio * newHeight;
					
					// Be sure newly computed width doesn't violate restriction
					newWidth  = Math.min( newWidth, maxWidth );
					
					// We can be sure this newHeight is less than or equal to
					// original newHeight as computed above
					newHeight = newWidth / aspectRatio;
				
					this.width = newWidth;
					this.height = newHeight;
					
					//this.setSize( newWidth, newHeight );
				}
			}
			
		});

		if (isPng && isIE) {
			// create a div
			node = $(document.createElement('div'));
						
			// This crazy ie-specific effect allows transparent PNGs as backgrounds of elements
			node.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='crop')";
			
			// In order to be able to fade the div element with the PNG filter,
			// we need to make a normal img element  with the PNG as a child of the div.
			// We don't want 2 PNGs, so we give this one zero opacity
			imgNode.setOpacity(0);
			node.appendChild(imgNode);
			//imgNode.setStyle({zIndex: -100});
			//var eventArea = $(document.createElement('div'));
			//eventArea.setStyle({position:'absolute'});
			//eventArea.id = 'event area';
			//node.appendChild(eventArea);
			//node.getEventArea = function() {
			//	return eventArea;
			//}
		} else {
			// All other browsers handle PNG transparency just fine.
			// Create a normal image
			node = imgNode;
		}
		
		// Special fixup for determining the image's size
		// before actually adding it to the body
		this.ieFix(imgNode, src);
				
		// Apply object extensions
		if (options && options.extend) {
			imgNode = Object.extend( imgNode, options.extend );
		}
		
		var that = this;
		
		// Watch the onload event
		
		if (!isIE) {
			imgNode.observe('load', function(e){
				this.onLoad( this );
			});
		}
		imgNode.observe('error', function(e){
			this.isReady  = true;
			this.hasError = true;
			
			if (this.options.preload) {
				that.onLoad();
			}
			
			if (this.options && this.options.onError) {
				this.options.onError();
			}
		});
		imgNode.observe('abort', function(e){
			this.isReady = true;
		});
		
				
		// Set style and apply options
		if (style) {
			node.setStyle( style );
		}
			
		if (options.hide == true) {
			node.hide();
		}
		
		// Load the image
		imgNode.src = src;
		
		// Add a method to change the image
		node = Object.extend( node, {
			setImage: function( src ) {
			
				var thisNode = this;
				if (isIE && isPng) {
				
					// Add the image to the hidden ie-only area so we get the dimensions correctly
					newImgNode = $(document.createElement('img'));
					newImgNode.observe('load', function(){
					
						// Reset dimensions for the parent node
						thisNode.setDimensions(this.width, this.height);
						
						// save opacity
						opacity = thisNode.getOpacity();
						
						// Set new image
						thisNode.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='scale')";
						
						// Restore opacity
						thisNode.setOpacity( opacity );

					});
					
					newImgNode.setStyle({visibility: 'hidden'});
					this.ieImageArea.appendChild(newImgNode);
					
					// Load the new image
					newImgNode.src = src;
				} else {
				
					// Regular image; simply change src
					this.src = src;
				}
			}
		});
	
		return node;
	},
	
	// Fixes an issue where IE won't report correct dimensions
	// unless the image is added to the page
	ieFix: function(imgNode, src) {

		if (Prototype.Browser.IE)
		{		
			var that = this;
		
			// We can only do this if the body exists
			if (!(document && document.body)) {
				Mekin.error('Mekin.Resource.createImage was called before the body was loaded.\nThis fails in IE because the image must be added to the body to work properly.');
				return null;
			}
		
			// If we don't add the image to the page, then IE won't actually load the image
			// and will report dimensions as zero
			// Create a hidden, 0 dimension div in the page and add the image to that
			if (this.ieImageArea == null) {
				
				// Doesn't exist yet; create it
				this.ieImageArea = $(document.createElement('div'));
				
				// Hide the image area
				this.ieImageArea.setStyle({
					width:    '0px',
					height:   '0px',
					overflow: 'hidden'
				});
				
				// Add it to the body tag
				document.body.appendChild( this.ieImageArea );
			}
			
			// Add the image to the hidden ie-only area so we get the dimensions correctly
            ieHack = $(document.createElement('img'));
			
            ieHack.observe('load', function() {
				// If the image is a png, then we should have already added a parent div
				// We need to set the parent div's dimensions
				if (imgNode.isPng) {
					if (imgNode.parentNode != null) {
						imgNode.parentNode.setStyle({
							width:  this.width  + 'px',
							height: this.height + 'px'
						});
					} else {
						// This shouldn't happen.  Throw an error.
						Mekin.error('Mekin.Resource.createImage detected a PNG in IE without a parent div');
					}
				}
				
				// Call custom image onLoad func
				imgNode.onLoad( this );
            });
			this.ieImageArea.appendChild(ieHack);
			ieHack.src = src;
		}
	},
	
	onLoad: function() {
		--this.resourcesRemaining;
		++this.resourcesLoaded;
				
		this.onUpdate();
		
		if (this.resourcesRemaining == 0 && this.isReadyToFire) {
			this.onFinish();
		}
	},
	
	onUpdate: function( ) {
		
		// Compute new percentage complete
		this.percentComplete = (this.totalResources > 0) ? (this.resourcesLoaded / this.totalResources) : 1;

		if (this.options && this.options.onUpdate) {
			this.options.onUpdate( this.percentComplete );
		}
	},
	
	load: function( options ) {
		this.options = options;
		this.isReadyToFire = true;
		
		// If all resources have already loaded, then fire finishing callback
		if (this.resourcesRemaining == 0) {
			this.onUpdate();
			this.onFinish();
		}
	},
	
	onFinish: function() {
	
		// Fire afterFinish callback
		if (this.options) {
			if (this.options.afterFinish) {
				this.options.afterFinish();
			}
			if (this.options.onUpdate) {
				this.options.onUpdate(1);
			}
		}
		
	}

}