/**
 * @author Robert
 */
var FbElement =  new Class({
	initialize: function(element, options) {
		this.plugin = '';
		this.strElement = element;
		this.setOptions(element, options);
	},
	
	attachedToForm: function()
	{
		//put ini code in here that can't be put in initialize()
		// generally any code that needs to refer to  this.form, which
		//is only set when the element is assigned to the form.
	},

	setOptions: function(element, options) {
		if($(element)){
			this.element = $(element);
		}
		this.options = {
			element:  element,
			defaultVal: '',
			value:'',
			editable:false
		};
		$extend(this.options, options);
		this.setorigId();
	},
	
	/** allows you to fire an array of events to element /  subelements, used in calendar to trigger js events when the calendar closes **/
	fireEvents: function(evnts){
		if(this.hasSubElements()){
			this.subElements.each(function(el){
				$A(evnts).each(function(e){
					el.fireEvent(e);
				}.bind(this));
			}.bind(this));
		}else{
			$A(evnts).each(function(e){
				if($type(this.element) !== false){
					this.element.fireEvent(e);
				}else{
					fconsole('couldnt fire event ' + this.plugin);
				}
			}.bind(this));
		}
	},
	
	getElement: function()
	{
		//use this in mocha forms whose elements (such as database jons) arent loaded
		//when the class is ini'd
		if($type(this.element) === false){
			this.element = $(this.options.element); 
		}
		return this.element;
	},

	//used for elements like checkboxes or radio buttons
	_getSubElements: function(){
		var element = this.getElement();
		if($type(element) === false){
			return false;
		}
		this.subElements = element.getElements('.fabrikinput');
		return this.subElements;
	},
	
	hasSubElements: function(){
		this._getSubElements();
		if($type(this.subElements) === 'array'){
			return this.subElements.length > 0 ? true : false;
		}
		return false;
	},
	
	unclonableProperties:function()
	{
		return ['form'];
	},
	
	addNewEvent: function( action, js ){
		if(action == 'load'){
			if ($type(js) === 'function') {
	  		js.delay(0);
		  } else {
		  	eval(js);
		  }
		}else{
			if(!this.element){
				this.element = $(this.strElement);
			}
			if(this.element){
				this.element.addEvent( action, function(e){
					e = new Event(e).stop();
					if ($type(js) === 'function') {
				  	js.delay(0);
				  } else {
				  	eval(js);
				  }
				} );
				
				this.element.addEvent('blur', function(e){
					this.validate();
				}.bind(this));
			}
		}
	},
	
	validate:function(){},
	
	//store new options created by user in hidden field
	addNewOption: function(val, label)
	{
		var added = $(this.options.element + '_additions').value;
		var json = {'val':val,'label':label};
		if(added !== ''){
			var a = Json.evaluate(added);
		}else{
			a = [];
		}
		a.push(json);
		var s = '[';
		for(var i=0;i<a.length;i++){
			s += Json.toString(a[i]) + ',';
		}
		s = s.substring(0, s.length-1) + ']';
		$(this.options.element + '_additions').value = s;
	},
	
	//below functions can override in plugin element classes
	
	update: function(val){
		if(this.element){
			if (this.options.editable) {
				this.element.value = val;
			}else{
				this.element.innerHTML = val;
			}
		}
	},
	
	updateHTML: function(html)
	{
		if(this.element){
			this.element.setHTML(html);
		}else{
			fconsole('didnt find element to update '+ this.options.element);
		}
	},
	
	getValue: function(){
		if(this.element){
			if (this.options.editable) {
				return this.element.value;
			}else{
				return this.options.value;
			}
		}
		return false;
	},
	
	reset: function()
	{
		this.update(this.options.defaultVal);
	},
	
	clear:function()
	{
		this.update('');
	},
	
	onsubmit: function(){
		return true;
	},
	
	cloned: function(c){
		//run when the element is cloned in a repeat group
	},
	
	decloned: function(groupid){
		//run when the element is decleled from the form as part of a deleted repeat group
	},
	
	//get the wrapper dom element that contains all of the elements dom objects
	getContainer: function()
	{
		return this.element.findClassUp('fabrikElementContainer');
	},
	
	//get the dom element which shows the error messages
	getErrorElement: function()
	{
		return this.getContainer().getElement('.fabrikErrorMessage');
	},
	
	//get the fx to fade up/down element validation feedback text
	
	getValidationFx: function(){
		if(!this.validationFX){
			this.validationFX = this.getErrorElement().effects({duration:500, wait:true});
		}
		return this.validationFX;
	},
	
	setErrorMessage: function(msg, classname){
		var classes = ['fabrikValidating', 'fabrikError', 'fabrikSuccess'];
		var container = this.getContainer();
		
		classes.each(function(c){
			(classname == c) ? container.addClass(c) : container.removeClass(c);
		});
		this.getErrorElement().setHTML(msg);
		this.getErrorElement().removeClass('fabrikHide');

		var parent = this.form;
		if(classname == 'fabrikError' || classname == 'fabrikSuccess'){
			parent.updateMainError();
		}
		
		var fx = this.getValidationFx();
		switch(classname){
			case 'fabrikValidating':
			case 'fabrikError':
				fx.start({
		 			'opacity':1
		 		});
				break;
			case 'fabrikSuccess':
				fx.start({
			 			'opacity':1
			 		}).chain( function(){
			 		//only fade out if its still the success message
			 			if(container.hasClass('fabrikSuccess')){
			 					container.removeClass('fabrikSuccess');
				 				this.start.delay(700, this, {
									'opacity': 0,
									'onComplete':function(){
										parent.updateMainError();
										classes.each(function(c){
											container.removeClass(c);
										});
									}
								});
							}
			 		});
				break;
		}
	},
	
	setorigId: function()
	{
		if(this.options.repeatCounter > 0){
			var e = this.options.element;
			this.origId = e.substring(0, e.length - 1 - this.options.repeatCounter.toString().length);
		}
	}
});

