/*
 * eRube 2.0 Javascript Framework
 * Dependencies: eRube LDialog system, HTML5, Prototype
 */

var eRube = Object.extend(eRube || {}, {
  
  submitOnComplete: function(response) {
    var r = Object.clone(response.responseJSON);
  	// Find any buttons or other text items that are showing "loading" text
  	// and set them back to their original Text
  	$$('.eRubeLoadingText').each(function(e){
  		e.update(e.retrieve('eRubeOriginalText'));
  		e.removeClassName('eRubeLoadingText');
  		e.removeClassName('disabled');
  	});

  	// Remove anything that was added automatically previously	
  	// To avoid duplicate error messsages from subsequent retries
  	$$('.eRubeSubmitAuto').invoke('remove');


  	if (r._debugContent){
  		if (r._debugContent != ''){
  			$$('body').first().insert({bottom:r._debugContent});
  		}
  	}

	var shouldScrollBody = false;
  	if (r.actions){
  		r.actions.each(function(item){
			if (eRube.doAction(item)){
				shouldScrollBody = true;
			}
  		});
  	}	
	
	
	$$('form.eRubeSubmitting').first().removeClassName('eRubeSubmitting');
	
	// We dont' want to always do the scrolling thing, need to figure out what triggers it 
	if (shouldScrollBody){
		$$('body').first().scrollTo();
	}
  },
  
	alertMessage: function(message,classname){
		var alert_message = new Element('div').addClassName('alert-message').addClassName('eRubeAutoError').addClassName(classname).update(new Element('p').update(message));
		$$('form.eRubeSubmitting').first().insert({top:alert_message});
	},
  
  doAction: function(r){

	/* Right now FormErrors always get added to the top of the form that was submitted, however would like to add the ability to specify a container to receive these */
	if (r.FormWarning){
		eRube.alertMessage(r.FormWarning,'warning');
		return true;
	}

	if (r.FormError){
		eRube.alertMessage(r.FormError,'error');
		return true;
	}
	
	if (r.FormSuccess){
		eRube.alertMessage(r.FormSuccess,'success');
		return true;
	}
	
	if (r.FormInfo){
		eRube.alertMessage(r.FormInfo,'info');
		return true;
	}

	if (r.FieldError){
  		var f = $(r.FieldError);
  		if (f){
  			var dcf = $(r.FieldError).up('div.clearfix');
  			if (dcf){
  				dcf.addClassName('error').addClassName('eRubeAutoError');
  				if (r.Message){
  					var message = new Element('span').addClassName('help-block').addClassName('eRubeSubmitAuto').update(r.Message);
  					$(r.FieldError).insert({after:message});
  				}
  			}
  		}
  		return true;

  	}
	
	if (r.SetFieldValue){
  		var f = $(r.SetFieldValue);
  		if (f){
			f.setValue(r.FieldValue);
  		}
  		return;	
	}	

  	if (r.Alert){
  		alert(r.Alert);
  		return;
  	}

  	if (r.Reload){
  		location.href = r.Reload;			
  		return;
  	}
  	if (r.ReloadPage){
  		location.href = r.ReloadPage;
  		return;
  	}

  	if (r.DialogURL){
  		lDialogs.lastDialog.updateContentViaAjax(
  			{
  				url:r.DialogURL
  			}
  		);
  		return;
  	}

  	if (r.DivContent){
  		var theDiv = $(r.DivId);
  		theDiv.update(r.DivContent);
  		LDialog.resize();
  		return;
  	}
	


  	if (r.InsertContent){
  		var theElement    = $(r.ElementId);
		var content = {};
		content[r.InsertionPoint] = r.InsertContent;
  		theElement.insert( content );
  		LDialog.resize();
  		return;
  	}
	
  	if (r.DialogContent){
  		var ld = lDialogs.lastDialog;
  		if (ld){
  			ld.updateTitle(r.Title);
  			ld.updateContent(r.DialogContent);
  		} else {
  			new LDialog({
  				title: r.Title, 
  				content: r.DialogContent});
  		}
  		// Register any new observers that might have loaded with this content update
  		eRube.registerObservers($('dialogContent'));
  		eRube.callbackInitializers($('dialogContent'));

  		return;			
  	}

  	if (r.Focus){
  		$(r.Focus).focus();
  	}
  	if (r.Activate){
  		$(r.Activate).activate();
  	}
  },
  
  /*
  *	Register observers looks for all of the input|textarea.eRubeObserve form elements, 
  * 	finds a data-erube-observer attribute, on the element or an ancenstor "form" elemnent
  *	and then creates a new Form.Element.Observer,
  *
  *	For select elements, it regisers 'click' event handlers instead, since clicking on a select 
  *
  *
  */
  registerObservers: function(element){
  	// Look for all the eRubeObserve elements
  	var observedInputs = null;
  	if (element == false) {
  		observedInputs = $$('input.eRubeObserve, textarea.eRubeObserve');
  	} else {
  		observedInputs = element.select('input.eRubeObserve, textarea.eRubeObserve');
  	}
  	observedInputs.each(eRube.registerObserverChanges);

  	var observedSelects = null;
  	if (element == false) {
  		observedSelects = $$('select.eRubeObserve');
  	} else {
  		observedSelects = element.select('select.eRubeObserve');
  	}
  	observedSelects.each(eRube.registerObserverClicks);
	
  	var observedInputsOnLoad = null;
  	if (element == false) {
  		observedInputsOnLoad = $$('input.eRubeObserveLoad');
  	} else {
  		observedInputsOnLoad = element.select('input.eRubeObserveLoad');
  	}
  	observedInputsOnLoad.each(eRube.invokeLoadObserver);
	
  },
  
  getObserver: function(element){
  	var observer = element.readAttribute('data-erube-observer');
  	if (observer){
  		return observer;
  	} else {	
  		var form = element.up('form');
  		var formObserver = form.readAttribute('data-erube-observer');
  		if (formObserver){
  			return formObserver;
  		}
  	}
  },
  
  createObserver_eRubeSubmit: function(element){
  	// Here we try to create a Special Observer Callback that does a simple
  	// eRubeSubmit, if -formid or -url are on the observed element, this
  	// is what we want to happen.
  	var formid   = element.readAttribute('data-erube-formid');
  	var url      = element.readAttribute('data-erube-url');

  	if (formid || url){
  		return function(event){
  			eRube.submit({formid:formid,url:url});
  		}; 
  	} else {
  		return false;
  	}
  },
  
  createObserver: function(observer){
  	return function(event){
  		var element = event.findElement();
  		if (observer){
  			//console.log("calling Observer:"+observer);		
  			window[observer]({event:event,element:element,newvalue:null,init:false});	
  		}
  	};
  },
  
  createFormElementObserver_eRubeSubmit: function(element){
  	// Here we try to create a Special Observer Callback that does a simple
  	// eRubeSubmit, if -formid or -url are on the observed element, this
  	// is what we want to happen.
  	var formid   = element.readAttribute('data-erube-formid');
  	var url      = element.readAttribute('data-erube-url');

  	if (formid || url){
  		return function(ignoredarg1,ignoredarg2){
  			eRube.submit({formid:formid,url:url});
  		}; 
  	} else {
  		return false;
  	}
  },
  
  createFormElementObserver: function(observer){
  	return function(element,newvalue){
  		if (observer){
  			//console.log("calling FormElementObserver:"+observer);		
  			window[observer]({event:null,element:element,newvalue:newvalue,init:false});	
  		}
  	};
  },
  
  registerObserverClicks: function(element){
  	var observer_name    = null;
  	var ObserverCallback = null;

  	// Check for eRubeSubmit Special Handler Setup
  	ObserverCallback     = eRube.createFormElementObserver_eRubeSubmit(element);

  	if ( ! ObserverCallback ) {
  		observer_name    = eRube.getObserver(element);
  		if (observer_name){
  			ObserverCallback = eRube.createObserver(observer_name);
  		}
  	}

  	// Now Register the Callback if it is good
  	if ( ObserverCallback ) {
  		element.observe('change', ObserverCallback);
  	}
  },
  
  registerObserverChanges: function(element){
  	var observer_name    = null;
  	var ObserverCallback = null;
  	var freq             = 0.33;	

  	// Override default frequency
  	if (element.readAttribute('data-erube-observer-freq')){
  		freq = element.readAttribute('data-erube-observer-freq');
  	}

  	// Check for eRubeSubmit Special Handler Setup
  	ObserverCallback     = eRube.createFormElementObserver_eRubeSubmit(element);

  	if ( ! ObserverCallback ) {
  		observer_name = eRube.getObserver(element);	
  		if (observer_name){
  			ObserverCallback = eRube.createFormElementObserver(observer_name);
  		} 
  	}

  	// Now Register the Callback if it is good
  	if ( ObserverCallback ) {
  		new  Form.Element.Observer(element, freq, ObserverCallback);
  	}
  },

  invokeLoadObserver: function(element){
  	var observer_name    = null;
  	var ObserverCallback = null;

  	// Check for eRubeSubmit Special Handler Setup
  	ObserverCallback     = eRube.createFormElementObserver_eRubeSubmit(element);

  	if ( ! ObserverCallback ) {
  		observer_name = eRube.getObserver(element);	
  		if (observer_name){
  			ObserverCallback = eRube.createFormElementObserver(observer_name);
  		} 
  	}

  	// Now Register the Callback if it is good
  	if ( ObserverCallback ) {
		ObserverCallback(element);
  	}

  },
  
  callbackInitializers: function(element){

  	// Look for all the eRubeObserve elements
  	var forms = null;
  	if (element == false){
  		forms = $$('form');
  	} else {
  		forms = element.select('form');
  	}
  	forms.each(eRube.callbackInitializer);
  },
  
  callbackInitializer: function(element){
  	var initCallback = element.readAttribute('data-erube-init');
  	if (initCallback){
  		window[initCallback]( {
  			event:null,
  			element:element,
  			newvalue:null,
  			is_init:true } );
  	}
  },
  
  submit: function(options){
  	if (options.preDialog){

  	}

  	if (options.formid && options.url){
		$(options.formid).addClassName('eRubeSubmitting');
  		new Ajax.Request( options.url,{
  			parameters: $(options.formid).serialize(true),
  			onComplete: eRube.submitOnComplete	
  		});
  	}else if (options.formid){
		$(options.formid).addClassName('eRubeSubmitting');
  		$(options.formid).request( {
  			onComplete: eRube.submitOnComplete	
  		});
  	} else if (options.url){
  		new Ajax.Request( options.url,{
  			onComplete: eRube.submitOnComplete	
  		});
  	}
  },
  
  submitCB: function(event,element){

  	if (element.hasClassName('disabled')){
  		event.stop();
  		return;
  	}
	var isLeftClick = event.isLeftClick();
	var isIE = Prototype.Browser.IE;
  	if ( isLeftClick || isIE ){
  		var options = {};
  		if (element.readAttribute('data-erube-confirm')){
  			var dec = element.readAttribute('data-erube-confirm');
  			var response = confirm(dec);
  			if (!response){
				event.stop();			
  				return;
  			}
  		}	
		
		if (element.readAttribute('data-erube-stopevent')){
			event.stop();
			return;
		}

  		if (element.readAttribute('data-erube-formid')){
  			options.formid = element.readAttribute('data-erube-formid');
  		}
  		if (element.readAttribute('data-erube-url')){
  			options.url = element.readAttribute('data-erube-url');
  		}
  		if (element.readAttribute('data-erube-loadingid')){
  			options.preDialog = element.readAttribute('data-erube-loadingid');
  		}	

  		if (element.readAttribute('data-erube-waiting-button-text')){
  			element.store('eRubeOriginalText',element.innerHTML);
  			element.update(element.readAttribute('data-erube-waiting-button-text'));
  			element.addClassName('eRubeLoadingText').addClassName('disabled');
  		}	


  		/*
  		Some things to add
  		data-erube-toggleclassed - toggle elements with referenced class
  		data-erube-togglenearbyclassed - toggle nearest cousin element(s) with referenced class
  		data-erube-showclassed - show elements with referenced class
  		data-erube-shownearbyclassed - show nearest cousin element(s) with referenced class
  		data-erube-hideclassed - hide elements with referenced class
  		data-erube-hidenearbyclassed - hide nearest cousin element(s) with referenced class

  		*/

		if (element.readAttribute('data-erube-hideclassed')){
			var toggleclasses = element.readAttribute('data-erube-hideclassed');
  			$w(toggleclasses).each(function (classname){
					$$('.' + classname).invoke('hide');
  				}
  			);		
		}
		if (element.readAttribute('data-erube-toggleclassed')){
			var toggleclasses = element.readAttribute('data-erube-toggleclassed');
  			$w(toggleclasses).each(function (classname){
					$$('.' + classname).invoke('toggle');
  				}
  			);		
		}
  		if (element.readAttribute('data-erube-toggleclasses')){
  			var toggleclasses = element.readAttribute('data-erube-toggleclasses');
  			$w(toggleclasses).each(function (classname){
  					element.toggleClassName(classname);
  				}
  			);
  		}	



  		if (element.hasClassName('eRubeCloseDialog')){
  			LDialog.close();
  		}
  		if (options.preDialog){
  			var content = $(options.preDialog).firstDescendant().clone(true);		
  			var title   = $(options.preDialog).readAttribute('data-title');
  			var ld = lDialogs.lastDialog;
  			if (ld){
  				ld.updateTitle(title);				
  				ld.updateContentHideOld(content);
  			} else {
  				new LDialog({
  					title: title,
  					content: content});
  			}
  		}
		if (options.formid){
			$$('.alert-message.eRubeAutoError').each(function(i){i.remove();});
			$$('.error.eRubeAutoError').each(function(i){i.removeClassName('error').removeClassName('eRubeAutoError');});
		}
  		if (options.url || options.formid){
  			eRube.submit(options);
			event.stop();
  		}	

		// If we got this far, but the href is just a # or an empty string, don't bother following it
  		if (element.readAttribute('href')){
			var href = element.readAttribute('href');
			if ((href == '#') || (href == '')){
				event.stop();
			}			
		}
		// If a url or formid weren't set, just do what you would normally do
		// Which is probably to follow an href
  		
  	}
  },
  
  LDialogCloseCB: function(event,element){
  	LDialog.close();
  	if (element.hasClassName('FollowLink')){
  		return;
  	}
  	event.stop();
  }
  
});


new Event.Handler( document, 'click', '.eRubeSubmit',       eRube.submitCB ).start();

document.observe("dom:loaded", function(){
	eRube.registerObservers(false);
});


/*
			function attemptLogin(event) {
				if (event.keyCode == Event.KEY_RETURN) {
					$('loginform').submit();
				}
			}
			$('login').observe('keyup', attemptLogin);
			$('password').observe('keyup', attemptLogin);
*/


