﻿/* ==============================================================================
	ValidationUtils.js 
	
	- Functions to validate forms
============================================================================== */


/* ======================================================================
FUNCTION:	RemoveSpace(strInput)
INPUT:		strInput - Input String to remove spaces
RETURNS:		The input string without spaces
====================================================================== */
function RemoveSpace(strInput) 
{  
	var tmp = "";

	for (var i=0; i < strInput.length; i++)
		if (strInput.charAt(i) != ' ')
			tmp += strInput.charAt(i);

  return tmp;
}

/* ======================================================================
FUNCTION:	isValidInput(objInput)
INPUT:		objInput - Input object to validate
RETURNS:		true, if the object has a valid non empty value
				false, otherwise.
====================================================================== */
function isValidInput(objInput)
{
	if (objInput.value == '' || 
		objInput.value == 'undefined' || 
		objInput.value == null)
		return false;
		
	return true;
}

/* ======================================================================
FUNCTION:	hasOnlyNumbers(objInput)
INPUT:		objInput - Input object to validate
RETURNS:		true, if the object has a non empty value with only numbers
				false, otherwise.
====================================================================== */
function hasOnlyNumbers(objInput)
{
	if (!isValidInput(objInput))
		return false;
	
	var input = String(objInput.value);
	
	for (var i=0; i<input.length; i++)
	{
		var charCode = input.charCodeAt(i);
		
		if (charCode < 48 || charCode > 57)
			return false;
	}
	
	return true;
}

/* ======================================================================
FUNCTION:	hasOnlyNumbersString(strInput)
INPUT:		strInput - Input string to validate
RETURNS:		true, if the string has a value with only numbers
				false, otherwise.
====================================================================== */
function hasOnlyNumbersString(strInput)
{
	if (strInput == '' || strInput == 'undefined' || strInput == null)
		return false;
	
	for (var i=0; i<strInput.length; i++)
	{
		var charCode = strInput.charCodeAt(i);
		
		if (charCode < 48 || charCode > 57)
			return false;
	}
	
	return true;
}

/* ======================================================================
FUNCTION:	hasNumbers(objInput)
INPUT:		objInput - Input object to validate
RETURNS:		true, if the object has a non empty value with 1 or more numbers
				false, otherwise.
====================================================================== */
function hasNumbers(objInput)
{
	if (!isValidInput(objInput))
		return false;
	
	var input = String(objInput.value);
	
	for (var i=0; i<input.length; i++)
	{
		var charCode = input.charCodeAt(i);
		
		if (charCode >= 48 && charCode <= 57)
			return true;
	}
	
	return false;
}

/* ======================================================================
FUNCTION:	isValidEmail(strEmail)
INPUT:		strEmail - String representing the e-mail to validade
RETURNS:		true, if the e-mail is valid according to the regular expression
				false, otherwise.
====================================================================== */
function isValidEmail(strEmail)
{
	var reg = /^(\w+(?:(\.|\-)\w+)*)@((?:\w+(?:(\.|\-)\w+)*\.)+)([a-z\d]{2,})$/i;
	return reg.test(strEmail);
}

