/**
 * jQuery.ScrollTo - Easy element scrolling using jQuery.
 * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Date: 2/19/2008
 * @author Ariel Flesler
 * @version 1.3.3
 */
;(function($){var o=$.scrollTo=function(a,b,c){o.window().scrollTo(a,b,c)};o.defaults={axis:'y',duration:1};o.window=function(){return $($.browser.safari?'body':'html')};$.fn.scrollTo=function(l,m,n){if(typeof m=='object'){n=m;m=0}n=$.extend({},o.defaults,n);m=m||n.speed||n.duration;n.queue=n.queue&&n.axis.length>1;if(n.queue)m/=2;n.offset=j(n.offset);n.over=j(n.over);return this.each(function(){var a=this,b=$(a),t=l,c,d={},w=b.is('html,body');switch(typeof t){case'number':case'string':if(/^([+-]=)?\d+(px)?$/.test(t)){t=j(t);break}t=$(t,this);case'object':if(t.is||t.style)c=(t=$(t)).offset()}$.each(n.axis.split(''),function(i,f){var P=f=='x'?'Left':'Top',p=P.toLowerCase(),k='scroll'+P,e=a[k],D=f=='x'?'Width':'Height';if(c){d[k]=c[p]+(w?0:e-b.offset()[p]);if(n.margin){d[k]-=parseInt(t.css('margin'+P))||0;d[k]-=parseInt(t.css('border'+P+'Width'))||0}d[k]+=n.offset[p]||0;if(n.over[p])d[k]+=t[D.toLowerCase()]()*n.over[p]}else d[k]=t[p];if(/^\d+$/.test(d[k]))d[k]=d[k]<=0?0:Math.min(d[k],h(D));if(!i&&n.queue){if(e!=d[k])g(n.onAfterFirst);delete d[k]}});g(n.onAfter);function g(a){b.animate(d,m,n.easing,a&&function(){a.call(this,l)})};function h(D){var b=w?$.browser.opera?document.body:document.documentElement:a;return b['scroll'+D]-b['client'+D]}})};function j(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);
function $_get(controlId)
{
	return document.getElementById(controlId);
}

function $F(controlId)
{
	return $_get(controlId).value;
}

function Validator()
{
	this.controlToFocus = null;
	this.errors = new Array();
}

Validator.prototype._isLeapYear = function(year)
{
	if (year % 4 != 0) 
    { 
        return false; 
    }
    else 
    { 
        if (year % 100 != 0) 
        { 
            return true; 
        } 
        else 
        { 
            if (year % 400 != 0) 
            { 
                return false; 
            } 
            else 
            { 
                return true;   
            } 
        } 
    } 
}

Validator.prototype._updateError = function(ctlId, message)
{
	if(this.controlToFocus == null)
	{
		this.controlToFocus = ctlId;
	}
	this.errors[this.errors.length] = message;
}

Validator.prototype.checkData = function(ctlId, message)
{
	if($F(ctlId) == '')
	{
		this._updateError(ctlId, message);
		
		return false;
	}
	
	return true;
}

Validator.prototype.checkEmail = function(ctlId, message)
{
	var email = $F(ctlId);
	
	if(email == '')
	{
		return true;
	}
	
	//var emailRegxp = /^([\w]+)(.[\w]+)*@([\w]+)(.[\w]{2,3}){1,2}$/;
	var emailRegxp = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i); 
	if(emailRegxp.test(email) != true)
	{
		this._updateError(ctlId, message);
		
		return false;
	}
	
	return true;
}

Validator.prototype.checkDate = function(ctlId, message)
{
	var dateValue = $F(ctlId);
	
	if(dateValue == '') return true;
	
	var parts = dateValue.split('/');
	
	if(parts.length != 3)
	{
		this._updateError(ctlId, message);
		return false;
	}
	
	var day = parseInt(parts[0] ,10);
	var month = parseInt(parts[1] ,10);
	var year = parseInt(parts[2] ,10);
	
	if(isNaN(day) || isNaN(month) || isNaN(year))
	{
		this._updateError(ctlId, message);
		return false;
	}
	
	if(year > 1990 && year < 3000)
	{
		if(month >= 1 && month <= 12)
		{
			var isLeapYear = this._isLeapYear(year);
			
			var daysInMonth = 31;
			
			if(month == 2 )
			{
				if(isLeapYear)
				{
					daysInMonth = 29;
				}
				else
				{
					daysInMonth = 28;
				}
			}
			else if(month == 4 || month == 6 || month == 9 ||  month == 11)
			{
				daysInMonth = 30;
			}
			else
			{
				daysInMonth = 31;
			}
			
			if(day >= 1 && day <= daysInMonth)
			{
				return true;
			}
		}
	}
	
	this._updateError(ctlId, message);
	return false;
}

Validator.prototype.checkNumeric = function(ctlId, message)
{
	if($F(ctlId) != '')
	{
		if( isNaN($F(ctlId)) )
		{
			this._updateError(ctlId, message);
		
			return false;
		}
	}
	
	return true;
}

Validator.prototype.addError = function(ctlId, message)
{
	this._updateError(ctlId, message);
}

Validator.prototype.isValid = function()
{
	return (this.errors.length == 0);
}

Validator.prototype.putFocus = function()
{
	var ctl = $_get(this.controlToFocus);
	
	if(ctl && ctl.focus)
	{
		ctl.focus();
		
		if(ctl.select)
		{
			ctl.select();
		}
	}
}

Validator.prototype.showMessageBox = function()
{
	var totalErrors = this.errors.length;
	
	if(totalErrors > 0)
	{
		var txt = '';//'<div class="' + errorCss + '">';
		
		txt += "Please check the following error(s):\n";
		
		for(var i = 0; i < totalErrors; i++)
		{
			txt += '* ' + this.errors[i] + '\n';
		}
		
		alert(txt);
		
		return true;
	}
	
	return false;
}


Validator.prototype.report = function(container, errorCss)
{
	var totalErrors = this.errors.length;
	
	if(totalErrors > 0)
	{
		var html = '';//'<div class="' + errorCss + '">';
		
		html += '<b>Please check the following error(s):</b><ul>';
		
		for(var i = 0; i < totalErrors; i++)
		{
			html += '<li>' + this.errors[i] + '</li>';
		}
		
		html += '</ul>';
		
		//html += '</div>';
		
		//$(container).style.display = '';
		/*$(container).className = errorCss;
		$(container).innerHTML = html;*/
		$("#"+container).attr('class', errorCss).html(html).fadeIn();
		return true;
	}
	
	return false;
}



/**
 * Class: FrameRequest
 *
 * author: Mohammad Ruhul Amin <ruhulshakib@yahoo.com>
 * date: 29 Jul 2006
 * version: 1.0.0
 */
var FrameRequest = 
{
	/**
	 * post request in frame
	 *
	 * @param string frameName
	 * @param string fromName
	 * @param string url
	 */
	doPost: function(frameName, formName, url)
	{
		var frm = document.forms[formName];
		
		frm.action = url;
		
		frm.target = frameName;
		
		frm.submit();
	},
	
	
	/**
	 * get request in frame
	 *
	 * @param string frameName
	 * @param string url
	 */
	doGet: function(frameName, url)
	{
		$_get(frameName).src = url;
	}
}


/**
 * common functions
 */
function message(container, msg, css)
{
	scroll(0,0);
	$('#' + container).html(msg).attr('class', css).slideDown('fast');
	/*
	$_get(container).innerHTML = msg;
	$_get(container).className = css;
	$_get(container).show();*/
}

function toJsonObj(data)
{
	var obj = null;
	
	eval('obj = ' + data + ';');
	
	return obj;
}

function busy(message, css)
{
	var id = '__ajx_status';
	
	var ctl = $_get(id);
	
	if(!ctl)
	{
		ctl = document.createElement('div');
		document.body.appendChild(ctl);
	}
	
	ctl.id = id;
	ctl.innerHTML = message;
	ctl.className = css;
	ctl.style.zIndex = 400;
	ctl.style.position = 'absolute';
	
	var pos = 0;
	
	if (window.innerHeight)
	{
		  pos = window.pageYOffset
	}
	else if (document.documentElement && document.documentElement.scrollTop)
	{
		pos = document.documentElement.scrollTop
	}
	else if (document.body)
	{
		  pos = document.body.scrollTop
	}
	
	ctl.style.top = pos + 'px';
	ctl.style.right = '0px';
	
	ctl.style.display = '';
}

function free()
{
	var id = '__ajx_status';
	if($_get(id))
	{
		$_get(id).style.display = 'none';
	}
}

function toggleDisplay(control, controlToFocus)
{
	if($_get(control).style.display == '')
	{
		$_get(control).style.display = 'none';
	}
	else
	{
		$_get(control).style.display = '';
		
		if($_get(controlToFocus))
		{
			if($_get(controlToFocus).focus)
			{
				$_get(controlToFocus).focus();
			}
			if($_get(controlToFocus).select)
			{
				$_get(controlToFocus).select();
			}
		}
	}
}

/// <reference name="MicrosoftAjax.js"/>

var $U =
{
    ctl : function(e)
    {
        if(typeof e != 'object')
        {
            e = document.getElementById(e);
        }
        
        return e;
    },
    
    defined: function(e)
    {
        return (typeof e != 'undefined'); 
    },
    
    build : function()
    {
        var ctl = $U.ctl(arguments[0]);
        
        if(!ctl || !ctl.id)
        {
            var tag = 'div';
            
            if(arguments.length > 1) tag = arguments[1];
            
            ctl = document.createElement(tag);
            ctl.id = arguments[0];
            
            var container = document.body;
            
            if(arguments.length > 2) container = $U.ctl(arguments[2]);
            
            container.appendChild(ctl);
        }
        
        return ctl;
    },
    
    show : function(e)
    {
        var ctl = $U.ctl(e);
        ctl.style.display = '';
    },
    
    hide : function(e)
    {
        var ctl = $U.ctl(e);
        ctl.style.display = 'none';
    },
    
    visible : function(e, status)
    {
        var ctl = $U.ctl(e);
        
        if(status)
        {
            ctl.style.visibility = 'visible';
        }
        else
        {
            ctl.style.visibility = 'hidden';
        }
    },
    
    focus : function(e)
    {
        var ctl = $U.ctl(e);
        if(ctl.select)
        {
            ctl.select();
        }
        if(ctl.focus)
        {
            ctl.focus();
        }
    },
    
    html : function(e, html)
    {
        var ctl = $U.ctl(e);
        ctl.innerHTML = html;
    },
    
	checked: function(e)
	{
		var ctl = $U.ctl(arguments[0]);
		
		if(arguments.length > 1)
		{
			ctl.checked = arguments[1];
			
			return;
		}
		
		return ctl.checked;
	},
	
	
	
	disabled: function(e)
	{
		var ctl = $U.ctl(arguments[0]);
		
		if(arguments.length > 1)
		{
			ctl.disabled = arguments[1];
			return;
		}
		
		return ctl.disabled;
	},
	
	radioVal: function()
	{
		var total = arguments.length;
		
		var ctls = document.getElementsByName(arguments[0]);
		
		if(total == 2)
		{
			var val = arguments[1];
			// set
			for(var i = 0; i < ctls.length; i++)
			{
				var ctl = ctls[i];
				
				if(ctl.value == val)
				{
					ctl.checked = true;
					return true;
				}
			}
			
			return false;
		}
		else
		{
			// get
			for(var i = 0; i < ctls.length; i++)
			{
				var ctl = ctls[i];
				
				if(ctl.checked)
				{
					return ctl.value;
				}
			}
			
			return null;
		}
	},
	
    text : function()
    {
        var total = arguments.length;
        var ctl = $U.ctl(arguments[0]);
		
        if(ctl.type == 'text' || ctl.type == 'hidden' || ctl.type == 'file' || ctl.type == 'select-one' || ctl.type == 'textarea')
        {
            if(total == 1) return ctl.value;
            
            ctl.value = arguments[1];
        }
        else if(ctl.type == 'checkbox' || ctl.type == 'radio')
        {
            if(total == 1)
            {
                if(ctl.checked)
                {
                    return ctl.value;
                }
                
                return null;
            }
            else
            {
                ctl.checked = (ctl.value == arguments[1]);
            }
        }
    },
	
	listValues : function()
	{
		var total = arguments.length;
		var ctl = $U.ctl(arguments[0]);
		var totalOptions = ctl.options.length;
		
		if(total == 1)
		{
			var result = new Array();
			for(var i = 0; i < totalOptions; i++)
			{
				var opt = ctl.options[i];
				
				if(opt.selected)
				{
					result[result.length] = opt.value;
				}
			}
			
			return result;
		}
		
		var data = arguments[1];
		var totalData = data.length;
		for(var i = 0; i < totalOptions; i++)
		{
			var opt = ctl.options[i];
			opt.selected = false;
			for(var j = 0; j < totalData; j++)
			{
				if(opt.value == data[j])
				{
					opt.selected = true;
				}
			}
		}
	},
    
    clearOptions : function(e)
    {
        var ctl = $U.ctl(e);
        
        var total = ctl.options.length;
        
        for(var i = 0; i < total; i++)
        {
            ctl.options[0] = null;
        }
    },
    
    addOption : function(e, text, value)
    {
        var ctl = $U.ctl(e);
        
        ctl.options[ctl.options.length] = new Option(text, value);
    },
    
    removeOption: function(e, value)
    {
        var ctl = $U.ctl(e);
        
        var total = ctl.options.length;
        
        for(var i = 0; i < total; i++)
        {
            if(ctl.options[i].value == value)
            {
                ctl.options[i] = null;
                
                return;
            }
        }
    },
    
    setDropDownDisplay : function(e)
    {
        var elements = document.getElementsByTagName('select');
        var total = elements.length;
        for(var i = 0; i < total; i++)
        {
            $U.visible(elements[i], e);
        }
    },
    
    viewPortInfo: function()
    {
        var vpWidth = 0;
        var vpHeight = 0;
        var cntHeight = 0;
        var scrollX = 0;
        var scrollY = 0;
        
        if(document.documentElement && document.documentElement.clientWidth)
        {
            vpWidth = document.documentElement.clientWidth;
            vpHeight = document.documentElement.clientHeight;
        }
        else if(document.body && document.body.clientWidth)
        {
            vpWidth = document.body.clientWidth;
            vpHeight = document.body.clientHeight;
        }
        else if(window.innerWidth)
        {
            vpWidth = window.innerWidth;
            vpHeight = window.innerHeight - 18;
        }
        
        if(document.body && document.body.offsetHeight)
        {
            cntHeight = document.body.offsetHeight;
        }
        
        if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop))
        {
            scrollX = document.documentElement.scrollLeft;
            scrollY = document.documentElement.scrollTop;
        }
        else if(document.body && (document.body.scrollLeft || document.body.scrollTop))
        {
            scrollX = document.body.scrollLeft;
            scrollY = document.body.scrollTop;
        }
        else if(window.pageXOffset || window.pageYOffset)
        {
            scrollX = window.pageXOffset;
            scrollY = window.pageYOffset;
        }
        else if(window.scrollX || window.scrollY)
        {
            scrollX = window.scrollX;
            scrollY = window.scrollY;
        }
        
        return {'width' : vpWidth, 'height' : vpHeight, 'contentHeight' : cntHeight, 'scrollX' : scrollX, 'scrollY' : scrollY};
    },
    
    
    position: function()
    {
        var ctl = $U.ctl(arguments[0]);
        
        if(arguments.length == 1)
        {
		    var width = ctl.offsetWidth;
		    var height = ctl.offsetHeight;
    		
		    var curleft = curtop = 0;
		    if (ctl.offsetParent) {
			    do {
				    curleft += ctl.offsetLeft;
				    curtop += ctl.offsetTop;
			    } while (ctl = ctl.offsetParent);
		    }
		    return {'left' : curleft, 'top' : curtop, 'width' : width, 'height': height};
		}
		else
		{
		    var pos = arguments[1];
		    
		    ctl.style.position = 'absolute';
		    if(!$U.defined(pos.noDisplay)) $U.show(ctl);
		    		    
		    if ($U.defined(pos.width)) ctl.style.width = pos.width + 'px';
	        if ($U.defined(pos.height)) ctl.style.height = pos.height + 'px';		    
	        
		    if(pos.align)
		    {
		        var info = $U.viewPortInfo();
		        
		        var x = ((info.width - ctl.offsetWidth)/2);
		        var y = ((info.height - ctl.offsetHeight)/2) + info.scrollY;
		        
		        if(pos.align == 't')
		        {
		            y = 0;
		        }
		        else if(pos.align == 'b')
		        {
		            y = (info.height - ctl.offsetHeight);
		        }
		        else if(pos.align == 'l')
		        {
		            x = 0;
		        }
		        else if(pos.align == 'r')
		        {
		            x = (info.width - ctl.offsetWidth);
		        }
		        else if(pos.align == 'tl' || pos.align == 'lt')
		        {
		            x = 0;
		            y = info.scrollY;
		        }
		        else if(pos.align == 'tr' || pos.align == 'rt')
		        {
		            x = (info.width - ctl.offsetWidth);
		            y = info.scrollY;
		        }
		        else if(pos.align == 'br' || pos.align == 'rb')
		        {
		            x = (info.width - ctl.offsetWidth);
		            y = (info.height - ctl.offsetHeight);
		        }
		        else if(pos.align == 'bl' || pos.align == 'lb')
		        {
		            x = 0;
		            y = (info.height - ctl.offsetHeight);
		        }
		        
				if(y < 0) y = 0;
				if(x < 0) x = 0;
				
		        ctl.style.top = y + 'px';
		        ctl.style.left = x + 'px';
		    }
		    else
		    {
		        if ($U.defined(pos.top)) ctl.style.top = pos.top + 'px';
		        if ($U.defined(pos.left)) ctl.style.left = pos.left + 'px';
		    }
		}
    },
    
    showProgress: function()
    {
        var ctl = $U.build('__ajax_status');
                
        $U.html(ctl, 'Working. Please wait...');
        ctl.className = 'progress';
        
        var args = arguments[0];
        var align = 'tr'; //top right align
        
        if( $U.defined(args))
        {
            if( $U.defined(args.message)) $U.html(ctl, args.message);
            if( $U.defined(args.css)) ctl.className = args.css;
            if( $U.defined(args.align)) align = args.align;
        }
        
        $U.position(ctl, {'align': align});
    },
    
    hideProgress: function()
    {
        var ctl = $U.ctl('__ajax_status');
        ctl.style.display = 'none';
    },
    
    showModal: function()
    {
        var ctl = $U.build('__ajax_block_ui');
        
        $U.setDropDownDisplay(false);
        //$U.hide('logo');
		
        var info = $U.viewPortInfo();
        
        ctl.className = 'blockUI';
        
        $U.position(ctl, {'top': 0, 'left': 0, 'width': info.width, 'height': Math.max(info.height, info.contentHeight)});
        
        
        var modal = $U.ctl(arguments[0]);
        modal.className = 'modal';
        
        var args = {'align' : 'c'};
        
        if(arguments.length > 1)
        {
            args = arguments[1];
            
            if(!$U.defined(args.align)) args.align = 'c';
        }
        
        $U.position(modal, args);
    },
    
    hideModal: function(e)
    {
        var modal = $U.ctl(e);
        //$U.hide(modal);
        
		$('#'+e).fadeOut('medium', 
		function()
		{
			var ctl = $U.ctl('__ajax_block_ui');
        	$U.hide(ctl);
			$U.setDropDownDisplay(true); 
			//$U.show('logo');
		});
    },
	
	showResponse : function(e, response)
	{
		if(response.succeed)
		{
			$U.message(e, response.message, 'message');
		}
		else
		{
			$U.message(e, response.message, 'error');
		}
	},
	
	message: function()
	{
		var ctl = $('#'+arguments[0]);
		
		var css = 'message';
		
		if(arguments.length > 2)
		{
			css = arguments[2];
		}
		
		$U.hideProgress();
		
		ctl.html(arguments[1]).addClass(css).fadeIn('fast');
	}
};
var FormValidator = function()
{
	this._errors = new Array();
	this._controls = new Array();
	this._toDate = function(data)
	{
		var parts = data.split('/');
		var str = parts[1]+'/'+parts[0]+'/'+parts[2];
		return new Date(str);
	};
	this._isEmpty = function(data)
	{
		return (data == null || data == '');
	};
	this._isEmail = function(data)
	{
		var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
		
		return filter.test(data);
	};
	this._isNumber = function(data)
	{
		return (!isNaN(data) && parseFloat(data) >= 0);
	};
	this._isDigitOnly = function(data)
	{
		if(this._isNumber(data))
		{
			if(data.indexOf(".") != -1)
			{
				return false;
			}
			return true;
		}
		return false;
	};
	this._isEqual = function(a, b)
	{
		return (a == b);
	};
	
	this._addError = function(controlId, message)
	{
		this._errors[this._errors.length] = message;
		this._controls[this._controls.length] = controlId;
	};
	this.checkEmpty = function(arg)
	{
		for(var controlId in arg)
		{
			var data = $U.text(controlId);
			if(this._isEmpty(data))
			{
				this._addError(controlId, arg[controlId]);
			}
		}
	};
	this.checkId = function(arg)
	{
		for(var controlId in arg)
		{
			var data = $U.text(controlId);
			if(this._isEmpty(data) || parseInt(data) == 0)
			{
				this._addError(controlId, arg[controlId]);
			}
		}
	};
	this.checkEmail = function(arg)
	{
		for(var controlId in arg)
		{
			var data = $U.text(controlId);
			if(!this._isEmpty(data) && !this._isEmail(data))
			{
				this._addError(controlId, arg[controlId]);
			}
		}
	};
	this.checkEqual = function(ctlToVal, ctlToComp, msg)
	{
		if(this._isEmpty(ctlToVal)) return;
		if($U.text(ctlToVal) != $U.text(ctlToComp))
		{
			this._addError(ctlToComp, msg);
		}
	};
	this.checkRange = function(ctlToVal, minAmt, maxAmt, msg)
	{
		if(this._isEmpty(ctlToVal)) return;
		
		var val = parseFloat($U.text(ctlToVal));
		
		if(val < minAmt || val > maxAmt)
		{
			this._addError(ctlToVal, msg);
		}
	};
	this.checkDigit = function(arg)
	{
		for(var controlId in arg)
		{
			var data = $U.text(controlId);
			if(!this._isEmpty(data) && !this._isDigitOnly(data))
			{
				this._addError(controlId, arg[controlId]);
			}
		}
	};
	this.checkNumber = function(arg)
	{
		for(var controlId in arg)
		{
			var data = $U.text(controlId);
			if(!this._isEmpty(data) && !this._isNumber(data))
			{
				this._addError(controlId, arg[controlId]);
			}
		}
	};
	this.checkRadio = function(arg)
	{
		for(var controlId in arg)
		{
			var data = $U.radioVal(controlId);
			
			if(data == null)
			{
				var ctl = document.getElementsByName(controlId);
				this._addError(ctl[0].id, arg[controlId]);
			}
		}
	};
	this.checked = function(arg)
	{
		for(var controlId in arg)
		{
			if(!$U.checked(controlId))
			{
				this._addError(controlId, arg[controlId]);
			}
		}
	};
	this.checkDate = function(arg)
	{
		for(var controlId in arg)
		{
			var data = $U.text(controlId);
			if(!this._isEmpty(data) && !DateValidator.isDate(data))
			{
				this._addError(controlId, arg[controlId]);
			}
		}
	};
	this.isValid = function()
	{
		return (this._errors.length == 0);
	};
	this.focus = function()
	{
		if(this._controls.length > 0)
		{
			$U.focus(this._controls[0]);
		}
	};
	this.html = function()
	{
		var total = this._errors.length;
		
		if(total == 0) return '';
		
		var html = '<b>Please check the following error(s):</b>';
		
		html += '<ul>';
		
		for(var i = 0; i < total; i++)
		{
			html += '<li>' + this._errors[i] + '</li>';
		}
		
		html += '</ul>';
		
		return html;
	};
	this.text = function()
	{
		var total = this._errors.length;
		
		if(total == 0) return '';
		
		var txt = 'Please check the following error(s):' + "\n";
		
		for(var i = 0; i < total; i++)
		{
			txt += '* ' + this._errors[i];
			
			if(i < (total -1))
			{
				txt += "\n";
			}
		}
		
		return txt;
	}
}

