// CPEP extensions to the jQuery validation plugin
// http://docs.jquery.com/Plugins/Validation/

$(document).ready(function(){
    $(".trim").change(function(event){
	$(this).val($.trim($(this).val()));
    });
    
    
    var validator = $("form:not(.noValidate)").validate({ // Validate all forms by default
	errorClass: 'inputValidationError',
	onkeyup: false,
	success: function(label) {
	    // IE needs a space to render the label
	    label.addClass('inputValidationSuccess').html(' <br/>');
	},
	
	errorPlacement: function(error, element) {
	    if (element.is(".xinha_textarea")) {
		error.insertBefore(element.parent().parent().parent().parent());
		error.attr('style', 'margin-left: 0;');
		element.parent().parent().parent().parent().attr('style', 'margin-top: 2px;');
	    } else if (element.is(".errorBefore")) {
		error.insertBefore(element);
		error.attr('style', 'margin-left: 0;');
	    } else if (element.is(".errorBeforeParent")) {
		error.insertBefore(element.parent());
		error.attr('style', 'margin-left: 0;');
	    } else if (element.is(".password") && element.parent().find(".password_strength").length) {
		error.insertAfter(element.parent().find(".password_strength"));
	    } else {
		error.insertAfter(element);
	    }
	}
    }); 
    
    if (typeof validator != 'undefined') validator.focusInvalid = function() {
	// put focus on xinha on submit validation
	
	if(this.settings.focusInvalid) {
	    try {
		var toFocus = $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []);
		if (toFocus.is("textarea")) {
		    if (toFocus.is(".xinha_textarea")) {
			$('#'+toFocus.attr('id')).attr('style', 'display: block;');
			$('#'+toFocus.attr('id')).focus();
			$('#'+toFocus.attr('id')).attr('style', 'display: none;');
			iLabelTop = parseInt($('#'+toFocus.attr('id')).parent().parent().parent().parent().prev('label').position().top);
		    } else {
			$('#'+toFocus.attr('id')).focus();
			iLabelTop = parseInt($('#'+toFocus.attr('id')).parent().prev('label').position().top);
		    }
		    
		    window.scrollTo(0, iLabelTop-36);
		} else {
		    $('#'+toFocus.attr('id')).focus();
		}
	    } catch(e) {
		// ignore IE throwing errors when focusing hidden elements
	    }
	}
    }
    
});

///////////////////////////////////////////////////////////////////////////////
// Validator methods

// Override default 'required' method to cope with xinha_textareas
$.validator.methods._required = $.validator.methods.required;

$.validator.addMethod("required", function(value, element, param) {

    if (element.className.indexOf('xinha_textarea') != -1) {
	// Special case for xinha_textareas
	element.value = $.trim(value);
	
	sContent = element.value;
	if (xinhaIsInitialised) {
	    sContent = $("#"+element.id).prev().contents().find('body').html();
	    sContent = sContent.replace(/<(.|\n)*?>/g, '');
	    sContent = sContent.replace(/&nbsp;/g, ' ');
	    sContent = $.trim(sContent);
	}
	return sContent.length > 0;

    } else if(element.className.indexOf('cpep_editor') != -1) {

	var data = $('#' + element.id).data('webeditor');
	if(data && data.mce) {
	    $('#' + element.id).tinymce().save();

	    var sContent = $('#' + element.id).tinymce().getContent({format : 'text'});
	    sContent = sContent.replace(/<(.|\n)*?>/g, '');
	    sContent = sContent.replace(/&nbsp;/g, ' ');
	    sContent = $.trim(sContent);
	    return sContent.length > 0;
	}
    }
    return $.validator.methods._required.call(this, value, element, param);
    
}, jQuery.validator.messages.required); // use default message

// Required if displayed
$.validator.addMethod("required-if-visible", function(value, element) {
    var required = $(element).is(":visible") ? true : false;

    return required ? value.length > 0 : true;
}, jQuery.validator.messages.required); // use default message

// Validate strict filename
$.validator.addMethod("strict-filename", function(value, element) {
    value = $.trim(value);
    return this.optional(element) || /^(.*?[\\\/])*[\w-\.]+$/.test(value);
}, 'The filename may only contain letters, numbers, underscores, hyphens and dots');

// Validate strict reference
$.validator.addMethod("strict-reference", function(value, element) {
    value = $.trim(value);
    return this.optional(element) || /^[\w-]*$/.test(value);
}, 'The reference may only contain letters, numbers, underscores and hyphens');

// Validate APR
$.validator.addMethod("apr", function(value, element){
    value = $.trim(value);
    return this.optional(element) || /^\d*\.\d$/.test(value);
}, 'This value should a number entered to 1 decimal place');

// Validate currency
$.validator.addMethod("currency", function(value, element){
    value = $.trim(value);
    return this.optional(element) || /^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(\.[0-9]{2})?$/.test(value);
}, 'This value should a number entered to 2 decimal places');

