var DV_MSG_PREFIX = "[Data Validator]";

/*========================
#
#   Supported types for validation
#
*/
var T_NOT_EMPTY         = 1;
var T_TIME              = 2;
var T_EMPTY_TIME        = 3;
var T_DATE_TIME         = 4;
var T_EMPTY_DATE_TIME   = 5;
var T_NUMBER            = 6;
var T_EMPTY_NUMBER      = 7;
var T_INT               = 8;
var T_WORD              = 9;
var T_EMAIL_VALID		= 10;



/*========================
#
#       Constructor
*/
function DataValidator (){
    this.is_valid   = dv__is_valid;
    this.trim       = dv__trim;
    this.warn       = dv__warn;

    // data validation methods
    this.not_empty          = dv__not_empty;
	this.email_valid		= dv__email_valid;
    this.time               = dv__time;
    this.empty_time         = dv__empty_time;
    this.date_time          = dv__date_time;
    this.empty_date_time    = dv__empty_date_time;
    this.number             = dv__number;
    this.empty_number       = dv__empty_number;
    this.int_num            = dv__int;
    this.word               = dv__word;
}


/*========================
#
#   Data validation method
*/
function dv__is_valid( value, data_type ){


    if ( typeof(value) == "undefined" || typeof(data_type) == "undefined" ){
        this.warn("Invalid usage of is_valid function\nUsage: is_valid(value,data_type)");
        return;
    }

    var result = false;

    switch ( data_type ){
        case T_NOT_EMPTY :  result = this.not_empty(value);
                            break;

        case T_EMAIL_VALID : result = this.email_valid(value);
                             break;

        case T_NUMBER : result = this.number(value);
                        break;

        case T_EMPTY_NUMBER : result = this.empty_number(value);
                        break;

        case T_INT : result = this.int_num(value);
                     break;

        case T_TIME :   result = this.time(value);
                        break;

        case T_EMPTY_TIME : result = this.empty_time(value);
                            break;

        case T_DATE_TIME :  result = this.date_time(value);
                            break;

        case T_EMPTY_DATE_TIME : result = this.empty_date_time(value);
                                 break;

        case T_WORD : result = this.word(value);
                                 break;

        default: this.warn("Incorect datatype passed!");;
    }

    return result;
}

function dv__empty_number(value){
    //DO NOT TRIM !!!

    if (value == ''){
        return true;
    }

    if (this.number(value)){
        return true;
    }

return false;
}

function dv__number(value){
    value = this.trim(value);

    if (!isNaN(value) && value != ''){
        return true;
    }

return false;
}

function dv__int(value){
    value = this.trim(value);

    if (!isNaN(value) && value != '' && value.indexOf(".",0) == -1){
        return true;
    }

return false;
}


function dv__email_valid(value){

	var emailPat=/^(.+)@(.+)$/
	var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
	var validChars="\[^\\s" + specialChars + "\]"
	var quotedUser="(\"[^\"]*\")"
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
	var atom=validChars + '+'
	var word="(" + atom + "|" + quotedUser + ")"
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$")
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$")
	var matchArray=value.match(emailPat)
	if (matchArray==null) {
	//	alert("Email address seems incorrect (check @ and .'s)")
		return false
	}
	var user=matchArray[1]
	var domain=matchArray[2]


	if (user.match(userPat)==null) {
		// user is not valid
	//    alert("The username doesn't seem to be valid.")
		return false
	}

	/* if the e-mail address is at an IP address (as opposed to a symbolic
	   host name) make sure the IP address is valid. */
	var IPArray=domain.match(ipDomainPat)
	if (IPArray!=null) {
		// this is an IP address
		  for (var i=1;i<=4;i++) {
			if (IPArray[i]>255) {
	//	        alert("Destination IP address is invalid!")
			return false
			}
		}
		return true
	}

	// Domain is symbolic name
	var domainArray=domain.match(domainPat)
	if (domainArray==null) {
	//	alert("The domain name doesn't seem to be valid.")
		return false
	}

	var atomPat=new RegExp(atom,"g")
	var domArr=domain.match(atomPat)
	var len=domArr.length
	if (domArr[domArr.length-1].length<2 || 
		domArr[domArr.length-1].length>3) {
	   // the address must end in a two letter or three letter word.
	  // alert("The address must end in a three-letter domain, or two letter country.")
	   return false
	}

	// Make sure there's a host name preceding the domain.
	if (len<2) {
	   var errStr="This address is missing a hostname!"
	//   alert(errStr)
	   return false
	}

	// If we've gotten this far, everything's valid!
	return true;
}



function dv__not_empty(value){
    value = this.trim(value);
    if ( value != "" ){
        return true;
    }
return false;
}


function dv__time(value){
    value = this.trim(value);

    timearray = value.split(":");

    if (isNaN(timearray[0]) || (timearray[0] == '') || (timearray[0].indexOf(".",0) != -1)){
        return false;
    }

    if (timearray[0].indexOf(":",0) != -1){
        if ((timearray[1] && isNaN(timearray[1])) || (Number(timearray[1]) > 59) || (timearray[1].indexOf(".",0) != -1)){
            return false;
        }
    }

return true;
}

function dv__empty_time(value){
    value = this.trim(value);

    if (value != ''){

        if (!this.time(value)){
            return false
        }

    }

return true;
}

function dv__date_time(value){
    value = this.trim(value);

    datetimearray = new Array();
    datearray = new Array();
    timearray = new Array();

    datetimearray = value.split(" ");
    if ((datetimearray.length != 2)){
        return false;
    }

    datearray = datetimearray[0].split(".");
    if (datearray.length != 3){
        return false;
    }

    timearray = datetimearray[1].split(":");
    if (timearray.length != 2){
        return false;
    }

    DateObject = new Date(datearray[0], Number(datearray[1])-1, datearray[2], timearray[0], timearray[1]);

    if (Number(DateObject.getYear()+1900) != Number(datearray[0])){
        return false;
    }

    if (Number(DateObject.getMonth()+1) != Number(datearray[1])){
        return false;
    }

    if (Number(DateObject.getDate()) != Number(datearray[2])){
        return false;
    }

    if (Number(DateObject.getHours()) != Number(timearray[0])){
        return false;
    }

    if (Number(DateObject.getMinutes()) != Number(timearray[1])){
        return false;
    }

return true;
}

function dv__empty_date_time(value){
    value = this.trim(value);

    if (value != ''){

        if (!this.date_time(value)){
            return false
        }

    }

    return true;
}

function dv__word(value){
    if (this.trim(value) == ""){
        return false;
    }

    var reg = /\W/;
    if (value.match(reg)){
        return false;
    }
    return true;
}

/*========================
#
#   Error Message method
*/
function dv__warn( msg ){
    alert( DV_MSG_PREFIX + "\n" + msg);
}



function dv__trim(string){

    // return it if it is empty string
    if ( string == "" ){ return string; }

    var trim_reg    = /^\s*((\S*\s*\S+)*)\s*$/;
    trim_reg.exec(string)
    return RegExp.$1;
}