
/*
NOTE: 

- Questa classe assume un certo setup css/html a monte (riferimento: files/css/shared.css)
In particolare:
*html e body sparati al 100% delle dimensioni; 
*un box che contiene l'elemento da ridimensionare (con dimensioni già settate alle sue massime o via data-size);
*l'elemento inizialmente nascosto;

- Questa classe non si occupa di far coprire all'immagine l'intera area dello schermo. 
Si occupa piuttosto di massimizzarne le dimensioni mantenendola però sempre visibile, ed in qualsiasi elemento.

*/

var ResizeManager = new Class({

	Implements:[Options,Events],
	
	options:{
		top_offset:0,
		bottom_offset:0,
		side_offset:0,//per tener conto delle frecce laterali
		min_height:null,
		min_width:null,
		min_priority:'height',
		child:null,//per ora il nome di un tag. In futuro valutare se passare un id o un riferimento.
		adjust_margin_left:false,
		adjust_margin_top:false,
		get_data_size:false,
		onResized:function(){}
	},
	
	initialize: function(box,element,contents,options){
		this.setOptions(options);
		
		this.box = $(document.body).getElement(box);
		this.element = $(document.body).getElement(element);
		this.contents = $(document.body).getElement(contents);//da vedere/gestire
		this.start_width;
		this.start_height;
				
		this.is_obj = this.element.match('object');
		
		this.start();
	},//end init
	
	start:function(){
		this.init_element();
		window.addEvent('resize', this.resize.bind(this));
	},
	
	init_element:function(){
		
		var size = null;
	
		if(this.options.get_data_size){
			size = this.expand_props(this.element.get('data-size'), true);
			this.start_width = size.width;
			this.start_height = size.height;
		} else if(this.is_obj){//un object (es. swf) con dimensioni già settate
			size = this.element.getProperties('width','height');
			this.start_width = size.width;
			this.start_height = size.height;
		} else {//un normale elemento mootools
			var size = this.element.getDimensions();
			this.start_width = size.x;
			this.start_height = size.y;
		}

		this.box.setStyle('overflow','hidden');//disattivato eventualmente nei calcoli delle dimensioni minime (vedi resize())

		this.element.setStyles({ 
			'display':'block',
			'visibility':'hidden'
		});

		this.resize();
		//this.resize();

		this.element.setStyle(
			'visibility','visible'
		);

		//window.fireEvent('resize');
	},
	
	resize:function(e){
				
		var width_ratio, new_height, new_width, height_ratio, child, margin_left, margin_top = null;

		//anzitutto ridimensiono il box contenitore. 
		//Sulla base del contenitore, calcolo le dimensioni finali di this.element		
		this.box.setStyles({
			'height':window.getSize().y-this.options.top_offset-this.options.bottom_offset
			//,'width':window.getSize().x
		});

		//calcolo rapporto altezza/base e poi li confronto per decidere se la priorità va all'altezza o alla base
		var box_size = this.box.getSize();
		var box_ratio = box_size.y/box_size.x;
		
		var element_ratio = this.start_height/this.start_width;
		
		var priority = (box_ratio < element_ratio) ? 'height' : 'width';

 		if(priority == 'height'){
 			new_height = box_size.y;
 			new_width = Math.ceil(this.start_width*(box_size.y/this.start_height));
 		} else {
 			new_width = box_size.x;
 			new_height = Math.ceil(this.start_height*(box_size.x/this.start_width));
 		}

		//finiti i calcoli di base, ricalcolo in base a options.min_height
		//TODO: aggiungere anche check di min_width
		if(this.options.min_height && new_height < this.options.min_height){
			this.box.setStyle('overflow','visible');
			var min_ratio = this.options.min_height/this.start_height;
			new_height = this.start_height*min_ratio;
			new_width = this.start_width*min_ratio;
		} else if(this.options.min_width && (new_width < this.options.min_width)){
			this.box.setStyle('overflow','visible');
			var min_ratio = this.options.min_width/this.start_width;
			new_height = this.start_height*min_ratio;
			new_width = this.start_width*min_ratio;
		} else {
			if(this.box.getStyle('overflow') == 'visible'){ this.box.setStyle('overflow','hidden'); }
		}

		//si da per scontato che il child sia l'unico e che prenda sempre le esatte dimensioni di this.element
		//viene inoltre verificato ad ogni resize, perché il child potrebbe venire iniettato DOPO l'inizializzazione di ResizeManager
		if(this.options.child){
			child = this.element.getElement(this.options.child);
		}
		
		var margin_left = (this.options.adjust_margin_left) ? -Math.round(new_width/2) : '';
		var margin_top = (this.options.adjust_margin_top) ? -Math.round(new_height/2) : '';

		if(!this.is_obj){
			$$(this.element,child).setStyles({
				'height':Math.round(new_height),
				'width':Math.round(new_width)
			});
		} else {
			this.element.setProperties({ 'width':new_width, 'height':new_height });
		}
	
		this.element.setStyles({
			'margin-left':margin_left,
			'margin-top':margin_top
		});
				
		this.box.setStyles({
			'height':new_height
			//,'width':window.getSize().x
		});

		this.fireEvent('onResized',[new_width,new_height,margin_left,margin_top]);
	},//end resize
	
	get_min_size:function(dimension){
	
	},

	expand_props:function(prop_string,to_int){
		var props = {};
		var string = prop_string.replace(" ","","g");
		
		var s = string.split(',').each(function(p,i){
			var clean = p.split(':');
			props[clean[0]] = (to_int) ? clean[1].toInt() : clean[1];
		},this);
		
		return props;
	},
	
	switch_element:function(element){
		this.element = element;
		this.init_element();
		return this;
	}
	
});//END


