var ContentSliderInfo={version:1};
var ContentSlider=new Class({
	options:
	{
	autoLoad:true,
	iTransforms:{active:function(){},passive:function(){}},
	iOptions:{}
	},
	/**
	 * content is optional but should consist of an array of html elements
	 */
	initialize:function(options, content){
		var me=this;

		//only add the following if user has not. (don't waste cycles)
		if(!options.titleEl) options.titleEl=new Element('div');	
		if(!options.contentEl) options.contentEl=newElement('div');
		if(!options.contentLoader) options.contentLoader=new ExampleLoader(null,{});

		//merge settings
		me.setOptions(options);

		//loadContent and process all on callback (probably ajax call)
		if(me.options.autoLoad)
			if(content){
				me.load(content);
			}else{
				me.options.contentLoader.load(function(c){
					me.load(c);
				});
			}

		//returns content and title elements, useful if not user defined.

	},

	/**
	 * content must be in this form. 
	 * var c={content:[el,...],active:[el,....]};
	 */
	load:function(content, options){
		var me=this;
		var config=$merge({
			clearCurrent:true,
			appendNew:true
		},options);
		ContentSlider.initializeMouseEvents(content.content, content.active, me.options.iOptions, me.options.iTransforms);
		if(config.clearCurrent)	$each(me.options.contentEl.childNodes,function(e){e.remove();});
		if(config.appendNew) $each(content.content,function(e){me.options.contentEl.appendChild(e);});
		return content.content;
	},
	importElements:function(parent, isActiveComparator){
		var comparator=isActiveComparator||function(el){
			return false;
		};
		$each(parent,function(child){

		});
	},
	setTitle:function(title){
		var me=this; me.options.titleEl.setText(title);
	},
	setContentLoader:function(loader){
		var me=this;
		me.options.contentLoader=loader;
	}
});
ContentSlider.implement(new Options(), new Events());

/**
 * initialises event listenters for all items in 'elements'
 * as though they were part of a single row. all items should be
 * placed in 'elements' array, those that are active (remain maximized) 
 * should also be placed in 'actives'
 * optionally an object containing transformation functions can be provided and
 * should be defined as follows.
 * 		transforms={
 * 			active:function(el){
 * 					//operate on an active item
 * 				},
 * 			passive:function(){
 * 					//operate on normal items
 * 				}
 * 			}
 */ 
ContentSlider.initializeMouseEvents=function(elements, actives, options, transformations){
	var me=this;
	var config=$merge({
		duration:200,
		openPx:200,
		closePx:100
	},options||{});
	var tx={
			both:transformations.both||function(a){},
			active:transformations.active||function(a){}, 
			passive:transformations.passive||function(a){},
			onActivate:transformations.onActivate||function(a){},
			onDeactivate:transformations.onDeactivate||function(a){}
	};
	$each(elements,function(el){

		var showFx=null;
		var hideFx=null;
		var duration=config.duration||200;
		var closeDuration=config.closeDuration;
		var openDuration=config.openDuration;
		var openPx=config.openPx;
		var closePx=config.closePx;

/**//**//**/
		var doHide=function(){
			tx.onDeactivate(el);
			var start=openPx;
			var end=closePx;
			var time=closeDuration||duration;
			if(showFx){
				time=time*(showFx.now/duration);
				start=showFx.now;
				showFx.stop();
				showFx=null;
			}
			hideFx=new Fx.Style(el, "width", {duration:time, onComplete:function(){hideFx=null;}});
			hideFx.start(start,end);
		};
		var doShow=function(){
			tx.onActivate(el);
			var start=closePx;
			var end=openPx;
			var time=openDuration||duration;
			if(hideFx){
				time=time*(hideFx.now/duration);
				start=hideFx.now;
				hideFx.stop();
				hideFx=null;
			}
			showFx=new Fx.Style(el, "width", {duration:time, onComplete:function(){showFx=null;}});
			showFx.start(start,end);
		};		
/**//**//**/
		tx.both(el);
		if(inArray(el, actives)){
			tx.active(el);
			//simply attach methods, no listeners. passive elements will be responsible for calling on interaction
			// el.doShow=doShow;
			// el.doHide=doHide;
		}
		else{
			tx.passive(el);

			// el.addEvent("mouseover", doShow);
			// el.addEvent("mouseout", doHide);

			//squeeze active elements while opening self
			el.addEvent("mouseover",function(){$each(actives, function(a){
				// a.doHide();
			});});
			//restore active elements while closing self
			el.addEvent("mouseout",function(){$each(actives, function(a){
				// a.doShow();
			});});		
		}
	});
};



var ContentLoader=new Class({
	options:
	{
	transforms:[function(a){return a;}]
	},
	initialize:function(filter,options){
		var me=this;
		if(filter){
			me.filter=filter;
		}
		me.setOptions(options);
	},
	load:function(callback){
		var me=this;
		me.retrieveRawData(function(data){
			if($type(me.options.transforms)=='function'){
				callback(me.options.transforms(data));
			}
			if($type(me.options.transforms)=='array'){
			$each(me.options.transforms,function(trans){data=trans(data);});
			callback(data);
			}
		});
	},
	retrieveRawData:function(callback){}
});
ContentLoader.implement(new Options(), new Events());

ContentFilter=new Class({
	initialize:function(options){},
	addFilter:function(name,obj){
		var me=this;
		me[name]=obj;
		fireEvent('onAddFilter',me[name]);
	},
	setFilter:function(name,obj){
		var me=this;
		var filter=me[name];
		$each(obj,function(v,k){
			filter[k]=v;
		});
		me.fireEvent('onSetFilter',filter);
	}
});
ContentFilter.implement(new Options(), new Events());

AjaxServerFilter=ContentFilter.extend({


});

AjaxContentLoader=ContentLoader.extend({
	options:
	{
	transforms:[]
	},
	initialize:function(server,filter){
		var me=this;
		me.server=server;
		me.filter=filter;
	},
	retrieveRawData:function(callback){
		var me=this;
		var json={};
		if(me.filter){
			json.filter=me.filter.generate();
		}

		var query=new AjaxQuery.JsonResponse(me.server, 'actors', json);
		query.addEvent('onSuccess', function(resp){
			callback(resp);
		});
		query.execute();
	}
});