FbElement.implement(new Events);

/**
 * @author Rob
 * contains methods that are used by any element which manipulates files/folders
 */

	
var FbFileElement = FbElement.extend({
	
	initialize:function(){
		this.folderlist = [];
	},
	
	ajaxFolder: function()
	{
		this.folderlist = [];
		if($type(this.element) === false){
			return;
		}
		var el = this.element.findClassUp('fabrikElement');
		this.breadcrumbs = el.getElement('.breadcrumbs');
		this.folderdiv = el.getElement('.folderselect');
		this.slider = new Fx.Slide(this.folderdiv , {duration: 500});
		this.slider.hide();
		this.hiddenField = el.getElement('.folderpath');
		el.getElement('.toggle').addEvent('click', function(e){
			new Event(e).stop();
			this.slider.toggle();
		}.bind(this));
		this.watchAjaxFolderLinks();
	},
	
		
	watchAjaxFolderLinks: function()
	{
		this.folderdiv.getElements('a').addEvent('click', this.browseFolders.bindAsEventListener(this));
		this.breadcrumbs.getElements('a').addEvent('click', this.useBreadcrumbs.bindAsEventListener(this));
	},
	
		
	browseFolders: function(e){
		e = new Event(e).stop();
		var a = $(e.target);
		this.folderlist.push(a.innerHTML);
		var dir = this.options.dir + this.folderlist.join(this.options.ds);
		this.addCrumb(a.innerHTML);
		this.doAjaxBrowse(dir);
	},
	
	useBreadcrumbs: function(e)
	{
		e = new Event(e).stop();
		var found = false;
		var a = $(e.target);
		var c = a.className;
		this.folderlist = [];
		var res = this.breadcrumbs.getElements('a').every(function(link){
			if(link.className == a.className){
				return false;
			}
			this.folderlist.push(a.innerHTML);
			return true;
		}, this);
		
		var home = [this.breadcrumbs.getElements('a').shift().clone(),
		this.breadcrumbs.getElements('span').shift().clone()];
		this.breadcrumbs.empty();
		this.breadcrumbs.adopt(home);
		this.folderlist.each(function(txt){
			this.addCrumb(txt);
		}, this);
		var dir = this.options.dir + this.folderlist.join(this.options.ds);
		this.doAjaxBrowse(dir);
	},
	
	doAjaxBrowse: function( dir ){
		var url = this.options.liveSite+"index.php?option=com_fabrik&format=raw&controller=plugin&task=pluginAjax&plugin=fabrikfileupload&method=ajax_getFolders&element_id="+ this.options.id;
	
		new Ajax(url, {
			data:{'dir':dir},
			onComplete:function(r){
				r = Json.evaluate(r);
				this.folderdiv.empty();
				
				r.each(function(folder){
					new Element('li', { 'class':'fileupload_folder'}).adopt(
					new Element('a', {'href':'#'}).setText(folder)).injectInside(this.folderdiv);
				}.bind(this));
				if (r.length == 0){
					this.slider.hide();
				}else{
					this.slider.slideIn();
				}
				this.watchAjaxFolderLinks();
				this.hiddenField.value =  '/'+this.folderlist.join('/') + '/';
				this.fireEvent('onBrowse');
			}.bind(this)
		}).request();
	},
	
		
	addCrumb:function(txt){
		this.breadcrumbs.adopt(
		new Element('a', {'href':'#', 'class':'crumb'+ this.folderlist.length}).setText(txt),
		new Element('span').setText(' / ')
		);
	}
});
