/**
 * QiPHP Framework for PHP 5.2.x
 * 
 * The Qi Form framework is a form generator package
 * Future versions will integrate with Archetype and will 
 * also include other Archetype transformation utilities.
 * 
 * @filesource
 * @package		jquery-qiform-tools.js
 * @version		5.2.x-1.0
 * @copyright	(C) 2009, Transio LLC
 * @author		Steven Moseley
 * @link		http://www.qiphp.com/
 * @license		GNU General Public License (see below)
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program, LICENSE.txt.
 * 
 * If not, see <http://www.gnu.org/licenses/>.
 */

var prefixSeparator = "__";

// Form setup
$(document).ready(function(){
	// Set up date inputs
	$('.qf-date').datepicker({
		yearRange: '1910:2010',
		dateFormat: 'yy-mm-dd',
		constrainInput: true,
		changeMonth: true,
		changeYear: true
	}).each(function() {
		// Check other classes for desired date formats
	});
	
	showWatermarks();
	
	
	$(".qf-input").focus(function(event){
		hideWatermark(this);
	});
	
	$(".qf-input").blur(function(event){
		showWatermarks();
	});
	
	// Int format requirements
	$(".qf-format-int").keypress(function(event){
		$(this).attr("value", formatNumber($(this).attr("value"), false));
	});
	
	// Numeric format (allows one ".")
	$(".qf-format-numeric").keypress(function(event){
		$(this).attr("value", formatNumber($(this).attr("value"), true));
	});
	
	// Percentage format (allows one ".", ends with "%", divides by 100 for final result)
	$(".qf-format-percentage").focus(function(event){
            var percentage = formatNumber($(this).attr("value"), true);
            //if (percentage < 1) {
                    percentage = Math.round(percentage * 1000000)/10000;
            //}
            $(this).attr("value", "" + percentage + "%");
            adjustPercentageCaret(this, true);
    }).blur(function(event){
            var percentage = formatNumber($(this).attr("value"), true);
            //if (percentage > 1) {
                    percentage = Math.round(percentage*10000) / 1000000;
            //}
            $(this).attr("value", percentage);
    }).keyup(function(event) {
            var percentage = formatNumber($(this).attr("value"), true);
            $(this).attr("value", "" + percentage + "%");
            adjustPercentageCaret(this, false);
    });
    function adjustPercentageCaret(input, force) {
            var pos = caret(input);
            var len = $(input).attr("value").length;
            if (force || pos >= len) {
                    caret(input, len-1);
            }
    }
	
    function caret(input, begin, end) {
            if (input.length == 0) return;
            if (typeof begin == 'number') {
                    end = (typeof end == 'number') ? end : begin;
                    if (input.setSelectionRange) {
                            input.focus();
                            input.setSelectionRange(begin, end);
                    } else if (input.createTextRange) {
                            var range = input.createTextRange();
                            range.collapse(true);
                            range.moveEnd('character', end);
                            range.moveStart('character', begin);
                            range.select();
                    }
                    return true;
            } else {
                    if (input.setSelectionRange) {
                            begin = input.selectionStart;
                            end = input.selectionEnd;
                            return begin;
                    } else if (document.selection && document.selection.createRange) {
                            var range = document.selection.createRange();
                            begin = 0 - range.duplicate().moveStart('character', -100000);
                            end = begin + range.text.length;
                            return begin;
                    }
                    return { begin: begin, end: end };
            }
    };

	
	// Apply masks
	$(".qf-format-phone").mask("(999) 999-9999");
	$(".qf-format-dob").mask("99/99/9999");
	$(".qf-format-ccdate").mask("99/9999");
	$(".qf-format-ccnumber").mask("9999-9999-9999-9999");
	$(".qf-format-ssn").mask("999-99-9999");
	
});

function refreshCaptcha(id) {
	var d = new Date();
	$("#"+id+"__img").attr("src", "/_/qf_captcha?id="+id+"&t="+d.getTime());
}

/**
 * Show all watermarks
 */
