var Shake = new Class({
	Implements:[Options,Events],
		options:{
			distance: 6,
			duration: 50,
			transition: Fx.Transitions.Sine.easeInOut,
			loops: 2
		},
		
	initialize:function(element,options){
		this.setOptions(options);
		this.element=$(element);		
		if(this.element.getStyle('position')!='absolute') this.element.setStyle('position','relative');
		this.loading=this.element.getElement('img.loading');
		this.tween = new Fx.Tween(this.element,{ 
			link: 'chain', 
			duration: this.options.duration,
			transition: this.options.transition
		});
		
		if(this.element.get('tag')!='form')	this.form=this.element.getElement('form');
		else this.form=this.element;
		this.form.addEvent('submit',function(event){
			event.stop();
			var req=new Request.JSON({
				url: this.form.get('action'),
				method: 'post',
				onRequest: function(){
					this.loading.setStyle('display','inline');
				}.bind(this),
				onComplete:function(requestJSON){
					this.loading.setStyle('display','none');
					if(requestJSON==0) {
						this.shake();
						this.fireEvent('onFailure');
					} else this.fireEvent('onSuccess');
				}.bind(this)
			}).post(this.form);
		}.bind(this));
	},
	
	shake:function(){
		var d=this.options.distance;
		for(x=0;x<this.options.loops;x++) this.tween.start('left',d).start('left',-d);
		this.tween.start('left',d).start('left',0);
	}
	
});

var AutoLogout = new Class({
	Implements:[Options,Events],
		options:{
			/* onLogout: $empty */
			display: false,
			timeout: 300,
			data: '',
			logout: 'logout.php',
			ping: 'detectuser.php',
			pingTimeout: 30
		},
	
	initialize: function(options){
		this.setOptions(options);
		if(this.options.display) this.display=$(this.options.display);
		this.counter=0;
		this.pinger=0;
		this.attach();
		this.start();
	},
	
	addCount: function(){
		this.counter++;
		this.pinger++;
		if(this.display) this.display.set('text',this.counter);
		if(this.counter>this.options.timeout) this.logout();
		if(this.pinger>this.options.pingTimeout) this.ping();
	},
	
	logout:function(){
		var req=new Request.HTML({
			method:'post',
			data: {'data':this.options.data},
			url: this.options.logout,
			onComplete:function(){
				this.fireEvent('onLogout');
			}.bind(this)
		}).send();
	},
	
	ping: function(){
		this.pinger=0;
		var req=new Request.HTML({
			method:'post',
			data: {'data':this.options.data},
			url: this.options.ping
		}).send();
	},
	
	start: function(){
		this.periodical=this.addCount.periodical(1000,this);
	},
	
	stop: function(){
		$clear(this.periodical);
	},
	
	reset:function(){
		this.counter=0;
	},
	
	attach: function(){
		document.addEvents({
			keyup:function(){
				this.reset();
			}.bind(this),
			click:function(){
				this.reset();
			}.bind(this)
		});
	},
	
	deattach: function(){
		document.removeEvent('keyup');
		document.removeEvent('click');
	}
});

var SmartTextArea = new Class({
	
	initialize: function(selector){
		this.areas=$$(selector);
		this.attach();
	},
	
	grow:function(area){
		if(area.get('value')!=''){
			var ss=area.getScrollSize().y;
			var s=area.getSize().y;
			if(s+10<ss) area.setStyle('height',ss);
		}
	},
	
	attach: function(){
		this.areas.each(function(area){
			area.setStyle('overflow-y','hidden');
			this.grow(area);
			area.addEvents({
				focus: function(){
					this.grow(area);
					if(area.hasClass('empty')) {
						area.removeClass('empty');
						area.value='';
					}
				}.bind(this),
				keyup: function(){
					this.grow(area)
				}.bind(this)
			});
		}.bind(this));
	},
	
	detach: function(){
		this.areas.each(function(area){
			area.setStyle('overflow-y','');
			area.removeEvent('focus');
			area.removeEvent('keyup');
		}.bind(this));
	}
});

