/**
 * @author Peter Swan
 */
var Collection = Class.create({
	initialize: function(elm){
		this.container = $(elm);
		if( !this.container ) throw('ProjectCollection: invalid container');
		this.current_action_element = null;
		this.pe = null;
		this.times = 0;
		this.options = Object.extend({
			autostart: false,
			times: 0,
			interval: 3
		}, arguments[1] || {})
		this.anim_options = Object.extend({
			queue: {scope: this.container.identify()},
			duration: 1
		}, arguments[2] || {});
		this.scope = this.container.identify();
		if( ['absolute', 'relative', 'fixed'].indexOf(this.container.getStyle('position')) == -1){
			this.container.makePositioned();
		}
		this.elements = this.container.select('.item');
		this.current_element = null;
		this.elements.each(function(e){
			if( e.getStyle('display') != 'none' && !this.current_element ){
				this.current_element = e;
			}else{
				e.hide();
			}
			e.setStyle({
				position: 'absolute',
				top: '0px',
				left: '0px'
			});
			var s = '.' + e.readAttribute('id') + '_action-open';
			$$(s).each(function(ae){
				ae.observe('click', this.open.bindAsEventListener(this, e));
			}, this);
		}, this);
		if( this.options.autostart ){
			this.start(1);
		}
	},
	start: function(direction){
		if( this.pe ) return;
		var f = direction>0?this.next.bind(this):this.previous.bind(this);
		this.pe = new PeriodicalExecuter(f, this.options.interval);
		this.container.fire('collection:start');
	},
	stop: function(){
		if( this.pe ){
			this.pe.stop();
			this.pe = null;
			this.container.fire('collection:stop');
			this.times = 0;
		}
	},
	previous: function(){
		if( this.options.times != 0 && (this.times > this.options.times) ){
			this.stop();
			return;
		}
		var elm = this.current_element?this.current_element.previous():this.elements.first();
		this.open(elm);
		this.times++;
		this.container.fire('collection:previous', {element: elm});
	},
	next: function(){
		if( this.options.times != 0 && (this.times > this.options.times) ){
			this.stop();
			return;
		}
		var elm = this.current_element?this.current_element.next():this.elements.first();
		this.open(elm);
		this.times++;
		this.container.fire('collection:next', {element: elm});
	},
	open: function(){
		var action_elm = null;
		var elm = null;
		if( arguments.length == 2){
			arguments[0].stop();
			action_elm = arguments[0].element();
			elm = this._getElement(arguments[1]);
		}else if( arguments.length == 1){
			elm = this._getElement(arguments[0]);
		}else{
			throw('ProjectCollection: open - invalid number of arguments');
		}
		if( elm ){
			if (this.current_element) {
				new Effect.Parallel(
					[new Effect.Appear(elm, {sync: true}), new Effect.Fade(this.current_element, {sync: true})],
					Object.extend(this.anim_options, 
					{
						beforeStart: this._openBeforeStart.bind(this, elm, action_elm),
						afterFinish: this._openAfterFinish.bind(this, elm, action_elm)
					})
				);
			}else{
				new Effect.Appear(elm, Object.extend(this.anim_options, {
					beforeStart: this._openBeforeStart.bind(this, elm, action_elm),
					afterFinish: this._openAfterFinish.bind(this, elm, action_elm)
				}));
			}
		}
	},
	close: function(){
		if (this.current_element) {
			new Effect.Fade(this.current_element, Object.extend(this.anim_options, {
				beforeStart: this._closeBeforeStart.bind(this)
			}));
		}
	},
	_getElement: function(e){
		var elm;
		if( Object.isNumber(e) ){
			elm = this.elements[e];
		}else if( Object.isElement(e) ){
			elm = this.elements.find(function(i){
				return i===e;
			});
		}
		return elm;
	},
	_openBeforeStart: function(elm, action_elm){
		if( this.current_action_element){
			this.current_action_element.removeClassName('active');	
		}
		if(action_elm){
			action_elm.addClassName('active');
			this.current_action_element = action_elm;
		}else{
			this.current_action_element = null;
		}
		this.current_element = elm;
		this.container.fire('collection:beforeopen', {element: elm});
	},
	_openAfterFinish: function(elm, action_elm){
		this.container.fire('collection:afteropen', {element: elm});
	},
	_closeBeforeStart: function(){
		if( this.current_action_element){
			this.current_action_element.removeClassName('active');
			this.current_action_element = null;
		}
		this.current_element = null;
		this.container.fire('collection:beforeclose', {element: elm});
	},
	observe: function(){
		this.container.observe.apply(this.container, arguments);
	}
});