//
// create closure
//
(function($) {
  //
  // plugin definition
  // 

  $.fn.rbajax = function(options) {  	
		$selector = $(this);
   	// build main options before element iteration
   	var opts = jQuery.extend({
   	type: '',
   	url: '',	
    iframe: false,
	  messageTarget: 'output',
	  validateOptions: {rules: {}, messages: {}},
	  loadCss: false,
	  loadJs: false,
	  faceboxId: '',
	  beforeSubmit: '',
	  beforeSuccess: '',
	  afterSuccess: '',
	  beforeError: '',
	  afterError: ''
  	}, options);
 
 		// the loaders
 		//$selector.ajaxStart(function(){
   		//	$.blockUI(opts.blockUIOptions); 
 		//	});
 			
		//$selector.ajaxStop(function(){
		//		$.unblockUI();
		//	});
			
 		//$selector.ajaxError(function(){
 		//		$.unblockUI();
		//	});	
			
	$('#'+opts.messageTarget).attr('tabindex', -1);
	$.fn.displayMessage = function (msg, opts){
		$('#'+opts.messageTarget).focus().html(msg);
  	};
	  
	var resetMessage = function (opts){
		$('#'+opts.messageTarget).html('');
	};

	var updateContent = function(response, status, opts){
		if(status === undefined || status != 'success'){
			$.fn.displayMessage(response, opts);
			return;
		}

		if (response.message !== undefined) 
			$.fn.displayMessage(response.message, opts);
		else
			resetMessage(opts);
			
		switch(response.status){
			case 'success':
				// load css
				//$.requireConfig.routeCss = '<?php echo DIR_WS_TEMPLATE;?>css/';
				if(opts.loadCss && response.load !== undefined){
					jQuery.each(response.load['css'], function(i, val) {
						if(val !== undefined) 
		      	$.include(val);
		  		});	
				}
	  		// facebox?
	  		if(opts.faceboxId != ''){
	  			$.facebox('<div id="'+opts.faceboxId+'"></div>');
//	  			$.rbajax("#"+opts.faceboxId, opts.faceboxOptions);
	  		}
	  		
				// update the content
				if(response.content !== undefined){
					jQuery.each(response.content, function(i, val) {
						if(val != '') 
		      	$("#" + i).html(val);
		  		});			
				}
								
	  		if(response.action !== undefined){
//					switch(response.action.type){
//						case 'autosubmit':
//							$(selector + ' .step[title='+currentIndex+'] ' + response.action.id).ajaxSubmit({ 
//							  success: function(data, textStatus){
//			         	updateContent(data, textStatus, opts);
//			        	},
//							  dataType:  'json',
//								error: function(xhr) {
//									$.fn.displayMessage('Error: ' + xhr.status + ' ' + xhr.statusText + ' ' + xhr.responseText, opts);
//								}
//							 });
//							$(selector + ' .step[title='+currentIndex+'] .loader').fadeIn();
//						break;
//					}
				}
				else if(opts.loadJs){			
					// load external js files
					if(response.load !== undefined){
						jQuery.each(response.load['jscript'], function(i, val) {
							if(val !== undefined) 
			      	$.include(val);
			  		});	
			  		
			  		// inline js
			  		$('#'+opts.messageTarget).append(response.load['jscript_inline']);
			  		
			  		// onload js
			  		if(response.load['jscript_onload'].length > 0)
			  			eval(response.load['jscript_onload']);	
					}
				}
				break;
			case 'redirect':
				var url = urldecode(response.url);
				if($.fn.rbajax.redirect[response.redirect_type] !== undefined)
					$.fn.rbajax.redirect[response.redirect_type](url, updateContent, opts);
				else
					$.fn.rbajax.redirect.defaultRedirect(url, updateContent, opts); 
				break;
		}
	};
	   
	/*`
	 * End of function and var definition
	 * Begin binding
	 */		
	var elementType = opts.type == '' ? $selector.attr('tagName') : opts.type;
	
	if(elementType=='A'){
		// binding to link
		$selector.live('click', function(e){
			if( (!$.browser.msie && e.button == 0) || ($.browser.msie && e.button == 0)) {
				var element = this;
				if(opts.beforeSubmit != '') opts.beforeSubmit(element, opts);
				$.ajax({
	  		type: "GET",
				url: opts.url != '' ? opts.url : $(this).attr('href'),
				dataType: 'json',
				success: function(data, textStatus){
								if ($.isFunction(opts.beforeSuccess))
									opts.beforeSuccess(element, data, textStatus, opts);
			         	
								updateContent(data, textStatus, opts);
			         	
			         	if ($.isFunction(opts.afterSuccess))
									opts.afterSuccess(element, data, textStatus, opts);
			        	},
			  error: function(xhr) {
			  				if ($.isFunction(opts.beforeError))
	  							opts.beforeError(element, data, textStatus, opts);
	  							
								$.fn.displayMessage('Error: ' + xhr.status + ' ' + xhr.statusText + ' ' + xhr.responseText, opts);
								
								if ($.isFunction(opts.afterError))
	  							opts.afterError(element, data, textStatus, opts);
								}
				});
				return false;
			}
		}); 
	}
	
	else if(elementType == 'FORM'){	
		// binding to forms	
	 	$selector.live("submit", function(){
	 		//if($(this).validate({rules: opts.validateOptions.rules,messages: opts.validateOptions.messages}).form())
	 		var element = this;
	 		if(opts.beforeSubmit != '') opts.beforeSubmit(element, opts);
			$(this).ajaxSubmit({ 
				dataType:  'json',
			  success: function(data, textStatus){
			  	if ($.isFunction(opts.beforeSuccess))
							opts.beforeSuccess(element, data, textStatus, opts);
	         	
						updateContent(data, textStatus, opts);
	         	
	         	if ($.isFunction(opts.afterSuccess))
							opts.afterSuccess(element, data, textStatus, opts);
    		},
				error: function(xhr) {
					if ($.isFunction(opts.beforeError))
							opts.beforeError(element, data, textStatus, opts);
							
						$.fn.displayMessage('Error: ' + xhr.status + ' ' + xhr.statusText + ' ' + xhr.responseText, opts);
						
						if ($.isFunction(opts.afterError))
							opts.afterError(element, data, textStatus, opts);
				},
				data: { isajaxrequest: '1', iframe: opts.iframe ? '1' : '0' } ,
				iframe: opts.iframe,
				url: opts.url != '' ? opts.url : $(element).attr('action')
			 });
			return false;
  	})
	}
 }
  $.fn.rbajax.redirect = [];
  
  //
  // private function for debugging
  //
  function debug($obj) {
	if (window.console && window.console.log)
	  window.console.log('rbajax selection count: ' + $obj.size());
  };
	
	function urldecode( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Philip Peterson
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: AJ
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir
    // %          note: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
    // *     example 1: urldecode('Kevin+van+Zonneveld%21');
    // *     returns 1: 'Kevin van Zonneveld!'
    // *     example 2: urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
    // *     returns 2: 'http://kevin.vanzonneveld.net/'
    // *     example 3: urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
    // *     returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
    
    var histogram = {};
    var ret = str.toString();
    
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
    
    // The histogram is identical to the one in urlencode.
    histogram["'"]   = '%27';
    histogram['(']   = '%28';
    histogram[')']   = '%29';
    histogram['*']   = '%2A';
    histogram['~']   = '%7E';
    histogram['!']   = '%21';
    histogram['%20'] = '+';
    histogram['&'] = '&amp;';
 
    for (replace in histogram) {
        search = histogram[replace]; // Switch order when decoding
        ret = replacer(search, replace, ret) // Custom replace. No regexing   
    }
    
    // End with decodeURIComponent, which most resembles PHP's encoding functions
    ret = decodeURIComponent(ret);
 
    return ret;
}

  //
  // the default redirection method
  //
  $.fn.rbajax.redirect.defaultRedirect = function(redirect_url, updateContent, opts) {
  	$.ajax({
  		type: "GET",
			url: redirect_url,
			dataType: 'json',
			success: function(data, textStatus){
			         	updateContent(data, textStatus, opts);
			        },
			error: function(xhr) {
									$.fn.displayMessage('Error: ' + xhr.status + ' ' + xhr.statusText + ' ' + xhr.responseText, opts);
								}
  	});
		return;
  };
  
  $.fn.rbajax.redirect.forceRedirect = function(redirect_url, updateContent, opts) {
  	window.location=redirect_url;
  	return;
  };
  
  $.fn.rbajax.redirect.noRedirect = function(redirect_url, updateContent, opts) {
		return;
  };
})(jQuery);