// Validate mileage
$.validator.addMethod("mileage", function(value, element){
    value = $.trim(value);
    value = value.replace(/[^\d^\.]/g, '');
    
    if (value.length !=5) return false;
    
    return this.optional(element) || /^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)?$/.test(value);
}, 'Mileage should be 5 figures, with no decimal places');

$.validator.addMethod("gt0", function(value, element) {
    return this.optional(element) || (parseFloat(value) > 0);
}, "This must be greater than zero");

// Unique value check
$.validator.addMethod("unique", function(value, element){
    // This function checks if a field value has already been used by 
    // comparing it to the aUsed/aUsed[element.name] array
    // Also works with arrays of objects (checking the textNode property)
    
    value = $.trim(value);
    value = value.toLowerCase();
    
    // Determine what type of aUsed validation we're doing (none, old array, json array or object containing many json arrays)
    if(typeof aUsed === 'undefined') { 
	return true;
    } else if (typeof aUsed == 'object') {
	if(typeof aUsed.length == 'number') { // It's an json array
	    // Zero length array objects always validate
	    if(!aUsed.length) { return true; }
	} else { // It's an object with json arrays as attributes (named after elements)
	    if (typeof aUsed[element.name] == 'undefined' || !aUsed[element.name].length) {
		// Missing element's name from the aUsed object, or empty array
		return true;
	    }
	}
    } 
    
    aThisUsed = (typeof aUsed[0] == 'undefined') ? aUsed[element.name] : aUsed;
    
    if (typeof sCurrent == 'object') {
	sThisCurrent = sCurrent[element.name];
    } else if (typeof sCurrent == 'string') {
	sThisCurrent = sCurrent;
    } else {
	sThisCurrent = '';
    }
    
    // We need to replace &quot; with \" to do our testing, as the 
    // sCurrent uses HTML character entities not javascript escaping.
    if (sThisCurrent) {
	rExpression = /&quot;/gi;
	sThisCurrent = sThisCurrent.replace(rExpression,'\"').toLowerCase();
	if (value == sThisCurrent) return true;
    }
    
    //  Now test to see if the reference has been used.
    checkJSON = (typeof aThisUsed[0].textNode == 'undefined') ?  0 : 1;
    for (var i=0; i<aThisUsed.length; i++) {
	if(checkJSON) {
	    if($.trim(String.prototype.toLowerCase.apply(aThisUsed[i].textNode)) == value) {
		return false;
	    }
	} else {
	    if($.trim(String.prototype.toLowerCase.apply(aThisUsed[i][1])) == value){
		return false;
	    }
	}
    }
    return true;
    
}, 'This value has already been used. Please choose another.');

// Unique value check via ajax
$.validator.addMethod("unique-ajax", function(value, element){
    
    url = element.form.action;
    data = {};
    
    for (var i=0; i < element.form.elements.length; i++) {
	if (element.form.elements[i].name) {
	    value = element.form.elements[i].value || '';
	    data[element.form.elements[i].name] = value;
	}
    }
    
    data['unique_columns'] = element.name;
    data['ajax'] = 1;
    
    $.ajax({
	url: element.form.action,
	type: 'POST',
	dataType: 'json',
	data: data,
	async: false,
	success: function(json) {
	    valid = json[element.name] ? false : true;
	}
    });
    
    return this.optional(element) || valid;
    
}, 'This value has already been used. Please choose another.');


// Passwords
//$.validator.addMethod("password",function(value,element,params){
//    return this.optional(element) || (password_strength() >= params["minstrength"]);
//}, "Please choose a stronger password.");
//
//password_strength = function() {
//    var strength = 0;
//    if ($(".password_strength").length) {
//        strength = $(".password_strength").attr("class").replace(/.*password_strength_(\d+).*/, '$1');
//    }
//    return strength;
//}

$(document).ready(function(){
    // This stuff should probably be somewhere else

    if ($(".password").length) {
	var password_minstrength = 4;
	var password_minlength = 8;
	
	if (typeof $(".password").password_strength == 'function') {
	    $(".password").password_strength({minLength:password_minlength});
	    $(".password_strength").css('display', 'none');
	} else {
	    password_minstrength = 0;
	}
	$(".password").rules("add", {
	    minlength:password_minlength,
	    password:{minstrength:password_minstrength}
	});
	$(".password").keyup(function() {
	    $(this).parents("form").valid();
	    if ($(".password_strength").html() == '') {
		$(".password_strength").css('display', 'none');
	    } else {
		$(".password_strength").css('display', 'inline');
	    }
	});
	
	if ($(".password-confirm").length) {
	    $(".password-confirm").keyup(function() {
		$(this).valid();
	    });
	    $(".password-confirm").rules("add", {
		equalTo: ".password",
		messages: {
		    equalTo: "This does not match the passsword you entered above"
		}
	    });
	}
    }
});

///////////////////////////////////////////////////////////////////////////////
// Formatting

// Format mileage
(function ($) {
    $.fn.formatMileage = function () {
	return this.each(function () {
	    $(this).formatCurrency({ 
		symbol: '',
		roundToDecimalPlace: 0,
		negativeFormat: '-%s%n'
	    });
	});
    };
})(jQuery);

