/*
 * Main Controller Classes for JS Framework
 * Uses the very nice - Mootools Framework
 * @Author Andy Johnston (andy [at] parca [dot] com [dot] au)
 * @Updated July 2007
 *  
 * Sets up base controlling class, and view controller class.
 * Extend at view level to implement controller like so :
 
	<script>
	var View = {
		controller: null,
		init: function(){
			// Here we are overriding some properties for the tooltip module in this view
			this.controller = new ViewController({
				tooltipProps : {
					maxTitleChars : 50,
				}
			});		
			// Example of calling controller methods on setup
			this.controller.setupTips();
		},
	}
	// Fires the init super chain on Dom Ready event
	window.onDomReady(View.init.bind(View));	
	</script>

 * 
 */

var Controller = new Class({

	/* Public Properties */

	options: {
		codeName : "Controller Class",
		accordionProps : {
			id : "dl.Accordion",
			toggleClass : "dt.acc_toggle",
			elements : "dd.acc_content"
		},
		tooltipProps : {
			tipClass : ".hasTip",
			timeOut : 500,
			maxTitleChars : 50,
			maxOpacity : 0.9
		},
		slidysetProps : {
			mode : "vertical"
		},
		hideShowProps : {
			duration : 700
		},
		effectProps : {
			duration : 500,
			inTransition: Fx.Transitions.sineIn,
			outTransition: Fx.Transitions.sineOut
		}
	},
	
	/* Private Properties */
	
	staggeredEffects : [],
	sliderSets : [],
	hideShowSets : [],	
	elements : [],	
	
	/* Constructor */

    initialize: function(options){
	    this.setOptions(options);
	    this.elements["hideShow"] = [];
    },
    
   	/* Public setupAccordions - activate all accordions in the view */
    
    setupAccordions: function(){		
    	props = this.options.accordionProps;

		$$(props.id).each(function(el){
			new Accordion(el.getElements(props.toggleClass), el.getElements(props.elements));
		});
	},		
	
	/* Public setupTips - activate all tips in the view */
	
	setupTips: function(){
		props = this.options.tooltipProps;
		
		var myTips = new Tips($$(props.tipClass), {
			timeOut: props.timeOut,
			maxTitleChars: props.maxTitleChars,
			maxOpacity: props.maxOpacity
		});
	},
	
	/* Public createSlidySet - allows elements to be slid - registers a set of slide controls */
	
	setupSlidySet: function(element, id, inControl, outControl, toggleControl, hideControl, showControl, callback){
		
		props = this.options.slidysetProps;
		
		this.sliderSets[id] = new Fx.Slide(element, {mode: props.mode});
		
		var slider = this.sliderSets[id];
		
		slider.hide();
		
		if(inControl!=null){
			$(inControl).addEvent('click', function(e){
				e = new Event(e);
				slider.slideIn();
				if(callback!=null){
					callback(id, this);
				}
				e.stop();
			});
		}
		 
		if(outControl!=null){
			$(outControl).addEvent('click', function(e){
				e = new Event(e);
				slider.slideOut();
				if(callback!=null){
					callback(id, this);
				}
				e.stop();
			});
		}
		
		if(toggleControl!=null){		 
			$(toggleControl).addEvent('click', function(e){
				e = new Event(e);
				slider.toggle();
				if(callback!=null){
					callback(id, this);
				}
				e.stop();
			});
		}
			 
		if(hideControl!=null){
			$(hideControl).addEvent('click', function(e){
				e = new Event(e);
				slider.hide();
				if(callback!=null){
					callback(id, this);
				}
				e.stop();
			});
		}
		
		if(showControl!=null){
			$(showControl).addEvent('click', function(e){
				e = new Event(e);
				slider.show();
				if(callback!=null){
					callback(id, this);
				}
				e.stop();
			});
		}

	},
	
	/* Public createSlidySet - allows elements to be slid - registers a set of slide controls */
	
	setupHideShowSet: function(element, id, inControl, callback){
		
		var el = $(element);		
		props = this.options.hideShowProps;		
		
		this.elements["hideShow"][id] = el;
		this.hideShowSets[id] = new Fx.Styles(el, {duration: props.duration});		
		
		el.setStyle('display', 'none');	
		
		if(inControl!=null){
			// hide others		
			var inEl = $(inControl);
			inEl.master = this;
			inEl.addEvent('click', function(e){
				this.master.styleElements(this.master.elements["hideShow"], "display", 'none');
				e = new Event(e);	
				var el = this.master.elements["hideShow"][id];
				el.setStyle('display', 'block');	
				if(callback!=null){
					callback(id, this);
				}
				e.stop();
			});
		}

	},
	
	styleElements: function(collection, prop, value){
		
		for (var i=0;i<collection.length;i++) {
			var target = collection[i];
			target.setStyle(prop, value);
		}

	},
	
	/* Public create style effect */
	
	createStyleEffect: function(element, targetProp, effectObj){
		return new Fx.Style(element, targetProp, effectObj);
	},
	
	/* Public create styles effect */
	
	createStylesEffect: function(elements, effectObj){
		return new Fx.Styles(elements, effectObj);
	},	
	
	/* Public fade in - effects function */
	
	createFadeIn: function(element, effectObj){
	
		element.setStyle('opacity', '0');
	
		return this.createStyleEffect(element, 'opacity', effectObj);		

	},
	
	/* Public fade - effects function */
	createFade: function(element, effectObj){
	
		return this.createStyleEffect(element, 'opacity', effectObj);		

	},
	
	/* Public apply mouse over */
	
	applyMouseEffects: function(element, transitionEffectObj, overEffectObj, outEffectObj){		
	
		var effector = this.createStylesEffect(element, transitionEffectObj) ;		
 
		element.addEvent('mouseenter', function(){
			effector.start(overEffectObj);
		});
	 
		element.addEvent('mouseleave', function(){
			effector.start(outEffectObj);
		});
	},
	
	/* Public Stagger Effects - performs a delay between each effect */
	
	staggerEffects: function(element, index, timeIncrement, funcName, effectObj){
		timer += timeIncrement;		
		this.staggeredEffects[index] = this[funcName](element, effectObj);
		this.staggeredEffects[index].start.delay(timer, this.staggeredEffects[index], 1);
	},
	
	/* Public loop collection - loop an element set calling method on each. */
	
	loopCollection: function(selector, handler){
		var elements = $$(selector);		
		elements.each(handler, this);
	},
	
	/* Public element handler - does something to an element */
	
	elHandler_StaggerIn: function(element, index){	
	
		props = this.options.effectProps;
	
		var effectObj = { 
			duration: props.duration, 
			transition: props.inTransition,
			wait: false		
		}
		
		this.staggerEffects(element, index, 50, "createFadeIn", effectObj);
	},
	
	/* Public element handler - does something to an element */
	
	elHandler_FadeIn: function(element, index){	
	
		props = this.options.effectProps;
	
		var effectObj = { 
			duration: props.duration, 
			transition: props.inTransition,
			wait: true 			
		}

		var effector =  this.createFadeIn(element,effectObj);	
		effector.start(1);	
	},
	
	/* Public element handler - does something to an element */
	
	elHandler_FadeOut: function(element, index){	
	
		props = this.options.effectProps;
	
		var effectObj = { 
			duration: props.duration, 
			transition: props.inTransition,
			wait: true	
		}

		var effector =  this.createFade(element,effectObj);	
		effector.start(0);	
	},
	
	/* Public element handler - does something to an element */
	
	elHandler_Hover: function(element, index){
		var transitionEffectObj = { 
			duration: 200, 
			wait: false		
		}
		overEffectObj = {
			'margin-left': 5,
			'background-color': '#666',
			color: '#ff8'
		}
		outEffectObj = {
			'margin-left': 0,
			'background-color': '#333',
			'color': '#888'
		}
		this.applyMouseEffects(element,transitionEffectObj,overEffectObj,outEffectObj)
	}
	

	
});

Controller.implement(new Events);
Controller.implement(new Options);

var ViewController = Controller.extend({
	options: {
		codeName : "View Controller Class"
	},
	initialize: function(options){
		this.parent(options);
	}
});

