MOWAccordion = Class.create();
MOWAccordion.prototype = {
	initialize: function(PlaceHolderDIV) {

		// Eventuali altri parametri
		this.pars = $H({
			PositionHReference:			'center',
			PositionVReference:			'top',
			SeparatorWidth:				4,
			SmallSliceWidth:			100,
			BorderColor:				'#FF00FF',
			CreateAtPageBottom:			false,
			AutoStart:					true,
			Debug:						false
		});
		this.pars = this.pars.merge($H(arguments[1] || {}));

		this.Name = this.RandomID();
		eval(this.Name+'=this');

		this.doDebug = false;
		this.DebugLayer = null;
	
		// Div dove creare il menu
		this.PlaceHolderDivID = PlaceHolderDIV;	
		this.HolderDiv = null;
		
		this.Elements = new Array();
		this.Types = new Array();
		this.Holders = new Array();
		this.Overs = new Array();
		this.OnClickEvents = new Array();
		this.OberversCreated = new Array();
		this.TotalSlicesToWaitFor = 0;
		
		this.CurrentlyShown = -1;
		this.HandleOvers = true;
		this.CurrentEffect = null;
		
		Event.observe(window, 'load', this.onWindowLoad.bindAsEventListener(this)); 
		
	},
	
	onWindowLoad: function() {
		this.PlaceHolderDiv		= $(this.PlaceHolderDivID);
		this.width				= this.PlaceHolderDiv.getWidth();
		this.height				= this.PlaceHolderDiv.getHeight();	
		this.HolderDiv 			= this.createHolder();
		
		this.couldStart			= true;
		
		if (this.pars.get('Debug'))
			this.enableDebug();		
		
		if (this.pars.get('AutoStart'))
			this.start();		
	},
		
	enableDebug: function() {
		this.DebugLayer = new Element('div', {style:'position:absolute;overflow-y:auto;top:0px;right:0px;height:600px;width:300px;display:none;background-color:#000;color:#FFF;'});
		Play = new Element('div', {style:'padding:4px;position:absolute;top:10px;right:310px;height:30;width:80px;display:none;background-color:#000;color:#FFF;', onClick:this.Name+'.start();'});
		Stop = new Element('div', {style:'padding:4px;position:absolute;top:50px;right:310px;height:30;width:80px;display:none;background-color:#000;color:#FFF;', onClick:this.Name+'.stop();'});
		new Element.insert(this.HolderDiv, {after: this.DebugLayer}); this.DebugLayer.innerHTML = '<b>MOWSAccordion::DebugMode</b><br />'; new Effect.Appear(this.DebugLayer, {from:0.0, to:0.7, duration:1});		
		new Element.insert(this.HolderDiv, {after: Play}); Play.innerHTML = 'Play'; new Effect.Appear(Play, {from:0.0, to:0.7, duration:1});		
		new Element.insert(this.HolderDiv, {after: Stop}); Stop.innerHTML = 'Stop'; new Effect.Appear(Stop, {from:0.0, to:0.7, duration:1});		
		this.doDebug = true;
		PositionInfo = this.findRealPosition(this.PlaceHolderDiv);
		this.debug('Posizione Holder<br /> left: '+ PositionInfo['x']+'px, top: '+PositionInfo['y']+'px<br /> width: '+this.width+'px, height: '+this.height+'px<br />');
	},
	
	debug: function(text) {
		if (this.doDebug)
			this.DebugLayer.innerHTML += text+'<br />';
	},

	/**
	*	Crea il contenitore x le slide, in posizione assoluta e fissa rispetto alla pagina, clonando la posizione e dimensione del
	*	div contenitore delle slide.
	*/ 
	createHolder: function() {
		//this.PlaceHolderDiv.innerHTML = '';
		PositionInfo = this.findRealPosition(this.PlaceHolderDiv);
		Position = {position: 'absolute', left: PositionInfo['x']+'px', top: PositionInfo['y']+'px', width: this.width+'px', height: this.height+'px'};
		
		
		// Cambia il posizionamento da assoluto a "centrato" orizzontalmente
		if (this.pars.get('PositionHReference') == 'center') {
			DocumentWidth = document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth;
			Position.left = '50%';
			Position.marginLeft = (PositionInfo['x'] - DocumentWidth/2)+'px';
		}
		// Cambia il posizionamento da assoluto a "centrato" verticalmente
		if (this.pars.get('PositionVReference') == 'center') {
			DocumentHeight = document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight;
			Position.top = '50%';
			Position.marginTop = (PositionInfo['y'] - DocumentHeight/2)+'px';
		}
		
		aHolderDiv = new Element('div', {style:'position:absolute;overflow:hidden;'});
		aHolderDiv.setStyle(Position);

		if (this.pars.get('keepOver')) {
			this.keepOver(this.pars.get('keepOver'));
		}

		if (this.holderDiv) {
			new Element.insert(this.holderDiv, {after: aHolderDiv});
		} else {
			if(this.pars.get('CreateAtPageBottom')) {
				new Element.insert(window.document.body, {bottom: aHolderDiv});
			} else {
				new Element.insert(this.PlaceHolderDiv, {after: aHolderDiv});
			}
		}
		
		return aHolderDiv;
	},
	
	keepOver: function(Element) {
		Element = $(Element);
		PositionInfo = this.findRealPosition(Element);
		Position = {left: PositionInfo['x']+'px', top: PositionInfo['y']+'px', position: 'absolute'};

		// Cambia il posizionamento da assoluto a "centrato" orizzontalmente
		if (this.pars.get('PositionHReference') == 'center') {
			DocumentWidth = document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth;
			Position.left = '50%';
			Position.marginLeft = (PositionInfo['x'] - DocumentWidth/2)+'px';
		}
		// Cambia il posizionamento da assoluto a "centrato" verticalmente
		if (this.pars.get('PositionVReference') == 'center') {
			DocumentHeight = document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight;
			Position.top = '50%';
			Position.marginTop = (PositionInfo['y'] - DocumentHeight/2)+'px';
		}

		new Insertion.After(this.PlaceHolderDiv, Element);

		$(Element).setStyle(Position);	
	},
		
		
	addImage: function(imageUrl) {
		ElementNumber = this.Elements.length;
		// Eventuali altri parametri
		Pars = $H({
			Anchor:				'left',
			OnClick:			null
		});
		Pars = Pars.merge($H(arguments[1] || {}));	
		
		NewImage = new MOWImage(imageUrl);
		
		if (Pars.get('Anchor') == 'left') {
			NewImage.setStyle({position:'absolute', top:'0px', left:'0px'});
		} else {
			NewImage.setStyle({position:'absolute', top:'0px', right:'0px', left:null});
		}
			
		this.Elements[ElementNumber] = NewImage;
		this.Types[ElementNumber] = 'MOWImage';
		this.OnClickEvents[ElementNumber] = Pars.get('OnClick');
	},

	addMOWSlide: function(MOWSlideDefinition) {
		ElementNumber = this.Elements.length;
		// Eventuali altri parametri
		Pars = $H({
			OnClick:			null
		});
		Pars = Pars.merge($H(arguments[1] || {}));		
		
		this.Elements[ElementNumber] = MOWSlideDefinition;
		this.Types[ElementNumber] = 'MOWSlide';
		this.OnClickEvents[ElementNumber] = Pars.get('OnClick');
	},
	
	startMOWSlideHandling: function(subtract) {
		this.TotalSlicesToWaitFor--;
		
		if (this.TotalSlicesToWaitFor == -1) {
			ElementCount = this.Elements.length;
			for (ElCount=0; ElCount<ElementCount; ElCount++) {
				if (!this.OberversCreated[ElCount]) {
					this.Overs[ElCount].observe('mouseover', this.OpenToSlice.bindAsEventListener(this,ElCount));
					this.Overs[ElCount].observe('mouseout', this.RestoreSlices.bindAsEventListener(this,ElCount));
				
					if (this.OnClickEvents[ElCount] != null) {
						this.Overs[ElCount].setStyle({cursor:'pointer'});
						this.Overs[ElCount].observe('click', this.OnClickEvents[ElCount]);
					}
				}
			}
		}
	},
		
	createMenu: function() {
		ElementCount = this.Elements.length;
		AvailableWidth = this.width - this.pars.get('SeparatorWidth')*(ElementCount-1);
		NormalWidth = Math.floor(AvailableWidth / ElementCount);
		LargerBlocks = LBCount = AvailableWidth % ElementCount;
		
		
		//this.debug('Available Width: ' + AvailableWidth + ' (' + ElementCount + ' elementi)');
		
		for (ElCount=0; ElCount<ElementCount; ElCount++) {
			if (this.Types[ElCount] == 'MOWSlide')
				this.TotalSlicesToWaitFor++;
		}
		
		for (ElCount=0; ElCount<ElementCount; ElCount++) {
			this.Holders[ElCount] = new Element('div', {style:'position:absolute;overflow:hidden;width:'+(NormalWidth + (LBCount-- > 0 ? 1 : 0))+'px;height:100%;top:0px;left:'+((NormalWidth+this.pars.get('SeparatorWidth'))*(ElCount)+Math.min(ElCount,LargerBlocks))+'px;'});
			Element.insert(this.HolderDiv, {bottom: this.Holders[ElCount]});
			
			this.Overs[ElCount] = new Element('div', {style:'background-color:#000;position:absolute;overflow:hidden;width:100%;height:100%;top:0px;left:0px;'});
			this.Overs[ElCount].setOpacity(0.01);

			switch (this.Types[ElCount]) {
				case 'MOWImage':
					Element.insert(this.Holders[ElCount], {top: this.Elements[ElCount].theObject});
					break;
					
				case 'MOWSlide':
					this.Elements[ElCount] = new MOWSlide(this.Holders[ElCount], this.Elements[ElCount], {CreateInAbsoluteDiv:true, Debug:false, PrefetchSeconds:1, onStop:this.startMOWSlideHandling.bindAsEventListener(this,ElCount)});
					this.Elements[ElCount].onWindowLoad();
					//this.debug('MOWSlide: '+this.Elements[ElCount].Name);
					break;
			}
			
			Element.insert(this.Holders[ElCount], {bottom: this.Overs[ElCount]});
		}
		
		this.startMOWSlideHandling();
		
	},
	
	MouseOverListener: function(SliceNumber) {
		// Verifica se non c'e' gia' un azione in corso
		if (!this.HandleOvers) return;
		this.HandleOvers = false;
		
		this.debug('Over: '+SliceNumber);
		
		/*
		// Nascondi l'over della slice corrente
		ElementCount = this.Elements.length;
		for (i=0; i<ElementCount; i++) {
			if (i==SliceNumber) this.Overs[i].hide(); else this.Overs[i].show(); 
		}
		*/
		
		this.CurrentlyShown = SliceNumber;
		this.OpenToSlice(SliceNumber);
	},
	
	MouseOutListener: function(SliceNumber) {
		// Verifica se non c'e' gia' un azione in corso
		if (!this.HandleOvers) return;
		this.HandleOvers = false;
		
		this.debug('Out: '+SliceNumber);
		
		/*
		// Nascondi l'over della slice corrente
		ElementCount = this.Elements.length;
		for (i=0; i<ElementCount; i++) {
			if (i==SliceNumber) this.Overs[i].hide(); else this.Overs[i].show(); 
		}
		*/
		
		this.CurrentlyShown = SliceNumber;
		this.RestoreSlices();
	},
	
	SobstituteEffect: function(toEvalEffect) {
		if (this.CurrentEffect != null)
			this.CurrentEffect.cancel();
		eval('this.CurrentEffect = '+toEvalEffect);
	},
	
	OpenToSlice: function(e, SliceNumber) {
		//this.debug('Over '+SliceNumber);
		ElementCount = this.Elements.length;
		EffectToEval = 'new Effect.Parallel([';
			LeftPosition = 0;
			for (ec=0; ec<ElementCount; ec++) {
				Width = this.pars.get('SmallSliceWidth');
				if (ec == SliceNumber)
					Width = this.width - this.pars.get('SeparatorWidth')*(ElementCount-1) - this.pars.get('SmallSliceWidth')*(ElementCount-1);
				Left = LeftPosition;
				LeftPosition += Width+this.pars.get('SeparatorWidth');
				if (ec!=0) EffectToEval +=',';
				EffectToEval += 'new Effect.Morph(this.Holders['+ec+'], {sync:true, style:\'left:'+Left+'px; width:'+Width+'px;\'})';
				if (this.Types[ec] == 'MOWSlide') {
					if (ec == SliceNumber)
						this.Elements[ec].changeSequence('MouseOver');
					else 
						this.Elements[ec].changeSequence('MouseOut');
				}
			}
		EffectToEval += '], {duration: 0.5, delay:0.0});';
		this.SobstituteEffect(EffectToEval);
	},
	
	RestoreSlices: function(e, SliceNumber) {
		ElementCount = this.Elements.length;
		AvailableWidth = this.width - this.pars.get('SeparatorWidth')*(ElementCount-1);
		NormalWidth = Math.floor(AvailableWidth / ElementCount);
		LargerBlocks = LBCount = AvailableWidth % ElementCount;

		EffectToEval = 'new Effect.Parallel([';
			LeftPosition = 0;
			for (ec=0; ec<ElementCount; ec++) {
				if (ec!=0) EffectToEval +=',';
				EffectToEval += 'new Effect.Morph(this.Holders['+ec+'], {sync:true, style:\'width:'+(NormalWidth + (LBCount-- > 0 ? 1 : 0))+'px;left:'+((NormalWidth+this.pars.get('SeparatorWidth'))*ec+Math.min(ec,LargerBlocks))+'px;\'})';
				if (this.Types[ec] == 'MOWSlide') {
						this.Elements[ec].changeSequence('MouseOut');
				}
			}	
		EffectToEval += '], {duration: 0.5, delay:0.0});';
		this.SobstituteEffect(EffectToEval);
	},
	
	start: function() {
		this.createMenu();
	},
	
	//--- UTILITY -------------------------------------------------------------------------------------------
	//-------------------------------------------------------------------------------------------------------

		findRealPosition: function(obj) {
			var curleft = curtop = 0;
			if (obj.offsetParent) {
				curleft = obj.offsetLeft
				curtop = obj.offsetTop
				while (obj = obj.offsetParent) {
					curleft += obj.offsetLeft
					curtop += obj.offsetTop
				}
			}
			return {'x': curleft, 'y': curtop};
		},
		
		RandomID: function() {
			var sRnd = '';
			var sChrs = 'abcdefghijklmnoqrstuwxyz';
			for (var i=0; i <= 16; i++) {
				var randomPoz = Math.floor(Math.random() * sChrs.length);
				sRnd += sChrs.substring(randomPoz,randomPoz+1);
			}
			return sRnd;
		}
	
}