if (TFI == undefined) {
    var TFI = {};
}

TFI.Validation = {
    fatherSelector: ".validationReceiver",
    fatherClassName: "warning",
    messageAttribute: "msg",
    messageClassSuffix: "Validate",
    onError: null,

    init: function() {

    },
    // Format must be dd/mm/yyyy, Date must be at least 16 years in the past 
    // (date <= today - 16 years)
    isXYearsOld: function(selector, age) {
        var now1 = new Date();
        // Substract one day to the date
        var now = new Date(now1.getFullYear(), now1.getMonth(), now1.getDate() - 1);
        var birthDay = $(selector).val();
        var birthDayArray = birthDay.split('/');
        var born = new Date(birthDayArray[2], birthDayArray[1] - 1, birthDayArray[0]);
        var years = new Date(now.getTime() - born.getTime());
        var base = new Date(0);
        var ageCalculated = years.getFullYear() - base.getFullYear();
        return (ageCalculated >= age);
    },
    /*isXYearsOld: function(selector, age) {
    var now = new Date();
    var birthDay = $(selector).val();
    var birthDayArray = birthDay.split('/');
    // Substract one day to the date
    var born = new Date(birthDayArray[2], birthDayArray[1] * 1 - 1, birthDayArray[0]);
    var years = new Date(now.getTime() - born.getTime());
    var base = new Date(0);
    var ageCalculated = years.getFullYear() - base.getFullYear();
    return (ageCalculated >= age);
    },*/



    IsValidDate: function(selector) {
        var dateStr = $(selector).val();
        var reg2 = /^\d{2}(\/)\d{2}\1\d{4}$/
        // If it doesn't conform to the right format -> fail
        if (reg2.test(dateStr) == false) { return false; }
        var parts = dateStr.split(RegExp.$1); // Split into 3 parts based on what the divider was
        var dd = parts[0];
        var mm = parts[1];
        var yy = parts[2];
        if (parseFloat(yy) <= 50) { yy = (parseFloat(yy) + 2000).toString(); }
        if (parseFloat(yy) <= 99) { yy = (parseFloat(yy) + 1900).toString(); }
        var dt = new Date(parseFloat(yy), parseFloat(mm) - 1, parseFloat(dd), 0, 0, 0, 0);
        // If it doesn't conform a valid date -> fail
        if (parseFloat(dd) != dt.getDate()) { return false; }
        if (parseFloat(mm) - 1 != dt.getMonth()) { return false; }
        return true;
    },

    compareDates: function(selector1, selector2) {
        var strDate1 = $(selector1).val();
        var strDate2 = $(selector2).val();
        var date1Array = strDate1.split('/');
        var date2Array = strDate2.split('/');
        var date1 = new Date(date1Array[2], date1Array[1] - 1, date1Array[0]);
        var date2 = new Date(date2Array[2], date2Array[1] - 1, date2Array[0]);
        if (date1 < date2) {
            return 1;
        } else {
            if (date1 > date2) {
                return -1;
            } else {
                return 0;
            }
        }
    },

    // The input must be a date in the future, in the format dd/MM/yyyy.
    isAFutureDate: function(selector) {
        var now = new Date();
        var dateToCompare = $(selector).val();
        var newDate = dateToCompare.split('/');
        // Convert to dd/mm/yyyy, and substract one day to the date
        var toCompare = new Date(newDate[2], newDate[1] * 1 - 1, newDate[0]);
        return (toCompare > now);
    },

    // At least 1 value must be checked. (CheckBox)
    isAtLeastOneSelected: function(selector) {
        return ($('input[type=checkbox]:checked', selector).length > 0);
    },

    // At most N values are selected (CheckBox)
    areAtMostXSelected: function(selector, max) {
        return ($('input[type=checkbox]:checked', selector).length <= max);
    },

    //Are N selected (CheckBox)
    areNSelected: function(selector, N) {
        return ($('input[type=checkbox]:checked', selector).length == N);
    },

    // The input endDate must be a date equal or greater than the date in the startDate,
    // in the format dd/MM/yyyy.
    isDateGreaterThan: function(selector, compareTo) {
        selectorLength = $(selector).val().length;
        // TODO Finish
        return (selectorLength > 0);
    },

    // The input must be equal or greater than min
    isLengthGreaterThan: function(selector, min) {
        return (($(selector).val() != null) && ($(selector).val().length > min));
    },

    // Must be (min characters >= length of value >= max characters)
    isLengthBetween: function(selector, min, max) {
        selectorLength = $(selector).val().length;
        return (selectorLength >= min) && (selectorLength <= max);
    },

    // Value must be exactly N characters
    isLengthEqualTo: function(selector, selectorLength) {
        return ($(selector).val().length == selectorLength);
    },

    // The input must not be null or empty
    isNotNullOrEmpty: function(selector) {
        element = jQuery.trim($(selector).val());
        return ((element != null) && (element.length > 0));
    },

    //  The input must be checked (radio button)
    isSelected: function(selector) {
        return ($('input[type=radio]:checked', selector).length > 0);
    },

    //  Must select a value (dropDownList)
    isItemSelected: function(selector) {
        return ($(selector)[0].selectedIndex > 0);
    },

    // Returns true if the passed value is found in the
    // array. Returns false if it is not.
    inArray: function(searhArray, value) {
        var i;
        for (i = 0; i < searhArray.length; i++) {
            if (searhArray[i].value == value) {
                return true;
            }
        }
        return false;
    },

    // Show or hide the message error
    showCustomErrorMessage: function(selector, message, father, show) {
        var messageControl = $(selector);
        var fatherControl = $(father);
        if (show) {
			if(selector.indexOf("ucRegistrationCivilStatus_txtPostalCodeValidate")!=-1
				&& message=="Merci de ne saisir que des chiffres" 
				&& $("select.ddlCountryCS").val()!="1") // change the error message for zip code in the candidate registration
														// page, if selected country isn't France
				message += " et des lettres";
            messageControl.text(message);
            if (!fatherControl.hasClass(TFI.Validation.fatherClassName)) {
                fatherControl.addClass(TFI.Validation.fatherClassName);
            }
        }
        else {
            messageControl.text("");
            if (fatherControl.hasClass(TFI.Validation.fatherClassName)) {
                fatherControl.removeClass(TFI.Validation.fatherClassName);
            }
        }
        try {
            if (TFI.Validation.onError != null)
                eval("TFI.Validation.onError(fatherControl, " + show + ")");
        }
        catch (Error) {
            //alert(Error);
        }
    },

    validateGroup: function(groupName) {
        var validators = $("p[validationGroup='" + groupName + "']");
        var result = true;
        var firstErrorControl = null;

        validators.each(function(index, element) {
            var item = 0;
            var lastValidItem = false;
            var resultValidator = false;

            while (lastValidItem == false) {
                functionToValidate = $(this).attr("type" + item);
                if (functionToValidate != null) {
                    controlToValidate = $(this).attr("ControlToValidate");
                    resultValidator = eval("TFI.Validation." + functionToValidate + "('#" + controlToValidate + "')");
                    TFI.Validation.showCustomErrorMessage("#" + $(this).attr("ID"),
                                                          $(this).attr("msg" + item),
                                                          "#" + $(this).attr("ValidationReceiverID"),
                                                          !resultValidator);
                    if (resultValidator) // If result == true, validate next function
                    {
                        item += 1;
                    }
                    else {
                        //Save first error control to focus on it
                        if (firstErrorControl == null) {
                            firstErrorControl = "#" + controlToValidate;
                        }
                        lastValidItem = true; // do not evalute the next function
                    }
                }
                else {
                    lastValidItem = true;
                }
            }
            result = result && resultValidator;
        });

        //Set focus on first error control
        if (firstErrorControl != null) {
            var control = $(firstErrorControl);
            if (control.length > 0 && control[0].tagName == "SPAN") {
                control = control.find(":input");
            }
            if (control.length > 0) {
                try { //If the control is hidden, focus fails
                    control[0].focus();
                } catch (e) { }
            }
        }
        return result;
    },

    removeWarningClass: function(groupName) {
        var validators = $("p[validationGroup='" + groupName + "']");

        validators.each(function(index, element) {
            var item = 0;
            TFI.Validation.showCustomErrorMessage("#" + $(this).attr("ID"),
                                                  $(this).attr("msg" + item),
                                                  "#" + $(this).attr("ValidationReceiverID"),
                                                  false);
        });
    },

    // ***************************************
    // Personal Civil Status Screen Validators
    // ***************************************    
    // The input must not be null or empty
    EmptyValidating: function(selector) {
        return TFI.Validation.isNotNullOrEmpty(selector);
    },

    EmptyTxtTownValidating: function(selector) {
        return TFI.Validation.isNotNullOrEmpty(".txtTownCS");
    },

    MaxLengthValidating: function(selector) {
        return ($(selector).val().length <= $(selector).attr("MaxLength"));
    },

    MaxLengthTxtTownValidating: function(selector) {
        return ($(".txtTownCS").val().length <= $(".txtTownCS").attr("MaxLength"));
    },

    NotAlphabeticValidating: function(selector) {
        //var regularExpression = /[^\-a-zA-ZéáàâäæçèêëíîïóôœúùûüÀÂÄÆÇÉÈÊËÎÏÔŒÙÛÜ\'\ ]+$/;
        //return !regularExpression.test($(selector).val());

        //var validChars = "abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZéáàâäçèêëíîïóôúùûüÀÂÄÇÉÈÊËÎÏÔÙÛÜ";
        var validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-' \u00C0\u00C2\u00C6\u00C8\u00C9\u00CA\u00CB\u00CE\u00CF\u0152\u00D9\u00DB\u00DC\u0178\u00C7\u00E0\u00E2\u00E6\u00E8\u00E9\u00EA\u00EB\u00EE\u00EF\u00F4\u0153\u00F9\u00FB\u00FC\u00FF\u00E7\u00E1\u00E9\u00ED\u00F3\u00FA\u00F1\u00C1\u00C9\u00CD\u00D3\u00DA\u00D1";
        var result = true;
        var textValue = $(selector).val();
        var textLength = textValue.length;
        for (i = 0; i < textLength; i++) {
            if (validChars.indexOf(textValue.charAt(i)) == -1) {
                return false;
            }
        }
        return true;
    },

    AreDigitsValidating: function(selector) {
        var regularExpression = /^[\d]+$/;
        return regularExpression.test($(selector).val());
    },

	AreDigitsOrCharsValidating: function(selector) {
		var regExp;
		if($("select.ddlCountryCS").val()=="1") { // France : digits only
			regExp = /^[\d]+$/;
		} else { // Other country : digits or alpha characters
			regExp = /^[a-zA-Z0-9]+$/;
		}
		return regExp.test($(selector).val());
	},
	
	ZipCodeLengthValidating: function(selector) {
		if($("select.ddlCountryCS").val()=="1") { // France : length == 5
			return ($(selector).val().length == $(selector).attr("MaxLength"));
		} 
		// Other country : between 1 and 5
		return ($(selector).val().length>0 && $(selector).val().length <= $(selector).attr("MaxLength"));
	},

    EmptyListValidating: function(selector) {
        return ($(selector)[0].selectedIndex > 0);
    },

    isLengthEqualToMaxLengthValidating: function(selector) {
        return ($(selector).val().length == $(selector).attr("MaxLength"));
    },

    IsSelectedValidating: function(selector) {
        return ($('input[type=radio]:checked', selector).length > 0);
    },

    IsValidDateValidating: function(selector) {
        //var regularExpression = /^(3[01]|0?[1-9]|[12])(\/|-)(0?[1-9]|1[012])(\/|-)([0-9]){4}$/;
        //return regularExpression.test($(selector).val());
        return TFI.Validation.IsValidDate(selector);
    },

    IsValidEmailAddress: function(selector) {
        var re1 = /^(\s)*([a-zA-Z0-9])+([\.\-_]?[a-zA-Z0-9\-\s\_]+)*@[a-zA-Z0-9]+([\._\-]?[a-zA-Z0-9]+)*\.[a-zA-Z]{2,10}$/;
        var re2 = /^(\s)*([^w]|w[^w]|ww[^w]|www[^\.])/ig;
        return (re1.test($(selector).val()) && re2.test($(selector).val()));
    },

    IsXYearsOldValidating: function(selector) {
        return TFI.Validation.isXYearsOld(selector, 16);
    },

    QW10EmptyDateToValidating: function(selector) {
        return TFI.Validation.isNotNullOrEmpty(".askdoc_datefin");
    },

    QW10DateFormatToValidating: function(selector) {
        return TFI.Validation.IsValidDate(".askdoc_datefin");
    },

    QW10TooOldValidating: function(selector) {
        return !TFI.Validation.isXYearsOld(selector, 2);
    },

    QW10TooOldToValidating: function(selector) {
        return !TFI.Validation.isXYearsOld(".askdoc_datefin", 2);
    },

    QW10DateRangeValidating: function(selector) {
        if (TFI.Validation.compareDates(selector, ".askdoc_datefin") == -1)
            return false;
        else
            return true;
    },

    QW1FileFormatFileUploadValidating: function(selector) {
        var ext = $(selector).val();
        ext = ext.substring(ext.length, ext.length - 4);
        if (ext.toUpperCase() != ".PDF" && ext.toUpperCase() != ".TIF")
            return false;
        else
            return true;
    },

    QW1FileSizeFileUploadValidating: function(selector) {
        if (navigator.appName.indexOf("Netscape") != -1) 
        {
            var resultFileSize = TFI.ClientServices.ClientHelper.GetConfigListValue("UpdateAdministrativeFolderMaxSizeFile");
            if ($(selector)[0].files[0].fileSize > resultFileSize.value) 
            {
                return false;
            } else 
            {
                return true;
            }
        }
        else 
        {
            return true;
        }
    },

    QW1IsLengthGreaterThanValidating: function(selector) {
        if (TFI.Validation.isLengthGreaterThan(selector, 4000)) {
            return false;
        } else {
            return true;
        }
    },

    QW10IsLengthGreaterThanValidating: function(selector) {
        if (TFI.Validation.isLengthGreaterThan(selector, 4000)) {
            return false;
        } else {
            return true;
        }
    },

    // *********************************    
    // Define Password Screen validators
    // *********************************    
    IsEmailRegistered: function(selector) {
        if (TFI.Candidate.pageMode == TFI.Const.EnumPageMode.Edit) {
            return true;
        }
        else {
            var result = TFI.ClientServices.Candidate.ValidateEmailExits($(selector).val());
            return !result.value;
        }
    },

    areEmailsEquals: function(selector) {
        return ($(selector).val() == $(".txtEmailCS").val());
    },

    ValidPasswordLengthValidating: function(selector) {
        var password = $(selector).val().length;
        return (password >= 8 && password <= 20);
    },

    ValidPasswordValidating: function(selector) {
        //R1: Allow symbol characters such as áàâäæçéèêëíîïóôœúùûüÀÂÄÆÇÉÈÊËÎÏÔŒÙÛÜ &é~#{(-|è`_\ç^à@)°=+}¨^$£¤ù%*µ,?.\/:!§;"'[]
        //R2: The password must contain at least one alpha character (a-Z) and at least one numeric character (0-9)
        //The regular expression is ^[a-zA-Z0-9&]*([a-zA-Z]+[&]*[0-9]+|[0-9]+[&]*[a-zA-Z]+)[a-zA-Z0-9&]*$ replacing & by all allowed symbols
        //Use hexadecimal code for these character:
        //  ;   3B   ==> \x3B
        //  "   22	 ==> \x22
        //  '   27	 ==> \x27
        //  [   5B	 ==> \x5B
        //  ]   5D	 ==> \x5D       
        var numaric = $(selector).val();
        var hasNumeric = false;
        var hasAlpha = false;
        for (var j = 0; j < numaric.length; j++) {
            var alphaa = numaric.charAt(j);
            var hh = alphaa.charCodeAt(0);
            //invalid characters: '"&<> 
            /*if (hh == 39 || hh == 38 || hh == 34 || hh == 60 || hh == 62) {
                return false;
            }
            else */
            if (hh > 47 && hh < 58) {
                hasNumeric = true;
            }
            else if ((hh > 64 && hh < 91) || (hh > 96 && hh < 123)) {
                hasAlpha = true;
            }

        }
        return hasNumeric && hasAlpha;
    },

   
    IsSamePassword: function(selector) {
        return ($(selector).val() == $(".txtPasswordDP").val());
    },

    IsSameEmail: function(selector) {
        return ($(selector).val() == $(".txtEmailDP").val());
    },

    // *****************************
    // Target Jobs Screen Validators
    // *****************************
    // Validate if has a valid profession
    IsValideEmployValidating: function(selector) {
        var result = $(selector)[0].disabled;
        return result;
    },

    // Validate that the profession exists on the server (LEA), if the selector is enabled
    IsValideDataBaseEmployValidating: function(selector) {
        var result = true;
        if (!$(selector)[0].disabled) {
            if ($(selector).val().length > 0) {
                var profId = TFI.ClientServices.Candidate.ValidateProfession($(selector).val()).value;
                if ((profId != null) && (profId > 0)) {
                    $(selector).attr("profId", profId);
                } else {
                    result = false;
                }
            } else {
                result = false;
            }
        }
        return result;
    },

    // Validate if at least one value is selected
    IsAreaSelectedValidating: function(selector) {
        return TFI.Validation.isSelected(".rbRegionTJ") ||
               TFI.Validation.isSelected(".rbDepartmentsTJ") ||
               TFI.Validation.isSelected(".rbAllFranceTJ");
    },

    // Validate if at least one region is selected, if the radio button is checked
    IsValidRegionValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".rbRegionTJ")) {
            result = $(selector)[0].value > 0;
        }
        return result;
    },

    // Validate if at least one Department is filled
    AreValidsDepartmentsValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".rbDepartmentsTJ")) {
            result = ($(".rptDepartmentsTJ .pnlRow").length > 0);
        }
        return result;
    },

    // Validate if at least one Country is filled
    AreValidsCountriesValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".rbCountryTJ")) {
            result = ($(".rptCountriesTJ .pnlRow").length > 0);
        }
        return result;
    },

    // Are departments repeated
    IsRepeatedDepartmentsValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".rbDepartmentsTJ")) {
            var i, j, value;
            var controls = $(".txtDepartmentsTJ");
            for (i = 0; i < controls.length - 1; i++) {
                value = controls[i].value;
                if (value.length > 0) {
                    for (j = i + 1; j < controls.length; j++) {
                        if (controls[j].value == value) {
                            return false;
                        }
                    }
                }
            }
        }
        return result;
    },

    // Validate departments on the server (LEA)
    AreLeaValidsDepartmentsValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".rbDepartmentsTJ")) {
            var controls = $(".txtDepartmentsTJ");
            var i, value;
            var departments = [];
            for (i = 0; i < controls.length; i++) {
                value = controls.eq(i).val();
                if (value.length > 0) {
                    departments.push(value);
                }
            }
            var exist = TFI.ClientServices.Candidate.ValidateDepartmentsExits(departments.join(","));
            result = exist.value;
        }
        return result;
    },

    // Validate if the profession exists on the server (LEA)
    isAtLeastOneSelectedValidating: function(selector) {
        var result = TFI.Validation.isAtLeastOneSelected(".chkListContractsDCT");
        return result;
    },

    // Validate if at least one textBox is filled
    IsAtLeastOneDepartmentValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".rbDepartmentsTJ")) {
            var controlName = "#txtDepartments";
            var controls = $(".txtDepartmentsTJ");
            var i, value;
            for (i = 0; i < controls.length; i++) {
                value = controls.eq(i).val();
                if (value.length > 0) {
                    return true;
                }
            }
            result = false;
        }
        return result;
    },

    // *****************************
    // AddTraining Screen Validators
    // *****************************    
    FormationRadioValidating: function(selector) {
        return TFI.Validation.isSelected(".radTrainingTypeAT") ||
               TFI.Validation.isSelected(".radTrainingType2AT");
    },

    LevelSelectedValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".radTrainingTypeAT")) {
            result = TFI.Validation.isItemSelected(selector);
        }
        return result;
    },

    DomainSelectedValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".radTrainingTypeAT")) {
            result = TFI.Validation.isItemSelected(selector);
        }
        return result;
    },

    LicenseValidating: function(selector) {
        var result = true;
        if (TFI.Validation.isSelected(".radTrainingType2AT")) {
            result = TFI.Validation.isItemSelected(selector);
        }
        return result;
    },

    // *****************************
    // AddLanguage Screen Validators
    // *****************************     
    LanguageSelectedValidating: function(selector) {
        return TFI.Validation.isItemSelected(selector);
    },

    ExistLanguageValidating: function(selector) {
        //TODO How to do this validation?
        return true;
    },

    SetControlError: function(fatherControlError, fatherControl, showError) {
        if (showError) {
            fatherControlError.css("display", "");
            fatherControl.addClass("trBackGround");
        } else {
            fatherControlError.css("display", "none");
            fatherControl.removeClass("trBackGround");
        }
    }

}
