﻿/*
* TODO: Add Checkers Object
*/

var DefaultException = {
    required : { message : "This is require field" },
    maxlength : { message : "This is max length" },
    minlength : { message : "min length" },
    alphanumeric : { message : "" },
    numeric : { message : "" },
    alpha : { message : "" },
    email : { message : "" },
    lessthan : { message : "" },
    greaterthan : { message : "" },
    regexp : { message : "" },
    dontselect : { message : "" }
}

ValidationType = {
    required : 'required',
    maxlength : 'maxlength',
    minlength : 'minlength',
    alphanumeric : 'alphanumeric',
    numeric : 'numeric',
    alpha : 'alpha',
    email : 'email',
    lessthan : 'lessthan',
    greaterthan : 'greaterthan',
    regexp : 'regexp',
    dontselect : 'dontselect',
    custom : "custom"
}

Validation = function()
{
    var validators = [];
    var exception = "";
    var exceptions = [];
    this.errorsummary;
    
    var _callBack = function(exceptions, v)
    {
        v.renderError('errorsummary', v);                
    };

    this.onError = function(callBack)
    {
        _callBack = callBack;
    }
    this.add = function(field, type, value, msg, objName)
    {
        validators.push(new Validator(field, { type : type, value : value}, msg, objName));
    }
    this.checkValid = function()
    {
        exceptions = [];
        for (i = 0; i < validators.length; i ++)
        {
            exception = validators[i].test();
            if (exception)
            {
                exceptions.push(exception);
            }
        }
        if (exceptions.length > 0)
        {
            if (_callBack) _callBack(exceptions, this);
            return false;
        }
        else
        {
            this.removeRender('errorsummary');
            return true;
        }
    }
    this.removeRender = function(ele)
    {
        var dom = getDOM(ele);
        if (dom) dom.innerHTML = "";
    }
    this.getLastException = function()
    {
        return exception;
    }
    this.getExceptions = function()
    {
        return exceptions;
    }
    this.renderError= function(element, scope)
    {
        var errorsummary = getDOM(element);

        errorsummary.innerHTML = "";

        if (exceptions.length > 0)
        {
            if(exceptions[0].item)
                if(!exceptions[0].item.disabled)
                    if(exceptions[0].item.visibility)
                        exceptions[0].item.focus();
            
            var result = "";
            result = "<ul>";

            for (i = 0; i < exceptions.length; i++)
            {
                result += "<li>" + exceptions[i].message + "</li>";
            }

            result += "</ul>";            
            errorsummary.innerHTML = result;          
        }
    }
}

Validator = function(field, options, msg, objName)
{
    this.objName = objName;

    this.init(field, options);

    if (msg)
    {
        this.message = msg;
    }
}

Validator.prototype.init = function(field, options)
{
    this.field = getDOM(field)

    if (options.type)
    {
        this.command = options.type;

        if (options.type == ValidationType.custom)
        {
            this.fnc = options.value;
        } else
        {
            this.cmdvalue = options.value;
        }
    }
    else throw 'options must have a type';
}

Validator.prototype.getMessage = function()
{
    var message = "";
    if (this.message)
    {
        if (this.objName)
        {
            message = this.message.replace("{name}", this.objName);
        }
        else
        {
            message = this.message;
        }

        return { item : this.field, message : message };
    }
    else
    {
        var result = DefaultException[this.command];
        result.item = this.field;
        return result;
    }
}

