/**
 *
 * Cloud class
 *
 * JavaScript / MooTools 1.2.4
 *
 * Cloudy Trafic:  Statistici trafic.ro pentru cei cu capul in nori <http://www.punctsivirgula.ro/>
 * Copyright 2009, Ionut-Alexandru Lixandru - alex.lixandru@gmail.com
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright		Copyright 2009, Ionut-Alexandru Lixandru
 * @link				http://cloudy.punctsivirgula.ro/ Cloudy Trafic
 * @package			cloudy
 * @subpackage	cloudy.js
 * @since				v 0.0.1
 * @version			1
 * @author			Ionut-Alexandru Lixandru
 * @modifiedby		Ionut-Alexandru Lixandru
 * @lastmodified	n/a
 * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
 *
 */
 
var Cloud = new Class({
	
	Extends: Fx.Move,
	Implements: [Options],

	options: {
		height: 300, 						// what's the rank of the cloud
		maxHeight: 600, 				// what's the rank of the highest cloud
		index: 0, 							// the index of the cloud (0, 1, 2, ... ) 
		defaultCloudHeight: 30, 		// default height of a small cloud
		defaultCloudLeft: 40, 			// what's the starting position from the left
		defaultCloudTop: 40,			// what's the starting position from the top
		duration: 'long', 					// movement effect duration
		transition: 'expo:out', 			// movement effect
		clean: false, 						// should be true when displaying other clouds (after an ajax request
		debug: false 						// prints debugging info - works on firefox, chrome, opera
	},
	
	
	//initialization
	initialize: function(element, options) {
		// store a reference to the element 
		this.container = $( element );
		this.containerID = element;
		
		// count the number of total clouds defined for this page
		if( typeof( window[ 'CW_NB_CLOUDS' ] ) == 'number' ) window[ 'CW_NB_CLOUDS' ] = window[ 'CW_NB_CLOUDS' ] + 1;
		else window[ 'CW_NB_CLOUDS' ] = 1;
		
		//set options
		this.setOptions(options);
		
		// call the parent constructor
		this.parent( this.container, { duration: this.options.duration, transition: this.options.transition } );
		
		if( this.options.clean && this.options.index == 0 ) {
				window[ 'CW_CLOUDS_TOP' ] = new Array();
				window[ 'CW_LAST_LEFT' ] = this.options.defaultCloudLeft;
				window[ 'CW_NB_CLOUDS' ] = 1;
				window.removeEvents( 'resize' );
		}
		
		// set an event
		this.container.addEvents({
			'dblclick': this.disappear.bind( this ),
			'mouseenter': this.zoomin.bind( this ),
			'mouseleave': this.zoomout.bind( this )
		});
		
		window.addEvent('resize', this.regroup.bind( this ) );
		
		// make this draggable
		this.drag = new Drag.Move( this.container, {
			onComplete: this.showUp.bind( this )
		});
		
		window[ 'CW_CLOUDS_RESIZE' ] = 0;
		
		this.regroup( true );
	},
	
	
	
	// regroup recalculates the top/left for the object, this is usually called when window resizes
	regroup: function(initialization) {
		
		if( !initialization ) {
			if( window[ 'CW_CLOUDS_RESIZE' ] == 0 ) {
				// reset some globals
				window[ 'CW_CLOUDS_TOP' ] = new Array();
				window[ 'CW_LAST_LEFT' ] = this.options.defaultCloudLeft;
			}
			window[ 'CW_CLOUDS_RESIZE' ] += 1;
			if( window[ 'CW_CLOUDS_RESIZE' ] == window[ 'CW_NB_CLOUDS' ] ) window[ 'CW_CLOUDS_RESIZE' ] = 0;
		}
		
		// get the size of the window. if this is not available use the default value
		var windowSize = window.getSize();
		var windowHeight = windowSize.y - 100;
		var windowWidth = windowSize.x + 100;
		var maxCloundsOnPage = Math.round(windowWidth / 300);
		
		//calculate element's Top
		if( this.options.debug ) console.log( 'H/M ' + this.options.height + ' ' + this.options.maxHeight );
		elementTop = this.options.defaultCloudTop + windowHeight - Math.ceil( windowHeight * this.options.height / this.options.maxHeight );
		elementTop += this.options.index;
		
		// store all Top's
		if( !window[ 'CW_CLOUDS_TOP' ] ) window[ 'CW_CLOUDS_TOP' ] = [ elementTop ];
		else window[ 'CW_CLOUDS_TOP' ].push( elementTop );
		
		// set element's Left the default one
		elementLeft = this.options.defaultCloudLeft;
		
		// adjust element's Left if there are overlapping clouds
		if( this.options.index == 0 && initialization) {
			window[ 'CW_LAST_LEFT' ] = this.options.defaultCloudLeft;
			window[ 'CW_MOVED_2RIGHT' ] = 0;
		} else {
			if( Math.abs(elementTop - window[ 'CW_CLOUDS_TOP' ][ this.options.index - 1 ]) < this.options.defaultCloudHeight ) {
				elementLeft = window[ 'CW_LAST_LEFT' ] + 250;
				window[ 'CW_MOVED_2RIGHT' ] += 1;
				
				// if we're moving too many to the right we'll end up having clouds going out of the screen
				if( window[ 'CW_MOVED_2RIGHT' ] >= maxCloundsOnPage ) {
					elementLeft = this.options.defaultCloudLeft;
					window[ 'CW_MOVED_2RIGHT' ] = 0;
				}
			} else {
					window[ 'CW_MOVED_2RIGHT' ] = 0;
			}
			//elementLeft += this.options.index * 10;
			window[ 'CW_LAST_LEFT' ] = elementLeft;
		}
		
		if( this.options.debug ) console.log( 'Elem ' + this.options.index + ' Top: ' + elementTop + ' / Left: ' + elementLeft + " w: " + windowHeight );
		
		// store the coordinates
		this.styleTop = elementTop;
		this.styleLeft = elementLeft;
		
		// show the clouds
		if( initialization ) this.showUp( initialization );
		else this.showUp.delay( 100, this );
	},
	
	
	
	// showUp method is the function that makes the cloud appear on the page
	showUp: function(initialization) {
		if( initialization == true ) {
			this.container.setStyle( 'top', this.styleTop );
			this.container.setStyle( 'left', -300 );
			this.hidden = false;
		}
		
		// show it
		if( !this.hidden )
		this.start({
			relativeTo: document.body,
			position: 'upperLeft',
			edge: false,
			offset: {x:this.styleLeft, y:this.styleTop}
		});
		
	},
	
	
	
	// disappear method is the function that makes the cloud go off the screen
	disappear: function() {
		this.cancel();
		this.hidden = true;
		try {
			this.start({
				relativeTo: document.body,
				position: 'upperRight',
				edge: false,
				offset: {x:this.styleLeft * 2, y:this.styleTop}
			});
		} catch( e ) {
			// IE throws an exc sometimes
		}
		
	},
	
	
	
	// zoomin displays the big cloud
	zoomin: function() {
		if( this.hidden ) return;
		var more = this.containerID + '_img';
		
		if( this.morph ) this.morph.cancel();
		this.morph = new Fx.Morph( $( more ), {
			onStart: function() {
						//this.container.getElement( 'img' ).fade( 'show' );
						this.container.setStyle( 'z-index', 11 );
					}.bind( this ),
			onComplete: function() {
						this.container.getElement( 'div' ).fade( 'show' );
					}.bind( this ),
			duration: 300
		} ).start({
			height: 110,
			top: -55,
			left: -40,
			width: 350,
			opacity: 1
		});
	},
	
	
	
	// zoomout hides the big cloud
	zoomout: function() {
		if( this.hidden ) return;
		var more = this.containerID + '_img';
		
		if( this.morph ) this.morph.cancel();
		this.morph = new Fx.Morph( $( more ), {
			onComplete: function(){
						//this.container.getElement( 'img' ).hide();
						this.container.getElement( 'img' ).fade( 'hide' );
						this.container.setStyle( 'z-index', 1 );
					}.bind( this ),
			onStart: function() {
						this.container.getElement( 'div' ).fade( 'hide' );
					}.bind( this ),
			duration: 300
		} ).start({
			top: 3,
			left: 5,
			height: 30,
			width: 195
		});
		
		
	}
	
});
