 /* 
    #########################################
    Author : JACKSON OATES jackson@zeroninelab.com
    Company : ZERO NINE LAB, LLC - www.zeroninelab.com
    Date: 11/30/08 
    Updated: 09/04/09 to v0.3 
    * 
    #########################################

    PERIODICALLY TEST FOR EXISTENCE OF AN ASSET UNTIL IT IS FOUND (CREATED). ONCE
    ASSET IS FOUND, INJECT INTO DOM, AND KILL REQUEST. MAKES 'preview' EVENT AVAILABLE
     
    THIS CLASS IS MEANT TO BE EXTENDED, AND TO EASILY ADD ADDITIONAL FUNCTIONALITY TO NEW ASSET WITH 'preview' EVENT
    
    
    IMPLEMENT:  
	function assetTest(){
		* define parent, where asset will be injected and event will be attached
		par = $('secondary'); 
		new AssetTest({
			_parent:$('parentElement'),
			_url:'../../path/to/image/',
			_loadingImageSrc:'../../path/to/loading/image',
			_defaultFileName:'filename'
		});
		* preview event added to parente
		par.addEvents({
			'preview':onPreview
		});
		* customize event, in this case preview image is passed back and faded in/out on click
		function onPreview(url, previewImage, _parent) {
			var largePreview = new Element('img', {
				'id':'lgPreview',
				'src':url+previewImage,
				'styles': {
			        'position': 'absolute',
			        'top':0,
			        'left':0,
			        'opacity':0,
			        'z-index':10
			    },
				'events': {
			        'click': function(){
			            this.fade('out')
			        }
			    }
				
			})
	        largePreview.inject(_parent, 'top').fade('in')
		}
	}
    UPDATE LOG:
    09/04/09:
    v0.3 cured this.setOptions error when using with MT library version 1.2+
    added support for image dimensions, and a morph from loading image to injected asset,
    timeout added to kill request if asset is not found after x time.
    
*/


var AssetTest = new Class({
	Implements: [Options],	
    options:{
		_dimensions :	 ({x:'auto',y:'auto'}),
		_morphDuration : 1000,		
		_notFoundMarker	 : false,
		_notFoundMsg	 : 'Image Not Found',
		_loadingImageSrc : '../resources/images/backgrounds/loading_med.gif',
		_defaultFileName : '200.jpg',
		_errorClassName	 : 'missingImage',
		_timeout		 : 5000 // check for asset for 5 seconds then stop checking
    },
    initialize: function(options){
    	this.setOptions(options);
		this._parent			= this.setParent();
		this._url	 			= this.options._url;
		this._dimensions		= this.options._dimensions;
		this._morphDuration		= this.options._morphDuration;
		this._notFoundMarker	= this.options._notFoundMarker;
		this._notFoundMsg		= this.options._notFoundMsg;
		this._notFoundEl		= this.createNotFound();
		this._defaultFileName	= this.options._defaultFileName;
		this._defaultPreview	= this.options._defaultPreview;
		this._loadingImageSrc	= this.options._loadingImageSrc;
		this._loadingImage		= this.loadingImage();
		this._loadingImage.inject(this._parent, 'top');
		this._request			= this.requestAsset(); 
		this._cycle 			= this.requestAsset.periodical(2500,this);
    	this.timeout			= this.options._timeout;
		this._loadingImage.setStyles({
	        'top':0,
	        'left':0,
			'z-index':0
		});
		this.nfDelay = this.notFound.delay(this.timeout, this);
	},
	
	setParent : function(){
		p = $(this.options._parent);
		p.setStyle('position','relative');
		return p; 
	},
	
	createNotFound : function(){
		nf = new Element('span', {'html':this._notFoundMsg,'class':this.options._errorClassName});
		return nf;
	},
	
	notFound : function(){
		if(this._notFoundMarker == true) return;
		this.killRequest();
		this._notFoundEl.replaces(this._loadingImage);
		
	},
	
	killRequest : function(){
		$clear(this._cycle);
	},
	terminateTest: function() {
		$clear(this._cycle);
		$clear(this.nfDelay); 
	},
	
	requestAsset : function(){
		this._reqImage = new Asset.image(this._url + this._defaultFileName+'?t='+$time(), {
			onerror: this.requestFail,
			onload: this.requestSuccess.bindWithEvent(this)
		});
	},
	
	requestFail : function(){
		//console.log('asset not found: trying again ', this._url + this._defaultFileName);
	},
	
	requestSuccess : function(){
		/**
		 * TODO: debug flicker of image injected at full size, before it enteres the Morph.
		 */
		this._notFoundMarker = true;
		this.killRequest();
		this._loadingImage.set('src', this._url + this._defaultFileName);
		// skips FX.Morph error in Trident browsers
		if(Browser.Engine.trident){
			this._loadingImage.setStyles({
		        'height':400,
		        'width':507
			});
		}else{
			this.fx = new Fx.Morph(this._loadingImage,{duration:this._morphDuration,transition: Fx.Transitions.Quad.easeOut});
			this.fx.start({
				'width':this._dimensions.x,
				'height':this._dimensions.y
			})
			
		}
		this._loadingImage.addEvents({
			'click': this.onClick.bind(this)
		})
	},
	
	onClick: function() {
		this._parent.fireEvent('preview');
	},
		
	loadingImage : function(){
		image = new Asset.image(this._loadingImageSrc);
		return image;
	}
	
});
AssetTest.implement(new Events, new Options);