var DateValidator = {
	sep : '/',
	maxYear: 2100,
	minYear: 1900,
	msg: '',
	
	isInteger: function(s)
	{
		var i;
		for (i = 0; i < s.length; i++){   
			// Check that current character is number.
			var c = s.charAt(i);
			if (((c < "0") || (c > "9"))) return false;
		}
		// All characters are numbers.
		return true;
	},
	
	stripCharsInBag: function (s, bag){
		var i;
		var returnString = "";
		// Search through string's characters one by one.
		// If character is not in bag, append to returnString.
		for (i = 0; i < s.length; i++){   
			var c = s.charAt(i);
			if (bag.indexOf(c) == -1) returnString += c;
		}
		return returnString;
	},
	
	daysInFebruary: function  (year)
	{
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    	return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
	},
	
	DaysArray: function (n) {
		for (var i = 1; i <= n; i++) {
			this[i] = 31
			if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
			if (i==2) {this[i] = 29}
	   } 
	   return this
	},
	
	isDate: function (dtStr){
		var daysInMonth = DateValidator.DaysArray(12)
		var pos1=dtStr.indexOf(DateValidator.sep)
		var pos2=dtStr.indexOf(DateValidator.sep,pos1+1)
		var strDay=dtStr.substring(0,pos1)
		var strMonth=dtStr.substring(pos1+1,pos2)
		var strYear=dtStr.substring(pos2+1)
		strYr=strYear
		if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
		if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
		for (var i = 1; i <= 3; i++) {
			if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
		}
		month=parseInt(strMonth)
		day=parseInt(strDay)
		year=parseInt(strYr)
		if (pos1==-1 || pos2==-1){
			DateValidator.msg = "The date format should be : dd/mm/yyyy";
			return false
		}
		if (strMonth.length<1 || month<1 || month>12){
			DateValidator.msg = "Please enter a valid month";
			return false
		}
		if (strDay.length<1 || day<1 || day>31 || (month==2 && day> DateValidator.daysInFebruary(year)) || day > daysInMonth[month]){
			DateValidator.msg = "Please enter a valid day";
			return false
		}
		if (strYear.length != 4 || year==0 || year<DateValidator.minYear || year>DateValidator.maxYear){
			DateValidator.msg = "Please enter a valid 4 digit year between "+minYear+" and "+maxYear;
			return false
		}
		if (dtStr.indexOf(DateValidator.sep,pos2+1)!=-1 || DateValidator.isInteger(DateValidator.stripCharsInBag(dtStr, DateValidator.sep))==false){
			DateValidator.msg = "Please enter a valid date";
			return false
		}
		return true
	}
}
$.fn.fastSerialize = function() {
    var a = [];
    $('input,textarea,select,button', this).each(function() {
        var n = this.name;
        var t = this.type;
        if ( !n || this.disabled || t == 'reset' ||
            (t == 'checkbox' || t == 'radio') && !this.checked ||
            (t == 'submit' || t == 'image' || t == 'button') && this.form.clicked != this ||
            this.tagName.toLowerCase() == 'select' && this.selectedIndex == -1)
            return;
        if (t == 'image' && this.form.clicked_x)
            return a.push(
                {name: n+'_x', value: this.form.clicked_x},
                {name: n+'_y', value: this.form.clicked_y}
            );
        if (t == 'select-multiple') {
            $('option:selected', this).each( function() {
                a.push({name: n, value: this.value});
            });
            return;
        }
        a.push({name: n, value: this.value});
    });
    return a;
};