function showWatermarks() {
	$(".qf-watermark").each(function(event) {
		var input = $("#" + $(this).attr("for"));
		if (input.attr("value") == "") {
			input.attr("value", $(this).text());
		}
	});
}

/**
 * Hide all watermarks
 */
function hideWatermarks(form) {
	var selector = ".qf-watermark";
	if (form) {
		selector = "#" + $(form).attr("id") + " " +  selector;
	}
	$(selector).each(function(event) {
		var input = $("#" + $(this).attr("for"));
		if ($(this).attr("for") == $(input).attr("id")) {
			if (input.attr("value") == $(this).text()) {
				input.attr("value", "");
			}
		}
	});
}

/**
 * Hide watermarks for the specified imput
 * @param DOMElement input
 */
function hideWatermark(input) {
	$(".qf-watermark").each(function(event) {
		if ($(this).attr("for") == $(input).attr("id")) {
			if ($(input).attr("value") == $(this).text()) {
				$(input).attr("value", "")
			}
		}
	});
}

/**
 * Hide all errors
 */
function hideErrors(){
	$(".qf-input,.qf-select,.qf-textarea").each(function(event) {
		hideError(this);
	});
}

/**
 * Show an error
 * @param DOMEleemnt input
 */
function showError(input) {
	$(input).addClass("qf-error");
	$(input).parents("div.qf-input-wrapper,div.qf-select-wrapper,div.qf-textarea-wrapper").addClass("qf-error-wrapper");
}

/**
 * Hide an error
 * @param DOMEleemnt input
 */
function hideError(input) {
	$(input).removeClass("qf-error");
	$(input).parents("div.qf-error-wrapper").removeClass("qf-error-wrapper");	
}

function formatNumber(inValue, allowDecimals) {
	var outValue = "";
	var hasDecimal = false;
	for (var i = 0; i < inValue.length; i++) {
		var c = inValue.substring(i, i+1);
		if (c.length == 0 || (isNaN(c) && c != ".")) {
			// Not a number!
		} else {
			if (c == "." && (allowDecimals == false || hasDecimal == true)) {
				// Already has a "."!
			} else {
				if (c == ".") hasDecimal = true;
				outValue += c;
			}
		}
	}
	return outValue;
}

