/*
* Input Filter class
* Filters user input according to given regular expression
*
* @param string id of input element
* @param string regular expression with allowed chars
*/

function InputFilter(inputElementId, regExpr) {
    this.input = document.getElementById(inputElementId);
    this.input.filterObj = this;
    this.filter = new RegExp(regExpr,"g");
    this.container = this.input.parentNode.parentNode;

    /*
    * Constructor
    */
    this._construct = function()
    {
        this.input.onfocus = function()
        {
            // In this context variable "this" is linked to dom input element
            this.onkeyup = function()
            {
                this.filterObj.validate();
            }
        }

        this.input.onblur = function()
        {
            // In this context variable "this" is linked to dom input element
            this.onkeyup = null;
            this.filterObj.trim();
            this.filterObj.hideError();
            this.filterObj.validate();
        }

        this.validate();
    }

    this.validate = function()
    {
        if(this.input.value.length > 255) {
            this.input.value = this.input.value.substr(0,255);
        }

        var matches = this.input.value.match(this.filter);
        if(matches) {
            var selStart = this.getSelectionStart();
            selStart -= matches.join("").length;
            selStart = (selStart < 0) ? 0 : selStart;

            this.input.value = this.input.value.replace(this.filter, "");
            this.setCaretPosition(selStart, selStart);

            this.showError("Symbol(s) not permitted: "+this.htmlEncode(matches.toString()));
        }
    }

    this.htmlEncode = function(str)
    {
        str = str.replace(new RegExp("&","g"), "&amp;");
        str = str.replace(new RegExp("<","g"), "&lt;");
        str = str.replace(new RegExp(">","g"), "&gt;");
        str = str.replace(new RegExp("\"","g"), "&quot;");
        return str;
    }


    this.trim = function()
    {
        this.input.value = this.input.value.replace(new RegExp("^([ ]+)"), "");
        this.input.value = this.input.value.replace(new RegExp("([ ]+)$"), "");
        this.input.value = this.input.value.replace(new RegExp("([ ]+)", "g"), " ");
    }

    this.hideError = function()
    {
        var errorBox = document.getElementById(this.input.id+"error");
        if(errorBox) {
            errorBox.style.display = "none";
        }
    }

    this.showError = function(errorMessage)
    {
        var errorBox = document.getElementById(this.input.id+"error");
        if(!errorBox) {
            errorBox = document.createElement("div");
            var errorText = document.createTextNode(errorMessage);
            errorBox.id = this.input.id+"error";
            errorBox.style.color = "#ff0000";
            errorBox.style.marginLeft = "198px";
            errorBox.appendChild(errorText);
            this.container.insertBefore(errorBox, this.container.childNodes[0]);
        }

        errorBox.style.display = "";
        errorBox.innerHTML = errorMessage;

    }

    this.setCaretPosition = function(startPos, endPos){
    	var valLength = this.input.value.length;

    	if(isNaN(parseInt(startPos))){
    		return false;
    	} else {
    		startPos = parseInt(startPos);

    		if(startPos < 0){
    			startPos = 0
    		} else if(startPos > valLength){
    			startPos = valLength;
    		}
    	}

    	if(isNaN(parseInt(endPos)) || parseInt(endPos) < startPos){
    		endPos = startPos;
    	} else {
    		endPos = parseInt(endPos);

    		if(endPos < 0){
    			endPos = 0;
    		} else if(endPos > valLength){
    			endPos = valLength;
    		}
    	}


    	if(typeof(this.input.createTextRange) == "object"){
    		// IE
    		var range = this.input.createTextRange();

    		range.moveEnd("character", endPos - this.input.value.length);
    		range.moveStart("character", startPos);
    		range.select();

    		return true;
    	} else if (typeof(this.input.setSelectionRange) == 'function'){
    		// mozilla, opera, safari
    		this.input.setSelectionRange(startPos, endPos);

    		return true;
    	}

    	return false;
    }

    this.getSelectionStart = function()
    {
    	if (typeof(this.input.selectionStart) != "undefined") {
    		// mozilla and opera
    		var selStart = this.input.selectionStart;

    		// Safari bug when field is focused for first time
    		if(selStart == 2147483647){
    			selStart = 0;
    		}
    		return selStart;
    	} else if (document.selection) {
    		// IE black magic
    		return Math.abs(
    			document.selection.createRange().moveStart("character", -1000000)
    		);
    	}

    	return null;
    }

    this._construct();
}