/* --------------------------------------------- */


/*
name: ImagePreloader
description: ad ogni elemento-sorgente con classe indicata aggiunge uno spinner, precarica il path (immagine) in data-source, elimina lo spinner e l'elemento-sorgente, inietta nel parent l'immagine con opacity=0, fade-in dell'immagine
license: MIT-style license.
authors:
	- Luca Reghellin
requires: 
	- More/Assets.image
*/

var ImagePreloader= new Class({

	Implements:[Options,Events],
	
	options:{
		show_loader:false,
		loader_path:'../files/images/loader.gif',
		items_class:'image-preload',
		get_data_size:true,//false se l'item è già ridimensionato da un altro script. Allora rileva gli stili in linea.
		inject_inside:false,//se true, inietta l'immagine nel placeholder anziché distruggerlo
		onProgress:function(){},
		onFirstLoaded:function(){},
		onInject:function(){}
	},
	
	initialize:function(options){
		this.setOptions(options);
		this.images = [];
		this.items;
		this.data = [];
		this.image_index = 0;
		this.prepare();
		this.load_image();
	},//end initialize
	
	prepare:function(){
		this.items = $$('.'+this.options.items_class);
		
		this.items.each(function(item,index){
			
			//setup elemento
			var size
			
			if(!this.options.get_data_size){
				size = Object.map(item.getStyles('width','height'),function(value,key){ return value.toInt(); });
				//e basta, perché si presuppone che le dimensioni del placeholder siano già gestite altrove
				//in questo caso size viene usato dopo, per dare dimensioni all'immagine
			} else {
				var size_string;
				size_string = item.get('data-size');
				if(size_string){ size = this.expand_props(size_string,true); }			
				if(size) item.setStyles({ 'width':size.width, 'height':0, 'padding-top':size.height, 'overflow':'hidden' });
				//else????
								
				if(item.match('span')){
					item.setStyle('display','inline-block');
					if(Browser.ie7) item.setStyles({ 'zoom':1, 'display':'inline' });
				}
			}

			//setup data
			this.data.push({ src:item.get('data-source'), placeholder:item, size:size });
			
			if(this.options.show_loader){
				item.setStyles({
					'background-image':'url('+this.options.loader_path+')',
					'background-position':'center', 
					'background-repeat':'no-repeat'
				})
			}
			
		},this);//end each
		
	},
	
	expand_props:function(prop_string,to_int){
		var props = {};
		var string = prop_string.replace(" ","","g");
		var s = prop_string.split(',').each(function(p,i){
			var clean = p.split(':');
			props[clean[0]] = (to_int) ? clean[1].toInt() : clean[1];
		},this);
		return props;
	},
	
	load_image:function(){
		var img = new Asset.image(this.data[this.image_index].src/*+'?time='+Date.now()*/, {
			onLoad:function(img_tag){
				var image = $(img_tag);
				if(this.image_index == 0) this.fireEvent('onFirstLoaded');
				this.fireEvent('onProgress',[this.image_index,image.get('src')]);
				var data = this.data[this.image_index];
				
				//se la dimensione del placeholder era gestita altrove
				if(!this.options.get_data_size){ image.set({ 'width':data.size.width, 'height':data.size.height }) }
				
				image.setStyle('opacity',0)
				
				
				if(!this.options.inject_inside){
					//inietta a fianco del placeholder e distrugge il placeholder
					image.inject(data.placeholder,'after')
					data.placeholder.destroy();
				} else {
					//inietta dentro il placeholder
					image.inject(data.placeholder);
				}
				
				this.fireEvent('onInject',[this.image_index,data.placeholder]);
				
				image.fade('in');
				this.image_index += 1;
				if(this.image_index < this.data.length){ this.load_image(); }
			}.bind(this)//end onLoad
		});//end asset
	}
	
});//END