function validate(form) {
	if ($(form).hasClass("qi-form-ajax")) {
		// AJAX validation / submission
		window.alert("AJAX!");
	} else {
		// Hide existing errors
		hideErrors();
		
		// Hide watermarks during validation
		hideWatermarks(form);
		
		// Browser validation / standard submission
		// Server-side validation can be added in your Qi module
		var valid = true;
		var messages = Array();
		$(form).find(".qf-input,.qf-select,.qf-textarea").each(function (i) {
			// Ignore disabled fields
			if (this.disabled) {
				return;
			}
			
			// Input title (if exists)
			//var title = $(this).attr("title") ? $(this).attr("title") : "";
			var tagName = this.tagName ? this.tagName : "";
			var title = this.getAttribute("title") ? this.getAttribute("title") : "";
			var name = this.getAttribute("name") ? this.getAttribute("name") : "";
			
			// Validation rules
			var required = false;
			var minlength = 0;
			var maxlength = 0;
			var format = "";
			var confirm = "";
			
			// Parse class names
			var classes = $(this).attr("class");
			var classNames = classes.split(" ");
			
			// Traverse class names to determine applicable rules
			for (var i = 0; i < classNames.length; i++) {
				var className = classNames[i];
				if (className == "qf-required") required = true;
				if (className.substr(0, 13) == "qf-minlength-") minlength = className.substr(13);
				if (className.substr(0, 13) == "qf-maxlength-") maxlength = className.substr(13);
				if (className.substr(0, 10) == "qf-format-") format = className.substr(10);
			}
			
			var ok = true;
			
			// Check required fields
			if (required) {
				if (tagName == "select") {
					if (!$(this).val()) {
						messages[name] = "[" + title + "] is required.  Please make a selection.\n";
						ok = false;
					}
				} else {
					if (this.getAttribute("type") == "radio" && $("input[name='"+name+"']:checked").val() == null) {
						messages[name] = "[" + title + "] is required.  Please select one.";
						ok = false;
					} else if (this.getAttribute("type") == "checkbox" && $("input[name='"+name+"']:checked").val() == null) {
						messages[name] = "[" + title + "] is required.  Please check the box.";
						ok = false;
					} else if (this.value.length == 0) {
						messages[name] = "[" + title + "] is a required field.";
						ok = false;
					}
				}
			}
			
			// Confirm input test
			if (confirm.length > 0) {
				confirmInput = document.getElementById(confirm);
				if (confirmInput && this.value != confirmInput.value) {
					confirmTitle = confirmInput.getAttribute("title") ? confirmInput.getAttribute("title") : "Input";
					messages[name] = "[" + confirmTitle + "] and [" + title + "] do not match.";
					ok = false;
				}
			}
			
			// Format test
			if (format.length > 0 && required) {
				var filter = /^.*$/
				if (format.toLowerCase() == "email") {
					filter = /^(\w+[\-\.])*\w+@(\w+[\.\-]*)+\.[A-Za-z]+$/;
				} else if (format.toLowerCase() == "ssn") {
					filter = /^[0-9]{3}[\- ]?[0-9]{2}[\- ]?[0-9]{4}$/
				} else if (format.toLowerCase() == "phone") {
					filter = /^\([0-9]{3}\) [0-9]{3}\-[0-9]{4}$/
				} else if (format.toLowerCase() == "ccdate") {
					filter = /^[0-9]{2}\/[0-9]{4}$/
				} else if (format.toLowerCase() == "dob") {
					filter = /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/
				} else if (format.toLowerCase() == "ccnumber") {
					filter = /^[0-9]{4}\-[0-9]{4}\-[0-9]{4}\-[0-9]{4}$/
					} else if (format.toLowerCase() == "numeric" || format.toLowerCase() == "percentage") {
					filter = /^([0-9]*[\.]?)?[0-9]+$/
				} else if (format.toLowerCase() == "int") {
					filter = /^[0-9]+$/
				} else {
					eval("filter = /^" + decodeRegex(format) + "$/");
				}
				if (!filter.test(this.value)) {
					messages[name] = "[" + title + "] is not correctly formatted.";
					ok = false;
				}
			}
			
			// Minlength test
			if (minlength > 0) {
				if (this.value.length < minlength) {
					messages[name] = "[" + title + "] has a minimum required length of " + minlength + " characters.";
					ok = false;
				}
			}
			
			// Bad input should be styled appropriately
			if (!ok) {
				showError(this);
				valid = false;
			} else {
				hideError(this);
			}
		});
	}
	var message = "";
	for (id in messages) {
		message += messages[id] + "\n";
	}
	if (message.length > 0) {
		window.alert(message);
	}
	
	if (!valid) {
		// Show watermarks if validation failed
		showWatermarks();
		try {
			$(".qf-error:first").focus();
		} catch (e) {}
	}
	return valid;
}

// String encoding / decoding functions
function encodeRegex(str) {
	str = ""+str;
	str = str.replace(/\%/g, ":");
	return urlencode(str);
}

function decodeRegex(str) {
	str = ""+str;
	str = str.replace(/\:/g, "%");
	return urldecode(str);
}

function urlencode(str) {
	return escape(str).replace(/\+/g, "%2B").replace(/\%20/g, "+").replace(/\*/g, "%2A").replace(/\//g, "%2F").replace(/\@/g, "%40").replace(/[ ]/g, "+");
}

function urldecode(str) {
	return unescape(str.replace(/\+/g, " "));
}


/*
function getParameter(key) {
	var querystring = window.location.search.substring(1);
	var parameters = querystring.split("&");
	for (var i = 0; i < parameters.length; i++) {
		var pos = parameters[i].indexOf("=");
		if (pos > 0) {
			if (key == parameters[i].substring(0, pos)) {
				return "&" + parameters[i];
			}
		}
	}
	return "";
}
*/
