// *****************************************************************************************************************************************
// INPUT BOX by Br3tt aka Falstaff (c)2013-2015
// *****************************************************************************************************************************************

cInputbox = {
	temp_gr: gdi.CreateImage(1, 1).GetGraphics(),
	timer_cursor: false,
	cursor_state: true,
	doc: new ActiveXObject("htmlfile"),
	clipboard: null
};

oInputbox = function (w, h, default_text, empty_text, textcolor, backcolor, bordercolor, backselectioncolor, func, parentObjectName, id, font_size, bg_alpha) {
    this.id = id;
    this.font_size = font_size;
    this.font = gdi.Font("segoe ui", this.font_size, 0);
    this.font_italic = gdi.Font("segoe ui", this.font_size, 2);
    this.w = w;
    this.h = h;
    this.textcolor = textcolor;
    this.backcolor = backcolor;
    this.backcolor_alpha = bg_alpha;
	this.bordercolor = bordercolor;
	this.backselectioncolor = backselectioncolor;
    this.default_text = default_text;
    this.text = default_text;
    this.text_selected = "";
	this.prev_text = "01234567890123456789";
	this.empty_text = empty_text;
    this.stext = "";
    this.prev_text = "";
    this.func = func;
	var gfunc = func;
    var gfunc_launch_timer = false;
	var g_parentObjectName = parentObjectName;
	this.autovalidation = false;
    //
    this.edit = false;
    this.select = false;
    this.hover = false;
    this.Cpos = 0;
    this.Cx = 0;
    this.offset = 0;
    this.right_margin = 2;
    this.drag = false;
    //
    if(cInputbox.timer_cursor) window.ClearTimeout(cInputbox.timer_cursor);
    cInputbox.timer_cursor = false;
    this.ibeam_set = false;

    this.draw = function (gr, x, y) {
        this.x = x;
        this.y = y;
        if (this.edit) {
            var DT = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_CALCRECT;
        }; else {
            var DT = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_CALCRECT | DT_END_ELLIPSIS;
        };
        // draw bg
		gr.SetSmoothingMode(0);
        if(this.bordercolor) gr.DrawRect(x-2, y+0, (this.w+4)-1, this.h-1, 1.0, this.bordercolor);
        gr.FillSolidRect(x-1,y+1,(this.w+2),this.h-2,this.backcolor & RGBA(255,255,255,this.backcolor_alpha));
		
        // adjust offset to always see the cursor
        if(!this.drag && !this.select) {
            this.Cx = cInputbox.temp_gr.CalcTextWidth(this.text.substr(this.offset, this.Cpos - this.offset), this.font);
            while(this.Cx >= this.w - this.right_margin) {
                this.offset++;
                this.Cx = cInputbox.temp_gr.CalcTextWidth(this.text.substr(this.offset, this.Cpos - this.offset), this.font);
            };
        };
        // draw selection
        if(this.SelBegin!=this.SelEnd) {
            this.select = true;
            this.CalcText();
            if(this.SelBegin<this.SelEnd) {
                if(this.SelBegin<this.offset) {
                    var px1 = this.x;
                }; else {
                    var px1 = this.x + this.GetCx(this.SelBegin);
                };
                var px1 = this.GetCx(this.SelBegin);
                var px2 = this.GetCx(this.SelEnd);
                this.text_selected = this.text.substring(this.SelBegin, this.SelEnd);
            }; else {
                if(this.SelEnd<this.offset) {
                    var px1 = this.x;
                }; else {
                    var px1 = this.x - this.GetCx(this.SelBegin);
                };
                var px2 = this.GetCx(this.SelBegin);
                var px1 = this.GetCx(this.SelEnd);
                this.text_selected = this.text.substring(this.SelEnd, this.SelBegin);
            };
            if( (this.x + px1 + (px2-px1)) > this.x + this.w) {
                gr.FillSolidRect(this.x+px1, this.y+2, this.w-px1, this.h-4, this.backselectioncolor & 0xaaffffff);
            }; else {
                gr.FillSolidRect(this.x+px1, this.y+2, px2-px1, this.h-4, this.backselectioncolor & 0xaaffffff);
            };
        }; else {
            this.select = false;
            this.text_selected = "";
        };

        // draw text
        if(this.text.length>0) {
            gr.GdiDrawText(this.text.substr(this.offset), this.edit ? this.font : this.font, this.edit ? this.textcolor : blendColors(textcolor, backcolor, 0.5), this.x, this.y, this.w, this.h, DT);
        }; else {
            gr.GdiDrawText(this.empty_text, this.font_italic, blendColors(textcolor, backcolor, 0.5), this.x, this.y, this.w, this.h, DT);
        };
        // draw cursor
        if(this.edit && !this.select) this.drawcursor(gr);
    };
    
    this.drawcursor = function (gr) {
        if(cInputbox.cursor_state) {
            if(this.Cpos >= this.offset) {
                this.Cx = this.GetCx(this.Cpos);
                var x1 = this.x + this.Cx;
                var x2 = x1;
                var y1 = this.y + 2;
                var y2 = this.y + this.h - 3;
                var lt = 1;
                gr.DrawLine(x1, y1, x2, y2, lt, this.textcolor);
            };
        };
    };
    
    this.repaint = function () {
        if(g_parentObjectName=="this") {
            window.RepaintRect(this.x, this.y, this.w, this.h);
        }; else {
            eval(g_parentObjectName+".repaint()");
        };
		
    };
    
    this.CalcText = function () {
    	var arr = cInputbox.temp_gr.GdiDrawText(this.text.substr(this.offset), this.font, 0, 0, 0, 9999999, 9999999, DT_NOPREFIX | DT_CALCRECT).toArray();
    	this.TLength = arr[4];
    	this.TWidth = cInputbox.temp_gr.CalcTextWidth(this.text.substr(this.offset), this.font);
    };
    
    this.GetCx = function (pos) {
        if(pos >= this.offset) {
            var x = cInputbox.temp_gr.CalcTextWidth(this.text.substr(this.offset, pos - this.offset), this.font);
        }; else {
            var x = 0;
        };
        return x;
    };
    
    this.GetCPos = function (x) {
        var tx = x - this.x;
        var pos = 0;
        for(var i=this.offset; i<this.text.length; i++) {
            pos += cInputbox.temp_gr.CalcTextWidth(this.text.substr(i,1), this.font);
            if(pos >= tx+3) {
                break;
            };
        };
        return i;
    };

    this.on_focus = function (is_focused) {
        this.is_focused = is_focused;
        if (!this.is_focused && this.edit) {
            if (this.text.length == 0) {
                this.text = this.default_text;
                eval(gfunc);
            }; else {
                this.default_text = this.text;
                eval(gfunc);
            };
            this.edit = false;
            // clear timer
            if(cInputbox.timer_cursor) {
                window.ClearInterval(cInputbox.timer_cursor);
                cInputbox.timer_cursor = false;
                cInputbox.cursor_state = true;
            };
            this.repaint();
        }; else if(this.is_focused) {
            if(!cInputbox.timer_cursor) {
                this.resetCursorTimer();
            };
        };
    };
    
    this.resetCursorTimer = function() {
        if(cInputbox.timer_cursor) {
            window.ClearInterval(cInputbox.timer_cursor);
            cInputbox.timer_cursor = false;
            cInputbox.cursor_state = true;
        };
        cInputbox.timer_cursor = window.SetInterval(function() {
            cInputbox.cursor_state = !cInputbox.cursor_state;
			eval(g_parentObjectName+".repaint()");
        }, 500);
    };

    this.check = function (callback, x, y, delta) {
        this.hover = (x >= this.x - 2 && x <= (this.x + this.w + 1) && y > this.y && y < (this.y + this.h)) ? true : false;
        switch(callback) {
            case "down":
                this.on_focus(this.hover);
                if(this.hover) {
                    this.dblclk = false;
                    this.drag = true;
                    this.edit = true;
                    this.Cpos = this.GetCPos(x);
                    this.anchor = this.Cpos;
                    this.SelBegin = this.Cpos;
                    this.SelEnd = this.Cpos;
                    //this.on_focus(true);
                    if(!cInputbox.timer_cursor) {
                        this.resetCursorTimer();
                    };
                }; else {
                    this.edit = false;
					this.select = false;
					this.SelBegin = 0;
					this.SelEnd = 0;
					this.text_selected = "";
                    /*
					if(cInputbox.timer_cursor) {
						window.ClearInterval(cInputbox.timer_cursor);
						cInputbox.timer_cursor = false;
						cInputbox.cursor_state = true;
					};
                    */
                };
                this.repaint();
                break;
            case "up":
                if(!this.dblclk && this.drag) {
                    this.SelEnd = this.GetCPos(x);
                    if(this.select) {
                        if(this.SelBegin>this.SelEnd) {
                            this.sBeginSel = this.SelBegin;
                            this.SelBegin = this.SelEnd;
                            this.SelEnd = this.sBeginSel;
                        };
                    };
                }; else {
                    this.dblclk = false;
                };
				this.drag = false;
                break;
            case "dblclk":
				if(this.hover) {
					this.dblclk = true;
					this.SelBegin = 0;
					this.SelEnd = this.text.length;
					this.text_selected = this.text;
					this.select = true;
					this.repaint();
				};
                break;
            case "move":
                if(this.drag) {
                    this.CalcText();
                    var tmp = this.GetCPos(x);
                    var tmp_x = this.GetCx(tmp);
                    if(tmp<this.SelBegin) {
                        if(tmp<this.SelEnd) {
                            if(tmp_x<this.x) {
                                if(this.offset>0) {
                                    this.offset--;
                                    this.repaint();
                                };
                            };
                        }; else if(tmp>this.SelEnd) {
                            if(tmp_x+this.x>this.x+this.w) {
                                var len = (this.TWidth>this.w)?this.TWidth - this.w:0;
                                if(len>0) {
                                    this.offset++;
                                    this.repaint();
                                };
                            };
                        };
                        this.SelEnd = tmp;
                    }; else if(tmp>this.SelBegin) {
                        if(tmp_x+this.x>this.x+this.w) {
                            var len = (this.TWidth>this.w)?this.TWidth - this.w:0;
                            if(len>0) {
                                this.offset++;
                                this.repaint();
                            };
                        };
                        this.SelEnd = tmp;
                    };
                    this.Cpos = tmp;
                    this.repaint();
                };
                // Set Mouse Cursor Style
				if(this.hover || this.drag) {
					window.SetCursor(IDC_IBEAM);
				}; else if(this.ibeam_set) {
					window.SetCursor(IDC_ARROW);
				};
				this.ibeam_set = (this.hover || this.drag);
                break;
            case "right":
                if(this.hover) {
                    this.edit = true;
                    if(!cInputbox.timer_cursor) {
                        this.resetCursorTimer();
                    };
                    this.repaint();
                    this.show_context_menu(x, y);
                }; else {
                    this.edit = false;
					this.select = false;
					this.SelBegin = 0;
					this.SelEnd = 0;
					this.text_selected = "";
					if(cInputbox.timer_cursor) {
						window.ClearInterval(cInputbox.timer_cursor);
						cInputbox.timer_cursor = false;
						cInputbox.cursor_state = true;
					};
					this.repaint();
                };				
                break;
            case "wheel":
                break;
        };
    };
    
    this.show_context_menu = function(x, y) {
        var idx;
        var _menu = window.CreatePopupMenu();
        cInputbox.clipboard = cInputbox.doc.parentWindow.clipboardData.getData("Text");
        _menu.AppendMenuItem(this.select?MF_STRING:MF_GRAYED|MF_DISABLED, 1, "Copy");
        _menu.AppendMenuItem(this.select?MF_STRING:MF_GRAYED|MF_DISABLED, 2, "Cut");
        _menu.AppendMenuSeparator();
        _menu.AppendMenuItem(cInputbox.clipboard?MF_STRING:MF_GRAYED|MF_DISABLED, 3, "Paste");
        if(utils.IsKeyPressed(VK_SHIFT)) {
            _menu.AppendMenuSeparator();
            _menu.AppendMenuItem(MF_STRING, 20, "Properties");
            _menu.AppendMenuItem(MF_STRING, 21, "Configure...");
        };
        idx = _menu.TrackPopupMenu(x, y);
        switch(idx) {
            case 1:
                if(this.edit && this.select) {
                    cInputbox.doc.parentWindow.clipboardData.setData("Text", this.text_selected);
                };
                break;
            case 2:
                if(this.edit && this.select) {
                    cInputbox.doc.parentWindow.clipboardData.setData("Text", this.text_selected);
                    var p1 = this.SelBegin;
                    var p2 = this.SelEnd;
					this.offset = this.offset>=this.text_selected.length ? this.offset - this.text_selected.length : 0;
                    this.select = false;
                    this.text_selected = "";
                    this.Cpos = this.SelBegin;
                    this.SelEnd = this.SelBegin;
                    this.text = this.text.slice(0, p1) + this.text.slice(p2);
                    this.CalcText();
					
                    this.repaint();
					//eval(gfunc);
                };
                break;
            case 3:
                if(this.edit && cInputbox.clipboard) {
                    if(this.select) {
                        var p1 = this.SelBegin;
                        var p2 = this.SelEnd;
                        this.select = false;
                        this.text_selected = "";
                        this.Cpos = this.SelBegin;
                        this.SelEnd = this.SelBegin;
                        
                        if(this.Cpos < this.text.length) {
                            this.text = this.text.slice(0, p1) + cInputbox.clipboard + this.text.slice(p2);
                        }; else {
                            this.text = this.text + cInputbox.clipboard;
                        };
                        this.Cpos += cInputbox.clipboard.length;
                        this.CalcText();
                        this.repaint();
                    }; else {
                        if(this.Cpos>0) { // cursor pos > 0
                            this.text = this.text.substring(0, this.Cpos) + cInputbox.clipboard + this.text.substring(this.Cpos, this.text.length);
                        }; else {
                            this.text = cInputbox.clipboard + this.text.substring(this.Cpos, this.text.length);
                        };
                        this.Cpos += cInputbox.clipboard.length;
                        this.CalcText();
                        this.repaint();
                    };
					//eval(gfunc);
                };
                break;
            case 20:
                window.ShowProperties();
                break;
            case 21:
                window.ShowConfigure();
                break;
        };
        _menu.Dispose();
    };
    
    this.on_key_down = function (vkey) {
        if(!cInputbox.timer_cursor) {
            this.resetCursorTimer();
        };
        var kmask = GetKeyboardMask();
        this.on_key(vkey, kmask);
    };

    this.on_key = function (vkey, mask) {               
        if (mask == KMask.none) {
            switch (vkey) {
            case VK_SHIFT:
                break;
    		case VK_BACK:
                //save text before update
                this.stext = this.text;
    			if (this.edit) {
                    if(this.select) {
                        if(this.text_selected.length == this.text.length) {
                            this.text = "";
                            this.Cpos = 0;
                        }; else {
                            if(this.SelBegin > 0) {
                                this.text = this.text.substring(0, this.SelBegin) + this.text.substring(this.SelEnd, this.text.length);
                                this.Cpos = this.SelBegin;
                            }; else {
                                this.text = this.text.substring(this.SelEnd, this.text.length);
                                this.Cpos = this.SelBegin;
                            };
                        };
                    }; else {
                        if(this.Cpos>0) {
                            this.text = this.text.substr(0, this.Cpos - 1) + this.text.substr(this.Cpos, this.text.length - this.Cpos);
                            if(this.offset > 0) {
                                this.offset--;
                            };
                            this.Cpos--;
                            this.repaint();
                        };
                    };
    			};
                this.CalcText();
                this.offset = this.offset>=this.text_selected.length ? this.offset - this.text_selected.length : 0;               
                this.text_selected = "";
                this.SelBegin = this.Cpos;
                this.SelEnd = this.SelBegin;
                this.select = false;
                this.repaint();
    			break;
            case VK_DELETE:
                //save text before update
                this.stext = this.text;
    			if (this.edit) {
                    if(this.select) {
                        if(this.text_selected.length == this.text.length) {
                            this.text = "";
                            this.Cpos = 0;
                        }; else {
                            if(this.SelBegin > 0) {
                                this.text = this.text.substring(0, this.SelBegin) + this.text.substring(this.SelEnd, this.text.length);
                                this.Cpos = this.SelBegin;
                            }; else {
                                this.text = this.text.substring(this.SelEnd, this.text.length);
                                this.Cpos = this.SelBegin;
                            };
                        };
                    }; else {
                        if(this.Cpos<this.text.length) {
                            this.text = this.text.substr(0, this.Cpos) + this.text.substr(this.Cpos + 1, this.text.length - this.Cpos - 1);
                            this.repaint();
                        };
                    };
    			};
                this.CalcText();
                this.offset = this.offset>=this.text_selected.length ? this.offset - this.text_selected.length : 0;               
                this.text_selected = "";
                this.SelBegin = this.Cpos;
                this.SelEnd = this.SelBegin;
                this.select = false;
                this.repaint();
    			break;
            case VK_TAB:
    		case VK_RETURN:
    			if (this.edit && this.text.length>=0) {
                    eval(gfunc);
    			}; else {

    			};
    			break;
    		case VK_ESCAPE:
    			if (this.edit) {
    				this.edit = false;
                    this.text_selected = "";
                    this.text = this.default_text; // restore the inputbox initial value on ESC
                    this.select = false;                   
    				this.repaint();
    			};
    			break;
    		case VK_END:
    			if (this.edit) {
                    this.Cpos = this.text.length;
                    this.SelBegin = 0;
                    this.SelEnd = 0;
                    this.select = false;
                    this.repaint();
    			};
    			break;
    		case VK_HOME:
    			if (this.edit) {
                    this.Cpos = 0;
                    this.SelBegin = 0;
                    this.SelEnd = 0;
                    this.select = false;
                    this.offset = 0;
                    this.repaint();
    			};
    			break;
    		case VK_LEFT:
    			if (this.edit) {
                    if(this.offset > 0) {
                        if(this.Cpos <= this.offset) {
                            this.offset--;
                            this.Cpos--;
                        }; else {
                            this.Cpos--;
                        };
                    }; else {
                        if (this.Cpos > 0) this.Cpos--;
                    };
                    this.SelBegin = this.Cpos;
                    this.SelEnd = this.Cpos;
                    this.select = false;
                    this.repaint();
    			};
    			break;
    		case VK_RIGHT:
    			if (this.edit) {
                    if (this.Cpos < this.text.length) this.Cpos++;
                    this.SelBegin = this.Cpos;
                    this.SelEnd = this.Cpos;
                    this.select = false;
                    this.repaint();
    			};
    			break;
    		};
    		if (this.edit) this.repaint();
    	}; else {
            switch(mask) {
                case KMask.shift:
                    if(vkey==VK_HOME) { // SHIFT + HOME
                        if (this.edit) {
                            if(!this.select) {
                                this.anchor = this.Cpos;
                                this.select = true;
                                if (this.Cpos > 0) {
                                    this.SelEnd = this.Cpos;
                                    this.SelBegin = 0;
                                    this.select = true;
                                    this.Cpos = 0;
                                };
                            }; else {
                                if (this.Cpos > 0) {
                                    if(this.anchor<this.Cpos) {
                                        this.SelBegin = 0;
                                        this.SelEnd = this.anchor;
                                    }; else if(this.anchor>this.Cpos){
                                        this.SelBegin = 0;
                                    };
                                    this.Cpos = 0;
                                }; 
                            };
                            if(this.offset>0) {
                                this.offset = 0;
                            };
                            this.repaint();
                        };
                    };
                    if(vkey==VK_END) { // SHIFT + END
                        if (this.edit) {
                            if(!this.select) {
                                this.anchor = this.Cpos;
                                if (this.Cpos < this.text.length) {
                                    this.SelBegin = this.Cpos;
                                    this.SelEnd = this.text.length;
                                    this.Cpos = this.text.length;
                                    this.select = true;
                                };
                            }; else {
                                if (this.Cpos < this.text.length) {
                                    if(this.anchor<this.Cpos) {
                                        this.SelEnd = this.text.length;
                                    }; else if(this.anchor>this.Cpos){
                                        this.SelBegin = this.anchor;
                                        this.SelEnd = this.text.length;
                                    };
                                    this.Cpos = this.text.length;
                                };
                            };

                            this.Cx = cInputbox.temp_gr.CalcTextWidth(this.text.substr(this.offset, this.Cpos - this.offset), this.font);
                            while(this.Cx >= this.w - this.right_margin) {
                                this.offset++;
                                this.Cx = cInputbox.temp_gr.CalcTextWidth(this.text.substr(this.offset, this.Cpos - this.offset), this.font);
                            };
              
                            this.repaint();
                        };
                    };
                    if(vkey==VK_LEFT) { // SHIFT + KEY LEFT
                        if (this.edit) {
                            if(!this.select) {
                                this.anchor = this.Cpos;
                                this.select = true;
                                if (this.Cpos > 0) {
                                    this.SelEnd = this.Cpos;
                                    this.SelBegin = this.Cpos - 1;
                                    this.select = true;
                                    this.Cpos--;
                                };
                            }; else {
                                if (this.Cpos > 0) {
                                    if(this.anchor<this.Cpos) {
                                        this.SelEnd--;
                                    }; else if(this.anchor>this.Cpos){
                                        this.SelBegin--;
                                    };
                                    this.Cpos--;
                                }; 
                            };
                            if(this.offset>0) {
                                var tmp = this.Cpos;
                                var tmp_x = this.GetCx(tmp);
                                if(tmp<this.offset) {
                                    this.offset--;
                                };
                            };
                            this.repaint();
                        };
                    };
                    if(vkey==VK_RIGHT) { // SHIFT + KEY RIGHT
                        if (this.edit) {
                            if(!this.select) {
                                this.anchor = this.Cpos;
                                if (this.Cpos < this.text.length) {
                                    this.SelBegin = this.Cpos;
                                    this.Cpos++;
                                    this.SelEnd = this.Cpos;
                                    this.select = true;
                                };
                            }; else {
                                if (this.Cpos < this.text.length) {
                                    if(this.anchor<this.Cpos) {
                                        this.SelEnd++;
                                    }; else if(this.anchor>this.Cpos){
                                        this.SelBegin++;
                                    };
                                    this.Cpos++;
                                };
                            };
                            
                            // handle scroll text on cursor selection
                            var tmp_x = this.GetCx(this.Cpos);
                            if(tmp_x > (this.w - this.right_margin)) {
                                this.offset++;
                            };
                            this.repaint();
                        };
                    };
                    break;
                case KMask.ctrl:
                    if(vkey==65) { // CTRL+A
                        if(this.edit && this.text.length>0) {
                            this.SelBegin = 0;
                            this.SelEnd = this.text.length;
                            this.text_selected = this.text;
                            this.select = true;
							this.repaint();
                        };
                    };
                    if(vkey==67) { // CTRL+C
                        if(this.edit && this.select) {
                            cInputbox.doc.parentWindow.clipboardData.setData("Text", this.text_selected);
                        };
                    };
                    if(vkey==88) { // CTRL+X
                        if(this.edit && this.select) {
                            //save text avant MAJ
                            this.stext = this.text;
                            //
                            cInputbox.doc.parentWindow.clipboardData.setData("Text", this.text_selected);
                            var p1 = this.SelBegin;
                            var p2 = this.SelEnd;
                            this.select = false;
                            this.text_selected = "";
                            this.Cpos = this.SelBegin;
                            this.SelEnd = this.SelBegin;
                            this.text = this.text.slice(0, p1) + this.text.slice(p2);
                            this.CalcText();
                            this.repaint();
                        };
                    };
                    if(vkey==90) { // CTRL+Z (annulation saisie)
                        if(this.edit) {
                            this.text = this.stext;
                            this.repaint();
                        };
                    };
                    if(vkey==86) { // CTRL+V
                        cInputbox.clipboard = cInputbox.doc.parentWindow.clipboardData.getData("Text");
                        if(this.edit && cInputbox.clipboard) {
                            //save text avant MAJ
                            this.stext = this.text;
                            //
                            if(this.select) {
                                var p1 = this.SelBegin;
                                var p2 = this.SelEnd;
                                this.select = false;
                                this.text_selected = "";
                                this.Cpos = this.SelBegin;
                                this.SelEnd = this.SelBegin;
                                if(this.Cpos < this.text.length) {
                                    this.text = this.text.slice(0, p1) + cInputbox.clipboard + this.text.slice(p2);
                                }; else {
                                    this.text = this.text + cInputbox.clipboard;
                                };
                                this.Cpos += cInputbox.clipboard.length;
                                this.CalcText();
                                this.repaint();
                            }; else {
                                if(this.Cpos>0) { // cursor pos > 0
                                    this.text = this.text.substring(0, this.Cpos) + cInputbox.clipboard + this.text.substring(this.Cpos, this.text.length);
                                }; else {
                                    this.text = cInputbox.clipboard + this.text.substring(this.Cpos, this.text.length);
                                };
                                this.Cpos += cInputbox.clipboard.length;
                                this.CalcText();
                                this.repaint();
                            };
                        };
                    };
                    break;
            };
        };
        
        // autosearch: has text changed after on_key or on_char ?
		if(this.autovalidation) {
			if(this.text != this.prev_text) {           
				// launch timer to process the search
				gfunc_launch_timer && window.ClearTimeout(gfunc_launch_timer);
				gfunc_launch_timer = window.SetTimeout(function() {
					eval(gfunc);
					gfunc_launch_timer && window.ClearTimeout(gfunc_launch_timer);
					gfunc_launch_timer = false;
				}, 500);
				this.prev_text = this.text;
			};
        };
    };

    this.on_char = function (code, mask) {       
    	if (code == 1 && this.edit && mask == KMask.ctrl) {           
    		this.Spos = 0;
    		this.Cpos = this.text.length;
    		this.select = true;
    		this.repaint();
    	};
    	if (code > 31 && this.edit) {
            //save text before update
            this.stext = this.text; 
    		if (this.select) {
    			var p1 = this.SelBegin;
    			var p2 = this.SelEnd;
                this.text_selected = "";
                this.Cpos = this.SelBegin;
                this.SelEnd = this.SelBegin;
    		}; else {
    			var p1 = this.Cpos;
    			var p2 = (this.text.length - this.Cpos) * -1;
    		};
            if(this.Cpos < this.text.length) {
                this.text = this.text.slice(0, p1) + String.fromCharCode(code) + this.text.slice(p2);
            }; else {
                this.text = this.text + String.fromCharCode(code);
            };
            this.Cpos++;
            if(this.select) {
                this.CalcText();
                if(this.TWidth<=(this.w)) {
                    this.offset = 0;
                }; else {
                    if(this.Cpos-this.offset<0) {
                        this.offset = this.offset>0 ? this.Cpos - 1 : 0;
                    };
                };
                this.select = false;
            };
            this.repaint();
    	};
        
        // autosearch: has text changed after on_key or on_char ?
		if(this.autovalidation) {
			if(this.text != this.prev_text) {                      
				// launch timer to process the search
				gfunc_launch_timer && window.ClearTimeout(gfunc_launch_timer);
				gfunc_launch_timer = window.SetTimeout(function() {
					eval(gfunc);
					gfunc_launch_timer && window.ClearTimeout(gfunc_launch_timer);
					gfunc_launch_timer = false;
				}, 500);
				this.prev_text = this.text;
			};
        };
    };
};
