/* BEGIN ImagePreloader object 

ImagePreloader (c)2004 Petter Ellgård
A JavaScript Image Preloader object

Usage: 
ipl = new ImagePreloader([full path, base path, image name or array containing any of these values][,same ...][,...]);
ipl.add([full path, base path, image name or array containing any of these values][,same ...][,...]);

Example: 
---- ipl is initialized with a base path of images/. images/test.jpg, images/test2.jpg and
---- http://www.sample.site/img/sample.png are loaded. If no base path is set it defaults to
---- empty string (current folder). 
ipl = new ImagePreloader('images/','test.jpg','test2.jpg','http://www.sample.site/img/sample.png')

---- An array of images is created and added. The base path is still images/ so these images are loaded 
---- images/test3.jpg, images/test4.jpg and then the base path is switched to ../samples/source/pix and 
---- ../samples/source/pix/pic1.gif is also loaded.
a = new Array('test3.jpg','test4.jpg','../samples/source/pix','pic1.gif')
ipl.add(a);

---- myfolder/mypic.bmp is loaded but the base path remains as ../samples/source/pix
ipl.add('myfolder/mypic.bmp')

---- The base path is switched to myfolder/contents/stuff
ipl.add('myfolder/contents/stuff')

---- myfolder/contents/stuff/stuff1.gif and myfolder/contents/stuff/stuff2.gif is loaded
ipl.add('stuff1.gif','stuff2.gif')

... and so on.  
*/

//Just another syntax for: function ImagePreloader(){}
ImagePreloader = function(){
	//Force this function to be used as a constructor
	if(!(this instanceof ImagePreloader))return new ImagePreloader();

	//Private properties
	var aryImages = new Array();
	var aryFileExtensions = new Array('.gif','.jpg','.png','.bmp');
	var strBasePath = "";
	//Fix for a bug in ECMA script (when referencing this in private methods, use self instead)
	var self = this;
	
	if(document.images){
		if(arguments.length > 0)init(arguments);
		else init();
	}
	
	/*
	----- Privileged methods (accessible from the outside and from public methods, has access to private members) ----
	*/
	
	//Privileged method. Explicitly set current basepath, normally done with just add(base path) 
	function setBasePath(str){
		if(document.images)if(validateBasePath(str))strBasePath = str;
	}
	this.setBasePath = setBasePath;

	//Privileged method. Returns the current base path.
	function getBasePath(){
		if(document.images)return strBasePath;
	}
	this.getBasePath = getBasePath;

	//Privileged method. Add an image and/or set base path.
	function add(){
    		if(document.images)if(arguments.length > 0)create(arguments);
	};

	//Aliases for the add method.
	ImagePreloader.prototype.add = add;
	ImagePreloader.prototype.addImage = add;
	ImagePreloader.prototype.addImages = add;
	ImagePreloader.prototype.set = add;
	ImagePreloader.prototype.setImage = add;
	ImagePreloader.prototype.setImages = add;
	ImagePreloader.prototype.load = add;
	ImagePreloader.prototype.loadImage = add;
	ImagePreloader.prototype.loadImages = add;
	ImagePreloader.prototype.preload = add;
	ImagePreloader.prototype.preloadImage = add;
	ImagePreloader.prototype.preloadImages = add;

	//Privileged method. Add support for filetypes by extension
	ImagePreloader.prototype.addFileExtension = function(str){
		if(document.images)if(validateFileExtensionFormat(str))aryFileExtensions[aryFileExtensions.length] = str;
	};

	//Privileged method. Returns an array of all supported file extensions.
	ImagePreloader.prototype.getFileExtensions = function(){
		if(document.images)return aryFileExtensions;
	};

	//Privileged method. Returns an array of all stored images.
	ImagePreloader.prototype.getImages = function(){if(document.images)return aryImages;};

	/*
	---- Private methods (not accessible from the outside or from public methods) ----
	*/

	//Private method. Takes a maximum of one argument of type Array
	function init(){
		if(document.images)if(arguments.length == 1)create(arguments[0]);
	}
	
	//Private method. Argtype can be either a full path, a path base or an image name, anything else will set basepath to ''
	function getArgType(arg){
    		if(document.images){
			argType = 0; //empty path
			if(arg.indexOf('/')>-1){
				if(containsValidExtension(arg))argType = 1; //full path
				else argType = 2; //only path (no image name)
			}else if(containsValidExtension(arg))argType = 3; //only image name
			return argType;
		}
	}
	
	//Private method
	function validateBasePath(str){
		if(document.images){
			if(str == '' || str.indexOf('/') > -1)return true;
			else return false;
		}
	}

	//Private method
	function validateImageName(strImageName){
		if(document.images){
			//possibly check againts browsers mimetypes?
			isValid = false;
			if(strImageName.length > 4)isValid = containsValidExtension();
			return isValid;
		}
	}

	//Private method
	function containsValidExtension(str){
		if(document.images){
			c = false;
			for(var i=0;i<aryFileExtensions.length;i++){
				if(str.indexOf(aryFileExtensions[i])>-1){
					c = true;
					break;
				}
			}
			return c;
		}
	}
	
	//Private method
	function validateFileExtensionFormat(str){
		if(document.images){
			if(str.length >= 4 && str.charAt(0) == '.')return true;
			else return false;
		}
	}

	//Private method
	function create(){
    		if(document.images && arguments.length > 0){
			ary = new Array();
			l=0;
			arg = "";
		
			for(var i=0;i<arguments.length;i++){
				if(arguments[i] && typeof arguments[i] == 'object'){
					for(var j=0;j<arguments[i].length;j++){
						if(arguments[i][j] && typeof arguments[i][j] == 'object'){
							for(var k=0;k<arguments[i][j].length;k++){
								if(arguments[i][j][k] && typeof arguments[i][j][k] == 'object'){
									//alert('ImagePreloader: Argument has too many dimensions');
									continue;
								}else{
									arg = arguments[i][j][k];
									switch(getArgType(arg)){
										case 1:
											ary[l] = new Image();
											ary[l].src = arg;
											l++;
											break;
										case 2:
											setBasePath(arg);
											break;
										case 3:
											ary[l] = new Image();
											ary[l].src = getBasePath() + arg;
											l++;
											break;
										default:
											setBasePath('');
									}
								}
							}
						}else{
							arg = arguments[i][j];
							switch(getArgType(arg)){
								case 1:
									ary[l] = new Image();
									ary[l].src = arg;
									l++;
									break;
								case 2:
									setBasePath(arg);
									break;
								case 3:
									ary[l] = new Image();
									ary[l].src = getBasePath() + arg;
									l++;
									break;
								default:
									setBasePath('');
							}
						}
					
					}
				
				}else{
					arg = arguments[i];
					switch(getArgType(arg)){
						case 1:
							ary[l] = new Image();
							ary[l].src = arg;
							l++;
							break;
						case 2:
							setBasePath(arg);
							break;
						case 3:
							ary[l] = new Image();
							ary[l].src = getBasePath() + arg;
							l++;
							break;
						default:
							setBasePath('');
					}
				}
			
			}
			//add images to the main storage array
			if(aryImages.length > 0)for(var i=0;i<ary.length;i++)aryImages[aryImages.length] = ary[i];
			else aryImages = ary;
		}
	}
	
	
}

/*
---- Public methods (accessible from the outside, can not access private methods) ----

//Public method. Overrides Object.toString() method.
ImagePreloader.prototype.toString = function(){return "[object ImagePreloader]";};

/* END ImagePreloader object */
