/**
* COPYRIGHTED SOFTWARE
* PLEASE READ THE LICENSE AGREEMENT
*
* @copyright		Copyright 2008-2010 Dilltree Inc.
* @package			tPantherPro
* @license 			http://dilltree.com/license/tPantherPro/2.0
* @author			Jeremy Dill
*
**/
// formulate PLUGIN -JDILL
// @description:  configures a form for using validateForm
// @copyright Jeremy Dill - All Rights Reserved
// @notes: adding class of "nsoe" to an input element supresses the enter submit form event assignment for that input
// @notes: calling forumlate more than once will not create double bindings, but calling more than once should not be necessary.
// @ver .12
(function($){
  $.fn.formulate = function(o) {
	o = jQuery.extend({
		submitBtnSelector: ".x_submit", // null to NOT, bind letting you submit as real post.
		callbacks: '', // jcall functions to call after validate (csv) such as "resetPassword,sendEmail".  Optionally, pass a path of a tpl set to "servUp, such as "/myform/send", executed as jsonly.
		precalls: '', // jcall functions to call before validation (csv) such as "myFunc,doubleCheck".  Optionally, pass a path of a tpl set to "servUp, such as "/myform/precall", executed as jsonly.
		extraVars: {}, // any extra vars (non-form inputs) that you want to pass into validationForm function.  EX: {myvar:'test value'} becomes $extraVars[myvar] in php.  Also will be passed to precalls or callbacks (non-servUp jcall functions) as 2nd param.
		jcallOpts: null, // jcall loader opts.  By default, we will use submitBtnSelector for next to button loader functionality.
		formSel : $(this).selector, // selector of form.
		vdFromClass : true, // instead of assuming _vd, convert classes starting with vd- to commands.
		errLoc : "after", // loction of errors. Options are "before", "after", "instantPop",  (or special: "[sel]" - a selector for any container. (see jCall::setErr)
		autoLabels : false, // create <labels></labels> for me since I don't have any reason to do it manually. (also forces createErrSpans & autoLabelFor = true)
		createErrSpans : false, // automatically create vd_error spans (or you can do it yourself inside the label),
		autoLabelFor : false, // automatically add the label "for" attr.  Corresponds with errorloc, and assumes a <label></label> somewhere in the same block as the input (before or after)
		setFocusObj : $(this).find("[name]:enabled:visible:first")[0], // set focus on this object after formulate runs. null for none.
		passwordSaver : false, // posts form to hidden iframe to prompt browser to save password.  Use for login boxes.
		normalize : false, // special utility to remove _vd to element name property (use as a second call of formulate on same form).
		beforeProcessing : function(frm){}, // Do something before processing form and before submit...return false to prevent ajax jcall submission.
		beforeSubmit : function(frm,fdata,opts){}, // Do something before submit...return false to prevent ajax jcall submission.
		jaxify : false
	}, o);

	  var clickAction=function() {
			var frm=$(o.formSel);
			if (_PI.wait) return false;
			if(o.errLoc != "instantPop") frm.find(".vd_error").html('');
			//$("div[id^='" + $.uid(frm) + "_']").not(o.submitBtnSelector).remove();
			if(o.beforeProcessing(frm)===false) return false;
			if (o.vdFromClass) {
			    frm.find("[name]").each(function() {
					var jobj=$(this);
					if (jobj.data('fc')) return;
					jobj.data('fc',true);
			        var nm = jobj.attr('name');
					if(nm.indexOf('_vd') > 0) return;
			        var list = jobj.attr('class').split(" ");
			        for (var i = 0; i < list.length; i++) {
			            if (list[i].indexOf("vd-") >= 0) {
			                var cl = list[i].substring(3, list[i].length);
			                if (nm.indexOf('_vd') < 0) {
			                    jobj.attr('name', nm + "_vd-" + cl);
			                } else {
			                    jobj.attr('name', nm + "-" + cl);
			                }
			                break;
			            }
			        }
			    });
			}

			// call it up
			var fdata = frm.serialize();
			var opts={callbacks:o.callbacks, formSel:o.formSel, errLoc:o.errLoc, precalls:o.precalls, extraVars:o.extraVars};
			if(!o.jcallOpts) var ldr=o.submitBtnSelector;
			else var ldr=o.jcallOpts;
			if(o.beforeSubmit(frm[0],fdata,opts)!==false) _PI.jcall('validateForm', [fdata, opts],ldr);
			if (o.passwordSaver) {
				if ($('#psaver').length<1) {
				var baseurl=window.location.href.substring(0,window.location.href.indexOf("/",10));
				 $('body').append("<iframe src='"+baseurl+"/empty.html' id='psaver' name='psaver' style='display:none;height:0;width:0'></iframe>");
				}
				frm.attr("target","psaver").attr("action","empty.html").attr("method","post").submit();
				return true;
			}
			return false;
       }

      return this.each(function() {
			var obj = $(o.formSel);
			obj.data("selector",o.formSel);
			//obj.data("sbtn",o.submitBtnSelector);
			obj.data("sbtn",obj.find(o.submitBtnSelector));

			if (o.normalize) {
				 obj.find("[name]").each(function() {
					var jobj=$(this);
					  var nm = jobj.attr('name');
					  if (nm.indexOf('_vd') > 0) {
							jobj.attr('name', nm.substring(0, nm.indexOf('_vd')));
					  }
				 });
				 return;
			}

			// AUTOCREATE LABELS
			if (o.autoLabels) {
				 obj.find("[name*='_vd']").each(function(){
					var jobj=$(this);
					if(jobj.data('fc')) return;
					if (o.errLoc === "before") jobj.before("<label></label>");
					else jobj.after("<label></label>");
				});
				 o.createErrSpans = true;
				 o.autoLabelFor = true;
			}

			// ADD ERROR FIELDS
			if (o.createErrSpans || o.autoLabelFor) lbl = obj.find("label").each(function() {
				var jobj=$(this);
				if (jobj.data('fc')) return;
				 if (o.createErrSpans) if (jobj.find("span.vd_error").length < 1) jobj.append("<span class='vd_error'></span>");
				 if (o.autoLabelFor) {
					  // find relative
					  if (o.errLoc == "before") var elem = jobj.nextAll("[name]:first");
					  if (o.errLoc == "after") var elem = jobj.prevAll("[name]:first");
						var forid = elem.attr("name");
						elem.attr("id", forid);
						jobj.attr('for', forid);
				 }
			});

			// BIND FORM SUBMIT
			$(o.formSel+" "+o.submitBtnSelector).each(function(){
				var jobj=$(this);
				if (jobj.data('fc')) return;
				jobj.click(clickAction).data('fc',true);
			});

			// FOCUS FIRST
			if (o.setFocusObj){
				o.setFocusObj.focus();
				if(o.setFocusObj.select) o.setFocusObj.select();
			}

			// BIND ENTER KEY
			$(document).unbind('.formulate');
			$(o.formSel+" [name]").die().live('keydown.formulate',
				function(e) {
				if (e.keyCode == 13 ) {
					var jobj=$(this);
					if (jobj.hasClass("nsoe")) return true;
					var frm=jobj.parents("form:first");
					frm.data("sbtn").click();
					return false;
				}
				}
			)
      });
  }

})(jQuery);