/*
---
name: FitImage
description: fix in place and fitto screen any background image
license: MIT-style license.
authors:
  - Anton Suprun
  - Luca Reghellin
requires:
  - Core/Array
  - Core/Class.Extras
  - Core/DOMReady
  - Core/Element.Dimensions
provides: [FitImage]
...
*/

var FitImage = new Class({

	Implements: [Events, Options],

	options: {
		'class': 'resize-background',
		'pin': 'top_left',//'top_left', 'top_right', 'bottom_left', 'bottom_right', 'center'
		'minWidth': 1024,
		'minHeight': 768,
		'primary': 'auto',
		'injectElement': null,
		'injectPosition': 'top',
		'fadein':true,
		'onInjected':function(){}
	},

	initialize: function(image, options){
		options = options || {};
		options.primary = options.primary && ['width', 'height', 'auto'].contains(options.primary) ? options.primary : 'auto';
		this.setOptions(options);
		// *** Permanently bind some methods
		this.resize = this.resize.bind(this);
		//this.inject = this.inject.bind(this);
		
		this.image = null;
		var path = (Browser.firefox) ? image+'?nocache='+Date.now() : image;
		
		Asset.image(path, {
			 'class': this.options['class'],
			 onLoad: function(img_tag){
				this.inject_img(img_tag);
			}.bind(this)//end onLoad
		});
		
		// In case browser does not support load event for images
		this.attach();
	},
	
	attach: function(){
		window.addEvent('resize',this.resize);
	},
	
	detach: function(){
		window.removeEvent('resize',this.resize);
	},

	inject_img: function(img_tag){
		this.image = img_tag;
		if (!this.injected){
			if (!this.options.injectElement) this.options.injectElement = document.body;
			if(this.options.fadein ){//&& !Browser.firefox
				this.image.set('tween',{ duration:500 });
				this.image.setStyle('opacity',0);
			}
			
			this.image.inject(this.options.injectElement, this.options.injectPosition);
			this.injected = true;
		}
		// *** If image fails to resize, return launching resize on inject call even after inject becomes true
		this.resize();
		//if(this.options.fadein){ this.image.tween('opacity',1); }// && !Browser.firefox
		if(this.options.fadein){ this.image.fade('in'); }// && !Browser.firefox
		
		this.fireEvent('onInjected',this.image);
		return this;
	},
	
	

	resize: function(){
				
		var size = window.getSize(),
			rate = size.x / size.y,
			styles = {};

		if (!this.size || this.size.x == 0){
			// *** Detect image size
			if(!this.image) return;
			
			this.size = this.image.getSize();
			if (this.size.x == 0) return this; // Not loaded yet
			this.rate = this.size.x / this.size.y;
		}

		// *** Set first dimension size
		if (this.options.primary == 'width' || (this.options.primary == 'auto' && this.rate < rate)){
			styles.width  = size.x;
			styles.height = null;
		} else if (this.options.primary == 'height' || (this.options.primary == 'auto' && this.rate > rate)){
			styles.width  = null;
			styles.height = size.y;
		} else {
			// *** Perfect fit!
			styles.width  = size.x;
			styles.height = size.y;
		}

		// *** Min width && height
		if (styles.width  !== null && this.options.minWidth  > styles.width)  styles.width  = this.options.minWidth;
		if (styles.height !== null && this.options.minHeight > styles.height) styles.height = this.options.minHeight;

		// *** Calculate second dimension size
		if (styles.width  === null) styles.width  = Math.round(styles.height * this.size.x / this.size.y);
		if (styles.height === null) styles.height = Math.round(styles.width  * this.size.y / this.size.x);

		// *** Position in the center of the screen
		if (this.options.pin == 'center'){
			// *** Horizontal
			if (styles.width > size.x) styles.left = 0 - Math.round((styles.width - size.x) / 2);
			else if (styles.width < size.x) styles.left = Math.round((size.x - styles.width) / 2);
			else styles.left = 0;

			// *** Vertical
			if (styles.height > size.y) styles.top = 0 - Math.round((styles.height - size.y) / 2);
			else if (styles.height < size.y) styles.top = Math.round((size.y - styles.height) / 2);
			else styles.top = 0;
		} else {//se non è centrato, riporto a zero perché mi serve se l'immagine era stata spostata nel frattempo da altri programmi
			
			switch(this.options.pin){
				case 'center':
					break;
				case 'top_left':
					Object.merge(styles,{ 'top':0, 'left':0, 'right':'auto', 'bottom':'auto' });
					break;
				case 'top_right':
					Object.merge(styles,{ 'top':0, 'left':'auto', 'right':0, 'bottom':'auto' });
					break;
				case 'bottom_left':
					Object.merge(styles,{ 'top':'auto', 'left':0, 'right':'auto', 'bottom':0 });
					break;
				case 'bottom_right':
					Object.merge(styles,{ 'top':'auto', 'left':'auto', 'right':0, 'bottom':0 });
					break;
				default:
					Object.merge(styles,{ 'top':0, 'left':0, 'right':'auto', 'bottom':'auto' });
			}//end switch
		}

		this.image.setStyles(styles);
		return this;
	},

	toElement: function(){
		return this.image;
	},
	
	clear:function(){
		this.detach();
		this.image = null;
	}
	
});//END FitImage



