/*______________
|       ______  |   U I Z E     J A V A S C R I P T     A P I
|     /      /  |   -----------------------------------------
|    /    O /   |    MODULE : Uize.Widget.Swap.Image Class (version 1.1.0)
|   /    / /    |    AUTHOR : Chris van Rensburg (http://www.tomkidding.com)
|  /    / /  /| |    ONLINE : http://www.tomkidding.com/uize/uize-js-api
| /____/ /__/_| | COPYRIGHT : (c)2005-2008 UIZE
|          /___ |   LICENSE : Distributed under the terms of the GNU General Public License
|_______________|             http://www.gnu.org/licenses/gpl.txt
*/

/*
	DESCRIPTION
		Implements a JavaScript class for swapping images with dissolve support

	REQUIRES
		- Uize.Widget.Swap.js (superclass)
		- Uize.Node.js

	BUGS
		- noticed a problem in Firefox with an image that doesn't fill the entire view and is not being centered correctly.

	TO DO
		- feature to prefetch "next" image while current image is fading in
*/

/*ScruncherSettings Mappings="=d" LineCompacting="TRUE"*/

Uize.module ({
	name:'Uize.Widget.Swap.Image',
	required:'Uize.Node',
	builder:function (_superclass) {
		/*** Variables for Scruncher Optimization ***/
			var _Uize_Node = Uize.Node;

		/*** Object Constructor ***/
			var
				_class = _superclass.subclass (
					function () {
						var _this = this;
						/*** Private Instance Properties ***/
							_this._currentItemNo = 0;
							_this._imagesLoaded = [];
					}
				),
				_classPrototype = _class.prototype
			;

		/*** Setup Properties ***/
			_class.registerProperties ({
				_background:'background',
				_height:'height',
				_src:{
					name:'src|value',
					onChange:function () {
						var _this = this;
						if (_this.wired ()) {
							_this.fade.stop ();
							var
								_currentItem = _this.getNode ('item' + _this._currentItemNo),
								_nextItemNo = 1 - _this._currentItemNo,
								_nextItem = _this.getNode ('item' + _nextItemNo),
								_nextItemImg = _this.getNode ('item' + _nextItemNo + 'Image')
							;
							_nextItem.style.padding = '0px';
							_this.prepareForNextItem (_currentItem,_nextItem);

							function _loadNextImage () {
								var _image = _this._imagesLoaded [_this._src];
								_nextItem.style.paddingLeft = Math.floor ((_this.viewFinalCoords [2] + 1 - _image._width) / 2) + 'px';
								_nextItem.style.paddingTop = Math.floor ((_this.viewFinalCoords [3] + 1 - _image._height) / 2) + 'px';
								function _nextImageLoaded () {
									_nextItemImg.Uize_Widget_ImageSwap_src = _this._src;
									_this.unwireNodeEventsByMatch (_nextItemImg);
									_currentItem.style.zIndex = '0';
									_nextItem.style.zIndex = '1';
									_this._currentItemNo = _nextItemNo;
									_this.setCurrentItem (_nextItem);
								}
								if (_nextItemImg.Uize_Widget_ImageSwap_src === _this._src) {
									/* NOTE:
										In IE 5.2 and Safari 1.3- on Mac OS X, the onload event for an IMG node is not fired when that node's src is set again to its current value. So, when switching back and forth between two image URLs, the onload event cannot be relied upon for triggering the reveal, since we're toggling between two IMG nodes and sometimes an IMG node used to display an image will already have loaded that image from a previous toggle.
									*/
									_nextImageLoaded ();
								} else {
									_this.wireNodeEvents (
										_nextItemImg,
										{
											onload:_nextImageLoaded,
											onerror:_nextImageLoaded,
											onabort:_nextImageLoaded
										}
									);
									if (_Uize_Node.isIe && _this._src.search (/\.png$/i) > -1) {
										_nextItemImg.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + _this._src + '\', sizingMethod=\'crop\')';
										_nextItemImg.src = _class.getBlankImageUrl ();
										_nextItemImg.width = _image._width;
										_nextItemImg.height = _image._height;
									} else {
										_nextItemImg.src = _this._src;
									}
								}
							}
							if (_this._imagesLoaded [_this._src]) {
								_loadNextImage ();
							} else {
								var _imageLoader = new Image ();
								/* NOTE:
									we can't use the setImageHandler function here because Safari doesn't implement instances of the Image class as real DOM IMG nodes, and so the Uize.Node.wireEvents has no effect.
								*/
								_imageLoader.onload = _imageLoader.onerror = _imageLoader.onabort =
									function () {
										_imageLoader = null;
										_this._imagesLoaded [_this._src] = {
											_width:_this._width || this.width,
											_height:_this._height || this.height
										};
										_loadNextImage ();
									}
								;
								_imageLoader.src = _this._src;
							}
						}
					},
					value:''
				},
				_width:'width'
			});

		/*** Override Initial Values for Inherited Set-Get Properties ***/
			_class.set ({
				html:function () {
					var
						_this = this,
						_shellNode = _this.getNode (),
						_shellSize = _Uize_Node.getDimensions (_shellNode),
						_background = _this._background || Uize.Node.getEffectiveBgColor (_shellNode)
					;
					function _getItemTag (_itemNo) {
						return (
							'<div id="[#idPrefix]-item' + _itemNo +
							'" style="position:absolute; margin:0px; padding:0px; left:0px; top:0px; width:' + _shellSize.width +
							'px; height:' + _shellSize.height + 'px; background:' + _background +
							'; overflow:hidden;"><img id="[#idPrefix]-item' + _itemNo + 'Image" src="' +
							_class.getBlankImageUrl () + '"' +
							(typeof _this._width == 'number' ? (' width="' + _this._width + '"') : '') +
							(typeof _this._height == 'number' ? (' height="' + _this._height + '"') : '') + '/></div>'
						);
					}
					return _getItemTag (0) + _getItemTag (1);
				}
			});

		return _class;
	}
});

