LengthChecker = function(id, length, mess_el_id, message, line_length)
{
    this.elem = document.getElementById(id);
    this.len = length || 20;
    this.line_len = line_length;
    this.mess_el = mess_el_id ? document.getElementById(mess_el_id) : false;
    this.fields = ['input', 'textarea'];
    this.message = message || "Maximum " + this.len + " symbols";
    this.timer = null;
    
    var ths = this;
    
    this.addEvListener = function(element, eventname, listener, capture)
    {
        capture = capture || false;
        if(element.addEventListener)
        {
            element.addEventListener(eventname, listener, capture);
        }
        else if(element.attachEvent)
        {
            element.attachEvent('on' + eventname, listener, capture);
        };
    }
    
    
    this.inArray = function(arr, val)
    {

        for(var i=0; i<arr.length; i++)
        {
            if(typeof(val) == 'string')
            {
                var up_val = val.toUpperCase();
                var lo_val = val.toLowerCase();
            }
            else
            {
                var up_val = val;
                var lo_val = val;
            }
            
            if((arr[i] == up_val) || (arr[i] == lo_val))
            {
                return true;
            }
        }
        
        return false;
    }
    
    
    this.chklen = function()
    {
        return ths.elem.value.length <= ths.len;
    }
    
    
    this.check_line_len = function()
    {
        var lines = ths.elem.value.split('\n');
        var err = {'lines': lines, err_indexes: []};
        for(var i=0; i<lines.length; i++)
        {
            if(lines[i].length > ths.line_len)
            {
                err.err_indexes.push(i);
            }
        }
        
        if(!err.err_indexes.length)
        {
            return false;
        }
        else
        {
            return err;
        }
    }
    
    
    this.bindself = function()
    {
//        this.addEvListener(ths.elem, 'keypress', ths.keypress, false);
          this.timeCheck();
    }
    
    
    this.timeCheck = function()
    {
        ths.timer = setTimeout(ths.check, 100);
    }
    
    
    this.check= function()
    {
        clearTimeout(ths.timer);
        
        if(ths.elem.value && !ths.chklen())
        {
            ths.elem.value = ths.elem.value.substring(0,ths.len);
            ths.displayMSG();
        }
        else 
        {   err = ths.check_line_len();
            if(ths.elem.value && err)
            {
                for(var i=0; i<err.err_indexes.length; i++)
                {
                    err.lines[err.err_indexes[i]] = err.lines[err.err_indexes[i]].substring(0, ths.line_len);
                }
                
                ths.elem.value = err.lines.join('\n');
                ths.displayMSG('Maximum ' + ths.line_len + ' symboils per line');
            }
        }
        
        ths.timeCheck();
    }
    
    
    
    this.displayMSG = function(msg)
    {
        if(ths.mess_el)
        {
            ths.mess_el.innerHTML = msg || ths.message;
//            setTimeout(function() {ths.mess_el.innerHTML = ''}, 5000);
        }
        else
        {
            if(ths.elem.nextSibling)
            {
                ths.mess_el = document.createElement('div');
                ths.elem.parentNode.insertBefore(ths.mess_el, ths.elem.nextSibling);
            }
            else
            {
                ths.mess_el = document.createElement('div');
                ths.elem.parentNode.appendChild(ths.mess_el);
            }
            
            ths.displayMSG();
        }
        
    }
    
    
    this.keypress = function(event)
    {
        
        var keyCode = event.keyCode ? event.keyCode : event.charCode ? event.charCode : event.which; 
        var charCode = event.charCode;

        if((keyCode < 32))
        {
            return true;
        }
        else if((typeof(charCode) == 'number') && (charCode !== keyCode))
        {
            return true;
        }

        var el  = event.target || event.srcElement;
        
        if(el.tagName && ths.inArray(ths.fields, el.tagName))
        {
            if(ths.elem.value && !ths.chklen())
            {
                ths.elem.value = ths.elem.value.substring(0,ths.len);
                //alert(ths.message);
                
                //from prototype
                if (event.preventDefault) 
                {
                    event.preventDefault();
                    event.stopPropagation();
                } 
                else 
                {
                    event.returnValue = false;
                    event.cancelBubble = true;
                }
            }
            else if(ths.elem.value && !ths.check_line_len())
            {
                if (event.preventDefault) 
                {
                    event.preventDefault();
                    event.stopPropagation();
                } 
                else 
                {
                    event.returnValue = false;
                    event.cancelBubble = true;
                }
            }
            
        }
    }
        
    
    this.bindself();
}
