// e24Squares e24squares.js v0.2, Thu March 21 22:07:12 -0500 2008

// Copyright (c) 2008 equipo24 S.L.N.E. (http://www.equipo24.com)
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

var e24Squares = Class.create();
e24Squares.prototype = {
	initialize: function( p_eContainer, p_aImages, p_aOptions ) {
		this.m_fCallBack = p_aOptions.callback ? p_aOptions.callback : undefined;
		this.m_bAutoStart = p_aOptions.autostart;
		this.m_bHideOnFinish = p_aOptions.hideonfinish;
		this.m_sBase = p_aOptions.base;
		this.m_iWidth = p_aOptions.width;
		this.m_iHeight = p_aOptions.height;
		this.m_iRows = p_aOptions.rows?p_aOptions.rows:3;
		this.m_iCols = p_aOptions.cols?p_aOptions.cols:5;
		this.m_sColor = p_aOptions.color ? p_aOptions.color : '#fff';
		this.m_iDuration = p_aOptions.duration ? p_aOptions.duration : 1.0;
		this.m_iInterval = p_aOptions.interval ? p_aOptions.interval : 0.3;
		this.m_eContainer = $( p_eContainer );
		this.m_aImages = p_aImages;
		this.m_eContainer.setStyle( { overflow: 'hidden', position: 'relative'} );
		this.m_iLoaded = 0;
	    this.m_iCurrent = -1;
		this.m_iPrevious = -1;		
		this.m_eImages = [];
		this.m_aSquares = [];				
		
		if (this.m_bAutoStart) {
			//setTimeout(this.start.bind(this), this.m_iInterval * 1000);
			this.start();
		}	
	},


	start: function() {
	    this.m_eContainer.update('');
		var sqWidth = this.m_iWidth / this.m_iCols;
		var sqHeight = this.m_iHeight / this.m_iRows;
        for (var i = 0; i < this.m_iCols; i++) { 
		    this.m_aSquares[i] = [];
			for (var j = 0; j < this.m_iRows; j++) {
			    var sqLeft = i * sqWidth;
			    var sqTop = j * sqHeight;
				this.m_aSquares[i][j] = new Element('div', { 'style': 'opacity:0;background-color:' + this.m_sColor + ';position:absolute;z-index:6;left:' + sqLeft + 'px;top:' + sqTop + 'px;width:' + sqWidth + 'px;height:' + sqHeight + 'px;' });	
				this.m_eContainer.appendChild(this.m_aSquares[i][j]);
			}		
		}

		for (i = 0; i < this.m_aImages.length; i++) {
		  this._loadImage(this.m_aImages[i], i);
		}
	},

	_loadImage: function(p_Img, index) {
		var eImage =  new Element('img', { 'src': this.m_sBase + p_Img, 'style': 'opacity:0;position:absolute;z-index:5;left:0px;top:0px;width:' + this.m_iWidth + 'px;height:' + this.m_iHeight + 'px;' });	
		this.m_eContainer.appendChild( eImage );
		this.m_eImages[index] = eImage;
		if(!eImage.complete) {
			/* The image is not yet loaded, so fix the loading div */
			if (!this.m_eLoading) {
				this.m_eLoading = new Element('div', { 'style': 'position:absolute;left:5px;top:5px;color:#FFF'}).update('Loading...');
				this.m_eContainer.appendChild( this.m_eLoading );
			}	
			Event.observe( eImage, 'load', this._onLoad.bindAsEventListener( this ) );
		} else {
			/* The image is already loaded*/
			this._onLoad();
		}
	},
	
	_onLoad: function(eImage) {
		this.m_iLoaded++;
		if (this.m_iLoaded == this.m_aImages.length) {
			//this.m_eLoading.setStyle('visibility', 'hidden');
			if (this.m_eLoading) this.m_eLoading.hide();
			this.m_eBack = new Element('div', { 'style': 'opacity:0;position:absolute;z-index:4;left:0px;top:0px;width:' + this.m_iWidth + 'px;height:' + this.m_iHeight + 'px;' });				
		    this.m_eContainer.appendChild(this.m_eBack);
			
			if (this.m_bAutoStart) {
				this.m_iIntervalId = setInterval(this._load.bind(this), this.m_iInterval * 1000);
			}	
			else {
				this.transition(0);
			}
		}
	},
		
	transition: function(index, pCallBack) {
	    if (pCallBack) {
			fCallBack = pCallBack.bind(this); 		
		}
		else if (index < this.m_aImages.length - 1  || !this.m_bAutoStart) { 
			fCallBack = undefined; 
		} 
		else { 
			fCallBack = this._callBack.bind(this); 
		}
		
		if (index < this.m_aImages.length) {
		}
		else {
			if (this.m_bHideOnFinish) {
				new Effect.Parallel(
				[ 
					new Effect.Appear ( this.m_eImages[this.m_iPrevious], { from: 1.0, to: 0 } )
				],
				{ 
					sync: false,
					duration: this.m_iDuration
				});				
		        for (var i = 0; i < this.m_iRows; i++) { 
					var delay = Math.random() * 100;				
					for (var j = 0; j < this.m_iCols; j++) {
						var eSquare = this.m_aSquares[j][i];
						setTimeout(this._delayedAppear.bind(this, eSquare), delay);
					}		
				}
			}
			clearInterval(this.m_iIntervalId);
			return;
		}
		if (index == 0 || this.m_iPrevious == -1) {
			back = this.m_eBack;
		}
		else {
			back = this.m_eImages[this.m_iPrevious];		
		}
		
		new Effect.Parallel(
		[ 
			new Effect.Appear ( back, { from: 1.0, to: 0 }),
			new Effect.Appear ( this.m_eImages[index], { from: 0, to: 1.0 } )
		],
		{ 
			sync: false,
			duration: this.m_iDuration,
			afterFinish: fCallBack
		});			

       for (var i = 0; i < this.m_iCols; i++) { 
			for (var j = 0; j < this.m_iRows; j++) {
				var eSquare = this.m_aSquares[i][j];
				var delay = Math.random() * 100;				
				setTimeout(this._delayedAppear.bind(this, eSquare), delay);
			}		
		}	
		this.m_iPrevious = index;

	},
	
		
	_load: function( ) {
	    this.m_iCurrent++;
		this.transition(this.m_iCurrent);
	},

    _delayedAppear: function(eSquare)	{
		var opacity = Math.random();
		new Effect.Parallel(
		[ 
			new Effect.Appear ( eSquare, { from: 0, to: opacity, duration: 0.2 } ),
			new Effect.Appear ( eSquare, { from: opacity, to: 0, duration: 0.8} )
		],
		{ 
			sync: false
		});			
	},
	
	_callBack: function( p_oObj ) {
		if (this.m_fCallBack) {
		  this.m_fCallBack(this, p_oObj);
		}
	}
	
}	
