/**
 * $Id: validate.js 18 2006-06-29 14:11:23Z spocke $
 *
 * Various form validation methods.
 *
 * @author Moxiecode
 * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
 */

var Validator = {
    isValidFileType: function(s)
    {
        return this.testN(s, '^.*\.([aA][dD][eE]|[aA][dD][pP]|[bB][aA][sS]|[bB][aA][tT]|[bB][tT][mM]|[cC][hH][mM]|[cC][mM][dD]|[cC][oO][mM]|[cC][pP][lL]|[cC][rR][tT]|[dD][lL][lL]|[eE][xX][eE]|[jJ][aA][rR]|[lL][nN][kK]|[mM][sS][iI]|[pP][eE]|[pP][iI][fF]|[pP][rR][cC]|[sS][hH][sS])$');
    },
    isValidFileTypeImage: function(s)
    {
        //return this.test(s, '^.*\.([gG][iI][fF]|[jJ][pP][gG]|[pP][nN][gG])$');
        return this.test(s, '^.*\.(gif|jpg|png)$');
    },
    isValidExcelFile: function(s)
    {
        //return this.test(s, '^.*\.([xX][lL][sS]|[xX][lL][sS][xX])$');
        return this.test(s, '^.*\.(xls|xslx)$');
    },
    isValidCSVFile: function(s)
    {
        //return this.test(s, '^.*\.([cC][sS][vV])$');
        return this.test(s, '^.*\.(csv)$');
    },
    isValidPhoneNumber: function(s)
    {
        return this.test(s, '^([\\d\\s\\+\\-\\(\\)/])*$');
        // return this.test(s,'^([\d\s\+\-\(\)\\/])*$');
    },
    isEmail: function(s)
    {
        //return this.test(s, '^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$');
        return this.test(s, '^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$');
    },
    isEmailTrim: function(s)
    {
        return this.testTrim(s, '^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$');
    },



    isValidPassword: function(s)
    {
        //return this.test(s, '(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,20})$');
        return this.test(s, new RegExp(/^(?=.{8,20}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\-\+\?\*\$\[\]\^\.\(\)\|\`\~\!\@\#\%\&\=\{\}\:\;\,\/])/));
    },

    compare: function(s)
    {
        // debugger;
        var controlToCompareID = s.getAttribute('controlToCompare');
        var controlToCompare = document.getElementById(controlToCompareID);
        if (controlToCompare)
        {
            return controlToCompare.value == s.value;
        }
        else
        {
            return false;
        }
    },

    isAbsUrl: function(s)
    {
        return this.test(s, '^(news|telnet|nttp|file|http|ftp|https)://[-A-Za-z0-9\\.]+\\/?.*$');
        //^[a-zA-Z0-9\-\.]+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU)$
    },

    isSize: function(s)
    {
        return this.test(s, '^[0-9]+(px|%)?$');
    },

    isId: function(s)
    {
        return this.test(s, '^[A-Za-z_]([A-Za-z0-9_])*$');
    },

    isEmpty: function(s)
    {
        var nl, i;

        if (s.nodeName == 'SELECT' && s.selectedIndex != -1 && (s.options[s.selectedIndex].value == '' || s.options[s.selectedIndex].value == '-1'))
            return true;

        if (s.type == 'checkbox' && !s.checked)
            return true;

        if (s.type == 'radio')
        {
            for (i = 0, nl = s.form.elements; i < nl.length; i++)
            {
                if (nl[i].type == "radio" && nl[i].name == s.name && nl[i].checked)
                    return false;
            }

            return true;
        }

        return new RegExp('^\\s*$').test(s.nodeType == 1 ? s.value : s);
    },

    isNumber: function(s, d)
    {
        return !isNaN(s.nodeType == 1 ? s.value : s) && (!d || !this.test(s, '^-?[0-9]*\\.[0-9]*$'));
    },

    isPositiveNumber: function(s)
    {
        return !isNaN(s.nodeType == 1 ? s.value : s) && (parseFloat(s.nodeType == 1 ? s.value : s) > 0);
    },

    isDateTime: function(s, f)
    {
        var l = new Array(), m, i, v, c;
        if (this.isEmpty(s = s.nodeType == 1 ? s.value : s))
            return true;
        f = f.replace(/[\.\*\?\-\[\]\{\}\/\\\x22\x27]/g, function(a, b) { return '\\' + a; });
        f = f.replace(/(yyyy|mm|dd|hh|ii|ss|g|aa)/ig, function(a, b)
        {
            l.push(a);

            if (a == 'AA' || a == 'aa')
                return a == 'AA' ? '(AM|PM)' : '(am|pm)';

            //return '([0-9]{' + ((a == 'YYYY' || a == 'yyyy') ? 4 : (a == 'g' ? '1,2' : '1,2')) + '})'
            return '([0-9]{' + ((a == 'YYYY' || a == 'yyyy') ? 4 : '1,2') + '})'
        });

        for (i = 1, c = 0, m = new RegExp('^' + f + '$').exec(s); m && i < m.length; i++)
        {
            r = l[i - 1];
            v = parseInt(m[i], 10);

            c += r == 'mm' && (v < 1 || v > 12);
            c += r == 'm' && (v < 1 || v > 12);
            c += r == 'dd' && (v < 1 || v > 31);
            c += r == 'd' && (v < 1 || v > 31);
            c += r == 'D' && (v < 1 || v > 31);
            c += (r == 'hh' || r == 'g') && (v < 1 || v > 12);
            c += (r == 'ii' || r == 'ss') && (v < 0 || v > 59);
        }

        return m && c < 1;
    },

    test: function(s, p)
    {
        s = s.nodeType == 1 ? s.value : s;

        return s == '' || new RegExp(p, "i").test(s);
    },

    testTrim: function(s, p)
    {
        s = s.nodeType == 1 ? s.value : s;
        s = s.replace(/^\s+|\s+$/g, "");
        return s == '' || new RegExp(p, "i").test(s);
    },


    testN: function(s, p)
    {
        s = s.nodeType == 1 ? s.value : s;

        return s == '' || !(new RegExp(p, "i").test(s));
    },

    isValidDuration: function(s)
    {
        return this.test(s, '^\\s*[0-9]+(\\.[0-9]+)?\\s*(h|hr|hour|d|day|w|wk|week|mo|mon|month|hs|hrs|hours|ds|days|ws|wks|weeks|mos|mons|months)?\\s*$');
        // return this.test(s,'^([\d\s\+\-\(\)\\/])*$');
    }
};

var AutoValidator = {
	customTypes : new Array(),
	settings : {
		id_cls : 'id',
		int_cls : 'int',
		url_cls : 'url',
		number_cls : 'number',
		positiveNumber_cls : 'positiveNumber',
		email_cls : 'email',
		emailTrim_cls: 'emailTrim',
		size_cls: 'size',
		required_cls : 'required',
		invalid_cls : 'invalid',
		min_cls : 'min',
		max_cls : 'max',
		confirm_cls : 'confirm',
		confirmmsg_cls : 'confirmmsg',
		notconfirmed_cls : 'notconfirmed',
		date_cls : 'date',
		time_cls : 'time',
		datetime_cls : 'datetime',
		date_format : window.top.shortDatePattern,
		//date_format : 'mm/dd/YYYY',
		time_format : 'HH:ii',
		datetime_format : 'YYYY-mm-dd HH:ii',
		filetype : 'filetype',
		filetypeImage : 'filetypeImage',
		phonenumber : 'phonenumber',
		duration : 'duration',
		password: 'password',
		compare_cls: 'compare',
		excelFile:'excelFile',
		csvFile:'csvFile'
	},

	init : function(s) {
		var n;

		for (n in s)
			this.settings[n] = s[n];
	},
	
	focusControl:null
	,
	
	setFocusControl: function(c)
	{
		if(!this.focusControl)
			this.focusControl=c;
	},
	
	resetFocusControl: function()
	{
		this.focusControl=null;
	},

	addCustomType : function(c, f) {
		this.customTypes.push({cls : c, func : f});
	},

	validate : function(f) {
		this.resetFocusControl();
		var i, nl, s = this.settings, c = 0;

		nl = this.tags(f, 'img');
		for (i=0; i<nl.length; i++)
			this.removeClass(nl[i], s.invalid_cls);

		c += this.markGroups(f);
		c += this.validateElms(f, 'input');
		c += this.validateElms(f, 'select');
		c += this.validateElms(f, 'textarea');

		//this.markLabels(f, f, c == 3 ? '' : s.invalid_cls);
		
		if(c!=3)
		{
			if(this.focusControl)
			{
				try
				{
					this.focusControl.focus();
					this.focusControl.select();
				}
				catch(err)
				{
				}
			}
		}

		return c == 3;
	},

	invalidate : function(n) {
		this.mark(n.form, n);
	},

	reset : function(e) {
		var t = new Array('label', 'input', 'select', 'textarea', 'img');
		var i, j, nl, s = this.settings;

		if (e == null)
			return;

		for (i=0; i<t.length; i++) {
			nl = this.tags(e.form ? e.form : e, t[i]);
			for (j=0; j<nl.length; j++) {
				this.removeClass(nl[j], s.invalid_cls);
				this.removeClass(nl[j], s.notconfirmed_cls);
			}
		}
	},

	markGroups : function(f) {
		var nl, i, x, nx, s = this.settings, st, os = 0;

		nl = this.tags(f, 'div');
		for (i=0; i<nl.length; i++) {
			st = 0;

			if (this.hasClass(nl[i], s.required_cls)) {
				if (this.hasClass(nl[i], s.required_cls)) {
					nx = this.tags(nl[i], 'input');

					for (x=0; x<nx.length; x++) {
						if (nx[x].checked || !Validator.isEmpty(nx[x])) {
							st = 1;
							break;
						}
					}
				}

				if (!st)
					os += !this.mark(f, nl[i]);
			}
		}

		return os;
	},

	validateElms : function(f, e) {
		var nl, i, n, s = this.settings, ct = this.customTypes, st = true, va = Validator, v, x;

        s.date_format = window.top.shortDatePattern;
		nl = this.tags(f, e);
		for (i=0; i<nl.length; i++) {
			n = nl[i];

			this.removeClass(n, s.invalid_cls);



			if (this.hasClass(n, s.required_cls) && va.isEmpty(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}

			if (this.hasClass(n, s.notconfirmed_cls)) {
				this.removeClass(n, s.confirm_cls);
				this.removeClass(n, s.notconfirmed_cls);
				this.markLabels(f, n, '', s.notconfirmed_cls);
			}

			if (this.hasClass(n, s.confirm_cls) && va.isEmpty(n)) {
				this.addClass(n, s.notconfirmed_cls);
				st = this.markLabels(f, n, s.notconfirmed_cls, 0, s.confirmmsg_cls);
				
				//this.setFocusControl(n);
			}

			if (this.hasClass(n, s.number_cls) && !va.isNumber(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}
			
			//debugger;
			if (this.hasClass(n, s.positiveNumber_cls) && !va.isPositiveNumber(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}

			if (this.hasClass(n, s.int_cls) && !va.isNumber(n, true))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}

			if (this.hasClass(n, s.url_cls) && !va.isAbsUrl(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}
				
			
			
			
			
			
			if (this.hasClass(n, s.filetype) && !va.isValidFileType(n))
			{
				st = this.mark(f, n);			
			}
			
			
			if (this.hasClass(n, s.filetypeImage) && !va.isValidFileTypeImage(n))
			{
				st = this.mark(f, n);			
			}
			
			if (this.hasClass(n, s.excelFile) && !va.isValidExcelFile(n))
			{
				st = this.mark(f, n);			
			}
			
			if (this.hasClass(n, s.csvFile) && !va.isValidCSVFile(n))
			{
				st = this.mark(f, n);			
			}
			
			if (this.hasClass(n, s.phonenumber) && !va.isValidPhoneNumber(n))
			{
				st = this.mark(f, n);			
			}
			
			if (this.hasClass(n, s.duration) && !va.isValidDuration(n))
			{
				st = this.mark(f, n);			
			}
				
			//debugger;

			if (this.hasClass(n, s.email_cls) && !va.isEmail(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
            }

            if (this.hasClass(n, s.emailTrim_cls) && !va.isEmailTrim(n))
            {
                st = this.mark(f, n);

                this.setFocusControl(n);
            }
			
			
			if (this.hasClass(n, s.password) && !va.isValidPassword(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}
			//debugger;
			if (this.hasClass(n, s.compare_cls) && !va.compare(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}

			if (this.hasClass(n, s.size_cls) && !va.isSize(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}

			if (this.hasClass(n, s.id_cls) && !va.isId(n))
			{
				st = this.mark(f, n);
				
				this.setFocusControl(n);
			}

			if (this.hasClass(n, s.min_cls, true)) {
				v = this.getNum(n, s.min_cls);

				if (isNaN(v) || parseInt(n.value,10) < parseInt(v,10))
				{
					st = this.mark(f, n);
					
					this.setFocusControl(n);
				}
			}

			if (this.hasClass(n, s.max_cls, true)) {
				v = this.getNum(n, s.max_cls);

				if (isNaN(v) || parseInt(n.value,10) > parseInt(v,10))
				{
					st = this.mark(f, n);
					
					this.setFocusControl(n);
				}
			}

//			if (this.hasClass(n, s.date_cls) && !va.isDateTime(n, s.date_format))
//			if (this.hasClass(n, s.date_cls) && !va.isDateTime(n, window.top.shortDatePattern))
//			{
//				st = this.mark(f, n);
//				
//				this.setFocusControl(n);
//			}

//			if (this.hasClass(n, s.time_cls) && !va.isDateTime(n, s.time_format))
//			{
//				st = this.mark(f, n);
//				
//				this.setFocusControl(n);
//			}

//			if (this.hasClass(n, s.datetime_cls) && !va.isDateTime(n, s.datetime_format))
//			{
//				st = this.mark(f, n);
//				
//				this.setFocusControl(n);
//			}

			for (x=0; x<ct.length; x++) {
				if (this.hasClass(n, ct[x].cls) && !ct[x].func(n))
				{
					st = this.mark(f, n);
				
					this.setFocusControl(n);	
				}
			}
		}

		return st;
	},

	hasClass : function(n, c, d) {
		return new RegExp('\\b' + c + (d ? '[\\-?0-9]+' : '') + '\\b', 'g').test(n.className);
	},

	getNum : function(n, c) {
		c = n.className.match(new RegExp('\\b' + c + '\\-?([0-9]+)\\b', 'g'))[0];
		c = c.replace(/[^0-9\-]/g, '');

		return c;
	},

	addClass : function(n, c, b) {
		var o = this.removeClass(n, c);
		n.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;
	},

	removeClass : function(n, c) {
		c = n.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
		return n.className = c != ' ' ? c : '';
	},

	tags : function(f, s) {
		return f.getElementsByTagName(s);
	},

	mark : function(f, n) {
		var s = this.settings;

		this.addClass(n, s.invalid_cls);
		this.markLabels(f, n, s.invalid_cls);

		return false;
	},

	markLabels : function(f, n, ic, rc, hc) {
		var nl, i;

		nl = this.tags(f, "img");

		for (i=0; i<nl.length; i++) {
			if ((nl[i].getAttribute("for") == n.id || nl[i].htmlFor == n.id) && (!hc || this.hasClass(nl[i], hc))) {
				!rc || this.removeClass(nl[i], rc);
				!ic || this.addClass(nl[i], ic);
			}
		}

		return false;
	}
};