//require: swfobject v2.2
var FitSwf = new Class({

	Implements: [Events, Options],

	options: {
		'dom_class': 'resize-background',
		'center': true,
		'minWidth': 800,
		'minHeight': 600,
		'swf_width':800,//provvisorio: impostare su null
		'swf_height':450,//provvisorio: impostare su null
		'primary': 'auto',
		//'injectElement': null,
		'injectPosition': 'top',
		'fadein':true,
		'onInjected':function(){}
	},

	initialize: function(src, options){
		options = options || {};
		options.primary = options.primary && ['width', 'height', 'auto'].contains(options.primary) ? options.primary : 'auto';
		this.setOptions(options);
		
		if(!this.options.injectElement) return; // perché swfobject sovrascriverebbe il body stesso
		
		// *** Permanently bind some methods
		this.resize = this.resize.bind(this);
		
		this.rate = null;
		this.file = null;
		this.file_size = null;
		this.file_rate = null;
		this.main_box = null;
		this.flash_box = null;
		this.src = src;
		this.size = null;
		
		this.add_swf();
		//In case browser does not support load event for images
		this.attach();
	},
	
	add_swf:function(){
		this.main_box = new Element('div#test_box',{
				'styles':{ 
					'position':'fixed',
					'z-index':100000,
					'top':0,
					'left':0,
					'overflow':'hidden',
					'height':this.options.swf_height,
					'width':this.options.swf_width,
					'background-color':'#000'
					//,'opacity':0
			}
		}).inject($(document.body),'top');//end element
		
		this.flash_box = new Element('div#fit_flash').inject(this.main_box);//end element
		swfobject.embedSWF(this.src, 'fit_flash', '100%', '100%', "9.0.0", "files/swf/expressInstall.swf",null,null,null,this.start_app);
	
		this.resize();
	},
	
	remove_swf:function(){
		swfobject.removeSWF('fit_flash');
		this.main_box.destroy();
	},
	
	attach: function(){
		window.addEvent('resize',this.resize);
	},
	
	detach: function(){
		window.removeEvent('resize',this.resize);
	},

	start_app: function(e){
		this.injected = true;
		this.file = $(e.ref);
		//this.resize();
		this.fireEvent('onInjected',this.file);
		return this;
	},
	
	

	resize: function(){
		var size = window.getSize(),
			rate = size.x / size.y,
			styles = {};

		if (!this.size || this.size.x == 0){
			this.rate = this.options.swf_width / this.options.swf_height;			
		}

		// *** Set first dimension size
		if (this.options.primary == 'width' || (this.options.primary == 'auto' && this.rate < rate)){
			styles.width  = size.x;
			styles.height = null;
		} else if (this.options.primary == 'height' || (this.options.primary == 'auto' && this.rate > rate)){
			styles.width  = null;
			styles.height = size.y;
		} else {
			// *** Perfect fit!
			styles.width  = size.x;
			styles.height = size.y;
		}
		
		

		// *** Min width && height
		if (styles.width  !== null && this.options.minWidth  > styles.width)  styles.width  = this.options.minWidth;
		if (styles.height !== null && this.options.minHeight > styles.height) styles.height = this.options.minHeight;

		
		// *** Calculate second dimension size
		if (styles.width  === null) styles.width  = Math.round(styles.height * this.options.swf_width / this.options.swf_height);
		if (styles.height === null) styles.height = Math.round(styles.width * this.options.swf_height / this.options.swf_width);
		
		
		// *** Position in the center of the screen
		if (this.options.center){
			// *** Horizontal
			if (styles.width > size.x) styles.left = 0 - Math.round((styles.width - size.x) / 2);
			else if (styles.width < size.x) styles.left = Math.round((size.x - styles.width) / 2);
			else styles.left = 0;

			// *** Vertical
			if (styles.height > size.y) styles.top = 0 - Math.round((styles.height - size.y) / 2);
			else if (styles.height < size.y) styles.top = Math.round((size.y - styles.height) / 2);
			else styles.top = 0;
		} else {//se non è centrato, riporto a zero perché mi serve se l'immagine era stata spostata nel frattempo da altri programmi
			styles.left = 0;
			styles.top = 0;
		}

		this.main_box.setStyles(styles);//.tween('opacity',1);
		return this;
	},

	toElement: function(){
		return this.main_box;
	},
	
// 	close:function(){
// 		this.main_box.set('tween',{
// 			onComplete:function(){
// 				this.clear();				
// 			}.bind(this)
// 		});
// 		
// 		this.main_box.tween('opacity',0);
// 	},
	
	close:function(){
		this.detach();
		this.remove_swf();
		this.main_box = null;
		this.flash_box = null;
	}
	
});//END FitSwf


/* --------------------------------------------- */

//per IE7
function fix_inline_block(){
	if(Browser.ie7){
		var fix_styles = { 'zoom':1, 'display':'inline'};
		var elements = []; 
		if(arguments){
			Array.each(arguments,function(argument){
				var elem = $(document.body).getElement(argument);
				elements.push(elem);
			});
		} else {
			$(document.body).getElements('.fix-inline-block');
		}
		$$(elements).setStyles(fix_styles)
	}//end	
}//end fix_inline_block

window.addEvent('domready',function(){ 
	fix_inline_block('#header .menu');
});