Validator.prototype.methods = {
    required : function(validator)
    {
        if (eval(Trim(validator.field.value).length) == 0)
        {
            return validator.getMessage();
        }
        return null;
    },
    maxlength : function(validator)
    {
        if (eval(validator.field.value.length) > eval(validator.cmdvalue))
        {
            return validator.getMessage();
        }
        return null;
    },
    minlength : function(validator)
    {
        if (eval(validator.field.value.length) < eval(validator.cmdvalue))
        {
            return validator.getMessage();
        }
        return null;
    },
    alphanumeric : function(validator)
    {
        var charpos = validator.field.value.search("[^A-Za-z0-9_]");
        if (validator.field.value.length > 0 && charpos >= 0)
        {
            return validator.getMessage();
        }
        return null;
    },
    numeric : function(validator)
    {
        var charpos = validator.field.value.search("[^0-9]");
        if (validator.field.value.length > 0 && charpos >= 0)
        {
            return validator.getMessage();
        }
        return null;
    },
    alpha : function(validator)
    {
        var charpos = validator.field.value.search("[^A-Za-z]");
        if (validator.field.value.length > 0 && charpos >= 0)
        {
            return validator.getMessage();
        }
        return null;
    },
    email : function(validator)
    {
        if (!validateEmail(validator.field.value))
        {
            return validator.getMessage();
        }
        return null;
    },
    datetime : function(validator)
    {
        if (!validateDate(validator.field.value))
        {
            return validator.getMessage();
        }
        return null;
    },
    lessthan : function(validator)
    {
        if (isNaN(validator.field.value))
        {
            return DefaultException.numeric;
        }
        if (eval(validator.field.value) >= eval(validator.cmdvalue))
        {
            return validator.getMessage();
        }
        return null;
    },
    greaterthan : function(validator)
    {
        if (isNaN(validator.field.value))
        {
            return DefaultException.numeric;
        }
        if (eval(validator.field.value) <= eval(validator.cmdvalue))
        {
            return validator.getMessage();
        }
        return null;
    },
    regexp : function(validator)
    {
        if (!validator.field.value.match(validator.cmdvalue))
        {
            return validator.getMessage();
        }
        return null;
    },
    dontselect : function(validator)
    {
        if (validator.field.selectedIndex == null)
        {
            return validator.getMessage();
        }
        if (validator.field.selectedIndex == eval(validator.cmdvalue))
        {
            return validator.getMessage();
        }
        return null;
    },
    custom : function(validator)
    {
        if (!validator.fnc(validator.field))
        {
            return validator.getMessage();
        }
        return null;
    }
}

Validator.prototype.test = function()
{
    return this.methods[this.command](this);
}

function getDOM(mix)
{
    if (typeof mix == "object")
    {
        return mix;
    }
    else if (typeof mix == "string")
    {
        return document.getElementById(mix);
    }
}

function validateEmail(email)
{
    var splitted = email.match("^(.+)@(.+)$");
    if (splitted == null) return false;
    if (splitted[1] != null)
    {
        var regexp_user = /^\"?[\w-_\.]*\"?$/;
        if (splitted[1].match(regexp_user) == null) return false;
    }
    if (splitted[2] != null)
    {
        var regexp_domain = /^[\w-\.]*\.[A-Za-z]{2,4}$/;
        if (splitted[2].match(regexp_domain) == null)
        {
            var regexp_ip = /^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
            if (splitted[2].match(regexp_ip) == null) return false;
        }// if
        return true;
    }
    return false;
}
/*
Validate Date in dd/MM/yyyy format
dd/MM/yyyy hh:mm:ss
dd/MM/yyyy hh:mm AM/PM
*/
function validateDate(date)
{
    //var regexp = /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((1[6-9]|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((1[6-9]|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((1[6-9]|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/;
    var regexp = /^(?=\d)(?:(?!(?:(?:0?[5-9]|1[0-4])(?:\.|-|\/)10(?:\.|-|\/)(?:1582))|(?:(?:0?[3-9]|1[0-3])(?:\.|-|\/)0?9(?:\.|-|\/)(?:1752)))(31(?!(?:\.|-|\/)(?:0?[2469]|11))|30(?!(?:\.|-|\/)0?2)|(?:29(?:(?!(?:\.|-|\/)0?2(?:\.|-|\/))|(?=\D0?2\D(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:(?:\d\d)(?:[02468][048]|[13579][26])(?!\x20BC))|(?:00(?:42|3[0369]|2[147]|1[258]|09)\x20BC))))))|2[0-8]|1\d|0?[1-9])([-.\/])(1[012]|(?:0?[1-9]))\2((?=(?:00(?:4[0-5]|[0-3]?\d)\x20BC)|(?:\d{4}(?:$|(?=\x20\d)\x20)))\d{4}(?:\x20BC)?)(?:$|(?=\x20\d)\x20))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2}(?:\x20[aApP][mM]))|(?:[01]\d|2[0-3])(?::[0-5]\d){1,2})?$/;
    var isValid = regexp.test(date);
    return isValid;
}
function Trim(stringText)
{
    return stringText.replace(/^\s+|\s+$/, '');
}