/*
 * ImageLoader v3.1
 *     image preloader class for DHTML-Javascript 1.1 and
 *     DHTML-JScript 2.0
 *
 * by: Hyperion <noog@libero.it>
 *
 * Report bugs to the author
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details:
 * <URL: http://www.gnu.org/copyleft/lesser.html>
 *
 * NOTE: removing (but not modifying) the comments inside the code,
 * not including this block, won't be considered an actual modification
 * of the program
 */
 
function ImageLoader(){
/* private symbols */
	var _srcs = new Array();
	var _imgs = new Array();
	var _count = 0;
	var _done = 0;
	var _userdata = null;
	var _cancel = false;
	var _onerror_proc = null;
	var _onload_proc = null;
	var _oncomplete_proc = null;

/* private functions */
	/* stub for images' onerror event */
	function _onerror_stub(){
		if(_cancel){
			return false;
		}
		else{
			if(_onerror_stub.caller){
				cur = _onerror_stub.caller.id;
			}
			else{
				cur = -1;
			}

			++ _done;

			if(_onerror_proc)
				var ret = _onerror_proc(
					cur,
					_done,
					_count,
					_done / _count,
					_srcs[cur],
					_imgs[cur],
					_userdata
				);

			if((typeof(ret) == "undefined") || ret){
				if(_done == _count)
					if(_oncomplete_proc)
						_oncomplete_proc(_userdata);

				return true;
			}
			else{
				if(_oncomplete_proc)
					_oncomplete_proc(_userdata);

				_abort();
				return false;
			}
		}
	}
	/* stub for images' onload event */
	function _onload_stub(){
		if(_cancel){
			return false;
		}
		else{
			if(_onload_stub.caller){
				cur = _onload_stub.caller.id;
				time = _onload_stub.caller.timestamp;
			}
			else{
				cur = -1;
				time = new Date();
			}

			++ _done;

			if(_onload_proc)
				var ret = _onload_proc(
					cur,
					_done,
					_count,
					_done / _count,
					_srcs[cur],
					_imgs[cur],
					time,
					(new Date()) - time,
					_userdata
				);

			if((typeof(ret) == "undefined") || ret){
				if(_done == _count)
					if(_oncomplete_proc)
						_oncomplete_proc(_userdata);

				return true;
			}
			else{
				if(_oncomplete_proc)
					_oncomplete_proc(_userdata);

				_abort();
				return false;
			}
		}
	}
	/* stops & destroys any image */
	void function _abort(){
		for(_i in _imgs) delete _imgs[_i];
		_count = _done = 0;
		_cancel = true;
	}
	/* class entry point */
	void function _main(args){
		if(args.length == 1) for(_i in args[0]){
			_srcs[_count] = args[0][_i];
			_count ++;
		}
		else for(var _i = 0; _i < args.length; _i ++, _count ++){
			_srcs[_count] = args[_i];
		}
	}

/* public events */
	/* fired when an image fails to load */
	this.onerror = null; // function (cur, done, count, perc, src, img, userdata){return true}
	/* fired when an image successfully loads */
	this.onload = null; // function (cur, done, count, perc, src, img, started, elapsed, userdata){return true}
	/* fired at the end of image loading */
	this.oncomplete = null; // function (userdata){}

/* public functions */
	/* store pointers to event handlers and start loading images */
	this.load = function (vData){
		_onerror_proc = this.onerror;
		_onload_proc = this.onload;
		_oncomplete_proc = this.oncomplete;

		_userdata = vData;
		_cancel = false;

		for(_i in _srcs){
			_imgs[_i] = new Image();

			_imgs[_i].onerror = function (){_onerror_stub()};
			_imgs[_i].onload = function (){_onload_stub()};
			_imgs[_i].onerror.id = _imgs[_i].onload.id = _i;
			_imgs[_i].onload.timestamp = new Date();

			_imgs[_i].src = _srcs[_i];
		}
	}
	/* destroys images */
	this.unload = function (){
		if(arguments.length > 0) for(_i = 0; _i < arguments.length; _i ++){
			delete _imgs[_i];
		}
		else for(_i in _imgs) delete _imgs[_i];
	}
	/* exports _abort() */
	//this.abort = _abort;
	/* destroys private objects */
	this.free = function (){
		delete _imgs;
		delete _srcs;
		delete _userdata;
	}
/* jump to the entry point */
	//_main(arguments);
}
