/*#######################################################
#
#   COPYRIGHT 2006, Coskun SUNALI
#                   Coskun@SUNALI.com
#                   http://www.sunali.com
#
#   For more information about Coskun SUNALI,
#   please refer to http://www.sunali.com/kimim
#
#   Distributed under license of GPL.
#
#######################################################*/
// ctor
function validator(id)
{
    this.Id = id;
    this.InstanceCount = 0;
    this.Instances = new Array();
    this.AttachedEvents = new Array();
    this.LastInvalidInputs = null;
}
validator.prototype = {
    Initialize : function() {
        // iterate through an array and call AddValidation for each item
    },
    AddValidation : function(validationGroup, validationType, controlId, errorMessage, criteria) {
        var newInstanceId = this.InstanceCount++;
        this.Instances[newInstanceId] = new validation(this, validationGroup, validationType, controlId, errorMessage, criteria);
    },
    // calls Validate method through the validationGroup parameter
    ValidateGroup : function(validationGroup) {
        var isValid = true;
        this.LastInvalidInputs = new Array();
        var index = 0;
        
        for (index = 0; index < this.InstanceCount; index++)
        {
            if ( this.Instances[index].ValidationGroup == validationGroup )
            {
                this.Instances[index].RemoveError();
                
                if ( !this.HasAnyErrors(this.Instances[index].ControlId) )
                {
                    this.Instances[index].Validate(true);
    
                    if ( ! this.Instances[index].IsValid )
                        isValid = false;
                }
            }
        }
        
        return isValid;
    },
    
    // calls Validate method through the validationGroup parameter
    ValidateControl : function(controlId) {
        var isValid = true;
        this.LastInvalidInputs = new Array();
        var index = 0;
        
        for (index = 0; index < this.InstanceCount; index++)
        {
            if ( this.Instances[index].ControlId == controlId )
            {
                //alert("Will hide: " + this.Instances[index].ValidationType);
                this.Instances[index].RemoveError();
                
                if ( isValid )
                {
                    this.Instances[index].Validate(true);
    
                    if ( ! this.Instances[index].IsValid )
                    {
                        //alert("has shown: " + this.Instances[index].ValidationType);
                        isValid = false;
                    }
                }
            }
        }
        
        return isValid;
    },
    
    // returns true if the control has any invalid validation instances before this validation instance
    HasAnyErrors : function(controlId) {
        if ( this.LastInvalidInputs.length == 0)
            return false;
        
        var index = 0;
        
        for (index = 0; index < this.LastInvalidInputs.length; index++)
        {
            if ( this.LastInvalidInputs[index] == controlId )
            {
                return true;
            }
        }
        return false;
    },
    // Calls RemoveError method for all the validation instances
    RemoveErrors : function() {
        var index = 0;
        for (index = 0; index < this.InstanceCount; index++)
        {
            this.Instances[index].RemoveError();
        }
    },
    
    // Calls HideBaloon method for all the validation instances
    HideBaloons : function() {
        var index = 0;
        for (index = 0; index < this.InstanceCount; index++)
        {
            this.HideBaloon(index);
        }
    },
    
    ShowBaloon : function(instanceIndex) {
        var errorBaloonDiv = document.getElementById("errorBaloonDiv_" + instanceIndex);
        if ( errorBaloonDiv == null )
            return;
            
        this.HideBaloons();
            
        errorBaloonDiv.style.display = "block";
    },
    HideBaloon : function(instanceIndex) {
        var errorBaloonDiv = document.getElementById("errorBaloonDiv_" + instanceIndex);
        if ( errorBaloonDiv == null )
            return;
    
        errorBaloonDiv.style.display = "none";
    },
    
    HideBaloonWithDelay : function(instanceIndex, delay) {
        var errorBaloonDiv = document.getElementById("errorBaloonDiv_" + instanceIndex);
        if ( errorBaloonDiv == null )
            return;
        
        if ( delay == null )
            delay = 2000; // 2 saniye
    
        eval('window.setTimeout(\'document.getElementById("errorBaloonDiv_'+ instanceIndex +'").style.display = "none"\', '+ delay +');');
    }
}
function validation(validatorInstance, validationGroup, validationType, controlId, errorMessage, criteria)
{
    this.ValidatorInstance = validatorInstance;
    this.InstanceIndex = validatorInstance.InstanceCount-1;
    this.IsValid = true;
    
    this.ValidationGroup = validationGroup;
    this.ValidationType = validationType;
    this.ErrorMessage = errorMessage;
    this.ControlId = controlId;
    this.Control = document.getElementById(controlId);
    this.TagName = this.Control.tagName;
    this.InputType = this.Control.getAttribute("type");
    
   
    if ( validationType == "minlength" )
        this.MinLength = criteria;
    else if ( validationType == "maxlength" )
        this.MaxLength = criteria;
    else if ( validationType == "regexp" )
        this.Pattern = criteria;
        
    this.AttachEvent("blur",function () {validatorInstance.ValidateControl(controlId);});
}
validation.prototype = {
    // validates the validation instance and set the IsValid property to true if valid
    Validate : function(showError) {
        this.IsValid = true;
        
        if (this.ValidationType == "required")
        {
            var currentValue = this.GetValue();
            if ( currentValue == "" )
            {
                this.IsValid = false;
                
                if ( showError )
                    this.AddError();
                return;
            }
        }
        else if (this.ValidationType == "minlength")
        {
            var currentValue = this.GetValue();
            // DEBUG
            if ( this.MinLength == null )
            {
                alert("DEBUG: minlength criteria is null. controlId: " + this.ControlId );
                
                this.IsValid = false;
                return;
            }
            
            if ( currentValue.length < this.MinLength )
            {
                this.IsValid = false;
                
                if ( showError )
                    this.AddError();
                return;
            }
        }
        else if (this.ValidationType == "maxlength")
        {
            var currentValue = this.GetValue();
            
            // DEBUG
            if ( this.MaxLength == null )
            {
                alert("DEBUG: maxlength criteria is null. controlId: " + this.ControlId );
                
                this.IsValid = false;
                return;
            }
            
            if ( currentValue.length > this.MaxLength )
            {
                this.IsValid = false;
                
                if ( showError )
                    this.AddError();
                    
                return;
            }
        }
        else if (this.ValidationType == "regexp")
        {
            var currentValue = this.GetValue();
            
            // DEBUG
            if ( this.Pattern == null )
            {
                alert("DEBUG: pattern criteria is null. controlId: " + this.ControlId );
                
                this.IsValid = false;
                return;
            }
            
            var regExp = new RegExp(this.Pattern);
            if ( ! currentValue.match(regExp) )
            {
                this.IsValid = false;
                
                if ( showError )
                    this.AddError();
                    
                return;
            }
        }
    },
    
    // gets the value of control
    GetValue : function() {
        if ( this.TagName == "INPUT" )
        {
            if ( this.InputType == "text" || this.InputType == "password" )
            {
                //alert(this.ControlId);
                return trim(this.Control.value);
            }
        }
        else if ( this.TagName == "SELECT" )
        {
            return this.Control.options[this.Control.selectedIndex].value;
        }
    },
    
    // gets the X coordinate for the errorDiv
    GetBaloonX : function() {
        var offsetParentElement = this.Control;
        var offsetX = offsetParentElement.offsetLeft + offsetParentElement.offsetWidth + 5;
        
        while ( ( offsetParentElement = offsetParentElement.offsetParent ) != null )
        {
            offsetX += offsetParentElement.offsetLeft;
        }
        return offsetX;
    },
    
    // gets the Y coordinate for the errorDiv
    GetBaloonY : function() {
        var offsetParentElement = this.Control;
        var offsetY = offsetParentElement.offsetTop;
        
        while ( ( offsetParentElement = offsetParentElement.offsetParent ) != null )
        {
            offsetY += offsetParentElement.offsetTop;
        }
        
        return offsetY;
    },
    // adds the error icon and the baloon to the DOM for the instance
    AddError : function() {
        this.ValidatorInstance.LastInvalidInputs.push(this.ControlId);
        
        var errorBaloonTable = "<table cellpadding='0' cellspacing='0'>";
        errorBaloonTable += "<tr>";
        errorBaloonTable += "<td width='1%' valign='top' align='right' style='padding-top: 10px;'>";
        errorBaloonTable += "<img src='/images/baloon_tail.gif' border='0' />";
        errorBaloonTable += "</td>";
        errorBaloonTable += "<td valign='top' style='background:transparent url(/images/baloon.gif) no-repeat top left; padding: 10px;'>";
        errorBaloonTable += this.ErrorMessage;
        errorBaloonTable += "</td>";
        errorBaloonTable += "</tr>";
        errorBaloonTable += "</table>";
        
        var errorIcon = '<img src="/images/validation_error.gif" border="0" style="cursor:hand;" ';
        errorIcon += 'onmouseover="'+this.ValidatorInstance.Id+'.ShowBaloon('+this.InstanceIndex+');" ';
        errorIcon += 'onmouseout="'+this.ValidatorInstance.Id+'.HideBaloonWithDelay('+this.InstanceIndex+',2000);" ';
        errorIcon += 'onclick="document.getElementById(\''+this.ControlId+'\').focus();" ';
        errorIcon += '/>';
        
        var errorBaloonDiv = document.createElement("div");
        errorBaloonDiv.id = "errorBaloonDiv_" + this.InstanceIndex;
        errorBaloonDiv.className = "validationErrorBaloonDiv";
        
        var errorBaloonDivTop = this.GetBaloonY() - 15;
        if ( errorBaloonDivTop < 0 )
            errorBaloonDivTop = 1;
        
        errorBaloonDiv.style.top = errorBaloonDivTop;
        errorBaloonDiv.style.left = this.GetBaloonX() + 20;
        errorBaloonDiv.style.display = "none";
        errorBaloonDiv.innerHTML = errorBaloonTable;
        document.body.appendChild(errorBaloonDiv);
        
        var errorDiv = document.createElement("div");
        errorDiv.id = "errorDiv_" + this.InstanceIndex;
        errorDiv.innerHTML = errorIcon;
        errorDiv.className = "validationErrorIconDiv";
        errorDiv.style.top = this.GetBaloonY();
        errorDiv.style.left = this.GetBaloonX();
        errorDiv.style.display = "block";
        document.body.appendChild(errorDiv);
    },
    
    // removes the error icon and the baloon from the DOM for this instance
    RemoveError : function() {
        var errorDiv = document.getElementById("errorDiv_" + this.InstanceIndex);
        if ( errorDiv != null )
            document.body.removeChild(errorDiv);
            
        var errorBaloonDiv = document.getElementById("errorBaloonDiv_" + this.InstanceIndex);
        if ( errorBaloonDiv != null )
            document.body.removeChild(errorBaloonDiv);
    },
    
    AttachEvent : function(eventName, method) { //function () {tinyMCE.triggerSave(true, true);}
        //alert(this.ControlId +"-"+ eventName +"-"+this.HasEvent(eventName));
        if (this.HasEvent(eventName))
            return false;
            
        if (this.Control.attachEvent)
            this.Control.attachEvent("on" + eventName, method);
        else
            this.Control.addEventListener(eventName, method, false);
        
        this.ValidatorInstance.AttachedEvents.push(this.ControlId+"_"+eventName);
    },
    
    HasEvent : function(eventName) {
        if ( this.ValidatorInstance.AttachedEvents.length == 0)
            return false;
            
        var index = 0;
        
        for (index = 0; index < this.ValidatorInstance.AttachedEvents.length; index++)
        {
            if ( this.ValidatorInstance.AttachedEvents[index] == this.ControlId+"_"+eventName )
            {
                return true;
            }
        }
    }
}
// Removes leading whitespaces
function ltrim( value ) {
	
	var re = /\s*((\S+\s*)*)/;
	return value.replace(re, "$1");
	
}
// Removes ending whitespaces
function rtrim( value ) {
	
	var re = /((\s*\S+)*)\s*/;
	return value.replace(re, "$1");
	
}
// Removes leading and ending whitespaces
function trim( value ) {
	
	return ltrim(rtrim(value));
	
}