var SlideForm = new Class({
	Implements:[Options, Events],
		options:{
			listData: 'list.php',
			listTag: 'ul',
			listItemName: 'Contact',
			listDataAttribute: 'rel',
			formAction: 'dbi.php',
			formData: 'form.php',
			loadingSrc: 'assets/img/loading.gif'
		},
		
	initialize:function(element,options){
		this.setOptions(options);
		this.element=$(element);
		this.scroller=new Fx.Scroll(this.element);
		this.construct();
		this.loadList('load');
	},
	
	construct:function(){
		this.element.setStyles({
			'overflow-x':'hidden'
		});
		
		// SCROLL ELEMENT
		this.scrollElement=new Element('div',{
			'id': this.element.get('id')+'_scrollElement',
			'class': 'slideForm_scrollElement',
			'styles': {
				'width': this.element.getSize().x*2
			}
		}).inject(this.element);
		
		// BR
		var br=new Element('br',{
			'styles':{
				'clear':'both'
			}
		}).inject(this.element);
		
		
		// LIST CONTAINER
		this.listContainer=new Element('div',{
			'id': this.element.get('id')+'_listContainer',
			'class': 'slideForm_listContainer',
			'styles': {
				'float': 'left',
				'width': this.element.getSize().x
			}
		}).inject(this.scrollElement);
		
		// FORM CONTAINER
		this.formContainer=new Element('div',{
			'id': this.element.get('id')+'_formContainer',
			'class': 'slideForm_formContainer',
			'styles': {
				'float': 'right',
				'width': this.element.getSize().x
			}
		}).inject(this.scrollElement);
		
		// NAVs
		this.listNav=new Element('div',{
			'id': this.element.get('id')+'_listNav',
			'class': 'slideForm_listNav'
		}).inject(this.listContainer);
		
		this.formNav=new Element('div',{
			'id': this.element.get('id')+'_formNav',
			'class': 'slideForm_formNav'
		}).inject(this.formContainer);
		
		// BUTTONS
		this.addButton=new Element('button',{
			'id': this.element.get('id')+'_addButton',
			'class': 'slideForm_addButton',
			'text': 'Add a '+this.options.listItemName+' »',
			'events': {
				'click': function(){
		           this.loadForm('add');
		        }.bind(this)
		    }
		}).inject(this.listNav);
		
		this.backButton=new Element('button',{
			'id': this.element.get('id')+'_backButton',
			'class': 'slideForm_backButton',
			'text': '« Back to '+this.pluralize(),
			'events': {
				'click': function(){
		            this.scroller.toElement(this.listContainer)
		        }.bind(this)
		    }
		}).inject(this.formNav);
		
		// LIST ELEMENT
		this.list=new Element(this.options.listTag,{
			'id': this.element.get('id')+'_list',
			'class': 'slideForm_list'
		}).inject(this.listContainer);
		
		// FORM ELEMENT
		this.form=new Element('form',{
			'id': this.element.get('id')+'_form',
			'class': 'slideForm_form',
			'events': {
				'submit': function(event){
					event.stop();
					this.submitForm();
				}.bind(this)
			}
		}).inject(this.formContainer);	
		
		// loading indicator
		this.listLoading=new Element('img',{
			'src': this.options.loadingSrc,
			'styles':{
				'display':'none'				
			}
		}).inject(this.addButton,'after');
		
		this.formLoading=new Element('img',{
			'src': this.options.loadingSrc,
			'styles':{
				'display':'none'
			}
		}).inject(this.backButton,'after');
	},
	
	loadList: function(data){
		var req=new Request.HTML({
			url: this.options.listData,
			method: 'get',
			update: this.list,
			data: {'data':data,'uid':this.options.otherData},
			onRequest: function(){
				this.formLoading.setStyle('display','inline');
			}.bind(this),
			onComplete: function(){
				this.formLoading.setStyle('display','none');
				this.scroller.toElement(this.listContainer);
				this.attachListItems();
			}.bind(this)
		}).send();			
	},
	
	loadForm: function(data){
		var req=new Request.HTML({
			url: this.options.formData,
			method: 'get',
			update: this.form,
			data: {'data':data},
			onRequest: function(){
				this.listLoading.setStyle('display','inline');
			}.bind(this),
			onComplete: function(){
				this.listLoading.setStyle('display','none');
				this.scroller.toElement(this.formContainer);
				if(data!='add') this.attachRemove();
			}.bind(this)
		}).send();
	},
	
	attachListItems: function(){
		var elType;
		if(this.options.listTag=='ul') elType='li';
		else elType='tr'; 
		var listItems=this.list.getElements(elType);
		listItems.each(function(item){
			item.addEvent('click',function(){
				this.loadForm(item.get(this.options.listDataAttribute));
			}.bind(this));
		}.bind(this));
	},
	
	attachRemove: function(){
		var btn=this.form.getElement('button[type=remove]');
		btn.addEvent('click',function(event){
			event.stop();
			this.remove(btn.get('rel'));
		}.bind(this));
	},
		
	submitForm: function(){
		var req=new Request.JSON({
			url: this.options.formAction,
			onRequest: function(){
				this.formLoading.setStyle('display','inline');
			}.bind(this),
			onComplete: function(responseJSON){
				// unload happens in loadList
				this.loadList(responseJSON);
			}.bind(this)
		}).post(this.form);
	},
	
	remove: function(data){
		var answer = confirm("I'm going to remove this item, if that's 'OK' with you.");
		if (answer){
			var req=new Request.HTML({
				url: this.options.formAction,
				data: {'action': data},
				method: 'post',
				onRequest: function(){
					this.formLoading.setStyle('display','inline');
				}.bind(this),
				onComplete: function(responseHTML){
					this.loadList(responseHTML);
				}.bind(this)
			}).send();
		}
	},
	
	pluralize: function(){
		if(this.options.listItemName.charAt(this.options.listItemName.length-1)=='y') return this.options.listItemName.substr(0,this.options.listItemName.length-1)+'ies';
		else return this.options.listItemName+'s';
	}
	
});

window.addEvent('domready',function(){
	if(Browser.Engine.trident){
		$$('button').addEvent('click',function(){
			this.blur();
		});
	}
});