/* ======================================================================
FUNCTION:	isValidUrl(strUrl)
INPUT:		strUrl - String representing the url to validade
RETURNS:		true, if the url is valid according to the regular expression
				false, otherwise.
====================================================================== */
function isValidUrl(strUrl)
{
	var urlPattern = /^(?:(?:ftp|https?):\/\/)?(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+(?:com|edu|biz|org|gov|int|info|mil|net|name|museum|coop|aero|[a-z][a-z])\b(?:\d+)?(?:\/[^;"'<>()\[\]{}\s\x7f-\xff]*(?:[.,?]+[^;"'<>()\[\]{}\s\x7f-\xff]+)*)?/;
	return urlPattern.test(strUrl.toLowerCase());
}

/* ======================================================================
FUNCTION:	isValidDate_ddmmaaaa(strDate, strDelimiter)
INPUT:		strDate - String representing the date to validade
				strDelimiter - String representing the delimiter of the date elements
RETURNS:		true, if the date is valid according to the following format
				dd[delimiter]mm[delimiter]aaaa
				Examples: 
					23-12-2005 (valid date where [delimiter] = -)
					1112-1999 (invalid date)
					07.03.1985 (valid date where [delimiter] = .)
					13.13.2001 (invalid date)
				false, otherwise.
====================================================================== */
function isValidDate_ddmmaaaa(strDate, strDelimiter)
{
	var str = new String(strDate);

	try
	{ 	
		if (str.length != 10)
			return false;
		
		var str_arr = str.split(strDelimiter);
		
		if ((str_arr[0].length != 2) || (str_arr[1].length != 2) || (str_arr[2].length != 4))
			return false;
			
		if (!hasOnlyNumbersString(str_arr[0]) || !hasOnlyNumbersString(str_arr[1]) || !hasOnlyNumbersString(str_arr[2]) )
			return false;

		if (!CheckDateAux(parseInt(str_arr[0], 10), parseInt(str_arr[1], 10), parseInt(str_arr[2], 10)))
			return false;
	}
	catch (exception)
	{
		return false;
	}
		
	return true;			
}

/* ======================================================================
FUNCTION:	CheckDateAux(day, month, year)
INPUT:		day - Value of day to validate date
				month - Value of month to validate date
				year - Value of year to validate date
RETURNS:		true, if the date composed by the day, month and year is a valid date
				false, otherwise.
====================================================================== */
function CheckDateAux(day, month, year) 
{
	if (year < 1000)
		return false;
	
	if (month < 1 || month > 12)
		return false;
	
	if (day < 1 || day > 31)
		return false;
	
	return (day <= GetDaysInMonth(month, year));
}

/* ======================================================================
FUNCTION:	TestIfRegularYear(year)
INPUT:		year - Value of year to calculate Regular year
RETURNS:		true, if the year is regular
				false, otherwise.
====================================================================== */
function TestIfRegularYear(year)
{	
	return !(((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0);
}

/* ======================================================================
FUNCTION:	GetDaysInMonth(month, year)
INPUT:		month - Month to calculate number of days
				year - Year to calculate number of days in February 
RETURNS:		The number of days in the month, year 
====================================================================== */
function GetDaysInMonth(month, year)
{
	var minDaysInMonth = 30;
	var maxDaysInMonth = 31;
										
	if (month < 8)
	{
		if (month == 2) 
			return (TestIfRegularYear(year) ? 28 : 29);
		else
			return (minDaysInMonth + (month % 2));
	}
	else
	{
		return (maxDaysInMonth - (month % 2));
	}
}

/* ======================================================================
FUNCTION:	isCreditCardValid(strCC_Number, strCC_Type)
INPUT:		strCC_Number - A string representing a credit card number
				strCC_Type - A string representing a credit card type
								(Visa, American Express, Master Card, ...)
RETURNS:		true, if the credit card is valid (number, and type)
				false, otherwise.
====================================================================== */
function isCreditCardValid(strCC_Number, strCC_Type) 
{
	var CCTypeValidation;
	var strCC_Number_len = strCC_Number.length;
	var strCC_Type_Upper = String(RemoveSpace(strCC_Type.toUpperCase()));

	// O Número precisa de ter pelo menos 4 digitos para se efectuar as validações
	if (strCC_Number_len < 4)
		return false;
		
	var firstDigit = parseInt(strCC_Number.substr(0, 1), 10);
	var secondDigit = parseInt(strCC_Number.substr(1, 1), 10);
	var first4Digits = strCC_Number.substr(0, 4);
	
	switch (strCC_Type_Upper)
	{
		case "VISA":
			// Sample number: 4111 1111 1111 1111 (16 digits)
			if (((strCC_Number_len == 16) || (strCC_Number_len == 13)) 
				&& (firstDigit == 4))
				CCTypeValidation = true;
			else
				CCTypeValidation = false;
			break;
		case "MASTERCARD":
		case "EUROCARD":
			// Sample number: 5500 0000 0000 0004 (16 digits)
			if ((strCC_Number_len == 16) && (firstDigit == 5) 
				&& ((secondDigit >= 1) && (secondDigit <= 5)))
				CCTypeValidation = true;
			else
				CCTypeValidation = false;
			break;
		case "AMERICANEXPRESS":
			// Sample number: 340000000000009 (15 digits)
			if ((strCC_Number_len == 15) && (firstDigit == 3)
				&& ((secondDigit == 4) || (secondDigit == 7)))
				CCTypeValidation = true;
			else
				CCTypeValidation = false;
			break;
		case "DINERSCLUB":
		case "CARTEBLANCHE":
		case "EBLANCHE":
			// Sample number: 30000000000004 (14 digits)
			if ((strCC_Number_len == 14) && (firstDigit == 3)
				&& ((secondDigit == 0) || (secondDigit == 6) || (secondDigit == 8)))
				CCTypeValidation = true;
			else
				CCTypeValidation = false;
			break;
		case "DISCOVER":
			// Sample number: 6011000000000004 (16 digits) 
			if ((strCC_Number_len == 16) && (first4Digits == "6011"))
				CCTypeValidation = true;
			else
				CCTypeValidation = false;
			break;
		case "ENROUTE":
			// Sample number: 201400000000009 (15 digits)
			if ((strCC_Number_len == 15) && 
				((first4Digits == "2014") || (first4Digits == "2149")))
				CCTypeValidation = true;
			else
				CCTypeValidation = false;
			break;
		case "JCB":
			// Sample number:
			if ((strCC_Number_len == 16)
				&& ((first4Digits == "3088")
				|| (first4Digits == "3096")
				|| (first4Digits == "3112")
				|| (first4Digits == "3158")
				|| (first4Digits == "3337")
				|| (first4Digits == "3528")))
				CCTypeValidation = true;
			else
				CCTypeValidation = false;
			break;
		default:
			CCTypeValidation = true;
			break;
	}

	if (CCTypeValidation)
		return isCreditCardNumberValid(strCC_Number);
	else
		return false;
}

/* ======================================================================
FUNCTION:	isCreditCardNumberValid(strCC_Number)
INPUT:		strCC_Number - A string representing a credit card number
RETURNS:		true, if the credit card number passes the Luhn Mod-10 test. 
				false, otherwise.
====================================================================== */
function isCreditCardNumberValid(strCC_Number) 
{
	var auxDigit, i, tproduct, sum, mul, strCC_Number_len;
	
	sum = 0;
	mul = 1;
	strCC_Number_len = strCC_Number.length;

	// Encoding only works on cards with less than 19 digits
	if (strCC_Number_len > 19)
		return false;

	for (i = 0; i < strCC_Number_len; i++) 
	{
		auxDigit = strCC_Number.substr(strCC_Number_len - i - 1, 1);
		tproduct = parseInt(auxDigit, 10) * mul;
		
		if (tproduct >= 10)
			sum += (tproduct % 10) + 1;
		else
			sum += tproduct;

		if (mul == 1)
			mul++;
		else
			mul--;
	}

	if (sum % 10 == 0)
		return true;
	else
		return false;
}

