Ext.define("IceCap.component.Marker", {

	xtype: "icecap-marker",

	alias: [
		"widget-icecap-marker"
	],

	extend: "Ext.Component",

	hidden: true,

	width: "99%",

	height: "99%",

	config: {
		inUse:  false,
		xValue: 0,
		yValue: 0
	},

	listeners: {
		afterrender: {
			fn: function(i_marker) {

				i_marker.update();
			}
		},
		show: {
			fn: function(i_marker) {

				i_marker.update();
			}
		}
	},

	renderTpl: [
		"<div id=\"{id}-outer\" data-ref=\"outerEl\" ",
			"style=\"",
			"width:100%;",
			"height:100%;",
			"background-color:transparent;",
			"pointer-events: none;",
		"\">",
			"<div id=\"{id}-body\" data-ref=\"bodyEl\" ",
				"style=\"",
				"width:100%;",
				"height:100%;",
				"background-color:transparent;",
			"\">",
				"<div id=\"{id}-frameBody\" data-ref=\"frameBody\">",
						"<div id=\"{id}-markerVertical\" class=\"icecap-marker-vertical-{ui}\" data-ref=\"markerVertical\" ",
							"style=\"",
							"width: 0px;",
							"height: 100%;",
							"top: 0px;",
							"left: 0px;",
							"clear: Both;",
						"\"></div>",
						"<div id=\"{id}-markerHorizontal\" class=\"icecap-marker-horizontal-{ui}\" data-ref=\"markerHorizontal\" ",
							"style=\"",
							"height: 0px;",
							"width: 100%;",
							"top: 0px;",
							"left: 0px;",
						"\"></div>",
				"</div>",
			"</div>",
		"</div>"
	],

	childEls: [
		{
			name: "outerEl",
			itemId: "outer"
		},
		{
			name: "frameBody",
			itemId: "frameBody"
		},
		{
			name: "markerVerticalEl",
			itemId: "markerVertical"
		},
		{
			name: "markerHorizontalEl",
			itemId: "markerHorizontal"
		},

	],

	constructor: function(o_config) {

		var i_self = this;

		i_self.callParent(arguments);
	},

	updateInUse: function(value) {

		var i_self = this;

		i_self[value ? "show" : "hide"]();

		i_self.fireEvent(value ? "show" : "hide", i_self);
	},

	updateXValue: function(value) {

		var i_self = this;

		if (i_self.rendered) {

			var i_markerVertical = i_self.markerVerticalEl;
			i_markerVertical.setLeft(value);
		}
	},

	updateYValue: function(value) {

		var i_self = this;

		if (i_self.rendered) {

			var i_markerHorizontal = i_self.markerHorizontalEl;
			i_markerHorizontal.setTop(value);
		}
	},

	update: function() {

		var i_self = this;

		var n_x = i_self.getXValue();
		var n_y = i_self.getYValue();

		i_self.updateXValue(n_x);
		i_self.updateYValue(n_y);
	},

	move: function(a_position) {

		var i_self = this;

		i_self.setXValue(a_position[0]);
		i_self.setYValue(a_position[1]);
	},

	toggle: function() {

		var i_self = this;

		var b_InUse = i_self.getInUse();

		i_self.setInUse(!b_InUse);
	}
});
Ext.define("IceCap.component.Cursor", {

	xtype: "icecap-cursor",

	alias: [
		"widget-icecap-cursor"
	],

	extend: "Ext.Component",

	hidden: true,

	width: 9,

    height: 0,

    baseCls: Ext.baseCSSPrefix + "icecap-cursor",

	config: {
		inUse:  false,
		xValue: 0,
        yValue: 0,
        theme: "default"
	},

	listeners: {
        beforerender: {
            fn: function (i_cursor) {

                var i_self = this;

                var o_data = i_self.renderData || i_self.data || {};



                Ext.applyIf(o_data, {
                    width: i_self.width
                });

                i_self.renderData = i_self.data = o_data;
            }
        },
		afterrender: {
			fn: function(i_cursor) {

				i_cursor.update();
			}
		},
		show: {
			fn: function(i_cursor) {

				i_cursor.update();
			}
		}
	},

	renderTpl: [
        "<span id=\"{id}-cursor\" role=presentation data-ref=\"cursorEl\"",
        "style=\"",
            "width:{width}px;",
			"position: absolute !important;",
        "\">",
        "</span>"
	],

	childEls: [
		{
            name: "cursorEl",
            itemId: "cursor"
		},
    ],

	constructor: function(o_config) {

		var i_self = this;

        i_self.callParent(arguments);
    },

    initComponent: function() {

        var i_self = this;
        i_self.cls = ["iceCap-cursor", i_self.getTheme()].filter(Boolean).join("-");
    },

	updateInUse: function(value) {

		var i_self = this;

		i_self[value ? "show" : "hide"]();
	},

	updateXValue: function(value) {

		var i_self = this;

		if (i_self.rendered) {
            i_self.setLocalX(value);
		}
	},

	updateYValue: function(value) {

		var i_self = this;

		if (i_self.rendered) {

            i_self.setLocalY(value);
		}
	},

	update: function() {

		var i_self = this;

		var n_x = i_self.getXValue();
		var n_y = i_self.getYValue();

		i_self.updateXValue(n_x);
		i_self.updateYValue(n_y);
	},

	move: function(a_position) {

		var i_self = this;

		i_self.setXValue(a_position[0]);
		i_self.setYValue(a_position[1]);
	},

	toggle: function() {

		var i_self = this;

		var b_InUse = i_self.getInUse();

		i_self.setInUse(!b_InUse);
	}
});
Ext.define("IceCap.component.Input", {

    xtype: "icecap-input",

    alias: [
        "widget-icecap-input"
    ],

    mixins: {
        field: "Ext.form.field.Field"
    },

    extend: "Ext.Component",

    baseCls: Ext.baseCSSPrefix + "field",

    height: 24,

    width: 100,

    maxLength: 0,

    maskRe: "",

    validator: null,

    validateOnChange: true,

    allowBlank: true,

    renderTpl: [
        "<input id=\"{id}-input\"",
            "role=\"textbox\"",
            "type=\"text\"",
            "data-ref=\"inputEl\" ",
            "isInputField=true ",
            "<tpl if=\"readOnly\">",
                "readonly={readOnly} ",
            "</tpl>",
            "<tpl if=\"maxLength\">",
                "maxlength={maxLength} ",
            "</tpl>",
            "<tpl if=\"inputAttrTpl\">",
                " {inputAttrTpl} ",
            "</tpl>",
            "<tpl if=\"value\"> value=\"{[Ext.util.Format.htmlEncode(values.value)]}\"</tpl>",
            "class=\"x-form-text-{ui} x-form-trigger-wrap-icecap-field icecap-inputEl {inputCls}\"",
            "style=\"{style}",
        "\"></input>"
    ],

    childEls: [
        {
            name: "inputEl",
            itemId: "input"
        },
    ],

    listeners: {
        afterrender: {
            fn: function() {

                var i_self = this;
                var i_inputEl = i_self.inputEl;

                i_inputEl.on({
                    focus: {
                        fn: function() {
                            i_inputEl.addCls("x-form-trigger-wrap-focus");
                        }
                    },
                    blur: {
                        fn: function () {
                            i_inputEl.removeCls("x-form-trigger-wrap-focus");
                        }
                    },
                    input: {
                        fn: function(i_event) {
                            i_self.checkChange();
                        }
                    },
                    keyup: {
                        fn: function(i_event) {
                            i_self.fireEvent("keyup", i_self, i_event);
                        }
                    },
                    keypress:  {
                        fn: function(i_event) {

                            if ((i_event.ctrlKey && !i_event.altKey) || i_event.isSpecialKey()) {
                                return;
                            }

                            if (i_self.maskRe) {
                                var s_key = i_event.event.key;
                                if (!i_self.maskRe.test(s_key)) {
                                    i_event.stopEvent();
                                }
                                else {
                                    i_self.fireEvent("keypress", i_self, i_event);
                                }
                            }
                            else {
                                i_self.fireEvent("keypress", i_self, i_event);
                            }
                        }
                    },
                    keydown: {
                        fn: function (i_event) {

                            var s_key = i_event.event.key;
                            
                            if (i_event.keyCode < 112 || i_event.keyCode > 123) {
                                if (i_self.maskRe) {
                                    if (!i_event.isSpecialKey() && !i_self.maskRe.test(s_key)) {
                                        if (!i_event.ctrlKey && s_key != "v") {
                                            i_event.stopEvent();
                                        }
                                        else {
                                            i_self.fireEvent("keydown", i_self, i_event);
                                        }
                                    }
                                    else {
                                        i_self.fireEvent("keydown", i_self, i_event);
                                    }
                                }
                                else {
                                    i_self.fireEvent("keydown", i_self, i_event);
                                }
                            }
                        }
                    },
                });
            }
        },
        beforerender: {
            fn: function () {

                var i_self = this;

                var o_data = i_self.renderData || i_self.data || {};

                var o_style = i_self.fieldStyle || i_self.style || {};

                Ext.apply(o_style, {
                    height: "100%",
                    display: "block",
                    width: "100%",
                    overflow:"hidden"
                });

                var a_style = [];

                Ext.Object.each(o_style, function(s_key, value) {
                    a_style.push(s_key +":" + value);
                });


                Ext.applyIf(o_data, {
                    width: i_self.width || 100,
                    height: i_self.height || 30,
                    maxLength: i_self.maxLength || 0,
                    value: i_self.value,
                    style: a_style.join(";"),
                    inputAttrTpl: i_self.inputAttrTpl,
                    ui: i_self.ui,
                    readOnly: i_self.readOnly,
                    inputCls: i_self.inputCls || ""
                });

                i_self.renderData = i_self.data = o_data;
            }
        },
        keypress: {
            fn: function (i_field, i_event) {

                var i_self = this;

                var s_modified = i_self.getModified();

                var a_split = s_modified.split("");

                if (i_event.keyCode == Ext.event.Event.BACKSPACE) {
                    a_split.pop();
                }
                else if (i_event.key == Ext.event.Event.DELETE) {
                    a_split.shift();
                }
                else {
                    if (!i_event.isSpecialKey()) {
                        var s_key = i_event.event.key;
                        a_split.push(s_key);
                    }
                }

                s_modified = a_split.join("");

                i_self.setModified(s_modified);
            }
        },
        keydown: {
            fn: function(i_field, i_event) {

                var i_self = this;

                var s_modified = i_self.getModified();

                var a_split = s_modified.split("");

                if (i_event.keyCode == Ext.event.Event.BACKSPACE) {
                    a_split.pop();
                }
                else if (i_event.key == Ext.event.Event.DELETE) {
                    a_split.shift();
                }
                else {
                    if (!i_event.isSpecialKey()) {
                        var s_key = i_event.event.key;
                        a_split.push(s_key);
                    }
                }

                s_modified = a_split.join("");

                i_self.setModified(s_modified);
            }
        },
        focus: {
            fn: function (i_field) {

                if (i_field.readOnly) {
                    if (i_field.selectOnFocus) {
                        i_field.inputEl.dom.select();
                    }
                }
            },
            buffer: 10
        }
    },

    config: {
        modified: ""
    },

    constructor: function () {

        var i_self = this;

        i_self.callParent(arguments);
    },

    initComponent: function () {

        var i_self = this;

        i_self.initField();
        i_self.xtypesMap.field = true;
    },

    getValue: function() {

        var i_self = this;

        var value = i_self.mixins.field.getValue.call(i_self);

        if (i_self.inputEl) {
            value = i_self.inputEl.getValue();
        }

        return value;
    },

    setValue: function (value) {

        var i_self = this;

        i_self.mixins.field.setValue.call(i_self, value);

        if (i_self.inputEl) {
            i_self.inputEl.dom.value = value;
        }

        return value;
    },

    getFocusEl: function() {

        var i_self = this;
        var i_element;

        if (i_self.inputEl) {
            i_element = i_self.inputEl;
        }

        return i_element;
    },

    isDirty: function() {

        var i_self = this;
        var b_fieldDirty = i_self.mixins.field.isDirty.call(i_self);

        if (!b_fieldDirty) {
            b_fieldDirty = !Ext.isEmpty(i_self.getModified(), false);
        }

        return b_fieldDirty;
    },

    isValid: function() {

        var i_self = this;
        var value = i_self.getValue();

        var b_isValid = !i_self.disabled;

        var a_errors = [];

        if (!i_self.allowBlank) {
            b_isValid = value.length > 0;

            if (!b_isValid) {
                a_errors.push("This field must not be empty");
            }
        }

        a_errors = a_errors.concat(i_self.getErrors(value));

        b_isValid = i_self.disabled || Ext.isEmpty(a_errors);

        if (!i_self.disabled) {
            if (!i_self.preventMark) {
                if (b_isValid) {
                    i_self.clearInvalid();
                } else {
                    i_self.markInvalid(a_errors);
                }
            }
        }
        else {
            i_self.clearInvalid();
        }

        return i_self.disabled || b_isValid;
    },

    getErrors: function(value) {

        var i_self = this;
        var a_errors = [];

        value = value || i_self.getValue();

        var f_validator = i_self.validator;
        var s_error = "";

        if (Ext.isFunction(f_validator)) {

            s_error = f_validator.call(i_self, value);
            
            if (s_error) {
                a_errors.push(s_error);
            }
        }

        return a_errors;
    },

    markInvalid: function(a_errors) {

        var i_self = this;
        var i_inputEl = i_self.inputEl;

        if (i_inputEl) {
            i_inputEl.addCls("x-form-trigger-wrap-function-field x-form-trigger-wrap-invalid");

            var i_template = Ext.create("Ext.XTemplate",
                "<ul>",
                    "<tpl for=\".\">",
                        "<li>{.}</li>",
                    "</tpl>",
                "</ul>"
            );

            var s_tip = i_template.apply(a_errors);

            i_inputEl.dom.setAttribute("data-qtip", s_tip);
        }
        else {
            var s_inputCls = i_self.inputCls;

            if(s_inputCls) {
                var a_cls = [
                    s_inputCls,
                    "x-form-trigger-wrap-function-field x-form-trigger-wrap-invalid"
                ];

                s_inputCls = a_cls.join(" ");
            }
            else {
                s_inputCls = "x-form-trigger-wrap-function-field x-form-trigger-wrap-invalid";
            }

            i_self.inputCls = s_inputCls;
        }
    },

    clearInvalid: function() {
        
        var i_self = this;
        var i_inputEl = i_self.inputEl;

        if (i_inputEl) {
            i_inputEl.removeCls("x-form-trigger-wrap-function-field x-form-trigger-wrap-invalid");
            i_inputEl.addCls("x-form-trigger-wrap-icecap-field");
            i_inputEl.dom.removeAttribute("data-qtip");
        }
    }

});
Ext.define("IceCap.component.Selector", {

    xtype: "icecap-selector",

    autoEl: {
        tag: "span"
    },

    alias: [
        "widget-icecap-selector"
    ],

    extend: "Ext.Component",

    hidden: true,

    baseCls: Ext.baseCSSPrefix + "icecap-selector",

    draggable: {
        listeners: {
            beforedragstart: {
                fn: function (i_dragSoruce, i_event) {

                    var i_self = i_dragSoruce.comp;

                    var i_resizer = i_self.getResizer();

                    var a_handles = [
                        "n",
                        "s",
                        "e",
                        "w",
                        "nw",
                        "sw",
                        "se",
                        "ne"
                    ];

                    var b_within = true;

                    Ext.Array.each(a_handles, function (s_handle) {

                        var i_el;

                        switch (s_handle) {
                            case "s":
                                i_el = i_resizer.south;
                                break;
                            case "se":
                                i_el = i_resizer.southeast;
                                break;
                            case "sw":
                                i_el = i_resizer.southwest;
                                break;
                            case "e":
                                i_el = i_resizer.east;
                                break;
                            case "w":
                                i_el = i_resizer.west;
                                break;
                            case "n":
                                i_el = i_resizer.north;
                                break;
                            case "nw":
                                i_el = i_resizer.northwest;
                                break;
                            case "ne":
                                i_el = i_resizer.northeast;
                                break;
                        }

                        if (i_event.within(i_el)) {
                            b_within = false;
                        }
                    });

                    return b_within;
                }
            },
            dragend: {
                fn: function (i_dragSoruce, i_event) {

                    var i_self = i_dragSoruce.comp;

                    var i_region = i_self.getBox(false, true);

                    i_self.suspendEvent();

                    i_self.setLeft(Math.floor(i_region.left));
                    i_self.setTop(Math.floor(i_region.top));
                    i_self.setDragX(Math.floor(i_region.right));
                    i_self.setDragY(Math.floor(i_region.bottom));

                    i_self.resumeEvent();
                }
            }
        }
    },

    listeners: {
        removed: {
            fn: function() {

                var i_self = this;

                var i_resizer = i_self.getResizer();

                if (i_resizer) {
                    i_resizer.destroy();
                }
            }
        },
        beforerender: {
            fn: function () {

                var i_self = this;

                var o_data = i_self.renderData || i_self.data || {};

                Ext.applyIf(o_data, {
                    width: i_self.width || 0,
                    height: i_self.height || 0,
                });

                i_self.renderData = i_self.data = o_data;
            }
        },
        dragcomplete: {
            fn: function() {

                var i_self = this;

                var i_resizer = i_self.getResizer();

                if (!i_resizer) {

                    i_resizer = Ext.create("Ext.resizer.Resizer", {
                        target: i_self.getEl().dom,
                        transparent: true,
                        pinned: true,
                        handles: "all",
                        heightIncrement: IceCap.util.Handler.getHeight(),
                        widthIncrement: IceCap.util.Handler.getWidth(),
                        listeners: {
                            resize: {
                                fn: function() {

                                    var i_region = i_self.getBox(false, true);

                                    i_self.suspendEvent();

                                    i_self.setLeft( Math.floor(i_region.left));
                                    i_self.setTop( Math.floor(i_region.top));
                                    i_self.setDragX( Math.floor(i_region.right));
                                    i_self.setDragY( Math.floor(i_region.bottom));

                                    i_self.resumeEvent();
                                }
                            }
                        }
                    });

                    i_self.setResizer(i_resizer);
                }
            }
        }
    },

    renderTpl: [
        "<span id=\"{id}-selector\" class=\".icecap-selector\" draggable=false role=presentation data-ref=\"selectorEl\">",
        "</span>"
    ],

    childEls: [
        {
            name: "selectorEl",
            itemId: "selector"
        },
    ],

    config: {
        top: 0,
        left: 0,
        selecting: false,
        theme: "",
        dragX: 0,
        dragY: 0,
        dragSource: null,
        resizer: null
    },

    floating: true,

    alwaysOnTop: true,

    initComponent: function () {

        var i_self = this;
        i_self.cls = ["iceCap-selector", i_self.getTheme()].filter(Boolean).join("-");

        i_self.callParent(arguments);
    },

    updateSelecting: function(b_selecting) {

        var i_self = this;

        if (i_self.rendered) {
            i_self.calculateArea();
            if (b_selecting) {
                i_self.show();
            }
        }
    },

    updateLeft: function(value) {

        var i_self = this;

        if (i_self.rendered) {

            i_self.setLocalX(value);
        }
    },

    updateTop: function(value) {

        var i_self = this;

        if (i_self.rendered) {

            i_self.setLocalY(value);
        }
    },

    updateDragX: function(value) {

        var i_self = this;

        if (i_self.rendered) {
            i_self.calculateArea();
        }
    },

    updateDragY: function(value) {

        var i_self = this;

        if (i_self.rendered) {
            i_self.calculateArea();
        }
    },

    calculateArea: function() {

        var i_self = this;

        var n_left = i_self.getLeft();
        var n_top = i_self.getTop();

        var n_dragX = i_self.getDragX();
        var n_dragY = i_self.getDragY();

        var n_xMin = Math.min(n_left, n_dragX);
        var n_xMax = Math.max(n_left, n_dragX);

        var n_yMin = Math.min(n_top, n_dragY);
        var n_yMax = Math.max(n_top, n_dragY);


        var n_width = Math.ceil(n_xMax - n_xMin);
        var n_height = Math.ceil(n_yMax - n_yMin);

        if (i_self.getSelecting()) {

            i_self.setLocalXY([n_xMin, n_yMin]);
        }

        i_self.setSize(n_width, n_height);
    },

    resetPos: function(n_x, n_y) {

        var i_self = this;
        i_self.setSelecting(false);
        i_self.setLeft(n_x);
        i_self.setTop(n_y);
        i_self.setDragX(n_x);
        i_self.setDragY(n_y);
    }
});
if (Ext.ClassManager.aliasToName["widget.webcontainer"] == null) {
	Ext.define("IceCap.view.WebContainer", {

		extend: "Ext.Component",

		xtype: "icecap-webcontainer",

		alias: [
			"widget.icecap.view.webcontainer",
			"widget.webcontainer"
		],

		config: {
			src: ""
		},

		autoEl: {
			tag: "iframe",
			style: "height: 100%; width: 100%; border: none;",
			src: ""
		},

		listeners: {
			render: {
				fn: function (i_self) {

					var i_element = i_self.getEl();

					if (i_element) {
						i_element.dom.src = i_self.getSrc();
						i_self.setLoading(true);
					}
				}
			},
			load: {
				element: "el",
				fn: function (i_element) {

					var i_self = this.component;
					i_self.setLoading(false);
				}
			}
		},

		initComponent: function () {

			var i_self = this;
			i_self.callParent(arguments);
		},

		updateSrc: function (s_url) {

			var i_self = this;
			var i_element = i_self.getEl();

			if (i_element) {
				i_element.dom.src = s_url;
				i_self.setLoading(true);
			}
		}
	});
}


Ext.define("IceCap.util.Watchdog", {

    singleton: true,

    config: {
        socket: null
    },

    constructor: function (o_config) {

        var i_self = this;
        i_self.initConfig(o_config);

        var i_location = window.location;
        try {

            var s_protocol = location.protocol;

            var s_path = "ws://";

            if (s_protocol.indexOf("https") > -1) {
                s_path = "wss://";
            }

            var i_websocket = new WebSocket(s_path + i_location.host + "/icecap/watchdog/ping");

            i_self.setSocket(i_websocket);

            i_websocket.onmessage = function (i_event) {
                i_self.onMessage(i_event.data);
            };

            i_websocket.onopen = function (i_event) {
                i_self.onOpen(i_event);
            };

            var i_window = Ext.getWin();

            i_window.on({
                close: function () {
                    i_websocket.close();
                }
            });
        }
        catch(err) {
            console.log(err);
        }

    },

    onMessage: function(o_data) {

        var i_self = this;

        Ext.defer(i_self.ping, 5000, i_self);
    },

    onOpen: function () {

        var i_self = this;
        Ext.defer(i_self.ping, 5000, i_self);
    },

    ping: function() {

        var i_self = this;

        var i_websocket = i_self.getSocket();

        var i_provider = IceCap.util.Handler.getProvider();

        var a_terminals = Ext.Array.from(i_provider.get("activeterminals"));
        var a_sessions = IceCap.util.Handler.getSessions();

        i_websocket.send(JSON.stringify({
            "activeTerminals": a_terminals,
            "sessions": a_sessions
        }));
    },
})

Ext.define("IceCap.util.Scale", {

	singleton: true,

	config: {
		fixed: null,
		free: null
	},

	constructor: function(o_config) {

		var i_self = this;
		i_self.initConfig(o_config);

		i_self.setFixed({
			"16": {
				"textSize": 16,
				"colSize": 9.7,
				"defaultWidth": 18,
				"defaultHeight": 24,
				"lineHeight": 28
			},
			"15": {
				"textSize": 15,
				"colSize": 9.1,
				"defaultWidth": 17,
				"defaultHeight": 22,
				"lineHeight": 26
			},
			"14": {
				"textSize": 14,
				"colSize": 8.45,
				"defaultWidth": 17,
				"defaultHeight": 20,
				"lineHeight": 24
			},
			"13": {
				"textSize": 13,
				"colSize": 7.9,
				"defaultWidth": 15,
				"defaultHeight": 19,
				"lineHeight": 22
			},
			"12": {
				"textSize": 12,
				"colSize": 7.4,
				"defaultWidth": 14,
				"defaultHeight": 17,
				"lineHeight": 20
			},
			"11": {
				"textSize": 11,
				"colSize": 6.8,
				"defaultWidth": 13,
				"defaultHeight": 15,
				"lineHeight": 18
			}
		});

		i_self.setFree({
			"14": {
				"textSize": 13,
				"colSize": 12.2,
				"defaultWidth": 20,
				"defaultHeight": 20,
				"lineHeight": 24
			}
		});
	}
});
Ext.define("IceCap.util.Breakout", {

	alternateClassName: [
		"IceCap.breakout"
	],

	singleton: true,

	constructor: function(o_config) {

		var i_self = this;
		i_self.initConfig(o_config);
	},

	googleMap: function(o_data) {

		var i_self = this;

		o_data = o_data || {};

		if (s_title.toLowerCase() == "work with customers") {

			var s_url = "http://www.icebreak.org/geoCoding.html";

			var o_params = {
				address: "dk" + o_data.c5 + "," + o_data.c4
			};

			s_url = s_url + "?" + Ext.Object.toQueryString(o_params);

			Ext.GlobalEvents.fireEvent(i_self, "onAddWebContainer", {
				url: s_url
			});
		}
	},

	krak: function(o_data) {

		var i_self = this;

		o_data = o_data || {};

		if (s_title.toLowerCase() == 'work with customers') {

			var s_url = 'http://www.krak.dk/'
					+ o_data.c3.replace(' ', '+')
					+ '/'
					+ o_data.c4.replace(' ', '+')
					+ '+'
					+ o_data.c5
					+ '/søg.cs';

			Ext.GlobalEvents.fireEvent(i_self, "onAddWebContainer", {
				url: s_url
			});
		}
	}
});
Ext.define("IceCap.controller.Window", {
	extend: "Ext.app.ViewController",

	alias: "controller.icecap.view.window",

	onSendData: function(o_config, o_data) {

		var i_controller = this;
		var o_saved = Ext.clone(o_config);
		var i_view = i_controller.getView();
		var s_session = i_view.getSessionValue();

		var o_options = i_view.getOptions();

		o_data = Ext.apply(o_data, {
			i18nLearning: false
		});

		Ext.apply(o_config, {
			session: s_session,
			translateMode: i_view.getEdit()
		});

		Ext.apply(o_config, o_options);

		if (!i_view.getWorking()) {
			i_view.setWorking(true);
			i_view.doTimer();
			IceCap.util.Handler.getData(o_config, o_data, function(o_inputData) {

				if (o_inputData.statusUpdate) {

					i_view.setWorking(false);
					i_view.updateMessage(o_inputData);
					if (o_inputData.status > -1) {
						i_view.doCreateFromData(o_inputData);
					}
					i_controller.onSendData(o_saved, o_data);
				}
				else {

					i_view.setLoading(false);
					i_view.cancelTimer();

					var f_callback = i_view.getResponseCallBack() || Ext.emptyFn;

					if (f_callback != Ext.emptyFn) {

						f_callback(o_inputData);
					}

					var o_plugin = o_inputData.plugin || Ext.apply({}, {
						require: []
					});

					var a_require = o_plugin.require || [];
					var s_run = o_plugin.run || "";

					i_controller.doRequire(a_require, function() {

						if (s_run) {
							eval(s_run);
						}

						if (o_inputData.close) {
							i_view.fireEvent("applicationClose", true);
						}
						else {

							i_view.setWorking(false);
							i_view.doCreateFromData(o_inputData);
						}
					});
				}
			});
		}
	},

	onWheel: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();

		var b_hasGrid = i_view.query("gridpanel").length > 0;
		var b_mappanel = i_view.query("icecap-gmappanel").length > 0;

		var n_delta = i_event.getWheelDelta();
		var s_event = "";

		if (n_delta > 0) {
			s_event = "ROLLDOWN";
		}
		else {
			s_event = "ROLLUP";
		}

		if (!b_hasGrid && !b_mappanel && !i_event.ctrlKey) {
			i_controller.doKeyEvent(s_event);
		}
	},

	onDblClick: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var i_cursor = i_view.getCursor();

		var o_rules = i_view.getCssRules();

		var i_content = i_view.getContent();
		var i_region = i_content.getRegion(true, false);

		var b_fireEvent = i_view.getEnterOnDblClick();

		var o_click = Ext.apply({
			x: i_event.pageX - i_region.x,
			y: i_event.pageY - i_region.y
		});

		var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

		if (b_fireEvent) {

			var i_currentField = i_view.getCurrentField();

			if (i_currentField) {
				o_position = Ext.apply(o_position, {
					lin: i_currentField.lin,
					col: i_currentField.col
				});
				if (i_currentField.inputEl && i_currentField.getValue()) {
					o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);
				}
			}
			else {
				i_cursor.moveCursor(o_position);
				i_cursor.show();
			}

			i_view.setCurrentPosition(o_position);
			i_controller.doKeyEvent("ENTER");
		}
		else {

			var n_x = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
			var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

			var o_rect = Ext.apply(o_click, {
				x: n_x,
				y: n_y,
				width: IceCap.util.Handler.getWidth(1, o_rules.fontScale),
				height: IceCap.util.Handler.getHeight(1, o_rules.lineScale),
				left: n_x,
				right: n_x+  IceCap.util.Handler.getWidth(1, o_rules.fontScale),
				top: n_y,
				bottom: n_y + IceCap.util.Handler.getHeight(1, o_rules.lineScale)
			});

			var a_labels = IceCap.util.Handler.getLabels(i_view);

			Ext.Array.each(a_labels, function(i_label) {

				var i_labelRegion = i_label.getRegion(false, true);

				if (i_labelRegion.intersect(o_rect)) {

					var i_selector = i_view.getSelector();

					var o_labelPos = IceCap.util.Handler.toColAndLine(i_labelRegion, o_rules);

					var n_x = IceCap.util.Handler.getX(o_labelPos.col - 1, o_rules.fontScale);
					var n_y = IceCap.util.Handler.getY(o_labelPos.lin + 1, o_rules.lineScale);

					var a_split = i_label.el.dom.innerText.split(" ");

					var i_result;

					var n_posCol = 0;

					Ext.Array.each(a_split, function(s_word) {

						var n_wordX = i_labelRegion.x + IceCap.util.Handler.getX(n_posCol, o_rules.fontScale);
						var n_wordY = i_labelRegion.y;

						var i_wordRegion = Ext.util.Region.create();

						if(/[\/]/g.test(s_word)) {

							var a_temp = s_word.split(/[\/]/g);

							Ext.Array.each(a_temp, function(s_temp) {

								n_wordX = i_labelRegion.x + IceCap.util.Handler.getX(n_posCol, o_rules.fontScale);
								n_wordY = i_labelRegion.y

								Ext.apply(i_wordRegion, {
									x: n_wordX,
									y: n_wordY,
									width: IceCap.util.Handler.getWidth(s_temp.length, o_rules.fontScale),
									height: i_label.getHeight(),
									left: n_wordX,
									right: n_wordX +  IceCap.util.Handler.getWidth(s_temp.length, o_rules.fontScale),
									top: n_wordY,
									bottom: n_wordY + i_label.getHeight()
								});

								if (i_wordRegion.intersect(o_rect)) {
									i_result = i_wordRegion;
									return false;
								}

								n_posCol = n_posCol + s_temp.length + 1;
							});

						}
						else {

							Ext.apply(i_wordRegion, {
								x: n_wordX,
								y: n_wordY,
								width: IceCap.util.Handler.getWidth(s_word.length, o_rules.fontScale),
								height: i_label.getHeight(),
								left: n_wordX,
								right: n_wordX +  IceCap.util.Handler.getWidth(s_word.length, o_rules.fontScale),
								top: n_wordY,
								bottom: n_wordY + i_label.getHeight()
							});

							if (i_wordRegion.intersect(o_rect)) {
								i_result = i_wordRegion;
							}

							n_posCol = n_posCol + s_word.length + 1;
						}

						if (i_result) {
							return false;
						}
					});

					var n_dragX = IceCap.util.Handler.getX(o_labelPos.col, o_rules.fontScale);
					var n_dragY = IceCap.util.Handler.getY(o_labelPos.lin + 2, o_rules.lineScale);

					if (i_result) {

						n_x = i_result.x;
						n_y = i_result.y;

						n_dragX = i_result.right;
						n_dragY = i_result.bottom;
					}

					i_selector.resetPos(n_x, n_y);

					i_selector.show();

					i_selector.setSelecting(true);

					i_selector.setDragX(n_dragX);
					i_selector.setDragY(n_dragY);

					i_event.stopEvent();

					return false;
				}
			});
		}
	},

	onClick: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var o_inputData = i_view.getInputData();
		var i_cursor = i_view.getCursor();
		var i_content = i_view.getContent();
		var o_rules = i_view.getCssRules();

		var i_activeComponent = Ext.ComponentManager.getActiveComponent();

		var o_click = Ext.apply({
			x: i_event.pageX - i_content.getX(),
			y: i_event.pageY - i_content.getY() 
		});

		var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

		if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {

			var i_currentField = i_view.getCurrentField();

			var a_metaFields = o_inputData.metaFields || [];

			if (i_currentField) {
				o_position = Ext.apply(o_position, {
					lin: i_currentField.lin,
					col: i_currentField.col
				});
				if (i_currentField.inputEl && i_currentField.getValue()) {
					o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);
				}
			}
			else {

				var a_inputs = IceCap.util.Handler.getInputFields(i_view);

				var n_width = Math.ceil(IceCap.util.Handler.getWidth(1));
				var n_height = 2;

				var o_box = Ext.apply({
					x: IceCap.util.Handler.getX(o_position.col),
					y: IceCap.util.Handler.getY(o_position.lin),
					width: i_cursor.getWidth() || n_width,
					height: i_cursor.getHeight() || n_height,
					right: IceCap.util.Handler.getX(o_position.col) + i_cursor.getWidth(),
					bottom: IceCap.util.Handler.getY(o_position.lin) + i_cursor.getHeight()
				});

				var b_intersect = false;

				Ext.Array.each(a_inputs, function (i_field) {

					var i_element = i_field.getEl();

					if (i_element) {

						var i_region = i_field.getRegion(false, true);

						if (i_region.intersect(o_box)) {

							b_intersect = true;
							i_field.focus(false, 10);

							var n_start = o_position.col - i_field.col;
							var i_inputEl = i_field.inputEl;
							i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = n_start;

							return false;
						}
					}
				});

				if (!b_intersect) {

					if (o_position.col > o_inputData.width) {
						o_position.col = o_inputData.width;
					}

					if (o_position.lin > o_inputData.height) {
						o_position.lin = o_inputData.height;
					}

					i_cursor.moveCursor(o_position);

					i_cursor[a_metaFields.length === 0 ? "show" : "hide"]();
				}
			}
		}

		i_view.setCurrentPosition(o_position);
	},

	doArrowKeys: function (n_direction) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var a_fields = IceCap.util.Handler.getInputFields(i_view);
		var n_tabIndex = i_view.getCurrentTabIndex();

		var i_lastFocus = Ext.ComponentManager.getActiveComponent();

		var n_part = n_direction ? 1 : -1;

		if (i_lastFocus.isXType("field")) {

			var n_next = n_part > 0 ? n_tabIndex + 1 : n_tabIndex - 1;

			var i_found;

			i_found = Ext.Array.findBy(a_fields, function (i_field) {
				return i_field.getTabIndex() === n_next;
			});

			if (!i_found) {
				i_found = n_part > 0 ? a_fields[0] : a_fields[a_fields.length - 1];
			}

			if (i_found) {
				i_found.focus(true, 10);
				n_tabIndex = i_found.getTabIndex();
			}
		}

		i_view.setCurrentTabIndex(n_tabIndex);
	},

	doTabKey: function (n_direction) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var a_fields = IceCap.util.Handler.getInputFields(i_view);
		var n_tabIndex = i_view.getCurrentTabIndex();

		var i_lastFocus = Ext.ComponentManager.getActiveComponent();

		var n_part = n_direction ? 1 : -1;

		if (i_lastFocus.isXType("field")) {

			var n_next = n_part > 0 ? n_tabIndex + 1 : n_tabIndex - 1;

			var i_found;

			i_found = Ext.Array.findBy(a_fields, function (i_field) {
				return i_field.getTabIndex() === n_next;
			});

			if (!i_found) {
				i_found = n_part > 0 ? a_fields[0] : a_fields[a_fields.length - 1];
				n_tabIndex = i_found.getTabIndex();
			}

			if (i_found) {
				i_found.focus(true, 10);
				n_tabIndex = i_found.getTabIndex();
			}
		}
		else {
			var i_field = a_fields[0];
			i_field.focus(true, 10);
			n_tabIndex = i_field.getTabIndex();
		}

		i_view.setCurrentTabIndex(n_tabIndex);
	},

	doKeyEvent: function(s_value) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var o_rules = i_view.getCssRules();

		var i_cursor = i_view.getCursor();

		var o_data = {
			key: s_value
		};

		var o_position = i_view.getCurrentPosition() || {
			col: 1,
			lin: 1
		};

		if (i_cursor && i_cursor.getEl()) {
			o_position = IceCap.util.Handler.toColAndLine({
				x: i_cursor.getLocalX(),
				y: i_cursor.getLocalY()
			}, o_rules);
		}

		var i_content = i_view.getContent();
		var i_form = i_content.getForm();
		var i_collectionField = i_form.getFields();
		var o_values = {};

		Ext.Array.each(i_collectionField.items, function(i_field) {
			if (i_field.isDirty()) {
				var value = i_field.getSubmitValue ? i_field.getSubmitValue() : i_field.getValue();
				o_values[i_field.itemId || i_field.initialConfig.id || i_field.name] = value;
			}
		});

		Ext.Object.each(o_values, function(s_key, value) {
			var s_id = "ses2.win." + s_key;
			o_data[s_id] = value;
		});

		o_data = Ext.apply(o_data, {
			csrLin: o_position.lin,
			csrCol: o_position.col
		});

		var f_callback = i_view.getRequestCallBack() || Ext.emptyFn;

		if (f_callback != Ext.emptyFn) {

			f_callback(o_data);
		}

		i_controller.onSendData({
			func: ""
		}, o_data);
	},

	doFKey: function(s_value) {

		var i_controller = this;

		i_controller.doKeyEvent(s_value);
	},

	doRequire: function(a_require, f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		a_require = a_require || [];

		if (a_require.length > 0) {

			var a_external = Ext.Array.filter(Ext.Array.map(a_require, function(s_value) {
				if (s_value.indexOf("/") > -1) {
					return s_value;
				}
			}), function(value) {
				return value;
			});

			var a_internal = Ext.Array.filter(Ext.Array.map(a_require, function(s_value) {
				if (s_value.indexOf("/") < 0) {
					return s_value;
				}
			}), function(value) {
				return value;
			});

			if (a_external.length > 0) {
				Ext.Loader.loadScriptsSync(a_external);
			}

			if (a_internal.length > 0) {
				Ext.syncRequire(a_internal);
			}
		}

		f_callback();
	}
});
Ext.define("IceCap.view.Window", {

	xtype: "icecap-window",

	extend: "Ext.window.Window",

	layout: "fit",

	requires: [
		"IceCap.controller.Window"
	],

	alias: [
		"widget-icecap-view-window"
	],

	config: {
		inputData: null,
		lastTabIndex: 1,
		currentTabIndex: 1,
		content: null,
		keyArea: null,
		working: false,
		needFocus: 1,
		currentPosition: {
			col: 1,
			lin: 1
		},
		statusBar: null,
		main: null,
		sessionValue: "",
		cursor: null,
		timer: null,
		theme: "",
		requestCallBack: Ext.emptyFn,
		responseCallBack: Ext.emptyFn,
		enterOnDblClick: false,
		marker: null,
		markerActive: false,
		options: {},
		typeMode: 1,
		edit: false,
		level: 1,
		languages: [],
		translator: null,
		activeLanguage: "da",
		selector: null,
		viewArea: null,
		cssRules: null
	},

	closable: false,

	modal: false,

	controller: "icecap.view.window",

	listeners: {
		afterrender: {
			fn: function(i_panel) {

				var i_self = i_panel;

				i_self.addKeyEvents();

				var i_content = i_self.getContent();

				if (i_content) {

					var o_inputData = i_self.getInputData();

					var a_fields = IceCap.util.Handler.getInputFields(i_content);
					var b_found = false;
					var b_error = false;

					Ext.Array.each(a_fields, function(i_field) {
						if (i_field.getTabIndex() === i_self.getNeedFocus()) {
							if (!b_error) {
								setTimeout(function() {
									i_field.focus(false, 10);
								}, 10);
							}
							b_found = true;

							return false;
						}
					});

					if (!b_found) {

						i_self.setCurrentPosition({
							col: 2,
							lin: 1
						});

						if (!b_error) {
							i_self.findFocus();
						}
					}
				}
			},
			buffer: 100
		},
		dblclick: {
			fn: "onDblClick",
			element: "body"
		},
		click: {
			fn: "onClick",
			element: "body"
		},
		wheel: {
			fn: "onWheel",
			element: "body"
		},
		fieldoption: {
			fn: function(a_config) {

				var i_self = this;
				var i_controller = i_self.getController();

				var o_data = {};

				Ext.apply(o_data, {
					key: "ENTER"
				});

				Ext.Array.each(a_config, function(o_config) {

					var s_field = o_config.field;

					o_data[s_field] = o_config.option;

					Ext.apply(o_data, {
						csrCol: o_config.col,
						csrLin: o_config.lin
					});
				});

				i_self.setCurrentPosition({
					col: o_data.csrCol,
					lin: o_data.csrLin
				});

				i_controller.onSendData({
					func: ""
				}, o_data);
			}
		},
		key: {
			fn: function(s_value) {

				var i_self = this;
				var i_controller = i_self.getController();

				i_controller.doKeyEvent(s_value);
			}
		}

	},

	onKeyDown: Ext.emptyFn, // THIS IS NEEDED TO OVERRIDE Ext.util.Floating

	initComponent: function() {

		var i_self = this;

		var o_params = Ext.Object.fromQueryString(window.location.search);

		Ext.Object.each(o_params, function(s_key, value) {
			o_params[s_key] = Ext.decode(value, true) || value;
		});

		var o_options = Ext.apply(i_self.options, o_params.options || {});

		Ext.apply(i_self, {
			theme: i_self.theme || o_params.theme || ""
		});

		i_self.callParent(arguments);

		i_self.add(i_self.createLayout());

		i_self.enableBubble([
			"onAddWebContainer",
			"toWindow",
			"applicationClose"
		]);

		i_self.recreate();
	},

	createStatusBar: function () {

		var i_self = this;
		
		var o_rules = i_self.getCssRules();

		var i_translatorButton = Ext.widget("component", {
			itemId: "icecap-translator",
			cls: "pf-gearwheel",
			hidden: false,
			autoEl: {
				tab: "span",
				"data-qtip": "Toggle translation"
			},
			style: {
				"cursor": "pointer"
			},
			listeners: {
				afterrender: {
					fn: function(i_component) {

						var i_element = i_component.getEl();
						var b_edit = i_self.getEdit();

						if (b_edit) {
							i_element.addCls("x-base-color");
						}
						else {
							i_element.removeCls("x-base-color");
						}

						i_component.setStyle("font-size", "calc(1em * " + o_rules.fontScale + ")");

					}
				},
				click: {
					element: "el",
					fn: function () {

						var i_element = this;
						var b_edit = i_self.getEdit();

						b_edit = !b_edit;

						if (b_edit) {
							i_element.addCls("x-base-color");
						}
						else {
							i_element.removeCls("x-base-color");
						}

						i_self.setEdit(b_edit);
					}
				}
			}
		});

		var i_languageButton = Ext.widget("component", {
			itemId: "icecap-language",
			html: i_self.getActiveLanguage(),
			hidden: false,
			autoEl: {
				tab: "span",
				"data-qtip": "Toggle active language"
			},
			style: {
				"cursor": "pointer"
			},
			listeners: {
				afterrender: {
					fn: function (i_component) {

						i_component.setStyle("font-size", "calc(1em * " + o_rules.fontScale + ")");
					}
				},
				click: {
					element: "el",
					fn: function () {

						var i_menu = i_languageButton.menu;

						if (!i_menu) {

							var a_languages = i_self.getLanguages();

							var a_items = [];

							Ext.Array.each(a_languages, function (s_key) {

								var i_menuItem = Ext.widget("menuitem", {
									itemId: s_key,
									text: s_key,
									handler: function (i_item) {

										i_languageButton.setHtml(i_item.text);
										i_self.setActiveLanguage(i_item.text);
									}
								});

								a_items.push(i_menuItem);
							});

							i_menu = Ext.widget("menu", {
								items: a_items
							});

							i_languageButton.menu = i_menu;
						}

						i_menu.show();
						i_menu.alignTo(i_languageButton.getEl(), "bl-tr");

						i_menu.toFront();
					}
				}
			}
		});

		var i_statusbar = Ext.widget("toolbar", {
			ui: "statusbar",
			dock: "bottom",
			hidden: false,
			border: false,
			layout: {
				type: "hbox",
				align: "top"
			},
			defaults: {
				margin: "0 5 0 0"
			},
			height: 30,
			items: [
				{
					xtype: "label",
					itemId: "icecap-message",
					listeners: {
						afterrender: {
							fn: function (i_label) {

								i_label.setStyle("font-size", "calc(1em * " + o_rules.fontScale + ")");

								var i_tpl = Ext.create("Ext.XTemplate",
									"<ul style=\"list-style: none;",
									"margin:10px;",
									"padding:0;",
									"\">",
									"<tpl for=\".\">",
									"<li>{text}</li>",
									"</tpl>",
									"</ul>"
								);

								Ext.create("Ext.tip.ToolTip", {
									target: i_label.getEl(),
									html: "",
									anchor: true,
									defealtAlign: "b50-t50",
									listeners: {
										beforeshow: {
											fn: function (i_tip) {

												var b_hasError = i_label.hasCls("icecap-statusbar-error");

												var o_inputData = i_self.getInputData();

												var a_messages = Ext.Array.from(o_inputData.message);

												if (b_hasError && a_messages.length > 0) {
													var s_value = i_tpl.apply(a_messages);
													i_tip.update(s_value);
												}
												else {
													return b_hasError;
												}
											}
										}
									}
								});
							}
						},
						click: {
							element: "el",
							fn: function (i_event, i_element) {

								var o_input = {
									col: 3,
									lin: 24
								};

								i_self.setCurrentPosition(o_input);

								var i_cursor = i_self.getCursor();
								i_cursor.moveCursor(o_input);

								i_self.doKeyEvent("F1");
							}
						},
					}
				},
				{
					xtype: "tbfill"
				},
				i_languageButton,
				i_translatorButton,
				{
					xtype: "label",
					itemId: "icecap-position",
					listeners: {
						afterrender: {
							fn: function (i_label) {
	
								i_label.setStyle("font-size", "calc(1em * " + o_rules.fontScale + ")");
							}
						}
					}
				},
				{
					xtype: "component",
					autoEl: {
						tab: "span",
						"data-qtip": "Toggle input type"
					},
					style: {
						"cursor": "pointer"
					},
					html: "INS",
					itemId: "icecap-typemode",
					listeners: {
						afterrender: {
							fn: function (i_label) {
	
								i_label.setStyle("font-size", "calc(1em * " + o_rules.fontScale + ")");
							}
						},
						click: {
							element: "el",
							fn: function (i_element) {

								var n_type = i_self.getTypeMode();

								switch (n_type) {
									case IceCap.util.Handler.typeMode.OVERWRITE:
										n_type = IceCap.util.Handler.typeMode.FOCUS;
										break;
									case IceCap.util.Handler.typeMode.FOCUS:
										n_type = IceCap.util.Handler.typeMode.INSERT;
										break;
									default:
										n_type = IceCap.util.Handler.typeMode.OVERWRITE;
										break;
								}

								i_self.setTypeMode(n_type);
							}
						}
					}
				}
			],
			setText: function (s_text) {

				var i_toolbar = this;

				var i_message = i_toolbar.getComponent("icecap-message");

				if (i_message) {
					i_message.setText(s_text);
				}
			}
		});

		i_self.setTranslator(i_translatorButton);

		return i_statusbar;
	},

	createLayout: function() {

		var i_self = this;
		return i_self.createContent();
	},

	createContent: function() {

		var i_self = this;

		var i_panel = Ext.widget("panel", {
			layout: {
				type: "vbox",
				align: "stretch"
			},
			ui: "icecap",
			border: false,
			focusable: true,
			tabIndex: -1,
			items: i_self.createItems()
		});

		i_self.setMain(i_panel);

		var i_statusbar = i_self.createStatusBar();

		i_panel.addDocked(i_statusbar);

		i_self.setStatusBar(i_statusbar);

		var o_inputData = i_self.getInputData();

		i_self.updateMessage(o_inputData);

		return i_panel;
	},

	createItems: function() {

		var i_self = this;

		var a_items = [];

		var i_keyArea = Ext.widget("panel", {
			layout: {
				type: "column"
			},
			border: false,
			focusable: false,
			minHeight: 50,
			height: null,
			defaults: {
				margin: "5 5 0 5"
			},
			ui: "icecap-keyarea",
			cls: ["icecap-panel", i_self.getTheme()].join("-")
		});

		var i_center = Ext.widget("form", {
			border: false,
			layout: "absolute",
			flex: 1,
			ui: ["icecap", i_self.getTheme()].filter(Boolean).join("-"),
			style: {
				"margin-right": "10px"
			}
		});

		a_items.push(i_center);
		a_items.push(i_keyArea);

		i_self.setContent(i_center);
		i_self.setKeyArea(i_keyArea);

		return a_items;
	},

	createFields: function(a_created) {

		var i_self = this;
		var o_inputData = i_self.getInputData();

		var a_fields = [];

		var n_tabIndex = 1;
		var n_focus = o_inputData.focus;

		var n_inputWidth = o_inputData.width || 80;

		var a_sliced = Ext.Array.from(o_inputData.input || []);

		var o_rules = i_self.getCssRules();

		var n_elementWidth = IceCap.util.Handler.getWidth(1, o_rules.fontScale);

		Ext.Array.each(a_sliced, function(o_config, n_index) {

			var n_width = (n_elementWidth * o_config.len + (n_elementWidth / 2));

			var o_meta = o_config.metaData || {};

			var o_field = {
				xtype: "icecap-input",
				ui: "icecap-field"
			};

			var s_type = o_field.xtype || "icecap-input";
			var n_x = IceCap.util.Handler.getX(o_config.col, o_rules.fontScale) - 3;
			var n_y = IceCap.util.Handler.getY(o_config.lin, o_rules.lineScale);
			var b_password = o_config.atr == "27";
			var n_calc = 0;
			var n_height = null;

			if (o_config.len > (n_inputWidth + 1) || ((o_config.len + o_config.col) > (n_inputWidth + 1))) {
				n_calc = (n_inputWidth + 1) - o_config.col;
				n_width = (n_elementWidth * n_calc + (n_elementWidth / 2));
			}


			if (n_calc || (o_config.hasOwnProperty("colsize") && o_config.hasOwnProperty("rows") && o_config.rows > 1)) {

				var s_data = o_config.dta || "";

				var n_colSize = o_config.colsize || o_config.len;

				if (n_calc && n_colSize > n_calc) {
					o_config.rows = Math.ceil(n_colSize / n_calc);
				}

				var s_lineHeight = o_rules.sheet.rules[0].style.lineHeight;

				var n_parsed = parseFloat(s_lineHeight.replace("px"));

				n_height = n_parsed * o_config.rows;

				var o_box = {
					x: n_x,
					y: n_y,
					width: n_width,
					height: n_height,
					right: n_x + n_width,
					bottom: n_y + n_height
				};

				var i_region = Ext.util.Region.create({});

				Ext.apply(i_region, o_box);

				Ext.Array.each(a_created, function(i_label) {

					var o_rect = {
						x: i_label.x,
						y: i_label.y,
						width: i_label.html.length * n_elementWidth,
						height: n_parsed,
						right: i_label.x + (i_label.html.length * n_elementWidth),
						bottom: i_label.y + n_parsed
					};

					if (i_region.intersect(o_rect)) {

						o_config.rows = i_label.lin - o_config.lin;
						n_height = n_parsed * o_config.rows;

						if (o_config.len > (n_inputWidth + 1)) {
							var n_length = o_config.len /  o_config.rows;

							n_width = (n_elementWidth *n_length + (n_elementWidth / 2));
						}

						return false;
					}
				});

				s_type = "icecap-textarea";
				
				o_field.height = o_field.minHeight = n_height;

				var a_split = s_data.split("\n");

				var s_result = "";

				var n_split = a_split.length;

				Ext.Array.each(a_split, function(s_part, n_index) {

					var regex = new RegExp(".{" + n_colSize + "}", "g");

					var a_match = s_part.match(regex);

					if (a_match) {
						s_result += s_part;
					}
					else {
						if (n_index != n_split - 1) {
							s_result += s_part + "\n";
						}
						else {
							s_result += s_part;
						}
					}
				});

				o_config.dta = s_result;

				if (!b_password) {
					o_field.getSubmitValue = function() {

						var i_field = this;

						var s_value = i_field.stripReturns(i_field.getValue());

						var regex = new RegExp(".{1,"+ n_colSize +"}", "g");

						var a_split = s_value.match(regex) || [];

						return a_split.join("\n");
					};
				}
			}

			var o_listeners = Ext.apply({}, o_meta.listeners);
			delete o_meta.listeners;

			var a_field = ["icecap-field", i_self.getTheme()];

			var a_pass = [b_password ? "iceCap-input-password" : "iceCap-input-" + (o_config.atr || 20)];

			a_pass.push(i_self.getTheme());

			var a_cls = [a_field.filter(Boolean).join("-"), a_pass.filter(Boolean).join("-")];

			var s_cls = a_cls.join(" ");

			var s_name = IceCap.util.Handler.getRandomName();

			if (isNaN(n_x)) {
				n_x = IceCap.util.Handler.getWidth(1, o_rules.fontScale);
			}

			if (isNaN(n_y)) {
				n_y = IceCap.util.Handler.getHeight(1, o_rules.lineScale);
			}

			var s_ui = b_password ? "icecap-password-field" : "icecap-field";

			if (!o_meta.xtype) {
				Ext.apply(o_field, i_self.applyFFW(o_config));
				o_field.xtype = s_type;
			}

			var n_fieldIndex = n_tabIndex;

			if (o_field.unselected) {
				a_cls.push("x-unselectable-field");
				n_fieldIndex = -1;
			}

			s_cls = a_cls.join(" ");

			var i_field;

			if (b_password) {
				o_field.xtype = s_type = "icecap-input";
				o_field.height = o_field.minHeight = null;
				o_field.ui = "icecap-password-field";
			}

			if (s_type == "icecap-textarea") {
				s_ui = "icecap-textarea-field";
			}

			s_ui += o_rules.fieldCss;

			Ext.Object.merge(o_field, {
				width: n_width,
				enforceMaxLength: true,
				maxLength: o_config.len,
				minWidth: IceCap.util.Handler.getDefaultWidth(),
				tabIndex: n_fieldIndex,
				focusable: !o_field.readOnly,
				lin: o_config.lin,
				col: o_config.col,
				emuId: o_config.id,
				value: o_config.dta || "",
				itemId: o_config.id,
				name: s_name,
				inputAttrTpl: "tabindex=" + n_fieldIndex + " spellcheck=false autocomplete=\"new-password\" name=\"" + s_name + "\"",
				x: n_x,
				y: n_y,
				cls: s_cls,
				enableKeyEvents: true,
				selectOnFocus: false,
				ui: s_ui,
				listeners: {
					afterrender: {
						fn: function (i_field) {

							if (i_field.inputEl && !i_field.metaField) {
								if (i_field.xtype == "textarea" || i_field.xtype == "icecap-textarea") {
									i_field.inputEl.dom.setAttribute("rows", o_config.rows);
								}

								if (i_field.getTabIndex() === i_self.getNeedFocus()) {

									i_field.focus(false, 10, function () {
										var o_inputData = i_self.getInputData();

										var s_value = i_field.getValue();
										var n_col = i_field.col;
										var n_diff = 0;

										if (n_col < o_inputData.csrCol) {
											n_diff = o_inputData.csrCol - n_col;
											i_field.inputEl.el.dom.selectionEnd = i_field.inputEl.el.dom.selectionStart = i_field.inputEl.el.dom.selectionStart + n_diff;
										}

										var o_position = {
											col: o_inputData.csrCol,
											lin: o_inputData.csrLin
										};

										i_self.setCurrentPosition(o_position);

										var i_cursor = i_self.getCursor();
										i_cursor.moveCursor(o_position);
										i_cursor.hide();
									});
								}
							}
						}
					},
					change: {
						fn: function (i_field, value) {

							if (i_field.inputEl) {
								var s_direction = i_field.inputEl.el.dom.selectionDirection;

								var n_curpos = s_direction == "forward" ? i_field.inputEl.el.dom.selectionEnd : i_field.inputEl.el.dom.selectionStart;

								value = value || "";

								if (value.length == i_field.maxLength && n_curpos == i_field.maxLength) {
									i_self.doNavigationKey(1, true);
								}
							}
						}
					},
					focus: {
						fn: function (i_field) {

							var n_tabIndex = i_field.getTabIndex();
							i_self.setCurrentTabIndex(n_tabIndex);

							var o_position = {
								col: i_field.col,
								lin: i_field.lin
							};
							i_self.setCurrentPosition(o_position);

							var i_cursor = i_self.getCursor();
							i_cursor.moveCursor(o_position);
							i_cursor.hide();

							if (i_self.getTypeMode() == IceCap.util.Handler.typeMode.FOCUS) {
								var i_inputEl = i_field.inputEl;
								if (i_inputEl && i_inputEl.dom) {
									i_field.inputEl.dom.select();
								}
							}
						}
					},
					keyup: {
						fn: function (i_field, i_event) {

							var i_selector = i_self.getSelector();

							if (!i_selector.isHidden()) {
								return true;
							}

							if (i_field.xtype === "icecap-input") {

								var value = i_field.getValue();

								var s_direction = i_field.inputEl.el.dom.selectionDirection;

								var n_start = s_direction == "forward" ? i_field.inputEl.el.dom.selectionEnd : i_field.inputEl.el.dom.selectionStart;
								var n_add = n_start * IceCap.util.Handler.getWidth(1, o_rules.fontScale);

								if (n_start == i_field.maxLength) {
									n_add = n_add - IceCap.util.Handler.getWidth(1, o_rules.fontScale);
								}

								var o_input = Ext.apply({
									x: i_field.getLocalX() + n_add,
									y: i_field.lin * IceCap.util.Handler.getHeight(1, o_rules.lineScale)
								});

								var o_position = IceCap.util.Handler.toColAndLine(o_input, o_rules);
								i_self.setCurrentPosition(o_position);

								var i_cursor = i_self.getCursor();
								i_cursor.moveCursor(o_position);
							}
						}
					},
					keydown: {
						fn: function (i_field, i_event) {

							var i_selector = i_self.getSelector();

							if (!i_selector.isHidden()) {
								return true;
							}

							var i_regext = new RegExp("^.{1}$");

							var value = i_field.getValue();

							var n_selection = 0;

							var i_inputEl = i_field.inputEl;

							var o_input = {};
							var o_position = {};
							var o_box = {};

							var i_main = i_self.getMain();
							var i_cursor = i_self.getCursor();
							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							var b_intersect = false;

							var b_overshot = false;

							if (i_event.ctrlKey && !i_event.shiftKey) {

								if (i_event.keyCode == Ext.event.Event.DOWN ||
									i_event.keyCode == Ext.event.Event.UP) {

									n_selection = i_inputEl.dom.selectionEnd;

									i_event.stopEvent();

									o_position = {
										col: i_field.col + n_selection,
										lin: i_field.lin
									};

									if (i_event.keyCode == Ext.event.Event.DOWN) {

										var n_height = Math.ceil(i_field.getHeight() / IceCap.util.Handler.getHeight(1, o_rules.lineScale));

										n_height = (n_height > 1) ? n_height - 1 : n_height;

										o_position.lin = o_position.lin + n_height;

									}
									else {
										o_position.lin--;
									}

									if (n_selection !== i_field.maxLength) {
										o_position.col++;
									}

									i_self.setCurrentPosition(o_position);

									i_cursor.moveCursor(o_position);

									i_cursor.show();

									o_input = {
										x: i_cursor.getLocalX(),
										y: i_cursor.getLocalY()
									};

									Ext.apply(o_box, {
										width: i_cursor.getWidth(),
										height: i_cursor.getHeight(),
										right: i_cursor.getLocalX() + i_cursor.getWidth(),
										bottom: i_cursor.getLocalY() + i_cursor.getHeight()
									}, o_input);

									i_cursor.hide();

									Ext.Array.each(a_inputs, function (i_field) {

										var i_region = i_field.getRegion(false, true);

										if (i_region.intersect(o_box)) {
											b_intersect = true;
											i_field.focus(false, 10);
											return false;
										}
									});

									if (!b_intersect) {

										i_field.blur();
										i_cursor.show();

										i_main.focus(true, 10);
									}
								}
								if (i_event.keyCode == Ext.event.Event.LEFT ||
									i_event.keyCode == Ext.event.Event.RIGHT) {

									n_selection = i_event.keyCode == Ext.event.Event.LEFT ? i_inputEl.dom.selectionStart : i_inputEl.dom.selectionEnd;

									i_event.stopEvent();

									if (n_selection === 0 && i_event.keyCode === Ext.event.Event.LEFT) {

										o_position = {
											col: i_field.col,
											lin: i_field.lin
										};

										o_position.col--;

										o_input = {
											x: IceCap.util.Handler.getX(o_position.col, o_rules.fontScale),
											y: IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale)
										};

										i_self.setCurrentPosition(o_position);

										i_cursor.moveCursor(o_position);

										Ext.apply(o_box, {
											width: i_cursor.getWidth(),
											height: i_cursor.getHeight(),
											right: o_input.x + i_cursor.getWidth(),
											bottom: o_input.x + IceCap.util.Handler.getHeight(1, o_rules.lineScale)
										}, o_input);

										Ext.Array.each(a_inputs, function (i_field) {

											var i_region = i_field.getRegion(false, true);

											if (i_region.intersect(o_box)) {
												b_intersect = true;
												i_field.focus(false, 10);
												return false;
											}
										});

										if (!b_intersect) {

											i_field.blur();
											i_cursor.show();

											i_main.focus(true, 10);
										}
									}
									else if (n_selection == value.length && i_event.keyCode == Ext.event.Event.RIGHT) {

										o_position = {
											col: i_field.col + i_field.maxLength,
											lin: i_field.lin
										};

										if (o_position.col > o_inputData.width) {
											o_position.col = o_inputData.width;
										}

										o_position.col = o_position.col + 2;

										o_input = {
											x: IceCap.util.Handler.getX(o_position.col, o_rules.fontScale),
											y: IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale)
										};


										i_self.setCurrentPosition(o_position);
										i_cursor.moveCursor(o_position);

										Ext.apply(o_box, {
											width: i_cursor.getWidth(),
											height: i_cursor.getHeight(),
											right: o_input.x + i_cursor.getWidth(),
											bottom: o_input.x + IceCap.util.Handler.getHeight(1, o_rules.lineScale)
										}, o_input);

										Ext.Array.each(a_inputs, function (i_field) {

											var i_region = i_field.getRegion(false, true);

											if (i_region.intersect(o_box)) {
												b_intersect = true;
												i_field.focus(false, 10);
												return false;
											}
										});

										if (!b_intersect) {

											i_field.blur();
											i_cursor.show();

											i_main.focus(true, 10);
										}
									}
								}
							}
							else {

								if (i_field.xtype == "textarea" || i_field.xtype == "icecap-textarea") {

									if (i_event.keyCode == Ext.event.Event.ENTER) {
										i_event.preventDefault();
										i_self.doKeyEvent("ENTER");
										return false;
									}

									var n_row = 1;
									var n_char = 0;
									var n_left = 0;
									var n_current = 0;
									var n_nextLine = 0;
									var n_newPos = 0;

									if (i_event.keyCode == Ext.event.Event.UP && (!i_event.shiftKey && !i_event.ctrlKey)) {

										var s_value = i_field.stripReturns(i_field.getRawValue());

										var regex = new RegExp("^.*\n$|.{1," + n_colSize + "}", "gm");

										var a_lines = s_value.match(regex) || [];
										var a_newLines = s_value.split("\n");

										var n_start = i_field.inputEl.dom.selectionStart;

										if (a_lines.length > 0) {

											var s_first = a_lines[0];

											if (n_start > s_first.length) {
												i_event.stopPropagation();
											}
										}
										else {
											if (a_newLines.length > 0) {
												if (n_start > 0) {
													i_event.stopPropagation();
												}
											}
										}
									}

									if (i_event.keyCode == Ext.event.Event.DOWN && (!i_event.shiftKey && !i_event.ctrlKey)) {

										var s_value = i_field.stripReturns(i_field.getRawValue());
										var n_length = s_value.length;

										var regex = new RegExp("^.*\n$|.{1," + n_colSize + "}", "g");
										var n_start = i_field.inputEl.dom.selectionStart;

										var a_lines = s_value.match(regex) || [];
										var a_newLines = s_value.split("\n");

										if (a_lines.length < o_config.rows && a_newLines.length < o_config.rows) {

											i_event.stopEvent();

											s_value = s_value + "\n";

											i_field.setValue(s_value);

											i_field.inputEl.dom.setSelectionRange(s_value.length, s_value.length);
										}
										else {
											if (a_lines.length == o_config.rows) {

												var n_line = 0;

												Ext.Array.each(a_lines, function (s_line, n_index) {
													if (n_index < a_lines.length - 1) {
														n_line += s_line.length;
													}
												});

												n_line += a_newLines.length - 1;

												if (n_start < n_line) {
													i_event.stopPropagation();
												}
											}
											else {
												if (a_newLines.length > 0) {
													if (n_start < s_value.length) {
														i_event.stopPropagation();
													}
												}
											}
										}
									}
								}
								else if (i_field.xtype == "icecap-input") {

									var n_typeMode = i_self.getTypeMode();

									var s_direction = i_field.inputEl.el.dom.selectionDirection;

									var n_curpos = s_direction == "forward" ? i_field.inputEl.el.dom.selectionEnd : i_field.inputEl.el.dom.selectionStart;

									var s_key = i_event.event.key;

									var i_nearest;

									var n_temp;

									var n_valueTemp = 999;
									var n_curdiffCol = 999;

									if (i_regext.test(s_key)) {

										if (n_curpos < value.length && n_typeMode == IceCap.util.Handler.typeMode.OVERWRITE) {

											var a_values = value.split("");
											a_values[n_curpos] = i_event.event.key;
											value = a_values.join("");
											i_field.setValue(value);
											i_field.inputEl.el.dom.selectionEnd = i_field.inputEl.el.dom.selectionStart = n_curpos + 1;
											i_event.stopEvent();
										}
									}
									else {

										if (i_event.keyCode == Ext.event.Event.DOWN ||
											i_event.keyCode == Ext.event.Event.UP) {

											n_selection = i_inputEl.dom.selectionEnd;

											o_position = {
												col: i_field.col,
												lin: i_field.lin
											};

											if (i_event.keyCode === Ext.event.Event.UP) {

												Ext.Array.each(a_inputs, function (i_field) {

													if (i_field.col == o_position.col) {

														if (i_field.lin == (o_position.lin - 1)) {

															i_nearest = i_field;
														}
													}
												});

												if (!i_nearest) {

													n_posDiff = o_position.lin;

													n_valueTemp = 999;
													n_curdiffCol = 999;

													Ext.Array.each(a_inputs, function (i_field) {

														if (i_field.lin < o_position.lin) {

															var n_max = Math.max(i_field.lin, n_posDiff);
															var n_min = Math.min(i_field.lin, n_posDiff);

															var n_curDiff =  n_max - n_min;

															if (n_valueTemp >= n_curDiff) {

																n_max = Math.max(i_field.col, o_position.col);
																n_min = Math.min(i_field.col, o_position.col);

																var n_diff = n_max - n_min;

																if (n_valueTemp == n_curDiff) {

																	if (n_curdiffCol > n_diff) {
																		i_nearest = i_field;
																		n_valueTemp = n_curDiff;
																		n_curdiffCol = n_diff;
																	}
																}
																else {
																	i_nearest = i_field;
																	n_valueTemp = n_curDiff;
																	n_curdiffCol = n_diff;
																}
															}
														}
													});
												}

												if (i_nearest) {

													o_position.lin = i_nearest.lin;

													i_self.setCurrentPosition(o_position);

													i_cursor.moveCursor(o_position);

													i_nearest.focus(false, 10, function () {
														var i_element = i_nearest.inputEl;
														var value = i_nearest.getValue();
														if (i_self.getTypeMode() != IceCap.util.Handler.typeMode.FOCUS) {
															i_element.dom.selectionStart = i_element.dom.selectionEnd = n_selection;
														}
													});

													i_event.stopEvent();
												}
											}
											else if (i_event.keyCode == Ext.event.Event.DOWN) {

												Ext.Array.each(a_inputs, function (i_field) {

													if (i_field.col == o_position.col) {

														if (i_field.lin == (o_position.lin + 1)) {

															i_nearest = i_field;
														}
													}
												});

												if(!i_nearest) {

													n_posDiff = o_position.lin;
													n_tempCol = o_position.col;

													n_valueTemp = 999;
													n_curdiffCol = 999;

													Ext.Array.each(a_inputs, function (i_field) {

														if (i_field.lin > o_position.lin) {

															var n_max = Math.max(i_field.lin, n_posDiff);
															var n_min = Math.min(i_field.lin, n_posDiff);

															var n_diff = n_max - n_min;

															var n_curDiff =  n_max - n_min;

															if (n_valueTemp >= n_curDiff) {

																n_max = Math.max(i_field.col, o_position.col);
																n_min = Math.min(i_field.col, o_position.col);

																n_diff = n_max - n_min;

																if (n_curdiffCol > n_diff) {
																	i_nearest = i_field;
																	n_valueTemp = n_curDiff;
																	n_curdiffCol = n_diff;
																}
															}
														}
													});
												}

												if (i_nearest) {

													o_position.lin = i_nearest.lin;

													i_self.setCurrentPosition(o_position);

													i_cursor.moveCursor(o_position);

													i_nearest.focus(false, 10, function () {
														var i_element = i_nearest.inputEl;
														if (i_self.getTypeMode() != IceCap.util.Handler.typeMode.FOCUS) {
															i_element.dom.selectionStart = i_element.dom.selectionEnd = n_selection;
														}
													});

													i_event.stopEvent();
												}
											}
										}

										if (i_event.keyCode == Ext.event.Event.LEFT ||
											i_event.keyCode == Ext.event.Event.RIGHT) {

											var n_col = o_config.col;
											var n_tempCol = n_col;

											n_selection = i_event.keyCode == Ext.event.Event.LEFT ? i_inputEl.dom.selectionStart : i_inputEl.dom.selectionEnd;

											var a_selection = i_inputEl.getTextSelection();
											var n_selected = a_selection[2] == "forward" ? a_selection[1] - a_selection[0] : a_selection[2] - a_selection[1];

											if (n_selected == value.length && !Ext.isEmpty(value)) {

												if (i_event.keyCode == Ext.event.Event.LEFT) {
													i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = 0;
												}
												else {
													i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = n_selected;
												}

												i_event.stopEvent();

												return;
											}

											o_position = {
												col: i_field.col,
												lin: i_field.lin
											};

											n_posDiff = o_position.col + o_position.lin;

											if (n_selection === 0 && i_event.keyCode === Ext.event.Event.LEFT) {

												n_tempCol = o_position.col;

												Ext.Array.each(a_inputs, function (i_field) {

													if (i_field.lin == o_position.lin) {

														if (i_field.col < o_position.col) {

															i_nearest = i_field;
														}
													}
												});

												if (!i_nearest) {

													n_valueTemp = 999;

													n_posDiff = o_config.lin;


													Ext.Array.each(a_inputs, function (i_field) {

														if (i_field.lin < o_position.lin) {

															var n_curDiff = n_posDiff - i_field.lin;

															if (n_valueTemp > n_curDiff) {
																i_nearest = i_field;
																n_tempCol = i_field.col;
																n_valueTemp = n_curDiff;
															}
															else if (n_valueTemp == n_curDiff) {
																if (n_tempCol < i_field.col && i_field.col > o_position.col) {
																	i_nearest = i_field;
																	n_tempCol = i_field.col;
																}
															}
														}
													});
												}

												if (i_nearest) {

													o_position.col = i_nearest.col;

													i_self.setCurrentPosition(o_position);

													i_cursor.moveCursor(o_position);

													i_nearest.focus(false, 10, function () {
														var i_element = i_nearest.inputEl;
														var value = i_nearest.getValue();
														if (!b_overshot && i_self.getTypeMode() != IceCap.util.Handler.typeMode.FOCUS) {
															i_element.dom.selectionStart = i_element.dom.selectionEnd = value.length;
														}
													});
												}
											}
											else if (n_selection == value.length && i_event.keyCode == Ext.event.Event.RIGHT) {

												n_tempCol = i_field.col + i_field.maxLength;

												o_position = {
													col: i_field.col + i_field.maxLength,
													lin: i_field.lin
												};

												if (o_position.col > o_inputData.width) {
													o_position.col = n_tempCol = o_inputData.width;
												}

												Ext.Array.each(a_inputs, function (i_field) {

													if (i_field.lin == o_position.lin) {

														if (i_field.col > o_position.col) {

															i_nearest = i_field;
															return false;
														}
													}
												});

												if (!i_nearest) {

													n_valueTemp = 999;

													n_posDiff = o_config.lin;

													Ext.Array.each(a_inputs, function (i_field) {

														if (i_field.lin > o_position.lin) {

															var n_curDiff = i_field.lin - n_posDiff;

															if (n_valueTemp > n_curDiff) {
																if (n_tempCol >= i_field.col) {
																	i_nearest = i_field;
																	n_tempCol = i_field.col;
																}
																n_valueTemp = n_curDiff;
															}
															else if (n_valueTemp == n_curDiff) {
																if (n_tempCol > i_field.col && i_field.col < o_position.col) {
																	i_nearest = i_field;
																}
															}
														}
													});
												}

												if (i_nearest) {

													o_position.col = i_nearest.col;

													i_self.setCurrentPosition(o_position);

													i_cursor.moveCursor(o_position);

													i_nearest.focus(false, 10, function () {
														var i_element = i_nearest.inputEl;
														if (i_self.getTypeMode() != IceCap.util.Handler.typeMode.FOCUS) {
															i_element.dom.selectionStart = i_element.dom.selectionEnd = 0;
														}
													});

													i_event.stopEvent();
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}, o_meta);

			var o_clone = Ext.clone(o_field);

			if (o_meta.xtype) {

				o_clone.metaField = true;

				o_clone.xtype = s_type = o_meta.xtype;

				delete o_clone.cls;
				delete o_clone.fieldStyle;
				delete o_clone.inputType;
				delete o_clone.ui;
			}

			if (o_config.type == "grid") {

				s_type = "iceCapGrid";

				Ext.apply(o_clone, {
					xtype: s_type,
					gridConfig: o_config.grid,
					width: IceCap.util.Handler.getWidth(n_inputWidth, o_rules.fontScale)
				});

				delete o_clone.cls;
				delete o_clone.fieldStyle;
				delete o_clone.inputType;
				delete o_clone.listeners;
				delete o_clone.grid;

				Ext.apply(o_clone, {
					listeners: {
						fieldoption: {
							fn: function (a_config) {
								i_self.fireEvent("fieldoption", a_config);
							}
						},
						key: {
							fn: function (s_key) {
								i_self.fireEvent("key", s_key);
							}
						}
					}
				});
			}

			i_field = Ext.widget(s_type, o_clone);

			var o_on = {};

			Ext.Object.each(o_listeners, function (s_key, value) {

				if (Ext.isFunction(value)) {
					o_on[s_key] = Ext.apply({}, {
						fn: value,
						scope: i_self
					});
				}
				else if (Ext.isObject(value)) {
					value.scope = i_self;
					o_on[s_key] = value;
				}
			});

			i_field.on(o_on);

			if (!i_field.unselected) {
				i_field.focusable = true;
				n_tabIndex++;
			}

			if (o_config.atr == 25) {

				if (o_field.readOnly) {
					i_field.addCls("icecap-invalid");
				}
				else {
					i_field.markInvalid(true);
				}
			}

			a_fields.push(i_field);
		});

		n_tabIndex = n_tabIndex - 1;
		i_self.setLastTabIndex(n_tabIndex);
		i_self.setCurrentTabIndex(o_inputData.focus);

		i_self.setNeedFocus(n_focus);

		return a_fields;
	},

	createLabels: function () {

		var i_self = this;
		var o_inputData = i_self.getInputData();

		var o_rules = i_self.getCssRules();

		var i_fieldRule = o_rules.sheet.rules.item(0);
		var o_style = i_fieldRule.style;

		var a_fields = [];
		var a_bold = [];

		if (!i_self.getEdit()) {

			var a_lines = [];
			var a_temp = [];

			Ext.Array.each(o_inputData.output, function (o_config) {

				var o_line = Ext.Array.findBy(a_lines, function (o_line) {
					return o_line.lin == o_config.lin;
				});

				if (o_line) {
					o_line.items.push(o_config);
				}
				else {
					o_line = {
						items: [o_config],
						lin: o_config.lin,
						col: o_config.col
					};

					a_lines.push(o_line);
				}
			});

			Ext.Array.each(a_lines, function (o_line) {

				var a_items = [];

				Ext.Array.each(o_line.items, function (o_item) {

					var o_atr = Ext.Array.findBy(a_items, function (o_atr) {
						return (o_atr.atr || "") == (o_item.atr || "");
					});

					if (!o_atr && o_item.atr != "22") {
						o_atr = {
							lin: o_item.lin,
							items: [o_item],
							atr: o_item.atr || ""
						};

						a_items.push(o_atr);
					}
					else {

						if (o_item.atr != "22") {
							o_atr.items.push(o_item);
						}
						else {
							a_bold.push(o_item);
						}
					}
				});

				o_line.atr = a_items;
			});

			Ext.Array.each(a_lines, function (o_line) {

				Ext.Array.each(o_line.atr, function (o_atr) {

					var n_col = 0;
					var n_current = 0;
					var s_value = "";

					var o_field = {
						value: ""
					};

					Ext.Array.each(o_atr.items, function (o_config) {

						var s_data = o_config.dta || o_config.label || o_config.text || "";

						if (o_config.off) {
							s_data = Ext.String.leftPad(s_data, s_data.length + o_config.off);
						}

						if (n_col === 0) {

							n_col = o_config.col;
							n_current = (n_col + s_data.length);
							s_value = s_data;
						}
						else {

							var n_diff = o_config.col - n_current;

							if (n_diff > 0) {
								s_data = Ext.String.leftPad(s_data, s_data.length + n_diff);
							}

							n_current = (n_current + s_data.length);

							s_value = s_value + s_data;
						}
					});

					Ext.apply(o_field, {
						col: n_col,
						lin: o_line.lin,
						value: s_value,
						atr: o_atr.atr
					});

					a_temp.push(o_field);
				});
			});

			var a_splitTemp = [];

			Ext.Array.each(a_bold, function (o_config) {

				var s_value = o_config.value || o_config.dta || "";

				if (o_config.off) {
					s_value = Ext.String.leftPad(s_value, s_value.length + o_config.off);
				}

				var a_matches = Array.from(s_value.matchAll(/\S+/g));

				Ext.Array.each(a_matches, function (i_match) {
					a_splitTemp.push({
						value: i_match[0],
						lin: o_config.lin,
						col: i_match.index + o_config.col,
						atr: "22"
					});
				});
			});

			a_temp = a_temp.concat(a_splitTemp);

			Ext.Array.each(a_temp, function (o_config) {

				var s_value = o_config.value || o_config.dta;

				if (s_value) {

					if (o_config.off) {
						s_value = Ext.String.leftPad(s_value, s_value.length + o_config.off);
					}

					var n_x = IceCap.util.Handler.getX(o_config.col, o_rules.fontScale);
					var n_y = IceCap.util.Handler.getY(o_config.lin, o_rules.lineScale);

					var s_cls = (["iceCap-output-" + (o_config.atr || 20), i_self.getTheme()].filter(Boolean).join("-"));

					var o_field = {
						autoEl: {
							tag: "span"
						},
						html: s_value,
						x: n_x,
						y: n_y,
						lin: o_config.lin,
						col: o_config.col,
						cls: ["x-form-display-field-icecap-display" + o_rules.fieldCss, s_cls].join(" "),
						originalValue: s_value,
						textID: o_config.txtId || 0,
						style: {
							"white-space": "pre",
							"pointer-events": "none"
						},
						listeners: {
							afterrender: {
								fn: function (i_field) {
									i_field.el.dom.setAttribute("draggable", false);
								}
							}
						}
					};


					if (o_config.atr == "27") {
						o_field.hidden = true;
					}

					if (o_config.atr == "22") {

						Ext.apply(o_field.style, {
							"font-size": IceCap.util.Handler.getFontSize(o_rules.fontScale),
							"font-weight": "bold;"
						});
					}

					var i_field = Ext.widget("component", o_field);
					a_fields.push(i_field);
				}
			});
		}
		else {

			Ext.Array.each(o_inputData.output, function (o_config) {

				var s_value = o_config.dta || o_config.label || o_config.text || "";

				if (s_value) {

					if (o_config.off) {
						s_value = Ext.String.leftPad(s_value, s_value.length + o_config.off);
					}

					var n_x = IceCap.util.Handler.getX(o_config.col, o_rules.fontScale);
					var n_y = IceCap.util.Handler.getY(o_config.lin, o_rules.lineScale);

					var s_cls = (["iceCap-output-" + (o_config.atr || 20), i_self.getTheme()].filter(Boolean).join("-"));

					var o_field = {
						autoEl: {
							tag: "span"
						},
						html: s_value,
						x: n_x,
						y: n_y,
						lin: o_config.lin,
						col: o_config.col,
						cls: ["x-form-display-field-icecap-display" + o_rules.fieldCss, s_cls].join(" "),
						originalValue: s_value,
						textID: o_config.txtId || 0,
						style: {
							"white-space": "pre"
						},
						listeners: {
							mouseover: {
								element: "el",
								fn: function () {

									var i_element = this;
									i_element.addCls("x-base-background-color");
								}
							},
							mouseout: {
								element: "el",
								fn: function () {

									var i_element = this;
									i_element.removeCls("x-base-background-color");
								}
							},
							afterrender: {
								fn: function (i_field) {
									i_field.el.dom.setAttribute("draggable", false);

									var i_tpl = Ext.create("Ext.XTemplate",
										"<div style=\"width: 300px; overflow:hidden;\">",
										"<div>Position: {lin} / {col}</div>",
										"<div>Length: {len}</div>",
										"<div>Color: {color}</div>",
										"<div style=\"overflow:hidden; white-space: nowrap; text-overflow:ellipsis;\">Font: {font}</div>",
										"</div>"
									);

									Ext.create("Ext.tip.ToolTip", {
										target: i_field.el,
										html: "",
										anchor: true,
										defealtAlign: "b0-t0",
										listeners: {
											beforeshow: {
												fn: function (i_tip) {

													var o_data = {
														lin: o_config.lin,
														col: o_config.col,
														color: o_style.color,
														len: o_config.len,
														font: [
															o_style.fontSize,
															o_style.fontFamily
														].join(" ")
													};

													var s_value = i_tpl.apply(o_data);
													i_tip.update(s_value);
												}
											}
										}
									});
								}
							}
						}
					};


					if (o_config.atr == "27") {
						o_field.hidden = true;
					}

					if (o_config.atr == "22") {

						Ext.apply(o_field.style, {
							"font-size": IceCap.util.Handler.getFontSize(o_rules.fontScale),
							"font-weight": "bold;"
						});
					}

					var i_field = Ext.widget("component", o_field);
					a_fields.push(i_field);

					i_field.on({
						afterrender: {
							fn: function (i_field) {
								i_field.el.on({
									click: {
										fn: function () {

											o_config.originalValue = o_config.dta;

											if (i_field.textID) {
												IceCap.util.Handler.getTranslation({
													textID: i_field.textID,
													languages: i_self.getLanguages()
												}, function (o_data) {

														o_config.originalValue = o_data.text;

														var i_editor = i_self.createEditor(o_config, o_data, function (o_values, o_translation) {

															var s_value = o_translation[i_self.getActiveLanguage()] || o_data.text;

															i_field.setHtml(s_value);

															i_field.textID = o_config.txtId = o_values.txtId;
														});

														var o_translation = o_data.translation || {};

														var s_value = o_translation[i_self.getActiveLanguage()] || i_field.originalValue;

														i_editor.startEdit(i_field.getEl(), s_value, false);
												});
											}
											else {

												o_config.dta = i_field.originalValue;

												var i_editor = i_self.createEditor(o_config, {}, function (o_values, o_translation) {

													i_field.textID = o_config.txtId = o_values.txtId;

													var s_value = o_translation[i_self.getActiveLanguage()] || o_config.text;

													i_field.setHtml(s_value);
												});

												i_editor.startEdit(i_field.getEl(), undefined, false);
											}
										}
									}
								});
							}
						}
					});
				}
			});
		}

		return a_fields;
	},

	createKeys: function () {

		var i_self = this;
		var o_rules = i_self.getCssRules();
		var o_inputData = i_self.getInputData();
		var a_disabledKey = o_inputData.disabledKeys || [];
		var a_buttons = [];

		var i_template = Ext.create("Ext.XTemplate",
			"{id}={text}"
		);

		Ext.Array.each(o_inputData.keys, function (o_config) {

			var s_template = i_template.apply(o_config);

			var o_found = Ext.Array.findBy(a_disabledKey, function (o_disabled) {
				return o_config.id == o_disabled.id;
			});

			o_found = o_found || {
				showKey: 1
			};

			var b_hidden = Number(o_found.showKey) < 1 || false;

			var i_button = Ext.widget("button", {
				text: s_template,
				key: o_config.id,
				len: o_config.len,
				focusable: false,
				textID: o_config.txtId || 0,
				hidden: b_hidden,
				originalValue: s_template,
				style: {
					maxHeight: 30 * o_rules.lineScale + "px",
					minHeight: 30 * o_rules.lineScale + "px",
					minWidth: 80 * o_rules.fontScale + "px"
				},
				listeners: {
					afterrender: {
						fn: function(i_button) {
							i_button.btnEl.setStyle("min-height", "inherit");
							i_button.btnInnerEl.setStyle("font-size", "calc(1em * " +  o_rules.fontScale + ")");
						}
					}
				}
			});

			if (i_self.getEdit()) {
				i_button.on({
					afterrender: {
						fn: function (i_button) {
							i_button.el.on({
								click: {
									fn: function (i_event) {

										o_config.dta = o_config.text;

										o_config.originalValue = i_template.apply({
											id: i_button.key,
											text: o_config.text
										});

										i_event.stopEvent();

										if (i_button.textID) {
											IceCap.util.Handler.getTranslation({
												textID: i_button.textID,
												languages: i_self.getLanguages()
											}, function (o_data) {

													o_config.originalValue = o_data.text;

													var i_editor = i_self.createEditor(o_config, o_data, function (o_values, o_translation) {

														var s_value = o_translation[i_self.getActiveLanguage()];

														if (s_value) {

															s_value = i_template.apply({
																id: i_button.key,
																text: s_value
															});
														}
														else {
															if (o_data.text) {
																s_value = o_data.text;
															}
															else {
																s_value = i_template.apply({
																	id: i_button.key,
																	text: o_config.text
																});
															}
														}

														i_button.setText(s_value);

														i_button.textID = o_config.txtId = o_values.txtId;

													}, true);

													var o_translation = o_data.translation || {};

													var s_value = o_translation[i_self.getActiveLanguage()] || o_config.text;

													i_editor.startEdit(i_button.getEl(), s_value, false);
											});
										}
										else {

											o_config.originalValue = i_template.apply({
												id: i_button.key,
												text: o_config.text
											});

											o_config.dta = o_config.text;

											var i_editor = i_self.createEditor(o_config, {}, function (o_values, o_translation) {

												i_button.textID = o_config.txtId =  o_values.txtId;

												var s_value = o_translation[i_self.getActiveLanguage()];

												if (s_value) {

													s_value = i_template.apply({
														id: i_button.key,
														text: s_value
													});
												}
												else {
													s_value = i_template.apply({
														id: i_button.key,
														text: o_config.text
													});
												}

												i_button.setText(s_value);

											}, true);

											i_editor.startEdit(i_button.getEl(), o_config.dta, false);
										}
									}
								}
							});
						}
					}
				});
			}
			else {
				i_button.on({
					click: {
						fn: function () {
							i_self.doKeyEvent(i_button.key);
						}
					}
				});
			}

			a_buttons.push(i_button);
		});

		return a_buttons;
	},

	createMetaFields: function() {

		var i_self = this;
		var o_inputData = i_self.getInputData();

		var a_fields = [];
		var n_tabIndex = i_self.getLastTabIndex() || 0;

		var a_sliced = Ext.Array.slice(o_inputData.metaFields || []);

		var o_rules = i_self.getCssRules();

		Ext.Array.each(a_sliced, function(o_config) {

			var n_x = o_config.x;
			var n_y = o_config.y;

			if (!o_config.x) {
				n_x = IceCap.util.Handler.getX(o_config.col, o_rules.fontScale);
			}

			if (!o_config.y) {
				n_y = IceCap.util.Handler.getY(o_config.lin, o_rules.lineScale);
			}

			if (isNaN(n_x)) {
				n_x = IceCap.util.Handler.getWidth(1, o_rules.fontScale);
			}

			if (isNaN(n_y)) {
				n_y = IceCap.util.Handler.getHeight(1, o_rules.lineScale);
			}

			var o_listeners = o_config.listeners || {};

			Ext.apply(o_config, {
				tabIndex: n_tabIndex + 1,
				keys: Ext.Array.slice(o_inputData.keys),
				theme: i_self.getTheme(),
				x: n_x,
				y: n_y,
				listeners: {
					fieldoption: {
						fn: function(a_config) {
							i_self.fireEvent("fieldoption", a_config);
						}
					},
					key: {
						fn: function(s_key) {
							i_self.fireEvent("key", s_key);
						}
					}
				}
			});

			o_config.xtype = o_config.xtype || o_config.type || "icecap-input";

			o_config.name = o_config.id;

			delete o_config.id;

			var i_field = Ext.widget(o_config.xtype, o_config);

			var o_on = {};

			if (!Ext.Object.isEmpty(o_listeners)) {

				Ext.Object.each(o_listeners, function(s_key, value) {

					if (Ext.isFunction(value)) {
						o_on[s_key] = Ext.apply({}, {
							fn: value,
							scope: i_self
						});
					}
					else if (Ext.isObject(value)) {
						value.scope = i_self;
						o_on[s_key] = value;
					}
				});
			}

			i_field.on(o_on);

			a_fields.push(i_field);

			n_tabIndex++;
		});

		i_self.setLastTabIndex(n_tabIndex);

		return a_fields;
	},

	doCreateFromData: function(o_inputData) {

		var i_self = this;
		i_self.fireEvent("toWindow", i_self, o_inputData);
	},

	recreate: function() {

		var i_self = this;

		var i_content = i_self.getContent();
		var i_keyArea = i_self.getKeyArea();
		var i_main = i_self.getMain();
		var o_inputData = i_self.getInputData();

		var b_fixed = o_inputData.hasOwnProperty("fixed") ? o_inputData.fixed : true;

		var s_languages = o_inputData.languages || "";

		var a_languagesSplit = s_languages.split(",").filter(function(value) {
			return value;
		});

		var a_languages = i_self.getLanguages();

		Ext.Array.each(a_languagesSplit, function (s_value) {
			s_value = s_value.trim();
			a_languages.push(s_value);
		});

		i_self.setLanguages(a_languages);

		IceCap.util.Handler.setFixed(b_fixed);

		i_self.suspendLayouts();

		if (o_inputData.title) {
			i_self.setTitle(o_inputData.title);
		}

		var a_created = [];
		a_created = a_created.concat(i_self.createLabels());
		a_created = a_created.concat(i_self.createFields(a_created));
		a_created = a_created.concat(i_self.createMetaFields());

		a_created.push(i_self.createCursor());
		a_created.push(i_self.createMarker());
		a_created.push(i_self.createSelector());

		i_content.removeAll(true);
		i_keyArea.removeAll(true);

		i_content.add(a_created);

		var a_keys = i_self.createKeys();
		i_keyArea.add(a_keys);

		i_keyArea[a_keys.length === 0 ? "hide" : "show"]();

		var i_marker = i_self.getMarker();
		i_marker.setInUse(i_self.getMarkerActive());

		i_self.updateMessage(o_inputData);


		IceCap.util.Handler.setFixed(true);

		i_self.resumeLayouts(true);

		if (i_content) {
			a_fields = IceCap.util.Handler.getInputFields(i_content);

			var b_found = false;
			var b_error = false;

			if (o_inputData.msgBox && o_inputData.msgBox.text) {
				b_error = true;
			}

			if (a_fields.length > 0) {

				b_found = Ext.Array.findBy(a_fields, function (i_field) {
					return i_field.getTabIndex() === i_self.getNeedFocus();
				});
			}

			if (!b_found) {

				i_self.setCurrentPosition({
					col: o_inputData.csrCol || 1,
					lin: o_inputData.csrLin || 1
				});
			}

			if (b_error) {
				i_self.onError(o_inputData);
			}
			else {
				if (i_self.rendered) {
					i_self.findFocus();
				}
			}
		}

		var b_translation = !Ext.isEmpty(o_inputData.isTranslator) ? o_inputData.isTranslator : false;

		var i_translatorButton = i_self.getTranslator();

		b_translation = i_self.getLanguages().length > 0;

		i_translatorButton[b_translation ? "show" : "hide"]();
	},

	getCurrentField: function() {

		var i_self = this;

		var a_fields = IceCap.util.Handler.getInputFields(i_self);
		var n_tabIndex = i_self.getCurrentTabIndex();
		var i_currentField;

		Ext.Array.each(a_fields, function(i_field) {
			if (i_field.getTabIndex() === n_tabIndex && i_field.hasFocus) {
				i_currentField = i_field;
				return false;
			}
		});

		return i_currentField;
	},

	doKeyEvent: function(s_value, i_event) {

		if (i_event) {
			i_event.stopEvent();
		}

		var i_self = this;

		var i_controller = i_self.getController();

		var o_inputData = i_self.getInputData() || {};

		var a_disabledKeys = Ext.Array.from(o_inputData.disabledKeys || []);

		var o_found = Ext.Array.findBy(a_disabledKeys, function (o_key) {
			return s_value == o_key.id;
		});

		if (!o_found) {
			i_controller.doKeyEvent(s_value);
		}
		else {

			IceCap.util.Handler.messageBox({
				title: "Error",
				message: "Funktionstasten er ikke tilladt",
				yesText: "Ok",
				yesFn: function () {
					i_self.findFocus();
				}
			});
		}
	},

	doNavigationKey: function(n_direction, b_tab, i_event) {

		if (i_event) {
			i_event.stopPropagation();
			i_event.preventDefault();
		}

		var i_self = this;
		var i_controller = i_self.getController();
		i_controller[b_tab ? "doTabKey" : "doArrowKeys"](n_direction);
	},

	addKeyEvents: function() {

		var i_self = this;

		var a_bindings = [
			{
				key: Ext.event.Event.PAGE_DOWN,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					i_self.doKeyEvent("ROLLUP");
				}
			},
			{
				key: Ext.event.Event.PAGE_UP,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					i_self.doKeyEvent("ROLLDOWN");
				}
			},
			{
				key: Ext.event.Event.ENTER,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					i_self.doKeyEvent("ENTER");
				}
			},
			{
				key: Ext.event.Event.ESC,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {
						i_event.stopEvent();
						i_selector.hide();
					}
					else {
						i_self.doKeyEvent("ATTN");
					}
				}
			},
			{
				key: Ext.event.Event.LEFT,
				shift: false,
				ctrl: true,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_selector.getLocalY()
						}, o_rules);

						var n_col = o_coords.col - 1;

						var n_x = IceCap.util.Handler.getX(n_col, o_rules.fontScale);

						if (n_x == i_selector.getLocalX()) {
							n_x = IceCap.util.Handler.getX(n_col - 1, o_rules.fontScale);
						}

						i_selector.setLeft(n_x);

						var i_region = i_selector.getRegion(false, true);

						i_selector.dragX = i_region.right;
						i_selector.setDragY(i_region.bottom);
					}
				}
			},
			{
				key: Ext.event.Event.RIGHT,
				shift: false,
				ctrl: true,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_selector.getLocalY()
						}, o_rules);

						var n_col = o_coords.col;

						var n_x = IceCap.util.Handler.getX(n_col, o_rules.fontScale);

						if (n_x == i_selector.getLocalX()) {
							n_x = IceCap.util.Handler.getX(n_col + 1, o_rules.fontScale);
						}

						i_selector.setLeft(n_x);

						var i_region = i_selector.getRegion(false, true);

						i_selector.dragX = i_region.right;
						i_selector.setDragY(i_region.bottom);
					}
				}
			},
			{
				key: Ext.event.Event.LEFT,
				shift: true,
				ctrl: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					var i_target = i_event.getTarget();
					var i_element = Ext.get(i_target);
					var i_component = i_element.component;

					if (!i_component) {
						i_component = i_element.getParent().component;
					}

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var i_region = i_selector.getRegion(false, true);

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_region.right,
							y: i_selector.getLocalY()
						}, o_rules);

						var n_col = o_coords.col - 1;

						var n_x = IceCap.util.Handler.getX(n_col, o_rules.fontScale);

						if (n_x == Math.floor(i_region.right)) {
							n_x = IceCap.util.Handler.getX(n_col - 1, o_rules.fontScale);
						}

						i_selector.setDragX(n_x);
					}
					else {
						if (!i_component.isXType("field")) {

							var i_cursor = i_self.getCursor();

							var o_click = Ext.apply({
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY()
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col - 1, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							var n_dragX = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_dragY = IceCap.util.Handler.getY(o_position.lin + 1, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.show();

							i_selector.setSelecting(true);

							i_selector.setDragX(n_dragX);
							i_selector.setDragY(n_dragY);

							i_event.stopEvent();
						}
					}
				}
			},
			{
				key: Ext.event.Event.RIGHT,
				shift: true,
				ctrl: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					var i_target = i_event.getTarget();
					var i_element = Ext.get(i_target);
					var i_component = i_element.component;

					if (!i_component) {
						i_component = i_element.getParent().component;
					}

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var i_region = i_selector.getRegion(false, true);

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_region.right,
							y: i_selector.getLocalY()
						}, o_rules);

						var n_col = o_coords.col;

						var n_x = IceCap.util.Handler.getX(n_col, o_rules.fontScale);

						if (n_x == Math.floor(i_region.right)) {
							n_x = IceCap.util.Handler.getX(n_col + 1), o_rules.fontScale;
						}

						i_selector.setDragX(n_x);
					}
					else {
						if (!i_component.isXType("field")) {

							var i_cursor = i_self.getCursor();

							var o_click = Ext.apply({
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY()
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col - 1, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							var n_dragX = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_dragY = IceCap.util.Handler.getY(o_position.lin + 1, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.show();

							i_selector.setSelecting(true);

							i_selector.setDragX(n_dragX);
							i_selector.setDragY(n_dragY);

							i_event.stopEvent();
						}
					}
				}
			},
			{
				key: Ext.event.Event.UP,
				shift: false,
				ctrl: true,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_selector.getLocalY()
						}, o_rules);

						var n_lin = o_coords.lin;

						var n_y = IceCap.util.Handler.getY(n_lin, o_rules.lineScale);

						if (n_y == i_selector.getLocalY()) {
							n_y = IceCap.util.Handler.getY(n_lin - 1, o_rules.lineScale);
						}

						i_selector.setTop(n_y);

						var i_region = i_selector.getRegion(false, true);

						i_selector.dragY = n_y;
						i_selector.setDragX(i_region.right);
					}
				}
			},
			{
				key: Ext.event.Event.DOWN,
				shift: false,
				ctrl: true,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_selector.getLocalY()
						}, o_rules);

						var n_lin = o_coords.lin + 1;

						var n_y = IceCap.util.Handler.getY(n_lin, o_rules.lineScale);

						if (n_y == i_selector.getLocalY()) {
							n_y = IceCap.util.Handler.getY(n_lin + 1, o_rules.lineScale);
						}

						i_selector.setTop(n_y);

						var i_region = i_selector.getRegion(false, true);

						i_selector.dragY = n_y;
						i_selector.setDragX(i_region.right);
					}
				}
			},
			{
				key: Ext.event.Event.UP,
				shift: true,
				ctrl: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					var i_target = i_event.getTarget();
					var i_element = Ext.get(i_target);
					var i_component = i_element.component;

					if (!i_component) {
						i_component = i_element.getParent().component;
					}

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var i_region = i_selector.getRegion(false, true);

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_region.bottom
						}, o_rules);

						var n_lin = o_coords.lin;

						var n_y = IceCap.util.Handler.getY(n_lin, o_rules.lineScale);

						if (n_y == Math.floor(i_region.bottom)) {
							n_y = IceCap.util.Handler.getY(n_lin - 1, o_rules.lineScale);
						}

						i_selector.setDragY(n_y);
					}
					else {
						if (!i_component.isXType("field")) {

							var i_cursor = i_self.getCursor();

							var o_click = Ext.apply({
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY()
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col - 1, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							var n_dragX = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_dragY = IceCap.util.Handler.getY(o_position.lin + 1, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.show();

							i_selector.setSelecting(true);

							i_selector.setDragX(n_dragX);
							i_selector.setDragY(n_dragY);

							i_event.stopEvent();
						}
					}
				}
			},
			{
				key: Ext.event.Event.DOWN,
				shift: true,
				ctrl: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					var i_target = i_event.getTarget();
					var i_element = Ext.get(i_target);
					var i_component = i_element.component;

					if (!i_component) {
						i_component = i_element.getParent().component;
					}

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var i_region = i_selector.getRegion(false, true);

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_region.bottom
						}, o_rules);

						var n_lin = o_coords.lin + 1;

						var n_y = IceCap.util.Handler.getY(n_lin, o_rules.lineScale);

						if (n_y == Math.floor(i_region.bottom)) {
							n_y = IceCap.util.Handler.getY(n_lin + 1, o_rules.lineScale);
						}

						i_selector.setDragY(n_y);
					}
					else {
						if (!i_component.isXType("field")) {

							var i_cursor = i_self.getCursor();

							var o_click = Ext.apply({
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY()
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col - 1, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							var n_dragX = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_dragY = IceCap.util.Handler.getY(o_position.lin + 1, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.show();

							i_selector.setSelecting(true);

							i_selector.setDragX(n_dragX);
							i_selector.setDragY(n_dragY);

							i_event.stopEvent();
						}
					}
				}
			},
			{
				key: Ext.event.Event.UP,
				shift: false,
				ctrl: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {

						if (!i_event.target.type) {

							i_event.stopEvent();

							var i_cursor = i_self.getCursor();
							var o_position = i_self.getCurrentPosition();

							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							o_position.lin--;

							if (o_position.lin < 1) {
								o_position.lin = 1;
							}

							var o_box = {
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY() - IceCap.util.Handler.getHeight(1, o_rules.lineScale),
								width: i_cursor.getWidth(),
								height: i_cursor.getHeight(),
								right: i_cursor.getLocalX() + i_cursor.getWidth(),
								bottom: i_cursor.getLocalY(),
								height: 1
							};


							Ext.Array.each(a_inputs, function (i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {
									b_intersect = true;
									i_field.focus(false, 10);
									return false;
								}
							});

							var b_intersect = false;

							Ext.Array.each(a_inputs, function(i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {

									b_intersect = true;
									i_field.focus(false, 10);

									var n_start = o_position.col - i_field.col;
									var i_inputEl = i_field.inputEl;
									i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = n_start;

									return false;
								}
							});

							if (!b_intersect) {
								i_cursor.moveCursor(o_position);
							}
							i_self.setCurrentPosition(o_position);
						}
						else {
							i_self.doNavigationKey(0);
						}
					}
				}
			},
			{
				key: Ext.event.Event.DOWN,
				shift: false,
				ctrl: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {

						if (!i_event.target.type) {

							i_event.stopEvent();

							var i_cursor = i_self.getCursor();
							var o_position = i_self.getCurrentPosition();
							var o_inputData = i_self.getInputData();

							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							o_position.lin++;

							if (o_position.lin > o_inputData.height) {
								o_position.lin = o_inputData.height;
							}

							var o_box = {
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY() + IceCap.util.Handler.getHeight(1, o_rules.lineScale),
								width: i_cursor.getWidth(),
								height: i_cursor.getHeight(),
								right: i_cursor.getLocalX() + i_cursor.getWidth(),
								bottom: i_cursor.getLocalY() + IceCap.util.Handler.getHeight(1, o_rules.lineScale) + i_cursor.getHeight(),
								height: 1
							};

							var b_intersect = false;

							Ext.Array.each(a_inputs, function(i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {

									b_intersect = true;
									i_field.focus(false, 10);

									var n_start = o_position.col - i_field.col;
									var i_inputEl = i_field.inputEl;
									i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = n_start;

									return false;
								}
							});

							if (!b_intersect) {
								i_cursor.moveCursor(o_position);
							}
							i_self.setCurrentPosition(o_position);
						}
						else {
							i_self.doNavigationKey(1);
						}
					}
				}
			},
			{
				key: Ext.event.Event.LEFT,
				shift: false,
				ctrl: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {
						if (!i_event.target.type) {
							i_event.stopEvent();

							var i_cursor = i_self.getCursor();
							var o_position = i_self.getCurrentPosition();

							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							o_position.col--;

							if (o_position.col < 1) {
								o_position.col = 1;
							}

							var o_box = {
								x: i_cursor.getLocalX() - IceCap.util.Handler.getWidth(1, o_rules.fontScale),
								y: i_cursor.getLocalY(),
								width: i_cursor.getWidth(),
								height: i_cursor.getHeight(),
								right: (i_cursor.getLocalX() - IceCap.util.Handler.getWidth(1, o_rules.fontScale)) + i_cursor.getWidth(),
								bottom: i_cursor.getLocalY() + i_cursor.getHeight(),
								height: 1
							};


							var b_intersect = false;

							Ext.Array.each(a_inputs, function(i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {
									b_intersect = true;
									i_field.focus(false, 10);
									return false;
								}
							});

							if (!b_intersect) {
								i_cursor.moveCursor(o_position);
							}

							i_self.setCurrentPosition(o_position);
						}
					}
				}
			},
			{
				key: Ext.event.Event.RIGHT,
				shift: false,
				ctrl: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {
						if (!i_event.target.type) {

							i_event.stopEvent();

							var i_cursor = i_self.getCursor();
							var o_position = i_self.getCurrentPosition();
							var o_inputData = i_self.getInputData();

							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							o_position.col++;

							if (o_position.col > o_inputData.width) {
								o_position.col = o_inputData.width;
							}

							var o_box = {
								x: i_cursor.getLocalX() + IceCap.util.Handler.getWidth(1, o_rules.fontScale),
								y: i_cursor.getLocalY(),
								width: i_cursor.getWidth(),
								height: i_cursor.getHeight(),
								right: i_cursor.getLocalX() + IceCap.util.Handler.getWidth(1, o_rules.fontScale) + i_cursor.getWidth(),
								bottom: i_cursor.getLocalY() + i_cursor.getHeight(),
								height: 1
							};

							var b_intersect = false;

							Ext.Array.each(a_inputs, function(i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {
									b_intersect = true;
									i_field.focus(false, 10);
									return false;
								}
							});

							if (!b_intersect) {
								i_cursor.moveCursor(o_position);
							}

							i_self.setCurrentPosition(o_position);
						}
					}
				}
			},
			{
				key: Ext.event.Event.TAB,
				shift: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {
						i_event.stopEvent();
						i_event.stopPropagation();

						i_self.doNavigationKey(1, true);
					}


				}
			},
			{
				key: Ext.event.Event.TAB,
				shift: true,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {
						i_event.stopEvent();
						i_event.stopPropagation();

						i_self.doNavigationKey(0, true);
					}
				}
			},
			{
				key: Ext.event.Event.NUM_PLUS,
				fn: function(n_key, i_event) {

					i_event.stopEvent();

					var i_key = this;
					var i_self = i_key.target.component;

					var i_field = i_self.getCurrentField();

					if (i_field) {

						var n_start = i_field.inputEl.el.dom.selectionStart;

						var s_text = i_field.getValue();

						s_text = s_text.substr(0, n_start);

						i_field.setValue(s_text);

						i_self.doNavigationKey(1, true);
					}
				}
			},
			{
				key: Ext.event.Event.HOME,
				ctrl: true,
				alt: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();

					var i_key = this;
					var i_self = i_key.target.component;

					var b_markerActive = i_self.getMarkerActive();
					var i_marker = i_self.getMarker();

					i_self.setMarkerActive(!b_markerActive);

					i_marker.toggle();
				}
			},
			{
				key: Ext.event.Event.INSERT,
				ctrl: false,
				alt: false,
				fn: function (n_key, i_event) {

					var n_type = i_self.getTypeMode();
					switch (n_type) {
						case IceCap.util.Handler.typeMode.OVERWRITE:
							n_type = IceCap.util.Handler.typeMode.FOCUS;
							break;
						case IceCap.util.Handler.typeMode.FOCUS:
							n_type = IceCap.util.Handler.typeMode.INSERT;
							break;
						default:
							n_type = IceCap.util.Handler.typeMode.OVERWRITE;
							break;
					}

					i_self.setTypeMode(n_type);
				}
			},
			{
				key: Ext.event.Event.A,
				ctrl: true,
				alt: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;

					var i_target = i_event.getTarget();

					var i_element = Ext.get(i_target);

					if (!i_element.isInputField()) {
						var i_selector = i_self.getSelector();

						var o_inputData = i_self.getInputData();

						i_event.stopEvent();

						i_selector.setSelecting(true);


						i_selector.setLeft(IceCap.util.Handler.getX(1));
						i_selector.setTop(IceCap.util.Handler.getY(1));

						i_selector.setDragX(IceCap.util.Handler.getX(o_inputData.width));
						i_selector.setDragY(IceCap.util.Handler.getY(o_inputData.height + 1));

						i_selector.setSelecting(false);
					}
				}
			},
			{
				key: Ext.event.Event.C,
				ctrl: true,
				shift: true,
				alt: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (i_selector.isVisible()) {
						i_event.stopEvent();

						var i_field  = IceCap.util.Handler.getCopyArea();

						var a_inputs = IceCap.util.Handler.getInputFields(i_self);
						var a_labels = IceCap.util.Handler.getLabels(i_self);

						var i_region = i_selector.getRegion(true, true);

						var n_rows = Math.round(i_region.height / IceCap.util.Handler.getHeight(1, o_rules.fontScale));
						var n_cols = Math.round(i_region.width / IceCap.util.Handler.getWidth(1, o_rules.lineScale));

						var a_copyLabels = IceCap.util.Handler.getCopyValues(a_labels, n_rows, n_cols, i_region, o_rules, 0);
						var a_copyFields = IceCap.util.Handler.getCopyValues(a_inputs, n_rows, n_cols, i_region, o_rules, 1);

						var a_result = [];

						Ext.Array.each(a_copyLabels, function (s_label, n_index) {

							var s_result = "";

							var s_field = a_copyFields[n_index];

							var a_splitLabel = s_label.split("");
							var a_splitField = s_field.split("");

							var n_copy = a_splitLabel.length;

							for (var n_copyIndex = 0; n_copyIndex < n_copy; n_copyIndex++) {

								var s_charLabel = a_splitLabel[n_copyIndex];
								var s_charField = a_splitField[n_copyIndex];

								s_result += !Ext.isEmpty(Ext.String.trim(s_charLabel)) ? s_charLabel : s_charField;

							}

							a_result.push(s_result);
						});

						var s_result = a_result.join("\n");

						i_self.fireEvent("copyplus", s_result);
					}
				}
			},
			{
				key: Ext.event.Event.C,
				ctrl: true,
				alt: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (i_selector.isVisible()) {
						i_event.stopEvent();

						var i_field = IceCap.util.Handler.getCopyArea();

						i_field.setValue("");

						var a_inputs = IceCap.util.Handler.getInputFields(i_self);
						var a_labels = IceCap.util.Handler.getLabels(i_self);

						var i_region = i_selector.getRegion(true, true);

						var n_rows = Math.round(i_region.height / IceCap.util.Handler.getHeight(1, o_rules.lineScale));
						var n_cols = Math.round(i_region.width / IceCap.util.Handler.getWidth(1, o_rules.fontScale));

						var a_copyLabels = IceCap.util.Handler.getCopyValues(a_labels, n_rows, n_cols, i_region, o_rules, 0);
						var a_copyFields = IceCap.util.Handler.getCopyValues(a_inputs, n_rows, n_cols, i_region, o_rules, 1);

						var a_result = [];

						Ext.Array.each(a_copyLabels, function (s_label, n_index) {

							var s_result = "";

							var s_field = a_copyFields[n_index];

							var a_splitLabel = s_label.split("");
							var a_splitField = s_field.split("");

							var n_copy = a_splitLabel.length;

							for (var n_copyIndex = 0; n_copyIndex < n_copy; n_copyIndex++) {

								var s_charLabel = a_splitLabel[n_copyIndex];
								var s_charField = a_splitField[n_copyIndex];

								s_result += !Ext.isEmpty(Ext.String.trim(s_charLabel)) ? s_charLabel : s_charField;

							}

							a_result.push(s_result);
						});

						var s_result = a_result.join("\n");

						i_field.setValue(s_result);

						i_field.show();

						i_field.inputEl.dom.focus();

						i_field.inputEl.dom.select();

						document.execCommand("copy");

						i_selector.hide();

						i_field.hide();

						var i_main = i_self.getMain();
						i_main.focus();
					}
				}
			}
		];

		a_bindings = a_bindings.concat(i_self.getFKeys());

		var i_keyMap = Ext.create("Ext.util.KeyMap", {
			target: i_self.getEl(),
			binding: a_bindings
		});
	},

	getFKeys: function() {

		var i_self = this;

		var a_keys = [
			{
				key: Ext.event.Event.F1,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F1", i_event);
				}
			},
			{
				key: Ext.event.Event.F2,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F2", i_event);
				}
			},
			{
				key: Ext.event.Event.F3,
				shift: false,
				alt: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F3", i_event);
				}
			},
			{
				key: Ext.event.Event.F4,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F4", i_event);
				}
			},
			{
				key: Ext.event.Event.F5,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F5", i_event);
				}
			},
			{
				key: Ext.event.Event.F6,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F6", i_event);
				}
			},
			{
				key: Ext.event.Event.F7,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F7", i_event);
				}
			},
			{
				key: Ext.event.Event.F8,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F8", i_event);
				}
			},
			{
				key: Ext.event.Event.F9,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F9", i_event);
				}
			},
			{
				key: Ext.event.Event.F10,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F10", i_event);
				}
			},
			{
				key: Ext.event.Event.F11,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F11", i_event);
				}
			},
			{
				key: Ext.event.Event.F12,
				shift: false,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F12", i_event);
				}
			}
		];

		a_keys = a_keys.concat(i_self.getFShiftKeys());

		return a_keys;
	},

	getFShiftKeys: function() {

		var i_self = this;

		var a_keys = [
			{
				key: Ext.event.Event.F1,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F13", i_event);
				}
			},
			{
				key: Ext.event.Event.F2,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F14", i_event);
				}
			},
			{
				key: Ext.event.Event.F3,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F15", i_event);
				}
			},
			{
				key: Ext.event.Event.F4,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F16", i_event);
				}
			},
			{
				key: Ext.event.Event.F5,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F17", i_event);
				}
			},
			{
				key: Ext.event.Event.F6,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F18", i_event);
				}
			},
			{
				key: Ext.event.Event.F7,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F19", i_event);
				}
			},
			{
				key: Ext.event.Event.F8,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F20", i_event);
				}
			},
			{
				key: Ext.event.Event.F9,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F21", i_event);
				}
			},
			{
				key: Ext.event.Event.F10,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F22", i_event);
				}
			},
			{
				key: Ext.event.Event.F11,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F23", i_event);
				}
			},
			{
				key: Ext.event.Event.F12,
				shift: true,
				fn: function(n_key, i_event) {

					i_self.doKeyEvent("F24", i_event);
				}
			}
		];

		return a_keys;
	},

	createCursor: function() {

		var i_self = this;
		var o_inputData = i_self.getInputData();
		var o_rules = i_self.getCssRules();

		var i_cursor = Ext.widget("icecap-cursor", {
			theme: i_self.getTheme(),
			width: IceCap.util.Handler.getWidth(1, o_rules.fontScale),
			listeners: {
				show: {
					fn: function(i_cursor) {

						var i_marker = i_self.getMarker();
						var b_active = i_marker.getInUse();

						if (b_active) {
							i_marker.show();
						}
					}
				},
				render: {
					fn: function(i_item) {
						i_item.hide();
					}
				},
				afterrender: {
					fn: function(i_cursor) {

						var i_content = i_self.getContent();

						var a_fields = IceCap.util.Handler.getInputFields(i_content);

						if (a_fields.length === 0) {

							i_cursor.show();

							i_cursor.moveCursor({
								col: o_inputData.csrCol || 1,
								lin: o_inputData.csrLin || 1
							});
						}
					}
				}
			},
			moveCursor: function(o_position) {

				var i_cursor = this;
				var i_marker = i_self.getMarker();
				var o_rules = i_self.getCssRules();

				var n_x = IceCap.util.Handler.getX(o_position.col - 1);
				var n_y = IceCap.util.Handler.getY(o_position.lin + 1);

				i_cursor.move([
					(n_x * o_rules.fontScale) - (o_rules.fontScale < 1 ? (1/2) * o_rules.fontScale : 0),
					(n_y - 6) * o_rules.lineScale
				]);
				i_marker.move([
					n_x * o_rules.fontScale - (o_rules.fontScale < 1 ? (1/2) * o_rules.fontScale : 0),
					(n_y - 7) * o_rules.lineScale
				]);

				i_self.updateCurrentPosition(o_position);
			}
		});

		i_self.setCursor(i_cursor);

		return i_cursor;
	},

	createMarker: function() {

		var i_self = this;

		var i_marker = Ext.widget("icecap-marker", {
			hidden: true,
			active: false,
			inUse: false,
			ui: i_self.getTheme() || "default"
		});

		i_self.setMarker(i_marker);

		return i_marker;
	},

	findFocus: function() {

		var i_self = this;
		var i_main = i_self.getMain();
		var i_content = i_self.getContent();

		var a_fields = IceCap.util.Handler.getInputFields(i_content);

		if (a_fields.length > 0) {

			var i_field = a_fields[0];
			i_field.focus(true, 10);
		}
		else {
			i_main.focus(true, 10);
		}
	},

	doTimer: function() {

		var i_self = this;

		var i_timer = i_self.getTimer();
		if (!i_timer) {
			i_timer = new Ext.util.DelayedTask(function() {
				i_self.setLoading(true);
			});

			i_self.setTimer(i_timer);

			i_timer.delay(1000);
		}
	},

	cancelTimer: function() {

		var i_self = this;

		var i_timer = i_self.getTimer();

		if (i_timer) {
			i_timer.cancel();
			i_self.setTimer(null);
		}
	},

	onError: function(o_inputData) {

		var i_self = this;

		IceCap.util.Handler.messageBox({
			title: "Server Message",
			message: o_inputData.msgBox.text,
			yesText: "Ok",
			yesFn: function(btn) {
				i_self.findFocus();
			}
		});
	},

	updateMessage: function(o_inputData) {

		var i_self = this;
		var o_rules = i_self.getCssRules();
		var i_statusbar = i_self.getStatusBar();

		var a_messages = Ext.Array.from(o_inputData.message);

		var a_result = [];

		if (a_messages.length > 1) {

			a_result.push(a_messages[0].text);
		}
		else {
			Ext.Array.each(a_messages, function(o_message) {
				a_result.push(o_message.text);
			});
		}

		var i_messageLabel = i_statusbar.getComponent("icecap-message");
		var i_languageButton = i_statusbar.getComponent("icecap-language");
		var i_translatorButton = i_statusbar.getComponent("icecap-translator");
		var i_position = i_statusbar.getComponent("icecap-position");
		var i_type = i_statusbar.getComponent("icecap-typemode");

		var s_message = a_result.join(" ");

		if (Ext.String.startsWith(s_message.toLowerCase(), "(c)")) {
			i_messageLabel.removeCls("icecap-statusbar-error");

		}
		else {
			i_messageLabel.addCls("icecap-statusbar-error")
		}

		i_messageLabel.setText(s_message);

		i_messageLabel.setStyle("font-size", "calc(1em * " + o_rules.fontScale);
		i_languageButton.setStyle("font-size", "calc(1em * " + o_rules.fontScale);
		i_translatorButton.setStyle("font-size", "calc(1em * " + o_rules.fontScale);
		i_position.setStyle("font-size", "calc(1em * " + o_rules.fontScale);
		i_type.setStyle("font-size", "calc(1em * " + o_rules.fontScale);

	},

	applyFFW: function (o_config) {

		var i_self = this;
		var s_hex = o_config.ffw;
		var b_fixed = IceCap.util.Handler.getFixed();

		var o_field = {
			xtype: "icecap-input"
		};

		var o_fieldStyle = {
		};

		if (o_config.ta) {

			Ext.apply(o_fieldStyle, {
				"text-align": o_config.ta
			});
		}

		if (s_hex) {

			var n_hex = parseInt(s_hex);

			var n_sanHex = IceCap.util.Handler.createIndicators(s_hex);

			if (n_sanHex & IceCap.util.Handler.FFW.BYPASS) {

				Ext.apply(o_field, {
					readOnly: true,
					tabIndex: -1,
					unselected: true
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.IO_FEATURE) {

				Ext.apply(o_field, {
					readOnly: true,
					selectOnFocus: true
				});
			}


			if (n_sanHex & IceCap.util.Handler.FFW.ALPHA_ONLY) {

				Ext.apply(o_field, {
					maskRe: new RegExp("[a-z A-Z ,\\.\\-]")
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.NUMERIC_ONLY) {

				Ext.apply(o_field, {
					validator: function(value) {

						var b_valid = true;

						if (value) {
							var i_regex = new RegExp("^(?:\\+|\\-){0,1}[0-9]+(?:(,|\\.)[0-9]+){0,1}$");
							b_valid = i_regex.test(value);
						}
						
						return b_valid ? "" : "Must be pattern <strong>(+ or -) xxx ( , or . xxx)</strong> where x is <strong>0-9</strong><br>Anything in Parentheses is optinal";
					},
					maskRe: new RegExp("[\\+\\-,\\.0-9]")
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.DIGITS_ONLY) {

				Ext.apply(o_field, {
					maskRe: new RegExp("[0-9]")
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.MOD_DATA) {

				Ext.apply(o_field, {
					listeners: {
						afterrender: {
							fn: function (i_field) {

								i_field.originalValue = 0xFF;
							},
							single: true
						}
					}
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.AUTO_ENTER) {

				// THIS WE DONT NEED IN THE MODERN WORLD...

				// Ext.apply(o_field, {
				// 	listeners: {
				// 		blur: {
				// 			fn: function(i_field) {
				// 				i_self.doKeyEvent("ENTER");
				// 			}
				// 		}
				// 	}
				// });
			}

			if (n_sanHex & IceCap.util.Handler.FFW.MONOCASE) {

				// Ext.apply(o_fieldStyle, {
				// 	"text-transform": "uppercase"
				// });
			}

			if (n_sanHex & IceCap.util.Handler.FFW.MAND_ENTER) {

				Ext.apply(o_field, {
					allowBlank: false
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.RA_ZEROFILL ||
				n_sanHex & IceCap.util.Handler.FFW.RA_BLANKFILL ||
				n_sanHex & IceCap.util.Handler.FFW.RA_MANDATORY) {

				Ext.apply(o_fieldStyle, {
					"text-align": "right"
				});
			}

			if (o_config.atr == "27" && n_hex & (1 << 13)) {

				Ext.apply(o_field, {
					hidden: true,
					disabled: true
				});
			}
		}

		Ext.apply(o_field, {
			fieldStyle: o_fieldStyle
		});

		return o_field;
	},

	updateCurrentPosition: function (o_position) {

		var i_self = this;
		var i_statusbar = i_self.getStatusBar();

		if (i_statusbar) {
			var i_position = i_statusbar.getComponent("icecap-position");

			if (i_position) {

				var a_result = [
					o_position.lin,
					o_position.col
				];

				i_position.setText(a_result.join("/"));
			}

			i_self.updateTypeMode(i_self.getTypeMode())
		}
	},

	updateTypeMode: function (n_type) {

		var i_self = this;

		var i_statusbar = i_self.getStatusBar();

		if (i_statusbar) {

			var i_typeLabel = i_statusbar.getComponent("icecap-typemode");

			var a_mode = [
			];

			if (i_typeLabel) {

				switch (n_type) {
					case IceCap.util.Handler.typeMode.OVERWRITE:
						a_mode.push("DEL");
						break;
					case IceCap.util.Handler.typeMode.FOCUS:
						a_mode.push("WEB");
						break;

					default:
						a_mode.push("INS");
						break;
				}

				i_typeLabel.setHtml(a_mode.join(" "));
			}
		}
	},

	updateEdit: function (value) {

		var i_self = this;

		if (i_self.rendered) {

			IceCap.util.Handler.getData({
				func: "",
				i18nLearning: false,
				session: i_self.getSessionValue(),
				translateMode: value
			}, {}, function (o_inputData) {

				o_inputData = o_inputData || {};

				i_self.setInputData(o_inputData);

				i_self.recreate();
			});
		}
	},

	updateActiveLanguage: function (value) {

		var i_self = this;

		if (i_self.rendered) {

			IceCap.util.Handler.getData({
				func: "",
				i18nLearning: false,
				session: i_self.getSessionValue(),
				translateMode: value,
				language: value,
			}, {}, function (o_inputData) {

				o_inputData = o_inputData || {};

				i_self.setInputData(o_inputData);

					i_self.recreate();
			});
		}
	},

	createEditor: function(o_config, o_data, f_callback, b_split) {

		var i_self = this;
		var o_rules = i_self.getCssRules();

		var s_active = i_self.getActiveLanguage();

		f_callback = f_callback || Ext.emptyFn;

		var o_value = o_data.translation || {};

		var s_original = o_data.text || o_config.dta;
		var s_dta = s_original;

		var a_split = s_original.split("=");

		if (a_split.length > 1 && b_split) {
			s_dta = a_split.pop();
		}

		var i_editor = new Ext.Editor({
			updateEl: false,
			alignment: "l-l",
			hideEl: false,
			ignoreNoChange: true,
			allowBlur: true,
			field: {
				xtype: "icecap-i18n-textfield",
				ui: "icecap-field",
				enforceMaxLength: true,
				languages: i_self.getLanguages(),
				languageActive: s_active ? true : false,
				language: s_active,
				value: o_value,
				global: o_data.general,
				originalText: s_dta
			},
			getValue: function () {

				var i_editor = this;
				var i_field = i_editor.field;
				var value = i_field.getValue();

				return value;
			},
			listeners: {
				beforecomplete: {
					fn: function (i_editor) {

						var i_field = i_editor.field;
						var s_value = i_field.getValue();

						if (Ext.isObject(s_value)) {

							Ext.Object.each(s_value, function (s_key, value) {
								value = value.padEnd(i_field.maxLength);
								s_value[s_key] = value;
							});
						}
						else {
							s_value = s_value.padEnd(i_field.maxLength);
							i_field.setValue(s_value);
						}

						return !Ext.isEmpty(s_value);
					}
				},
				complete: {
					fn: function (i_editor, i_element) {

						var i_editorField = i_editor.field;
						var value = i_editorField.getValue();

						if (i_editorField.isDirty()) {

							var i_menu = i_editorField.getSelections();
							var i_check = i_menu.items.get("check-global");
							var b_check = i_check.checked;

							IceCap.util.Handler.doUpsertTranslation({
								screen_id: i_self.getOriginalTitle(),
								linno: o_config.lin,
								colno: o_config.col,
								maxLen: i_editorField.maxLength,
								tolinno: o_config.lin,
								text: o_config.originalValue,
								txtId: o_config.txtId || 0,
								general: b_check,
								translation: i_editorField.getValue()
							}, f_callback);
						}
					}
				},
				globalchange: {
					fn: function(i_editorField, b_checked) {

						if (i_editorField.isDirty()) {

							var i_menu = i_editorField.getSelections();
							var i_check = i_menu.items.get("check-global");
							var b_check = b_checked;

							IceCap.util.Handler.doUpsertTranslation({
								screen_id: i_self.getOriginalTitle(),
								linno: o_config.lin,
								colno: o_config.col,
								maxLen: i_editorField.maxLength,
								tolinno: o_config.lin,
								text: o_config.originalValue,
								txtId: o_config.txtId || 0,
								general: b_check,
								translation: i_editorField.getValue()
							}, Ext.emptyFn);
						}
					}
				},
				selectionopen: {
					fn: function(i_editorField) {
						i_editor.allowBlur = false;
					}
				},
				selectionclose: {
					fn: function(i_editorField) {
						i_editor.allowBlur = true;
					}
				},
				canceledit: {
					fn: function (i_editor) {
						var i_field = i_editor.field;
						var i_menu = i_field.getSelections();
						i_menu.hide();
					}
				}
			}
		});


		var n_width = (IceCap.util.Handler.getWidth(o_config.len, o_rules.fontScale) + (IceCap.util.Handler.getWidth(1, o_rules.fontScale) / 2)) + 45;
		var i_editorField = i_editor.field;
		i_editor.setWidth(n_width);
		i_editorField.setWidth(n_width);
		i_editorField.maxLength = o_config.len;
		i_editorField.focus(false, 50);

		return i_editor;
	},

	createSelector: function () {

		var i_self = this;

		var i_content = i_self.getContent();

		var i_selector

		if (i_content.rendered) {

			var i_region = i_content.getRegion(true);

			var o_inputData = i_self.getInputData();

			var i_selector = Ext.widget("icecap-selector", {
				left: 0,
				top: 0,
				dragX: 0,
				dragY: 0,
				selecting: false,
				renderTo: i_content.getEl(),
				shadow: false
			});

			i_self.setSelector(i_selector);
		}
		else {
			i_content.on({
				afterrender: {
					fn: function() {

						i_selector = i_self.createSelector();
						i_content.add(i_selector);

						i_content.on({
							mousedown: {
								element: "el",
								fn: function (i_event) {

									var i_selector = i_self.getSelector();

									var i_box = i_content.getRegion(true, false);

									var i_target = Ext.get(i_event.getTarget());

									if (i_box.contains(i_event.browserEvent) &&
										!i_target.isFocusable() &&
										!i_event.within(i_selector.getEl())) {

										var o_click = Ext.apply({
											x: i_event.pageX - i_box.x,
											y: i_event.pageY - i_box.y
										});

										var o_position = IceCap.util.Handler.toColAndLine(o_click);

										var n_x = IceCap.util.Handler.getX(o_position.col);
										var n_y = IceCap.util.Handler.getY(o_position.lin);

										i_selector.resetPos(n_x, n_y);

										i_selector.mouseDown = true;

										if (i_selector.isVisible()) {
											i_selector.setVisible(false);
										}
									}
								}
							},
							mousemove: {
								element: "el",
								fn: function (i_event) {

									var i_selector = i_self.getSelector();

									if (i_selector && i_selector.mouseDown) {

										var i_box = i_content.getRegion(true, false);

										var o_click = Ext.apply({
											x: i_event.pageX - i_box.x,
											y: i_event.pageY - i_box.y
										});

										var o_position = IceCap.util.Handler.toColAndLine(o_click);

										var n_x = IceCap.util.Handler.getX(o_position.col);
										var n_y = IceCap.util.Handler.getY(o_position.lin);


										i_selector.setDragX(n_x);
										i_selector.setDragY(n_y);

										i_selector.setSelecting(true);
									}
								}
							},
							mouseup: {
								element: "el",
								fn: function (i_event) {

									var i_selector = i_self.getSelector();

									if(i_selector) {
										i_selector.mouseDown = false;
										i_selector.setSelecting(false);
										i_selector.fireEvent("dragcomplete", i_selector);
									}
								}
							}
						});
					}
				}
			})
		}

		return i_selector;
	}
});
Ext.define("IceCap.controller.Main", {
	extend: "Ext.app.ViewController",

	alias: "controller.icecap.view.main",

	listen: {
		global: {
			beforelogout: {
				fn: function() {

					var i_controller = this;
					i_controller.onBeforeLogout();
				}
			}
		}
	},

	onAfterRender: function(i_panel) {

		var i_self = i_panel;

		i_self.addKeyEvents();

		var i_content = i_self.getContent();
		var i_main = i_self.getMain();
		var o_rules = i_self.getCssRules();

		var o_inputData = i_self.getInputData() || {};

		if (o_inputData.window) {
			i_self.doCreateFromData(o_inputData);
		}

		if (i_content) {

			var a_fields = IceCap.util.Handler.getInputFields(i_content);

			var i_found = Ext.Array.findBy(a_fields, function (i_field) {
				return i_field.getTabIndex() == i_self.getNeedFocus();
			});

			if (i_found) {
				i_found.focus(false, 10);
			}
			else {
				i_self.setCurrentPosition({
					col: o_inputData.csrCol,
					lin: o_inputData.csrLin
				});

				i_main.focus(true, 10);
			}

			i_content.on({
				mousedown: {
					element: "el",
					fn: function (i_event) {

						var i_selector = i_self.getSelector();

						var i_box = i_content.getRegion(true, false);

						var i_target = Ext.get(i_event.getTarget());
						var i_component = i_target.component || Ext.ComponentManager.getActiveComponent();

						if (!i_component.isXType("field") &&
							!i_event.within(i_selector.getEl())) {

							var o_click = Ext.apply({
								x: i_event.pageX - i_box.x,
								y: i_event.pageY - i_box.y
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.mouseDown = true;

							if (i_selector.isVisible()) {
								i_selector.setVisible(false);
							}
						}
					},
					buffer: 10
				},
				mousemove: {
					element: "el",
					fn: function (i_event) {

						var i_selector = i_self.getSelector();

						if (i_selector && i_selector.mouseDown) {

							var i_box = i_content.getRegion(true, false);

							var o_click = Ext.apply({
								x: i_event.pageX - i_box.x,
								y: i_event.pageY - i_box.y
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);


							i_selector.setDragX(n_x);
							i_selector.setDragY(n_y);

							i_selector.setSelecting(true);
						}
					}
				},
				mouseup: {
					element: "el",
					fn: function (i_event) {

						var i_selector = i_self.getSelector();

						if(i_selector) {
							i_selector.mouseDown = false;
							i_selector.setSelecting(false);
							i_selector.fireEvent("dragcomplete", i_selector);
						}
					}
				}
			});

			Ext.getBody().on({
				paste: {
					fn: function (i_event) {

						var i_target = i_event.getTarget();
						var i_element = Ext.get(i_target);

						if (i_element.isInputField()) {

							i_event.stopEvent();

							var i_clipboardData = i_event.browserEvent.clipboardData;

							var s_data = i_clipboardData.getData("text/plain") || "";

							var a_split = s_data.split("\n");

							if (a_split.length > 0) {

								Ext.suspendLayouts();

								var i_component = i_element.component;

								var i_window = i_component.up("icecap-window");

								var i_container = i_component.up("icecap-panel");

								if (i_window) {

									i_container = i_window.getContent();
								}

								var a_inputs = IceCap.util.Handler.getInputFields(i_container);

								var a_filtered = Ext.Array.filter(a_inputs, function (i_field) {

									var b_found = false;

									if (i_field.lin >= i_component.lin) {

										b_found = i_field.col == i_component.col;

										if (!b_found) {
											b_found = ((i_field.col + 2) == i_component.col || (i_field.col - 2 == i_component.col));
										}
									}

									return b_found;
								});

								var i_currentField = null;
								var a_temp = [];

								var n_index = 0;

								while (a_split.length > 0) {

									var s_value = a_split.shift();

									var i_found = Ext.Array.findBy(a_filtered, function (i_search) {
										return i_search.lin == (i_component.lin + n_index);
									});

									//s_value = s_value.trim();

									var s_result = "";

									if (i_found) {

										i_currentField = i_found;
										var a_temp = [];
										var n_maxLength = i_found.maxLength;
										var a_chars = s_value.split("");
										var n_char = 0;
										var b_allowed = true;
										
										s_result += a_chars[n_char];

										if (n_maxLength > 0 && s_value.length) {

											s_result = "";
											var b_allowed = true;
											while (b_allowed && s_result.length < n_maxLength && s_result.length < a_chars.length) {

												var s_char = a_chars[n_char];

												if (i_found.maskRe) {
													b_allowed = i_found.maskRe.test(s_char);
												}

												if (b_allowed) {
													s_result += s_char;
													n_char++;
												}
											}

										}

										if (s_result.length > 0) {
											a_temp.push(s_result);
										}
										
										if (a_split.length === 0 && n_char == a_chars.length) {

											i_currentField.setValue(a_temp.join("\n"));
											a_temp = [];
											i_currentField = null;
										}
										else {

											if (a_temp.length > 0) {
												i_currentField.setValue(a_temp.join("\n"));
											}

											var n_col = i_found.col + n_char;
											var n_currentCol = n_char;

											while(a_chars[n_currentCol] == " ") {
												n_currentCol++;
											}

											while (a_chars.length > n_char) {

												var i_temp = Ext.Array.findBy(a_inputs, function (i_search) {
													return i_search.col == n_col && i_search.lin == i_found.lin;
												});

												if (!i_temp) {
													n_col++;
													n_char++;
												}
												else {

													n_maxLength = i_temp.maxLength;
													if (n_maxLength > 0) {

														while(a_chars[n_currentCol] == " ") {
															n_currentCol++;
														}

														n_char = n_currentCol;

														var s_chars = "";
														var b_allowed = true;
														while (b_allowed && n_char < a_chars.length && s_chars.length < n_maxLength) {

															var s_char = a_chars[n_currentCol];

															if (i_temp.maskRe) {
																b_allowed = i_temp.maskRe.test(s_char);
															}
			
															if (b_allowed) {
																s_chars += s_char;
															}

															n_col++;
															n_char++;
															n_currentCol++;
														}
														if (s_chars.length > 0) {
															i_temp.setValue(s_chars);
														}
														
													}
												}

											}
										}
									}
									else {
										if (i_currentField) {

											var i_box = i_currentField.getRegion(false, true);

											var o_pos = {
												x: IceCap.util.Handler.getX(i_component.col, o_rules.fontScale),
												y: IceCap.util.Handler.getY(i_component.lin + n_index, o_rules.lineScale) - 9,
												width: IceCap.util.Handler.getWidth(1, o_rules.fontScale),
												height: IceCap.util.Handler.getHeight(1, o_rules.lineScale),
											};

											Ext.apply(o_pos, {
												left: o_pos.x,
												right: o_pos.x + o_pos.width,
												top: o_pos.y,
												bottom: o_pos.y + o_pos.height
											});

											if (i_box.intersect(o_pos)) {

												a_temp.push(s_value);

												if (a_split.length == 0) {

													i_currentField.setValue(a_temp.join("\n"));
													a_temp = [];
													i_currentField = null;
												}
											}
											else {
												i_currentField.setValue(a_temp.join("\n"));
												a_temp = [];
												i_currentField = null;
											}
										}
									}

									n_index++;
								}

								i_component.focus(true, 10);

								Ext.resumeLayouts(true);
							}
						}
					}
				}
			});
		}
	},

	onSendData: function(o_config, o_data) {

		var i_controller = this;
		var o_saved = Ext.clone(o_config);
		var i_view = i_controller.getView();
		var s_session = i_view.getSessionValue();

		var o_options = i_view.getOptions();

		o_data = Ext.apply(o_data, {
			i18nLearning: false
		});

		Ext.apply(o_config, {
			session: s_session,
			translateMode:i_view.getEdit()
		});

		Ext.apply(o_config, o_options);

		if (!i_view.getWorking()) {
			i_view.setWorking(true);
			i_view.doTimer();
			IceCap.util.Handler.getData(o_config, o_data, function(o_inputData) {

				if (o_inputData.statusUpdate) {

					i_view.setWorking(false);
					i_view.updateMessage(o_inputData);
					if (o_inputData.status > -1) {
						i_view.doCreateFromData(o_inputData);
					}
					i_controller.onSendData(o_saved, o_data);
				}
				else {

					i_view.setLoading(false);
					i_view.cancelTimer();

					var f_callback = i_view.getResponseCallBack() || Ext.emptyFn;

					if (f_callback != Ext.emptyFn) {

						f_callback(o_inputData);
					}

					var o_plugin = o_inputData.plugin || Ext.apply({}, {
						require: []
					});

					var a_require = o_plugin.require || [];
					var s_run = o_plugin.run || "";

					i_controller.doRequire(a_require, function() {

						if (s_run) {
							eval(s_run);
						}

						if (o_inputData.close) {
							i_view.close();
						}
						else {

							i_view.setWorking(false);
							i_view.doCreateFromData(o_inputData);

							i_view.fireEvent("stateupdate", i_view);
						}
					});
				}
			});
		}
	},

	onWheel: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();

		var i_content = i_view.getContent();

		if (i_content.body.getScrollTop() == 0) {
			var b_hasGrid = i_view.query("gridpanel").length > 0;
			var b_mappanel = i_view.query("icecap-gmappanel").length > 0;

			var n_delta = i_event.getWheelDelta();
			var s_event = "";

			if (n_delta > 0) {
				s_event = "ROLLDOWN";
			}
			else {
				s_event = "ROLLUP";
			}

			if (!b_hasGrid && !b_mappanel && !i_event.ctrlKey){
				i_controller.doKeyEvent(s_event);
			}
		}
	},

	onDblClick: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var o_inputData = i_view.getInputData();
		var i_cursor = i_view.getCursor();
		var o_rules = i_view.getCssRules();

		var i_content = i_view.getContent();
		var i_region = i_content.getRegion(true, false);

		var b_fireEvent = i_view.getEnterOnDblClick();

		var o_click = Ext.apply({
			x: i_event.pageX - i_region.x,
			y: i_event.pageY - i_region.y
		});

		var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

		if (b_fireEvent) {

			var a_metaFields = o_inputData.metaFields || [];

			var i_currentField = i_view.getCurrentField();

			if (i_currentField) {
				o_position = Ext.apply(o_position, {
					lin: i_currentField.lin,
					col: i_currentField.col
				});
				if (i_currentField.inputEl && i_currentField.getValue()) {
					o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);
				}
			}
			else {

				if (o_position.col > o_inputData.width) {
					o_position.col = o_inputData.width;
				}

				if (o_position.lin > o_inputData.height) {
					o_position.lin = o_inputData.height;
				}

				i_cursor.moveCursor(o_position);
				i_cursor[a_metaFields.length === 0 ? "show" : "hide" ]();
			}

			i_view.setCurrentPosition(o_position);

			if (a_metaFields.length === 0) {
				i_controller.doKeyEvent("ENTER");
			}
		}
		else {

			var n_x = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
			var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

			var o_rect = Ext.apply(o_click, {
				x: n_x,
				y: n_y,
				width: IceCap.util.Handler.getWidth(1, o_rules.fontScale),
				height: IceCap.util.Handler.getHeight(1, o_rules.lineScale),
				left: n_x,
				right: n_x+  IceCap.util.Handler.getWidth(1, o_rules.fontScale),
				top: n_y,
				bottom: n_y + IceCap.util.Handler.getHeight(1, o_rules.lineScale)
			});

			var a_labels = IceCap.util.Handler.getLabels(i_view);

			Ext.Array.each(a_labels, function(i_label) {

				var i_labelRegion = i_label.getRegion(false, true);

				if (i_labelRegion.intersect(o_rect)) {

					var i_selector = i_view.getSelector();

					var o_labelPos = IceCap.util.Handler.toColAndLine(i_labelRegion);

					var n_x = IceCap.util.Handler.getX(o_labelPos.col - 1, o_rules.fontScale);
					var n_y = IceCap.util.Handler.getY(o_labelPos.lin + 1, o_rules.lineScale);

					var a_split = i_label.el.dom.innerText.split(" ");

					var i_result;

					var n_posCol = 0;

					Ext.Array.each(a_split, function(s_word) {

						var n_wordX = i_labelRegion.x + IceCap.util.Handler.getX(n_posCol, o_rules.fontScale);
						var n_wordY = i_labelRegion.y;

						var i_wordRegion = Ext.util.Region.create();

						if(/[\/]/g.test(s_word)) {

							var a_temp = s_word.split(/[\/]/g);

							Ext.Array.each(a_temp, function(s_temp) {

								n_wordX = i_labelRegion.x + IceCap.util.Handler.getX(n_posCol, o_rules.fontScale);
								n_wordY = i_labelRegion.y

								Ext.apply(i_wordRegion, {
									x: n_wordX,
									y: n_wordY,
									width: IceCap.util.Handler.getWidth(s_temp.length, o_rules.fontScale),
									height: i_label.getHeight(),
									left: n_wordX,
									right: n_wordX +  IceCap.util.Handler.getWidth(s_temp.length, o_rules.fontScale),
									top: n_wordY,
									bottom: n_wordY + i_label.getHeight()
								});

								if (i_wordRegion.intersect(o_rect)) {
									i_result = i_wordRegion;
									return false;
								}

								n_posCol = n_posCol + s_temp.length + 1;
							});

						}
						else {

							Ext.apply(i_wordRegion, {
								x: n_wordX,
								y: n_wordY,
								width: IceCap.util.Handler.getWidth(s_word.length, o_rules.fontScale),
								height: i_label.getHeight(),
								left: n_wordX,
								right: n_wordX +  IceCap.util.Handler.getWidth(s_word.length, o_rules.fontScale),
								top: n_wordY,
								bottom: n_wordY + i_label.getHeight()
							});

							if (i_wordRegion.intersect(o_rect)) {
								i_result = i_wordRegion;
							}

							n_posCol = n_posCol + s_word.length + 1;
						}

						if (i_result) {
							return false;
						}
					});

					var n_dragX = IceCap.util.Handler.getX(o_labelPos.col, o_rules.fontScale);
					var n_dragY = IceCap.util.Handler.getY(o_labelPos.lin + 2, o_rules.lineScale);

					if (i_result) {

						n_x = i_result.x;
						n_y = i_result.y;

						n_dragX = i_result.right;
						n_dragY = i_result.bottom;
					}

					i_selector.resetPos(n_x, n_y);

					i_selector.show();

					i_selector.setSelecting(true);

					i_selector.setDragX(n_dragX);
					i_selector.setDragY(n_dragY);

					i_event.stopEvent();

					return false;
				}
			});
		}
	},

	onClick: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var o_inputData = i_view.getInputData();
		var i_cursor = i_view.getCursor();
		var i_content = i_view.getContent();
		var o_rules = i_view.getCssRules();

		var i_activeComponent = Ext.ComponentManager.getActiveComponent();

		var o_click = Ext.apply({
			x: i_event.pageX - i_content.getX(),
			y: i_event.pageY - i_content.getY() 
		});

		var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

		if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {

			var i_currentField = i_view.getCurrentField();

			var a_metaFields = o_inputData.metaFields || [];

			if (i_currentField) {
				o_position = Ext.apply(o_position, {
					lin: i_currentField.lin,
					col: i_currentField.col
				});
				if (i_currentField.inputEl && i_currentField.getValue()) {
					o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);
				}
			}
			else {

				var a_inputs = IceCap.util.Handler.getInputFields(i_view);

				var n_width = Math.ceil(IceCap.util.Handler.getWidth(1));
				var n_height = 2;

				var o_box = Ext.apply({
					x: IceCap.util.Handler.getX(o_position.col),
					y: IceCap.util.Handler.getY(o_position.lin),
					width: i_cursor.getWidth() || n_width,
					height: i_cursor.getHeight() || n_height,
					right: IceCap.util.Handler.getX(o_position.col) + i_cursor.getWidth(),
					bottom: IceCap.util.Handler.getY(o_position.lin) + i_cursor.getHeight()
				});

				var b_intersect = false;

				Ext.Array.each(a_inputs, function (i_field) {

					var i_element = i_field.getEl();

					if (i_element) {

						var i_region = i_field.getRegion(false, true);

						if (i_region.intersect(o_box)) {

							b_intersect = true;
							i_field.focus(false, 10);

							var n_start = o_position.col - i_field.col;
							var i_inputEl = i_field.inputEl;
							i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = n_start;

							return false;
						}
					}
				});

				if (!b_intersect) {

					if (o_position.col > o_inputData.width) {
						o_position.col = o_inputData.width;
					}

					if (o_position.lin > o_inputData.height) {
						o_position.lin = o_inputData.height;
					}

					i_cursor.moveCursor(o_position);

					i_cursor[a_metaFields.length === 0 ? "show" : "hide"]();
				}
			}
		}

		i_view.setCurrentPosition(o_position);
	},

	doArrowKeys: function (n_direction) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var a_fields = IceCap.util.Handler.getInputFields(i_view);
		var n_tabIndex = i_view.getCurrentTabIndex();

		var i_lastFocus = Ext.ComponentManager.getActiveComponent();

		var n_part = n_direction ? 1 : -1;

		if (i_lastFocus.isXType("field")) {

			var n_next = n_part > 0 ? n_tabIndex + 1 : n_tabIndex -1;

			var i_found;

			i_found = Ext.Array.findBy(a_fields, function (i_field) {
				return i_field.getTabIndex() === n_next;
			});

			if (!i_found) {
				i_found = n_part > 0 ? a_fields[0] : a_fields[a_fields.length - 1];
			}

			if (i_found) {
				i_found.focus(true, 10);
				n_tabIndex = i_found.getTabIndex();
			}
		}

		i_view.setCurrentTabIndex(n_tabIndex);
	},

	doTabKey: function (n_direction) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var a_fields = IceCap.util.Handler.getInputFields(i_view);
		var n_tabIndex = i_view.getCurrentTabIndex();

		var i_lastFocus = Ext.ComponentManager.getActiveComponent();

		var n_part = n_direction ? 1 : -1;

		if (i_lastFocus.isXType("field")) {

			var n_next = n_part > 0 ? n_tabIndex + 1 : n_tabIndex - 1;

			var i_found;

			i_found = Ext.Array.findBy(a_fields, function (i_field) {
				return i_field.getTabIndex() === n_next;
			});

			if (!i_found) {
				i_found = n_part > 0 ? a_fields[0] : a_fields[a_fields.length - 1];
				n_next = i_found.getTabIndex();
			}

			if (i_found) {
				i_found.focus(true, 10);
				n_tabIndex = i_found.getTabIndex();
			}
		}
		else {
			var i_field = a_fields[0];
			i_field.focus(true, 10);
			n_tabIndex = i_field.getTabIndex();
		}

		i_view.setCurrentTabIndex(n_tabIndex);
	},

	doKeyEvent: function (s_value) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var o_rules = i_view.getCssRules();

		var i_cursor = i_view.getCursor();

		var o_data = {
			key: s_value
		};

		var o_position = i_view.getCurrentPosition() || {
			col: 1,
			lin: 1
		};

		if (i_cursor && i_cursor.getEl()) {
			o_position = IceCap.util.Handler.toColAndLine({
				x: i_cursor.getLocalX(),
				y: i_cursor.getLocalY()
			}, o_rules);
		}


		var i_content = i_view.getContent();
		var i_form = i_content.getForm();
		var i_collectionField = i_form.getFields();
		var o_values = {};

		Ext.Array.each(i_collectionField.items, function (i_field) {
			if (i_field.isDirty()) {
				var value = i_field.getSubmitValue ? i_field.getSubmitValue() : i_field.getValue();
				o_values[i_field.itemId || i_field.initialConfig.id || i_field.name] = value;
			}
		});

		Ext.Object.each(o_values, function (s_key, value) {
			var s_id = "ses2.win." + s_key;
			o_data[s_id] = value;
		});

		o_data = Ext.apply(o_data, {
			csrLin: o_position.lin,
			csrCol: o_position.col
		});

		var f_callback = i_view.getRequestCallBack() || Ext.emptyFn;

		if (f_callback != Ext.emptyFn) {

			f_callback(o_data);
		}

		i_controller.onSendData({
			func: ""
		}, o_data);
	},

	doFKey: function(s_value) {

		var i_controller = this;

		i_controller.doKeyEvent(s_value);
	},

	doRequire: function(a_require, f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		a_require = a_require || [];

		if (a_require.length > 0) {

			var a_external = Ext.Array.filter(Ext.Array.map(a_require, function(s_value) {
				if (s_value.indexOf("/") > -1) {
					return s_value;
				}
			}), function(value) {
				return value;
			});

			var a_internal = Ext.Array.filter(Ext.Array.map(a_require, function(s_value) {
				if (s_value.indexOf("/") < 0) {
					return s_value;
				}
			}), function(value) {
				return value;
			});

			if (a_external.length > 0) {
				Ext.Loader.loadScriptsSync(a_external);
			}

			if (a_internal.length > 0) {
				Ext.syncRequire(a_internal);
			}
		}

		f_callback();
	},

	onPCO: function(o_inputData) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var i_keyMap = i_view.getKeyHandler();

		switch (o_inputData.cmdAct) {

			case 0:
				window.open(o_inputData.cmd, o_inputData.cmdTitle, "");
				break;
			case 1:

				var i_webcontainer = Ext.create("IceCap.view.WebContainer", {
					src: o_inputData.cmd
				});

				var i_window = Ext.widget("window", {
					title: o_inputData.cmdTitle,
					layout: "fit",
					collapsible: true,
					items: [
						i_webcontainer
					],
					width: window.outerWidth * 0.9,
					height: window.outerHeight * 0.9
				});

				i_window.show();
				break;
			default:

				var n_act = o_inputData.cmdWait || 0;

				if (n_act) {
					i_keyMap.disable();
				}


				var i_store = Ext.create('Ext.data.Store', {
					proxy: {
						type: "jsonp",
						timeout: "86400000",
						url: o_inputData.cmd,
						nocache: false,
						listeners: {
							exception: {
								fn: function(i_proxy, i_request, i_operation) {
									i_controller.onPCOError(i_operation.error, function() {
										if (n_act) {
											i_keyMap.enable();
											i_view.findFocus();
										}
									});
								}
							}
						}
					}
				});

				i_store.load({
					callback: function (o_result) {
						if (n_act) {
							i_keyMap.enable();
							i_view.findFocus();
						}
					}
				});
				break;
		}
	},

	onPCOError: function(s_error, f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		var i_template = new Ext.XTemplate(
			"<div class=\"iceCap-msg\">",
				"<h3>{header}</h3>",
				"<ul>",
					"<li>{message}</li>",
				"</ul>",
			"</div>"
		);

		var i_window = Ext.widget("window", {
			title: "PCO Error",
			width: 800,
			modal: true,
			closable: false,
			html: i_template.apply({
				header: "Error",
				message: s_error
			}),
			bodyPadding: 5,
			buttons: [{
				text: "Ok",
				tabIndex: 1,
				focusable: true,
				listeners: {
					afterrender: {
						fn: function(i_button) {
							setTimeout(function() {
								i_button.focus(false, 10);
							});
						}
					}
				},
				handler: function() {
					i_window.close();
					f_callback();
				}
			}]
		});

		i_window.show();
	},

	onDestroy: function(i_panel) {

		var s_session = i_panel.getSessionValue();

		var o_rules = i_panel.getCssRules();

		Ext.util.CSS.removeStyleSheet(o_rules.sheet);

		IceCap.util.Handler.removeSession(s_session);

		Ext.Ajax.request({
			method: "POST",
			url: IceCap.util.Handler.getPath({
				session: s_session,
				func: "",
				close: "on"

			})
		});
	},

	onBeforeDestroy: function() {

		var i_controller = this;
		var i_view = i_controller.getView();

		i_controller.onDestroy(i_view);

		var i_window = i_view.up("window");

		if (i_window) {
			i_window.close();
		}
	},

	onActivated: function() {

		var i_controller = this;
		var i_view = i_controller.getView();
		var i_cursor = i_view.getCursor();
		var i_main = i_view.getMain();
		var o_rules = i_view.getCssRules();

		var o_position = i_view.getCurrentPosition();

		var a_inputs = IceCap.util.Handler.getInputFields(i_view);


		var n_width = Math.ceil(IceCap.util.Handler.getWidth(1, o_rules.fontScale));
		var n_height = 2;

		var n_x = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
		var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

		if (i_cursor && i_cursor.rendered) {
			n_x = i_cursor.getLocalX();
			n_y = i_cursor.getLocalY();
		}

		var o_box = Ext.apply({
			x: n_x,
			y: n_y,
			width: n_width,
			height: n_height,
			right: n_x + n_width,
			bottom: n_y + n_height
		});

		var b_intersect = false;

		var o_inputData = i_view.getInputData() || {
			metaFields: []
		};

		var a_metaFields = o_inputData.metaFields || [];

		Ext.Array.each(a_inputs, function(i_field) {

			var i_element = i_field.getEl();

			if (i_element) {

				var i_region = i_field.getRegion(false, true);

				if (i_region.intersect(o_box)) {
					b_intersect = true;
					i_field.focus(false, 10);
					return false;
				}
			}
		});

		if (!b_intersect) {

			if (i_cursor) {

				i_cursor.moveCursor(o_position);

				i_cursor[a_metaFields.length === 0 ? "show" : "hide"]();
			}

			if (i_main) {
				setTimeout(function() {
					i_main.focus(true, 10);
				}, 10);
			}
		}
	},

	onApplicationClose: function() {

		var i_controller = this;
		var i_view = i_controller.getView();

		i_view.close();
	},

	onBeforeLogout: function() {

		var i_controller = this;
		var i_view = i_controller.getView();

		i_view.close();
	}
});
Ext.define("IceCap.view.Main", {

	xtype: "icecap-panel",

	extend: "Ext.panel.Panel",

	layout: "fit",

	ui: "",

	mixins: [
		"Ext.mixin.Mashup"
	],

	requires: [
		"IceCap.util.Handler",
		"IceCap.controller.Main",
		"IceCap.component.Cursor",
		"IceCap.component.Input",
		"IceCap.component.TextArea",
		"IceCap.component.Marker",
		"IceCap.component.Selector"
	],

	requiredScripts: [
		"/icecap/app/theme/default.css",
		"/icecap/app/icecap-overrides.js",
		"/system/shared/collection/fonts.css",
		"/icecap/app/theme/flags-svg.css"
	],

	config: {
		inputData: null,
		prevInputData: [],
		screenStack: [],
		lastTabIndex: 1,
		currentTabIndex: 1,
		content: null,
		keyArea: null,
		working: false,
		needFocus: 1,
		ignoreTitle: false,
		currentPosition: {
			col: 1,
			lin: 1
		},
		activeWindow: null,
		statusBar: null,
		main: null,
		sessionValue: "",
		keyMap: null,
		cursor: null,
		timer: null,
		func: "",
		initFunc: "",
		initCmd: "",
		responseCallBack: Ext.emptyFn,
		requestCallBack: Ext.emptyFn,
		theme: "",
		scale: 14,
		enterOnDblClick: false,
		marker: null,
		markerActive: false,
		options: {},
		messageText: "",
		typeMode: 3,
		resizeMode: 1,
		edit: false,
		originalTitle: "",
		languages: [],
		windows : [],
		translator: null,
		activeLanguage: "da",
		selector: null,
		keyHandler: null,
		cssRules: null
	},

	controller: "icecap.view.main",

	focusable: false,

	listeners: {
		afterrender: {
			fn: "onAfterRender",
			buffer: 100,
			single: true
		},
		activate: {
			fn: "onActivated",
			buffer: 10
		},
		dblclick: {
			fn: "onDblClick",
			element: "body"
		},
		click: {
			fn: "onClick",
			element: "body"
		},
		wheel: {
			fn: "onWheel",
			element: "body"
		},
		beforedestroy: {
			fn: "onBeforeDestroy"
		},
		applicationClose: {
			fn: "onApplicationClose"
		},
		fieldoption: {
			fn: function(a_config) {

				var i_self = this;
				var i_controller = i_self.getController();

				var o_data = {};

				Ext.apply(o_data, {
					key: "ENTER"
				});

				Ext.Array.each(a_config, function(o_config) {

					var s_field = o_config.field;

					o_data[s_field] = o_config.option;

					Ext.apply(o_data, {
						csrCol: o_config.col,
						csrLin: o_config.lin
					});
				});

				i_self.setCurrentPosition({
					col: o_data.csrCol,
					lin: o_data.csrLin
				});

				i_controller.onSendData({
					func: ""
				}, o_data);
			}
		},
		key: {
			fn: function(s_value) {

				var i_self = this;
				var i_controller = i_self.getController();

				i_controller.doKeyEvent(s_value);
			}
		},
		resize: {
			fn: function() {

				var i_self = this;
				if (!i_self.isCreating) {
					i_self.redraw();
				}
				
			}
		},

		detach: {
			fn: function() {

				var i_self = this;
				i_self.detach();
			}
		}
	},

	initComponent: function() {

		Ext.tip.QuickTipManager.init();

		var i_self = this;

		var o_params = Ext.Object.fromQueryString(window.location.search);

		Ext.Object.each(o_params, function(s_key, value) {
			o_params[s_key] = Ext.decode(value, true) || value;
		});

		var o_options = Ext.apply(i_self.options, o_params.options || {});

		Ext.apply(i_self, o_options);

		i_self.callParent(arguments);

		var o_rules = IceCap.util.Handler.createStyleSheetRules();

		i_self.setCssRules(o_rules);

		i_self.add(i_self.createLayout());

		var o_data = i_self.getInputData();
		var s_sessionValue = i_self.getSessionValue();

		if (o_data) {
			if (o_data.close) {
				i_self.close();
			}
			else {

				if (s_sessionValue) {

					IceCap.util.Handler.isSessionAlive(s_sessionValue, function(b_alive) {
						if (!b_alive) {
							i_self.setSessionValue(null);
							i_self.setInputData(null);

							i_self.doInit(function(o_data) {
								i_self.cancelTimer();
								i_self.setLoading(false);
								if (o_data.close) {
									i_self.close();
								}
								else {
									i_self.setInputData(o_data);
									i_self.doCreateFromData(o_data);
								}
							});
						}
						else {
							i_self.doCreateFromData(o_data);
						}
					});
				}
			}
		}
		else {
			i_self.doInit(function(o_data) {
				i_self.cancelTimer();
				i_self.setLoading(false);
				if (o_data.close) {
					i_self.close();
				}
				else {
					i_self.setInputData(o_data);
					i_self.doCreateFromData(o_data);
				}
			});
		}

		if (i_self.getTheme()) {
			Ext.Loader.loadScriptsSync([
				"/icecap/app/theme/" + i_self.getTheme() + ".css"
			]);
		}

		i_self.enableBubble("onAddWebContainer");
		i_self.enableBubble("stateupdate");
	},

	doInit: function(f_callback) {

		var i_self = this;

		if (i_self.getSessionValue()) {

			IceCap.util.Handler.addSession(i_self.getSessionValue());

			IceCap.util.Handler.getData(Ext.apply({
				session: i_self.getSessionValue(),
				func: i_self.getFunc(),
				initFunc: i_self.getInitFunc() || i_self.getInitCmd() || "",
			}, i_self.getOptions()), {}, function(o_data) {
				f_callback(o_data);
			});
		}
		else {

			IceCap.util.Handler.getNewSession(function(o_result) {

				if (o_result.success) {

					i_self.setSessionValue(o_result.session);
					i_self.doTimer();
					IceCap.util.Handler.getData(Ext.apply({
						session: o_result.session,
						func: i_self.getFunc(),
						initFunc: i_self.getInitFunc() || i_self.getInitCmd() || "",
					}, i_self.getOptions()), {}, function(o_data) {
						f_callback(o_data);
					});
				}
				else {
					IceCap.util.Handler.messageBox({
						title: "Error",
						message: "No session pls! retry to connect",
						yesText: "Ok"
					});
				}
			});
		}
	},

	createLayout: function() {

		var i_self = this;

		return i_self.createContent();
	},

	createContent: function() {

		var i_self = this;
		var o_inputData = i_self.getInputData() || {};

		var a_items = i_self.createItems();

		var i_keyArea = Ext.widget("panel", {
			layout: {
				type: "column"
			},
			border: false,
			focusable: false,
			minHeight: 50,
			height: null,
			defaults: {
				margin: "0 5 5 0"
			},
			ui: "icecap-keyarea",
			cls: ["icecap-panel", i_self.getTheme()].join("-")
		});

		a_items.push(i_keyArea);

		var i_statusbar = i_self.createStatusBar();

		var i_panel = Ext.widget("panel", {
			layout: {
				type: "vbox",
				align: "stretch"
			},
			border: false,
			focusable: true,
			tabIndex: -1,
			items: a_items
		});

		i_panel.addDocked(i_statusbar);

		i_self.setMain(i_panel);

		i_self.setKeyArea(i_keyArea);

		i_self.setStatusBar(i_statusbar);

		i_self.updateMessage(o_inputData);

		return i_panel;
	},

	createStatusBar: function() {

		var i_self = this;

		var i_translatorButton = Ext.widget("component", {
			itemId: "icecap-translator",
			cls: "pf-gearwheel",
			hidden: false,
			autoEl: {
				tab: "span",
				"data-qtip": "Toggle translation"
			},
			style: {
				"cursor": "pointer"
			},
			listeners: {
				click: {
					element: "el",
					fn: function (i_event) {

						i_event.stopEvent();

						var i_element = this;
						var b_edit = i_self.getEdit();

						b_edit = !b_edit;

						if (b_edit) {
							i_element.addCls("x-base-color");
						}
						else {
							i_element.removeCls("x-base-color");
						}

						i_self.setEdit(b_edit);
					}
				}
			}
		});

		var i_languageButton = Ext.widget("component", {
			itemId: "icecap-language",
			html: i_self.getActiveLanguage(),
			hidden: false,
			autoEl: {
				tab: "span",
				"data-qtip": "Toggle active language"
			},
			style: {
				"cursor": "pointer",
			},
			listeners: {
				click: {
					element: "el",
					fn: function (i_event) {

						i_event.stopEvent();
						var i_menu = i_languageButton.menu;

						var a_languages = i_self.getLanguages();

						var a_items = [];


						if (!i_menu) {

							Ext.Array.each(a_languages, function (s_key) {

								var i_menuItem = Ext.widget("menuitem", {
									itemId: s_key,
									text: s_key,
									iconCls: "icon flag " + s_key,
									handler: function (i_item) {

										i_languageButton.setHtml(i_item.text);
										i_self.setActiveLanguage(i_item.text);
									}
								});

								a_items.push(i_menuItem);
							});

							i_menu = Ext.widget("menu", {
								items: a_items
							});

							i_languageButton.menu = i_menu;
						}

						i_menu.show();
						i_menu.alignTo(i_languageButton.getEl(), "bl-tr");

						i_menu.toFront();
					}
				}
			}
		});

		var i_statusbar = Ext.widget("toolbar", {
			cls: "icecap-statusbar",
			hidden: false,
			dock: "bottom",
			ui: "statusbar",
			layout: {
				type: "hbox",
				align: "top"
			},
			height: 30,
			defaults: {
				margin: "0 10 0 0"
			},
			items: [
				{
					xtype: "label",
					itemId: "icecap-message",
					listeners: {
						afterrender: {
							fn: function(i_label) {

								var i_tpl = Ext.create("Ext.XTemplate",
									"<ul style=\"list-style: none;",
												"margin:10px;",
												"padding:0;",
									"\">",
										"<tpl for=\".\">",
											"<li>{text}</li>",
										"</tpl>",
									"</ul>"
								);

								Ext.create("Ext.tip.ToolTip", {
									target: i_label.getEl(),
									html: "",
									anchor: true,
									defealtAlign: "b50-t50",
									listeners: {
										beforeshow: {
											fn: function (i_tip) {

												var b_hasError = i_label.hasCls("icecap-statusbar-error");

												var o_inputData = i_self.getInputData();

												var a_messages = Ext.Array.from(o_inputData.message);

												if (b_hasError && a_messages.length > 0) {
													var s_value = i_tpl.apply(a_messages);
													i_tip.update(s_value);
												}
												else {
													return b_hasError;
												}
											}
										}
									}
								});
							}
						},
						click: {
							element: "el",
							fn: function (i_event, i_element) {

								var o_input = {
									col: 3,
									lin: 24
								};

								i_self.setCurrentPosition(o_input);

								var i_cursor = i_self.getCursor();
								i_cursor.moveCursor(o_input);

								i_self.doKeyEvent("F1");
							}
						},
					}
				},
				{
					xtype: "tbfill"
				},
				i_languageButton,
				i_translatorButton,
				{
					xtype: "label",
					itemId: "icecap-position",
					style: {
						"pointer-events": "none"
					}
				},
				{
					xtype: "component",
					autoEl: {
						tab: "span",
						"data-qtip": "Toggle input type"
					},
					style: {
						"cursor": "pointer"
					},
					html: "INS",
					itemId: "icecap-typemode",
					listeners: {
						click: {
							element: "el",
							fn: function(i_element) {

								var n_type = i_self.getTypeMode();

								switch (n_type) {
									case IceCap.util.Handler.typeMode.OVERWRITE:
										n_type = IceCap.util.Handler.typeMode.FOCUS;
										break;
									case IceCap.util.Handler.typeMode.FOCUS:
										n_type = IceCap.util.Handler.typeMode.INSERT;
										break;
									default:
										n_type = IceCap.util.Handler.typeMode.OVERWRITE;
										break;
								}

								i_self.setTypeMode(n_type);
							}
						}
					}
				}
			],
			setText: function(s_text) {

				var i_toolbar = this;

				var i_message = i_toolbar.getComponent("icecap-message");

				if (i_message) {
					i_message.setText(s_text);
				}
			}
		});

		i_self.setTranslator(i_translatorButton);

		return i_statusbar;
	},

	createItems: function() {

		var i_self = this;

		var a_items = [];

		var i_center = Ext.widget("form", {
			border: false,
			layout: "absolute",
			autoScroll: true,
			focusable: false,
			flex: 1,
			ui: ["icecap", i_self.getTheme()].filter(Boolean).join("-")
		});

		a_items.push(i_center);

		i_self.setContent(i_center);

		return a_items;
	},

	splitFields: function() {

		var i_self = this;
		var o_inputData = i_self.getInputData();

		var a_sliced = Ext.Array.from(o_inputData.fields || []);

		var a_outputs = Ext.Array.from(o_inputData.output || []);
		var a_inputs = Ext.Array.from(o_inputData.input || []);

		Ext.Array.each(a_sliced, function(o_config) {
			if (o_config.type == "input" || o_config.type == "grid") {
				a_inputs.push(o_config);
			}
			else if (o_config.type == "output") {
				a_outputs.push(o_config);
			}
		});

		var a_temp = a_inputs.slice();
		var a_newOut = [];

		Ext.Array.each(a_temp, function(o_input, n_index) {

			var s_hex = o_input.ffw;

			var n_sanHex = IceCap.util.Handler.createIndicators(s_hex);

			if (n_sanHex & IceCap.util.Handler.FFW.BYPASS) {
				o_input.atr = "";
				Ext.Array.remove(a_inputs, o_input);
				a_newOut.push(o_input);
			}
		});

		a_outputs = a_outputs.concat(a_newOut);

		a_outputs = a_outputs.sort(function(a, b) {
			return a.lin - b.lin || a.col - b.col;
		});

		Ext.apply(o_inputData, {
			input: a_inputs,
			output: a_outputs
		});

		if (a_sliced.length > 0) {
			o_inputData.processedFields = true;
		}

		delete o_inputData.fields;

		i_self.setInputData(o_inputData);
	},

	createFields: function(a_created) {

		var i_self = this;
		var o_inputData = i_self.getInputData();

		var a_fields = [];

		var n_tabIndex = 1;
		var n_focus = o_inputData.focus;

		var n_inputWidth = o_inputData.width || 80;

		var a_sliced = Ext.Array.from(o_inputData.input || []);

		var o_rules = i_self.getCssRules();

		var n_elementWidth = IceCap.util.Handler.getWidth(1, o_rules.fontScale);

		Ext.Array.each(a_sliced, function(o_config, n_index) {

			var n_width = (n_elementWidth * o_config.len + (n_elementWidth / 2));

			var o_meta = o_config.metaData || {};

			var o_field = {
				xtype: "icecap-input",
				ui: "icecap-field"
			};

			var s_type = o_field.xtype || "icecap-input";
			var n_x = IceCap.util.Handler.getX(o_config.col, o_rules.fontScale) - 3;
			var n_y = IceCap.util.Handler.getY(o_config.lin, o_rules.lineScale);
			var b_password = o_config.atr == "27";
			var n_calc = 0;
			var n_height = null;

			if (o_config.len > (n_inputWidth + 1) || ((o_config.len + o_config.col) > (n_inputWidth + 1))) {
				n_calc = (n_inputWidth + 1) - o_config.col;
				n_width = (n_elementWidth * n_calc + (n_elementWidth / 2));
			}


			if (n_calc || (o_config.hasOwnProperty("colsize") && o_config.hasOwnProperty("rows") && o_config.rows > 1)) {

				var s_data = o_config.dta || "";

				var n_colSize = o_config.colsize || o_config.len;

				if (n_calc && n_colSize > n_calc) {
					o_config.rows = Math.ceil(n_colSize / n_calc);
				}

				var s_lineHeight = o_rules.sheet.rules[0].style.lineHeight;

				var n_parsed = parseFloat(s_lineHeight.replace("px"));

				n_height = n_parsed * o_config.rows;

				var o_box = {
					x: n_x,
					y: n_y,
					width: n_width,
					height: n_height,
					right: n_x + n_width,
					bottom: n_y + n_height
				};

				var i_region = Ext.util.Region.create({});

				Ext.apply(i_region, o_box);

				Ext.Array.each(a_created, function(i_label) {

					var o_rect = {
						x: i_label.x,
						y: i_label.y,
						width: i_label.html.length * n_elementWidth,
						height: n_parsed,
						right: i_label.x + (i_label.html.length * n_elementWidth),
						bottom: i_label.y + n_parsed
					};

					if (i_region.intersect(o_rect)) {

						o_config.rows = i_label.lin - o_config.lin;
						n_height = n_parsed * o_config.rows;

						if (o_config.len > (n_inputWidth + 1)) {
							var n_length = o_config.len /  o_config.rows;

							n_width = (n_elementWidth *n_length + (n_elementWidth / 2));
						}

						return false;
					}
				});

				s_type = "icecap-textarea";
				
				o_field.height = o_field.minHeight = n_height;

				var a_split = s_data.split("\n");

				var s_result = "";

				var n_split = a_split.length;

				Ext.Array.each(a_split, function(s_part, n_index) {

					var regex = new RegExp(".{" + n_colSize + "}", "g");

					var a_match = s_part.match(regex);

					if (a_match) {
						s_result += s_part;
					}
					else {
						if (n_index != n_split - 1) {
							s_result += s_part + "\n";
						}
						else {
							s_result += s_part;
						}
					}
				});

				o_config.dta = s_result;

				if (!b_password) {
					o_field.getSubmitValue = function() {

						var i_field = this;

						var s_value = i_field.stripReturns(i_field.getValue());

						var regex = new RegExp(".{1,"+ n_colSize +"}", "g");

						var a_split = s_value.match(regex) || [];

						return a_split.join("\n");
					};
				}
			}

			var o_listeners = Ext.apply({}, o_meta.listeners);
			delete o_meta.listeners;

			var a_field = ["icecap-field", i_self.getTheme()];

			var a_pass = [b_password ? "iceCap-input-password" : "iceCap-input-" + (o_config.atr || 20)];

			a_pass.push(i_self.getTheme());

			var a_cls = [a_field.filter(Boolean).join("-"), a_pass.filter(Boolean).join("-")];

			var s_cls = a_cls.join(" ");

			var s_name = IceCap.util.Handler.getRandomName();

			if (isNaN(n_x)) {
				n_x = IceCap.util.Handler.getWidth(1, o_rules.fontScale);
			}

			if (isNaN(n_y)) {
				n_y = IceCap.util.Handler.getHeight(1, o_rules.lineScale);
			}

			var s_ui = b_password ? "icecap-password-field" : "icecap-field";

			if (!o_meta.xtype) {
				Ext.apply(o_field, i_self.applyFFW(o_config));
				o_field.xtype = s_type;
			}

			var n_fieldIndex = n_tabIndex;

			if (o_field.unselected) {
				a_cls.push("x-unselectable-field");
				n_fieldIndex = -1;
			}

			s_cls = a_cls.join(" ");

			var i_field;
			
			if (b_password) {
				o_field.xtype = s_type = "icecap-input";
				o_field.height = o_field.minHeight = null;
				o_field.ui = "icecap-password-field";
			}

			if (s_type == "icecap-textarea") {
				s_ui = "icecap-textarea-field";
			}

			s_ui += o_rules.fieldCss;

			Ext.Object.merge(o_field, {
				width: n_width,
				enforceMaxLength: true,
				maxLength: o_config.len,
				minWidth: IceCap.util.Handler.getDefaultWidth(),
				tabIndex: n_fieldIndex,
				focusable: !o_field.readOnly,
				lin: o_config.lin,
				col: o_config.col,
				emuId: o_config.id,
				value: o_config.dta || "",
				itemId: o_config.id,
				name: s_name,
				inputAttrTpl: "tabindex=" + n_fieldIndex + " spellcheck=false autocomplete=\"new-password\" name=\"" + s_name + "\"",
				x: n_x,
				y: n_y,
				cls: s_cls,
				enableKeyEvents: true,
				selectOnFocus: false,
				ui: s_ui,
				listeners: {
					afterrender: {
						fn: function (i_field) {

							if (i_field.inputEl && !i_field.metaField) {
								if (i_field.xtype == "textarea" || i_field.xtype == "icecap-textarea") {
									i_field.inputEl.dom.setAttribute("rows", o_config.rows);
								}

								if (i_field.getTabIndex() === i_self.getNeedFocus()) {

									i_field.focus(false, 10, function () {
										var o_inputData = i_self.getInputData();

										var s_value = i_field.getValue();
										var n_col = i_field.col;
										var n_diff = 0;

										if (n_col < o_inputData.csrCol) {
											n_diff = o_inputData.csrCol - n_col;
											i_field.inputEl.el.dom.selectionEnd = i_field.inputEl.el.dom.selectionStart = i_field.inputEl.el.dom.selectionStart + n_diff;
										}

										var o_position = {
											col: o_inputData.csrCol,
											lin: o_inputData.csrLin
										};

										i_self.setCurrentPosition(o_position);

										var i_cursor = i_self.getCursor();
										i_cursor.moveCursor(o_position);
										i_cursor.hide();
									});
								}
							}
						}
					},
					change: {
						fn: function (i_field, value) {

							if (i_field.inputEl) {
								var s_direction = i_field.inputEl.el.dom.selectionDirection;

								var n_curpos = s_direction == "forward" ? i_field.inputEl.el.dom.selectionEnd : i_field.inputEl.el.dom.selectionStart;

								value = value || "";

								if (value.length == i_field.maxLength && n_curpos == i_field.maxLength) {
									i_self.doNavigationKey(1, true);
								}
							}
						}
					},
					focus: {
						fn: function (i_field) {

							var n_tabIndex = i_field.getTabIndex();
							i_self.setCurrentTabIndex(n_tabIndex);

							var o_position = {
								col: i_field.col,
								lin: i_field.lin
							};
							i_self.setCurrentPosition(o_position);

							var i_cursor = i_self.getCursor();
							i_cursor.moveCursor(o_position);
							i_cursor.hide();

							if (i_self.getTypeMode() == IceCap.util.Handler.typeMode.FOCUS) {
								var i_inputEl = i_field.inputEl;
								if (i_inputEl && i_inputEl.dom) {
									i_field.inputEl.dom.select();
								}
							}
						}
					},
					keyup: {
						fn: function (i_field, i_event) {

							var i_selector = i_self.getSelector();

							if (!i_selector.isHidden()) {
								return true;
							}

							if (i_field.xtype === "icecap-input") {

								var value = i_field.getValue();

								var s_direction = i_field.inputEl.el.dom.selectionDirection;

								var n_start = s_direction == "forward" ? i_field.inputEl.el.dom.selectionEnd : i_field.inputEl.el.dom.selectionStart;
								var n_add = n_start * IceCap.util.Handler.getWidth(1, o_rules.fontScale);

								if (n_start == i_field.maxLength) {
									n_add = n_add - IceCap.util.Handler.getWidth(1, o_rules.fontScale);
								}

								var o_input = Ext.apply({
									x: i_field.getLocalX() + n_add,
									y: i_field.lin * IceCap.util.Handler.getHeight(1, o_rules.lineScale)
								});

								var o_position = IceCap.util.Handler.toColAndLine(o_input, o_rules);
								i_self.setCurrentPosition(o_position);

								var i_cursor = i_self.getCursor();
								i_cursor.moveCursor(o_position);
							}
						}
					},
					keydown: {
						fn: function (i_field, i_event) {

							var i_selector = i_self.getSelector();

							if (!i_selector.isHidden()) {
								return true;
							}

							var i_regext = new RegExp("^.{1}$");

							var value = i_field.getValue();

							var n_selection = 0;

							var i_inputEl = i_field.inputEl;

							var o_input = {};
							var o_position = {};
							var o_box = {};

							var i_main = i_self.getMain();
							var i_cursor = i_self.getCursor();
							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							var b_intersect = false;

							var b_overshot = false;

							if (i_event.ctrlKey && !i_event.shiftKey) {

								if (i_event.keyCode == Ext.event.Event.DOWN ||
									i_event.keyCode == Ext.event.Event.UP) {

									n_selection = i_inputEl.dom.selectionEnd;

									i_event.stopEvent();

									o_position = {
										col: i_field.col + n_selection,
										lin: i_field.lin
									};

									if (i_event.keyCode == Ext.event.Event.DOWN) {

										var n_height = Math.ceil(i_field.getHeight() / IceCap.util.Handler.getHeight(1, o_rules.lineScale));

										n_height = (n_height > 1) ? n_height - 1 : n_height;

										o_position.lin = o_position.lin + n_height;

									}
									else {
										o_position.lin--;
									}

									if (n_selection !== i_field.maxLength) {
										o_position.col++;
									}

									i_self.setCurrentPosition(o_position);

									i_cursor.moveCursor(o_position);

									i_cursor.show();

									o_input = {
										x: i_cursor.getLocalX(),
										y: i_cursor.getLocalY()
									};

									Ext.apply(o_box, {
										width: i_cursor.getWidth(),
										height: i_cursor.getHeight(),
										right: i_cursor.getLocalX() + i_cursor.getWidth(),
										bottom: i_cursor.getLocalY() + i_cursor.getHeight()
									}, o_input);

									i_cursor.hide();

									Ext.Array.each(a_inputs, function (i_field) {

										var i_region = i_field.getRegion(false, true);

										if (i_region.intersect(o_box)) {
											b_intersect = true;
											i_field.focus(false, 10);
											return false;
										}
									});

									if (!b_intersect) {

										i_field.blur();
										i_cursor.show();

										i_main.focus(true, 10);
									}
								}
								if (i_event.keyCode == Ext.event.Event.LEFT ||
									i_event.keyCode == Ext.event.Event.RIGHT) {

									n_selection = i_event.keyCode == Ext.event.Event.LEFT ? i_inputEl.dom.selectionStart : i_inputEl.dom.selectionEnd;

									i_event.stopEvent();

									if (n_selection === 0 && i_event.keyCode === Ext.event.Event.LEFT) {

										o_position = {
											col: i_field.col,
											lin: i_field.lin
										};

										o_position.col--;

										o_input = {
											x: IceCap.util.Handler.getX(o_position.col, o_rules.fontScale),
											y: IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale)
										};

										i_self.setCurrentPosition(o_position);

										i_cursor.moveCursor(o_position);

										Ext.apply(o_box, {
											width: i_cursor.getWidth(),
											height: i_cursor.getHeight(),
											right: o_input.x + i_cursor.getWidth(),
											bottom: o_input.x + IceCap.util.Handler.getHeight(1, o_rules.lineScale)
										}, o_input);

										Ext.Array.each(a_inputs, function (i_field) {

											var i_region = i_field.getRegion(false, true);

											if (i_region.intersect(o_box)) {
												b_intersect = true;
												i_field.focus(false, 10);
												return false;
											}
										});

										if (!b_intersect) {

											i_field.blur();
											i_cursor.show();

											i_main.focus(true, 10);
										}
									}
									else if (n_selection == value.length && i_event.keyCode == Ext.event.Event.RIGHT) {

										o_position = {
											col: i_field.col + i_field.maxLength,
											lin: i_field.lin
										};

										if (o_position.col > o_inputData.width) {
											o_position.col = o_inputData.width;
										}

										o_position.col = o_position.col + 2;

										o_input = {
											x: IceCap.util.Handler.getX(o_position.col, o_rules.fontScale),
											y: IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale)
										};


										i_self.setCurrentPosition(o_position);
										i_cursor.moveCursor(o_position);

										Ext.apply(o_box, {
											width: i_cursor.getWidth(),
											height: i_cursor.getHeight(),
											right: o_input.x + i_cursor.getWidth(),
											bottom: o_input.x + IceCap.util.Handler.getHeight(1, o_rules.lineScale)
										}, o_input);

										Ext.Array.each(a_inputs, function (i_field) {

											var i_region = i_field.getRegion(false, true);

											if (i_region.intersect(o_box)) {
												b_intersect = true;
												i_field.focus(false, 10);
												return false;
											}
										});

										if (!b_intersect) {

											i_field.blur();
											i_cursor.show();

											i_main.focus(true, 10);
										}
									}
								}
							}
							else {

								if (i_field.xtype == "textarea" || i_field.xtype == "icecap-textarea") {

									if (i_event.keyCode == Ext.event.Event.ENTER) {
										i_event.preventDefault();
										i_self.doKeyEvent("ENTER");
										return false;
									}

									var n_row = 1;
									var n_char = 0;
									var n_left = 0;
									var n_current = 0;
									var n_nextLine = 0;
									var n_newPos = 0;

									if (i_event.keyCode == Ext.event.Event.UP && (!i_event.shiftKey && !i_event.ctrlKey)) {

										var s_value = i_field.stripReturns(i_field.getRawValue());

										var regex = new RegExp("^.*\n$|.{1," + n_colSize + "}", "gm");

										var a_lines = s_value.match(regex) || [];
										var a_newLines = s_value.split("\n");

										var n_start = i_field.inputEl.dom.selectionStart;

										if (a_lines.length > 0) {

											var s_first = a_lines[0];

											if (n_start > s_first.length) {
												i_event.stopPropagation();
											}
										}
										else {
											if (a_newLines.length > 0) {
												if (n_start > 0) {
													i_event.stopPropagation();
												}
											}
										}
									}

									if (i_event.keyCode == Ext.event.Event.DOWN && (!i_event.shiftKey && !i_event.ctrlKey)) {

										var s_value = i_field.stripReturns(i_field.getRawValue());
										var n_length = s_value.length;

										var regex = new RegExp("^.*\n$|.{1," + n_colSize + "}", "g");
										var n_start = i_field.inputEl.dom.selectionStart;

										var a_lines = s_value.match(regex) || [];
										var a_newLines = s_value.split("\n");

										if (a_lines.length < o_config.rows && a_newLines.length < o_config.rows) {

											i_event.stopEvent();

											s_value = s_value + "\n";

											i_field.setValue(s_value);

											i_field.inputEl.dom.setSelectionRange(s_value.length, s_value.length);
										}
										else {
											if (a_lines.length == o_config.rows) {

												var n_line = 0;

												Ext.Array.each(a_lines, function (s_line, n_index) {
													if (n_index < a_lines.length - 1) {
														n_line += s_line.length;
													}
												});

												n_line += a_newLines.length - 1;

												if (n_start < n_line) {
													i_event.stopPropagation();
												}
											}
											else {
												if (a_newLines.length > 0) {
													if (n_start < s_value.length) {
														i_event.stopPropagation();
													}
												}
											}
										}
									}
								}
								else if (i_field.xtype == "icecap-input") {

									var n_typeMode = i_self.getTypeMode();

									var s_direction = i_field.inputEl.el.dom.selectionDirection;

									var n_curpos = s_direction == "forward" ? i_field.inputEl.el.dom.selectionEnd : i_field.inputEl.el.dom.selectionStart;

									var s_key = i_event.event.key;

									var i_nearest;

									var n_temp;

									var n_valueTemp = 999;
									var n_curdiffCol = 999;

									if (i_regext.test(s_key)) {

										if (n_curpos < value.length && n_typeMode == IceCap.util.Handler.typeMode.OVERWRITE) {

											var a_values = value.split("");
											a_values[n_curpos] = i_event.event.key;
											value = a_values.join("");
											i_field.setValue(value);
											i_field.inputEl.el.dom.selectionEnd = i_field.inputEl.el.dom.selectionStart = n_curpos + 1;
											i_event.stopEvent();
										}
									}
									else {

										if (i_event.keyCode == Ext.event.Event.DOWN ||
											i_event.keyCode == Ext.event.Event.UP) {

											n_selection = i_inputEl.dom.selectionEnd;

											o_position = {
												col: i_field.col,
												lin: i_field.lin
											};

											if (i_event.keyCode === Ext.event.Event.UP) {

												Ext.Array.each(a_inputs, function (i_field) {

													if (i_field.col == o_position.col) {

														if (i_field.lin == (o_position.lin - 1)) {

															i_nearest = i_field;
														}
													}
												});

												if (!i_nearest) {

													n_posDiff = o_position.lin;

													n_valueTemp = 999;
													n_curdiffCol = 999;

													Ext.Array.each(a_inputs, function (i_field) {

														if (i_field.lin < o_position.lin) {

															var n_max = Math.max(i_field.lin, n_posDiff);
															var n_min = Math.min(i_field.lin, n_posDiff);

															var n_curDiff =  n_max - n_min;

															if (n_valueTemp >= n_curDiff) {

																n_max = Math.max(i_field.col, o_position.col);
																n_min = Math.min(i_field.col, o_position.col);

																var n_diff = n_max - n_min;

																if (n_valueTemp == n_curDiff) {

																	if (n_curdiffCol > n_diff) {
																		i_nearest = i_field;
																		n_valueTemp = n_curDiff;
																		n_curdiffCol = n_diff;
																	}
																}
																else {
																	i_nearest = i_field;
																	n_valueTemp = n_curDiff;
																	n_curdiffCol = n_diff;
																}
															}
														}
													});
												}

												if (i_nearest) {

													o_position.lin = i_nearest.lin;

													i_self.setCurrentPosition(o_position);

													i_cursor.moveCursor(o_position);

													i_nearest.focus(false, 10, function () {
														var i_element = i_nearest.inputEl;
														var value = i_nearest.getValue();
														if (i_self.getTypeMode() != IceCap.util.Handler.typeMode.FOCUS) {
															i_element.dom.selectionStart = i_element.dom.selectionEnd = n_selection;
														}
													});

													i_event.stopEvent();
												}
											}
											else if (i_event.keyCode == Ext.event.Event.DOWN) {

												Ext.Array.each(a_inputs, function (i_field) {

													if (i_field.col == o_position.col) {

														if (i_field.lin == (o_position.lin + 1)) {

															i_nearest = i_field;
														}
													}
												});

												if(!i_nearest) {

													n_posDiff = o_position.lin;
													n_tempCol = o_position.col;

													n_valueTemp = 999;
													n_curdiffCol = 999;

													Ext.Array.each(a_inputs, function (i_field) {

														if (i_field.lin > o_position.lin) {

															var n_max = Math.max(i_field.lin, n_posDiff);
															var n_min = Math.min(i_field.lin, n_posDiff);

															var n_diff = n_max - n_min;

															var n_curDiff =  n_max - n_min;

															if (n_valueTemp >= n_curDiff) {

																n_max = Math.max(i_field.col, o_position.col);
																n_min = Math.min(i_field.col, o_position.col);

																n_diff = n_max - n_min;

																if (n_curdiffCol > n_diff) {
																	i_nearest = i_field;
																	n_valueTemp = n_curDiff;
																	n_curdiffCol = n_diff;
																}
															}
														}
													});
												}

												if (i_nearest) {

													o_position.lin = i_nearest.lin;

													i_self.setCurrentPosition(o_position);

													i_cursor.moveCursor(o_position);

													i_nearest.focus(false, 10, function () {
														var i_element = i_nearest.inputEl;
														if (i_self.getTypeMode() != IceCap.util.Handler.typeMode.FOCUS) {
															i_element.dom.selectionStart = i_element.dom.selectionEnd = n_selection;
														}
													});

													i_event.stopEvent();
												}
											}
										}

										if (i_event.keyCode == Ext.event.Event.LEFT ||
											i_event.keyCode == Ext.event.Event.RIGHT) {

											var n_col = o_config.col;
											var n_tempCol = n_col;

											n_selection = i_event.keyCode == Ext.event.Event.LEFT ? i_inputEl.dom.selectionStart : i_inputEl.dom.selectionEnd;

											var a_selection = i_inputEl.getTextSelection();
											var n_selected = a_selection[2] == "forward" ? a_selection[1] - a_selection[0] : a_selection[2] - a_selection[1];

											if (n_selected == value.length && !Ext.isEmpty(value)) {

												if (i_event.keyCode == Ext.event.Event.LEFT) {
													i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = 0;
												}
												else {
													i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = n_selected;
												}

												i_event.stopEvent();

												return;
											}

											o_position = {
												col: i_field.col,
												lin: i_field.lin
											};

											n_posDiff = o_position.col + o_position.lin;

											if (n_selection === 0 && i_event.keyCode === Ext.event.Event.LEFT) {

												n_tempCol = o_position.col;

												Ext.Array.each(a_inputs, function (i_field) {

													if (i_field.lin == o_position.lin) {

														if (i_field.col < o_position.col) {

															i_nearest = i_field;
														}
													}
												});

												if (!i_nearest) {

													n_valueTemp = 999;

													n_posDiff = o_config.lin;


													Ext.Array.each(a_inputs, function (i_field) {

														if (i_field.lin < o_position.lin) {

															var n_curDiff = n_posDiff - i_field.lin;

															if (n_valueTemp > n_curDiff) {
																i_nearest = i_field;
																n_tempCol = i_field.col;
																n_valueTemp = n_curDiff;
															}
															else if (n_valueTemp == n_curDiff) {
																if (n_tempCol < i_field.col && i_field.col > o_position.col) {
																	i_nearest = i_field;
																	n_tempCol = i_field.col;
																}
															}
														}
													});
												}

												if (i_nearest) {

													o_position.col = i_nearest.col;

													i_self.setCurrentPosition(o_position);

													i_cursor.moveCursor(o_position);

													i_nearest.focus(false, 10, function () {
														var i_element = i_nearest.inputEl;
														var value = i_nearest.getValue();
														if (!b_overshot && i_self.getTypeMode() != IceCap.util.Handler.typeMode.FOCUS) {
															i_element.dom.selectionStart = i_element.dom.selectionEnd = value.length;
														}
													});
												}
											}
											else if (n_selection == value.length && i_event.keyCode == Ext.event.Event.RIGHT) {

												n_tempCol = i_field.col + i_field.maxLength;

												o_position = {
													col: i_field.col + i_field.maxLength,
													lin: i_field.lin
												};

												if (o_position.col > o_inputData.width) {
													o_position.col = n_tempCol = o_inputData.width;
												}

												Ext.Array.each(a_inputs, function (i_field) {

													if (i_field.lin == o_position.lin) {

														if (i_field.col > o_position.col) {

															i_nearest = i_field;
															return false;
														}
													}
												});

												if (!i_nearest) {

													n_valueTemp = 999;

													n_posDiff = o_config.lin;

													Ext.Array.each(a_inputs, function (i_field) {

														if (i_field.lin > o_position.lin) {

															var n_curDiff = i_field.lin - n_posDiff;

															if (n_valueTemp > n_curDiff) {
																if (n_tempCol >= i_field.col) {
																	i_nearest = i_field;
																	n_tempCol = i_field.col;
																}
																n_valueTemp = n_curDiff;
															}
															else if (n_valueTemp == n_curDiff) {
																if (n_tempCol > i_field.col && i_field.col < o_position.col) {
																	i_nearest = i_field;
																}
															}
														}
													});
												}

												if (i_nearest) {

													o_position.col = i_nearest.col;

													i_self.setCurrentPosition(o_position);

													i_cursor.moveCursor(o_position);

													i_nearest.focus(false, 10, function () {
														var i_element = i_nearest.inputEl;
														if (i_self.getTypeMode() != IceCap.util.Handler.typeMode.FOCUS) {
															i_element.dom.selectionStart = i_element.dom.selectionEnd = 0;
														}
													});

													i_event.stopEvent();
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}, o_meta);

			var o_clone = Ext.clone(o_field);

			if (o_meta.xtype) {

				o_clone.metaField = true;

				o_clone.xtype = s_type = o_meta.xtype;

				delete o_clone.cls;
				delete o_clone.fieldStyle;
				delete o_clone.inputType;
				delete o_clone.ui;
			}

			if (o_config.type == "grid") {

				s_type = "iceCapGrid";

				Ext.apply(o_clone, {
					xtype: s_type,
					gridConfig: o_config.grid,
					width: IceCap.util.Handler.getWidth(n_inputWidth, o_rules.fontScale)
				});

				delete o_clone.cls;
				delete o_clone.fieldStyle;
				delete o_clone.inputType;
				delete o_clone.listeners;
				delete o_clone.grid;

				Ext.apply(o_clone, {
					listeners: {
						fieldoption: {
							fn: function (a_config) {
								i_self.fireEvent("fieldoption", a_config);
							}
						},
						key: {
							fn: function (s_key) {
								i_self.fireEvent("key", s_key);
							}
						}
					}
				});
			}

			i_field = Ext.widget(s_type, o_clone);

			var o_on = {};

			Ext.Object.each(o_listeners, function (s_key, value) {

				if (Ext.isFunction(value)) {
					o_on[s_key] = Ext.apply({}, {
						fn: value,
						scope: i_self
					});
				}
				else if (Ext.isObject(value)) {
					value.scope = i_self;
					o_on[s_key] = value;
				}
			});

			i_field.on(o_on);

			if (!i_field.unselected) {
				i_field.focusable = true;
				n_tabIndex++;
			}

			if (o_config.atr == 25) {

				if (o_field.readOnly) {
					i_field.addCls("icecap-invalid");
				}
				else {
					i_field.markInvalid(true);
				}
			}

			a_fields.push(i_field);
		});

		n_tabIndex = n_tabIndex - 1;
		i_self.setLastTabIndex(n_tabIndex);
		i_self.setCurrentTabIndex(o_inputData.focus);

		i_self.setNeedFocus(n_focus);

		return a_fields;
	},

	createLabels: function () {

		var i_self = this;
		var o_inputData = i_self.getInputData();

		var o_rules = i_self.getCssRules();

		var i_fieldRule = o_rules.sheet.rules.item(0);
		var o_style = i_fieldRule.style;

		var a_fields = [];
		var a_bold = [];

		if (!i_self.getEdit()) {

			var a_lines = [];
			var a_temp = [];

			Ext.Array.each(o_inputData.output, function (o_config) {

				var o_line = Ext.Array.findBy(a_lines, function (o_line) {
					return o_line.lin == o_config.lin;
				});

				if (o_line) {
					o_line.items.push(o_config);
				}
				else {
					o_line = {
						items: [o_config],
						lin: o_config.lin,
						col: o_config.col
					};

					a_lines.push(o_line);
				}
			});

			Ext.Array.each(a_lines, function (o_line) {

				var a_items = [];

				Ext.Array.each(o_line.items, function (o_item) {

					var o_atr = Ext.Array.findBy(a_items, function (o_atr) {
						return (o_atr.atr || "") == (o_item.atr || "");
					});

					if (!o_atr && o_item.atr != "22") {
						o_atr = {
							lin: o_item.lin,
							items: [o_item],
							atr: o_item.atr || ""
						};

						a_items.push(o_atr);
					}
					else {

						if (o_item.atr != "22") {
							o_atr.items.push(o_item);
						}
						else {
							a_bold.push(o_item);
						}
					}
				});

				o_line.atr = a_items;
			});

			Ext.Array.each(a_lines, function (o_line) {

				Ext.Array.each(o_line.atr, function (o_atr) {

					var n_col = 0;
					var n_current = 0;
					var s_value = "";

					var o_field = {
						value: ""
					};

					Ext.Array.each(o_atr.items, function (o_config) {

						var s_data = o_config.dta || o_config.label || o_config.text || "";

						if (o_config.off) {
							s_data = Ext.String.leftPad(s_data, s_data.length + o_config.off);
						}

						if (n_col === 0) {

							n_col = o_config.col;
							n_current = (n_col + s_data.length);
							s_value = s_data;
						}
						else {

							var n_diff = o_config.col - n_current;

							if (n_diff > 0) {
								s_data = Ext.String.leftPad(s_data, s_data.length + n_diff);
							}

							n_current = (n_current + s_data.length);

							s_value = s_value + s_data;
						}
					});

					Ext.apply(o_field, {
						col: n_col,
						lin: o_line.lin,
						value: s_value,
						atr: o_atr.atr
					});

					a_temp.push(o_field);
				});
			});

			var a_splitTemp = [];

			Ext.Array.each(a_bold, function (o_config) {

				var s_value = o_config.value || o_config.dta || "";

				if (o_config.off) {
					s_value = Ext.String.leftPad(s_value, s_value.length + o_config.off);
				}

				var a_matches = Array.from(s_value.matchAll(/\S+/g));

				Ext.Array.each(a_matches, function (i_match) {
					a_splitTemp.push({
						value: i_match[0],
						lin: o_config.lin,
						col: i_match.index + o_config.col,
						atr: "22"
					});
				});
			});

			a_temp = a_temp.concat(a_splitTemp);

			Ext.Array.each(a_temp, function (o_config) {

				var s_value = o_config.value || o_config.dta;

				if (s_value) {

					if (o_config.off) {
						s_value = Ext.String.leftPad(s_value, s_value.length + o_config.off);
					}

					var n_x = IceCap.util.Handler.getX(o_config.col, o_rules.fontScale);
					var n_y = IceCap.util.Handler.getY(o_config.lin, o_rules.lineScale);

					var s_cls = (["iceCap-output-" + (o_config.atr || 20), i_self.getTheme()].filter(Boolean).join("-"));

					var o_field = {
						autoEl: {
							tag: "span"
						},
						html: s_value,
						x: n_x,
						y: n_y,
						lin: o_config.lin,
						col: o_config.col,
						cls: ["x-form-display-field-icecap-display" + o_rules.fieldCss, s_cls].join(" "),
						originalValue: s_value,
						textID: o_config.txtId || 0,
						style: {
							"white-space": "pre",
							"pointer-events": "none"
						},
						listeners: {
							afterrender: {
								fn: function (i_field) {
									i_field.el.dom.setAttribute("draggable", false);
								}
							}
						}
					};


					if (o_config.atr == "27") {
						o_field.hidden = true;
					}

					if (o_config.atr == "22") {

						Ext.apply(o_field.style, {
							"font-size": IceCap.util.Handler.getFontSize(o_rules.fontScale),
							"font-weight": "bold;"
						});
					}

					var i_field = Ext.widget("component", o_field);
					a_fields.push(i_field);
				}
			});
		}
		else {

			Ext.Array.each(o_inputData.output, function (o_config) {

				var s_value = o_config.dta || o_config.label || o_config.text || "";

				if (s_value) {

					if (o_config.off) {
						s_value = Ext.String.leftPad(s_value, s_value.length + o_config.off);
					}

					var n_x = IceCap.util.Handler.getX(o_config.col, o_rules.fontScale);
					var n_y = IceCap.util.Handler.getY(o_config.lin, o_rules.lineScale);

					var s_cls = (["iceCap-output-" + (o_config.atr || 20), i_self.getTheme()].filter(Boolean).join("-"));

					var o_field = {
						autoEl: {
							tag: "span"
						},
						html: s_value,
						x: n_x,
						y: n_y,
						lin: o_config.lin,
						col: o_config.col,
						cls: ["x-form-display-field-icecap-display" + o_rules.fieldCss, s_cls].join(" "),
						originalValue: s_value,
						textID: o_config.txtId || 0,
						style: {
							"white-space": "pre"
						},
						listeners: {
							mouseover: {
								element: "el",
								fn: function () {

									var i_element = this;
									i_element.addCls("x-base-background-color");
								}
							},
							mouseout: {
								element: "el",
								fn: function () {

									var i_element = this;
									i_element.removeCls("x-base-background-color");
								}
							},
							afterrender: {
								fn: function (i_field) {
									i_field.el.dom.setAttribute("draggable", false);

									var i_tpl = Ext.create("Ext.XTemplate",
										"<div style=\"width: 300px; overflow:hidden;\">",
										"<div>Position: {lin} / {col}</div>",
										"<div>Length: {len}</div>",
										"<div>Color: {color}</div>",
										"<div style=\"overflow:hidden; white-space: nowrap; text-overflow:ellipsis;\">Font: {font}</div>",
										"</div>"
									);

									Ext.create("Ext.tip.ToolTip", {
										target: i_field.el,
										html: "",
										anchor: true,
										defealtAlign: "b0-t0",
										listeners: {
											beforeshow: {
												fn: function (i_tip) {

													var o_data = {
														lin: o_config.lin,
														col: o_config.col,
														color: o_style.color,
														len: o_config.len,
														font: [
															o_style.fontSize,
															o_style.fontFamily
														].join(" ")
													};

													var s_value = i_tpl.apply(o_data);
													i_tip.update(s_value);
												}
											}
										}
									});
								}
							}
						}
					};


					if (o_config.atr == "27") {
						o_field.hidden = true;
					}

					if (o_config.atr == "22") {

						Ext.apply(o_field.style, {
							"font-size": IceCap.util.Handler.getFontSize(o_rules.fontScale),
							"font-weight": "bold;"
						});
					}

					var i_field = Ext.widget("component", o_field);
					a_fields.push(i_field);

					i_field.on({
						afterrender: {
							fn: function (i_field) {
								i_field.el.on({
									click: {
										fn: function () {

											o_config.originalValue = o_config.dta;

											if (i_field.textID) {
												IceCap.util.Handler.getTranslation({
													textID: i_field.textID,
													languages: i_self.getLanguages()
												}, function (o_data) {

														o_config.originalValue = o_data.text;

														var i_editor = i_self.createEditor(o_config, o_data, function (o_values, o_translation) {

															var s_value = o_translation[i_self.getActiveLanguage()] || o_data.text;

															i_field.setHtml(s_value);

															i_field.textID = o_config.txtId = o_values.txtId;
														});

														var o_translation = o_data.translation || {};

														var s_value = o_translation[i_self.getActiveLanguage()] || i_field.originalValue;

														i_editor.startEdit(i_field.getEl(), s_value, false);
												});
											}
											else {

												o_config.dta = i_field.originalValue;

												var i_editor = i_self.createEditor(o_config, {}, function (o_values, o_translation) {

													i_field.textID = o_config.txtId = o_values.txtId;

													var s_value = o_translation[i_self.getActiveLanguage()] || o_config.text;

													i_field.setHtml(s_value);
												});

												i_editor.startEdit(i_field.getEl(), undefined, false);
											}
										}
									}
								});
							}
						}
					});
				}
			});
		}

		return a_fields;
	},

	createMetaFields: function() {

		var i_self = this;
		var o_inputData = i_self.getInputData();

		var a_fields = [];
		var n_tabIndex = i_self.getLastTabIndex() || 0;

		var a_sliced = Ext.Array.slice(o_inputData.metaFields || []);

		var o_rules = i_self.getCssRules();

		Ext.Array.each(a_sliced, function(o_config) {

			var n_x = o_config.x;
			var n_y = o_config.y;

			if (!o_config.x) {
				n_x = IceCap.util.Handler.getX(o_config.col, o_rules.fontScale);
			}

			if (!o_config.y) {
				n_y = IceCap.util.Handler.getY(o_config.lin, o_rules.lineScale);
			}

			if (isNaN(n_x)) {
				n_x = IceCap.util.Handler.getWidth(1, o_rules.fontScale);
			}

			if (isNaN(n_y)) {
				n_y = IceCap.util.Handler.getHeight(1, o_rules.lineScale);
			}

			var o_listeners = o_config.listeners || {};

			Ext.apply(o_config, {
				tabIndex: n_tabIndex + 1,
				keys: Ext.Array.slice(o_inputData.keys),
				theme: i_self.getTheme(),
				x: n_x,
				y: n_y,
				listeners: {
					fieldoption: {
						fn: function(a_config) {
							i_self.fireEvent("fieldoption", a_config);
						}
					},
					key: {
						fn: function(s_key) {
							i_self.fireEvent("key", s_key);
						}
					}
				}
			});

			o_config.xtype = o_config.xtype || o_config.type || "icecap-input";

			o_config.name = o_config.id;

			delete o_config.id;

			var i_field = Ext.widget(o_config.xtype, o_config);

			var o_on = {};

			if (!Ext.Object.isEmpty(o_listeners)) {

				Ext.Object.each(o_listeners, function(s_key, value) {

					if (Ext.isFunction(value)) {
						o_on[s_key] = Ext.apply({}, {
							fn: value,
							scope: i_self
						});
					}
					else if (Ext.isObject(value)) {
						value.scope = i_self;
						o_on[s_key] = value;
					}
				});
			}

			i_field.on(o_on);

			a_fields.push(i_field);

			n_tabIndex++;
		});

		i_self.setLastTabIndex(n_tabIndex);

		return a_fields;
	},

	createKeys: function () {

		var i_self = this;
		var o_rules = i_self.getCssRules();
		var o_inputData = i_self.getInputData();
		var a_disabledKey = o_inputData.disabledKeys || [];
		var a_buttons = [];

		var i_template = Ext.create("Ext.XTemplate",
			"{id}={text}"
		);

		Ext.Array.each(o_inputData.keys, function (o_config) {

			var s_template = i_template.apply(o_config);

			var o_found = Ext.Array.findBy(a_disabledKey, function (o_disabled) {
				return o_config.id == o_disabled.id;
			});

			o_found = o_found || {
				showKey: 1
			};

			var b_hidden = Number(o_found.showKey) < 1 || false;

			var i_button = Ext.widget("button", {
				text: s_template,
				key: o_config.id,
				len: o_config.len,
				focusable: false,
				textID: o_config.txtId || 0,
				hidden: b_hidden,
				originalValue: s_template,
				style: {
					maxHeight: 30 * o_rules.lineScale + "px",
					minHeight: 30 * o_rules.lineScale + "px",
					minWidth: 80 * o_rules.fontScale + "px"
				},
				listeners: {
					afterrender: {
						fn: function(i_button) {
							i_button.btnEl.setStyle("min-height", "inherit");
							i_button.btnInnerEl.setStyle("font-size", "calc(1em * " +  o_rules.fontScale + ")");
						}
					}
				}
			});

			if (i_self.getEdit()) {
				i_button.on({
					afterrender: {
						fn: function (i_button) {
							i_button.el.on({
								click: {
									fn: function (i_event) {

										o_config.dta = o_config.text;

										o_config.originalValue = i_template.apply({
											id: i_button.key,
											text: o_config.text
										});

										i_event.stopEvent();

										if (i_button.textID) {
											IceCap.util.Handler.getTranslation({
												textID: i_button.textID,
												languages: i_self.getLanguages()
											}, function (o_data) {

													o_config.originalValue = o_data.text;

													var i_editor = i_self.createEditor(o_config, o_data, function (o_values, o_translation) {

														var s_value = o_translation[i_self.getActiveLanguage()];

														if (s_value) {

															s_value = i_template.apply({
																id: i_button.key,
																text: s_value
															});
														}
														else {
															if (o_data.text) {
																s_value = o_data.text;
															}
															else {
																s_value = i_template.apply({
																	id: i_button.key,
																	text: o_config.text
																});
															}
														}

														i_button.setText(s_value);

														i_button.textID = o_config.txtId = o_values.txtId;

													}, true);

													var o_translation = o_data.translation || {};

													var s_value = o_translation[i_self.getActiveLanguage()] || o_config.text;

													i_editor.startEdit(i_button.getEl(), s_value, false);
											});
										}
										else {

											o_config.originalValue = i_template.apply({
												id: i_button.key,
												text: o_config.text
											});

											o_config.dta = o_config.text;

											var i_editor = i_self.createEditor(o_config, {}, function (o_values, o_translation) {

												i_button.textID = o_config.txtId =  o_values.txtId;

												var s_value = o_translation[i_self.getActiveLanguage()];

												if (s_value) {

													s_value = i_template.apply({
														id: i_button.key,
														text: s_value
													});
												}
												else {
													s_value = i_template.apply({
														id: i_button.key,
														text: o_config.text
													});
												}

												i_button.setText(s_value);

											}, true);

											i_editor.startEdit(i_button.getEl(), o_config.dta, false);
										}
									}
								}
							});
						}
					}
				});
			}
			else {
				i_button.on({
					click: {
						fn: function () {
							i_self.doKeyEvent(i_button.key);
						}
					}
				});
			}

			a_buttons.push(i_button);
		});

		return a_buttons;
	},

	doCreateFromData: function(o_inputData) {

		var i_self = this;
		var i_controller = i_self.getController();

		var a_inputs = i_self.getPrevInputData();

		i_self.setInputData(o_inputData);
		i_self.splitFields();

		i_self.isCreating = true;

		var s_languages = o_inputData.languages || "";

		var a_languagesSplit = s_languages.split(",").filter(function(value) {
			return value;
		});

		var a_languages = i_self.getLanguages();

		var o_rules = i_self.getCssRules();

		if (a_languages.length === 0) {

			Ext.Array.each(a_languagesSplit, function(s_value) {
				s_value = s_value.trim();
				a_languages.push(s_value);
			});

			i_self.setLanguages(a_languages);
		}

		i_self.setOriginalTitle(o_inputData.origTitle || "");

		var a_stack = i_self.getScreenStack();

		o_inputData.window = o_inputData.window || {};

		var a_reversed = a_stack.slice().reverse();
		var n_index = a_reversed.indexOf(o_inputData.title);
		var n_stackIndex = a_stack.indexOf(o_inputData.title);

		var s_title = a_reversed[n_index];
		var s_stack = a_stack[n_stackIndex];

		i_self.setInputData(o_inputData);

		if (n_index == -1 || (n_index > 1 && n_stackIndex != 0 && s_title != s_stack)) {
			a_stack.push(o_inputData.title);
			if (o_inputData.window.level > 0) {
				a_inputs.push({
					index: a_reversed.length
				});
			}
		}
		else {
			if (n_index >= 0) {
				a_reversed = Ext.Array.slice(a_reversed, n_index);
				a_stack = a_reversed.reverse();

				var n_itemIndex = a_stack.length;

				i_self.setScreenStack(a_stack);

				if (n_index == 1) {

					var o_found = Ext.Array.findBy(a_inputs, function (o_config) {
						return o_config.index == n_itemIndex;
					});

					if (o_found) {
						a_inputs.pop();
					}
				}
				else if (n_index > 1) {

					a_sliced = Ext.Array.slice(a_inputs);
					a_sliced = a_sliced.reverse();

					Ext.Array.each(a_sliced, function(o_config) {
						if (o_config.index > n_stackIndex) {
							a_inputs.pop();
						}
					});
				}

				i_self.setPrevInputData(a_inputs);
			}
		}

		if (o_inputData.window.level <= 0) {
			o_inputData.window.level = a_inputs.length > 0 ? 1 : 0;
		}

		var a_fields = [];
		var i_content;

		Ext.suspendLayouts();

		if (o_inputData.window && o_inputData.window.level > 0) {

			if (i_self.rendered) {

				i_self.mask(false);
				i_self.createWindow(o_inputData);

			}
		}
		else {

			i_self.setActiveWindow(null);

			if (i_self.rendered) {
				i_self.unmask();
			}

			if (o_inputData.title) {
				i_self.doTitleUpdate(o_inputData.title);
			}

			i_content = i_self.getContent();

			if (i_self.getResizeMode() == 2) {

				i_content.setSize({
					width: IceCap.util.Handler.getWidth(o_inputData.width + 7 || 87, o_rules.fontScale),
					height: IceCap.util.Handler.getHeight(o_inputData.height || 24, o_rules.lineScale)
				});
			}

			var i_keyArea = i_self.getKeyArea();

			if (i_content.rendered) {
				i_content.removeAll(true);
			}

			if (i_keyArea.rendered) {
				i_keyArea.removeAll(true);
			}

			i_self.setCursor(null);
			i_self.setMarker(null);
			i_self.setSelector(null);

			Ext.resumeLayouts(true);
			
			if (i_content.rendered) {

				var i_region = i_content.getScrollableClientRegion();
				IceCap.util.Handler.calculateChange(i_self, i_region);
			}

			var a_keys = i_self.createKeys();
			i_keyArea.add(a_keys);

			i_keyArea[a_keys.length === 0 ? "hide" : "show"]();

			Ext.suspendLayouts();

			var a_created = [];
			a_created = a_created.concat(i_self.createLabels());
			a_created = a_created.concat(i_self.createFields(a_created));
			a_created = a_created.concat(i_self.createMetaFields());

			a_created.push(i_self.createCursor());
			a_created.push(i_self.createMarker());
			a_created.push(i_self.createSelector());

			if (o_inputData.processedFields) {

				var a_toAdd = Ext.Array.slice(a_created);

				var n_inputWidth = o_inputData.width || 80;
				var n_inputHeight = o_inputData.height || 24;

				var i_container = Ext.widget("container", {
					layout: "anchor",
					width: IceCap.util.Handler.getWidth(n_inputWidth, o_rules.fontScale),
					height: IceCap.util.Handler.getHeight(n_inputHeight, o_rules.lineScale),
					focusable: false,
					tabIndex: -1,
					defaults: {
						margin: "5 0 0 0"
					},
					items: a_toAdd
				});

				a_created = [i_container];
			}

			i_content.add(a_created);

			i_self.updateMessage(o_inputData);

			if (o_inputData.cmd) {

				i_controller.onPCO(o_inputData);
				i_controller.doKeyEvent("ENTER");
			}

			var i_marker = i_self.getMarker();
			i_marker.setInUse(i_self.getMarkerActive());
		}

		IceCap.util.Handler.setFixed(true);

		Ext.resumeLayouts(true);

		if (i_content) {

			a_fields = IceCap.util.Handler.getInputFields(i_content);

			var b_found = false;
			var b_error = false;

			if (o_inputData.msgBox && o_inputData.msgBox.text) {
				b_error = true;
			}

			if (a_fields.length > 0) {

				b_found = Ext.Array.findBy(a_fields, function (i_field) {
					return i_field.getTabIndex() === i_self.getNeedFocus();
				});
			}

			if (!b_found) {

				i_self.setCurrentPosition({
					col: o_inputData.csrCol || 1,
					lin: o_inputData.csrLin || 1
				});
			}

			if (b_error) {
				i_self.onError(o_inputData);
			}
			else {
				i_self.findFocus();
			}
		}


		var a_metafields = o_inputData.metaFields || [];

		if (
			o_inputData.input.length === 0 &&
			o_inputData.input.length === 0 &&
			a_metafields.length === 0 && o_inputData.messageText) {

				var s_message = o_inputData.messageText;

				i_self.setMessageText(s_message);

				i_self.setLoading(s_message);
				i_controller.onSendData({
					func: ""
				}, {});
		}

		var b_translation = !Ext.isEmpty(o_inputData.isTranslator) ? o_inputData.isTranslator : false;

		var i_translatorButton = i_self.getTranslator();

		b_translation = i_self.getLanguages().length > 0;

		i_translatorButton[b_translation ? "show" : "hide"]();

		var i_active = i_self.getActiveWindow();

		if (i_active) {

			var i_main = i_self.getMain();

			if (i_main) {

				var o_mainBox = i_main.getBox();
				var o_activeBox = i_active.getBox();

				var a_xy = i_active.getXY();

				if (o_mainBox.bottom < o_activeBox.bottom) {

					var n_diff = o_activeBox.bottom - o_mainBox.bottom;

					i_active.setY(a_xy[1] - (n_diff + o_mainBox.top));
				}
			}
		}

		i_self.isCreating = false;

	},

	createWindow: function(o_inputData) {

		var i_self = this;
		var o_config = o_inputData.window;

		var i_active = i_self.getActiveWindow();

		var o_rules = i_self.getCssRules();

		// var a_windows = i_self.getWindows();

		// var i_active = a_windows[o_inputData.window.level -1];

		var i_content = i_self.getContent();

		o_config.width = o_config.width || 80;

		var o_size = {
			width: IceCap.util.Handler.getWidth(o_config.width + 2, o_rules.fontScale) + 7,
			height: IceCap.util.Handler.getHeight(o_config.height, o_rules.lineScale)
		};

		// Ext.Array.each(a_windows, function (i_window) {
		// 	i_window.setStyle({
		// 		"pointer-events": "all"
		// 	});
		// });

		if (i_active) {

			// Ext.Array.each(a_windows, function (i_window) {

			// 	if (i_window.getLevel() < i_active.getLevel()) {
			// 		i_window.setStyle({
			// 			"pointer-events": "none"
			// 		});
			// 	}
			// });

			i_active.hide();

			i_active.setHeight(null);
			i_active.setWidth(null);

			i_active.setTitle(o_config.title);

			i_active.getContent().setSize(o_size);

			i_active.setInputData(o_inputData);

			i_active.show();

			i_active.recreate();

		}
		else {

			i_active = Ext.create("IceCap.view.Window", {
				title: o_config.title,
				inputData: o_inputData,
				sessionValue: i_self.getSessionValue(),
				modal: false,
				onEsc: Ext.emptyFn,
				theme: i_self.getTheme(),
				markerActive: i_self.getMarkerActive(),
				options: i_self.getOptions(),
				ui: "icecap-window",
				bodyCls: ["icecap-window", i_self.getTheme()].join("-"),
				constrainHeader: true,
				typeMode: i_self.getTypeMode(),
				level: o_inputData.window.level,
				edit: i_self.getEdit(),
				activeLanguage: i_self.getActiveLanguage(),
				cssRules: o_rules,
				listeners: {
					destroy: {
						fn: function(i_window) {

							i_self.setActiveWindow(null);

							// var a_windows = i_self.getWindows();

							// a_windows = Ext.Array.remove(a_windows, i_window);

							// i_self.setWindows(a_windows);
						}
					},
					toWindow: {
						fn: function(i_window, o_inputData) {
							if (!o_inputData.close) {

								// var b_close = false;

								// if (!o_inputData.window.level) {

								// 	var a_windows = i_self.getWindows();

								// 	if (a_windows.length > 1) {
								// 		o_inputData.window.level = a_windows.length;
								// 	}
								// }
								// else {
								// 	if (o_inputData.window.level <= i_window.getLevel()) {
								// 		var n_diff = i_window.getLevel() - o_inputData.window.level;

								// 		if (n_diff > 1) {
								// 			o_inputData.window.level = i_window.getLevel()
								// 		}
								// 		else {
								// 			b_close = true;
								// 		}
								// 	}
								// }

								// if (b_close) {
								// 	i_window.close();
								// }

								if (!o_inputData.window.level) {
									i_window.close();
								}

								i_self.doCreateFromData(o_inputData);

							}
							else {
								i_window.close();
								i_self.close();
							}
						}
					},
					copyplus: {
						fn: function(s_copy) {

							var i_copyArea = IceCap.util.Handler.getCopyArea();

							var s_value = i_copyArea.getValue();

							var a_values = [
								s_value,
								s_result
							];

							a_values = Ext.Array.filter(a_values, function (s_value) {
								return s_value;
							});

							s_result = a_values.join("\n");

							i_field.setValue(s_result);

							i_copyArea.setValue(s_result);

							i_copyArea.show();

							i_copyArea.inputEl.dom.focus();

							i_copyArea.inputEl.dom.select();

							document.execCommand("copy");

							i_copyArea.hide();

						}
					}
				}
			});

			i_content.add(i_active);

			// var a_xy = [];

			// Ext.Array.each(a_windows, function(i_window) {
			// 	a_xy = i_window.getXY();
			// });


			// if (a_xy.length === 0) {
			// 	i_active.show(null, function() {
			// 		i_active.on({
			// 			resize: {
			// 				fn: function() {
			// 					i_active.center();
			// 				},
			// 				single: true
			// 			}
			// 		});

			// 		i_active.getContent().setSize(o_size);

			// 	});
			// }
			// else{
			// 	i_active.getContent().setSize(o_size);
			// 	i_active.showAt(a_xy[0] + 200, a_xy[1] + 30);
			// }

			// var b_center = false;

			// if (i_active.getSize().width > window.screen.width) {
			// 	i_active.setWidth(window.screen.width);
			// 	b_center = true;
			// }

			// if (i_active.getSize().height > window.screen.height) {
			// 	i_active.setHeight(window.screen.height);
			// 	b_center = true;
			// }

			// if (b_center) {
			// 	i_active.center();
			// }

			// a_windows.push(i_active);

			//i_self.setWindows(a_windows);

			// Ext.Array.each(a_windows, function(i_window) {

			// 	if (o_inputData.window.level > i_window.getLevel()) {
			// 		i_window.setStyle({
			// 			"pointer-events": "none"
			// 		});
			// 	}
			// });

			i_active.getContent().setSize(o_size);

			i_active.show();

		}

		i_self.setActiveWindow(i_active);

		var i_query = Ext.get(i_self.getMaskTarget().query(".x-mask"));

		Ext.Array.each(i_query.elements, function(i_mask) {
			Ext.get(i_mask).setStyle("opacity", 0);
		});
	},

	getCurrentField: function() {

		var i_self = this;

		var a_fields = IceCap.util.Handler.getInputFields(i_self);
		var n_tabIndex = i_self.getCurrentTabIndex();

		var i_currentField;

		Ext.Array.each(a_fields, function(i_field) {
			if (i_field.getTabIndex() === n_tabIndex && i_field.hasFocus) {
				i_currentField = i_field;
				return false;
			}
		});

		return i_currentField;
	},

	doKeyEvent: function(s_value) {

		var i_self = this;

		var i_controller = i_self.getController();

		var o_inputData = i_self.getInputData() || {};

		var a_disabledKeys = Ext.Array.from(o_inputData.disabledKeys || []);

		var o_found = Ext.Array.findBy(a_disabledKeys, function(o_key) {
			return s_value == o_key.id;
		});

		if (!o_found)  {
			i_controller.doKeyEvent(s_value);
		}
		else {

			IceCap.util.Handler.messageBox({
				title: "Error",
				msg: "Funktionstasten er ikke tilladt",
				yesText: "Ok",
				yesFn: function () {
					i_self.findFocus();
				}
			});
		}
	},

	doNavigationKey: function(n_direction, b_tab) {

		var i_self = this;
		var i_controller = i_self.getController();
		i_controller[b_tab ? "doTabKey" : "doArrowKeys"](n_direction);
	},

	addKeyEvents: function() {

		var i_self = this;

		var a_bindings = [
			{
				key: Ext.event.Event.PAGE_DOWN,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					i_self.doKeyEvent("ROLLUP");
				}
			},
			{
				key: Ext.event.Event.PAGE_UP,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					i_self.doKeyEvent("ROLLDOWN");
				}
			},
			{
				key: Ext.event.Event.ENTER,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					i_self.doKeyEvent("ENTER");
				}
			},
			{
				key: Ext.event.Event.ESC,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {
						i_event.stopEvent();
						i_selector.hide();
					}
					else {
						i_self.doKeyEvent("ATTN");
					}
				}
			},
			{
				key: Ext.event.Event.LEFT,
				shift: false,
				ctrl: true,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_selector.getLocalY()
						}, o_rules);

						var n_col = o_coords.col - 1;

						var n_x = IceCap.util.Handler.getX(n_col, o_rules.fontScale);

						if (n_x == i_selector.getLocalX()) {
							n_x = IceCap.util.Handler.getX(n_col - 1, o_rules.fontScale);
						}

						i_selector.setLeft(n_x);

						var i_region = i_selector.getRegion(false, true);

						i_selector.dragX = i_region.right;
						i_selector.setDragY(i_region.bottom);
					}
				}
			},
			{
				key: Ext.event.Event.RIGHT,
				shift: false,
				ctrl: true,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_selector.getLocalY()
						}, o_rules);

						var n_col = o_coords.col;

						var n_x = IceCap.util.Handler.getX(n_col, o_rules.fontScale);

						if (n_x == i_selector.getLocalX()) {
							n_x = IceCap.util.Handler.getX(n_col + 1, o_rules.fontScale);
						}

						i_selector.setLeft(n_x);

						var i_region = i_selector.getRegion(false, true);

						i_selector.dragX = i_region.right;
						i_selector.setDragY(i_region.bottom);
					}
				}
			},
			{
				key: Ext.event.Event.LEFT,
				shift: true,
				ctrl: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					var i_target = i_event.getTarget();
					var i_element = Ext.get(i_target);
					var i_component = i_element.component;

					if (!i_component) {
						i_component = i_element.getParent().component;
					}

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var i_region = i_selector.getRegion(false, true);

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_region.right,
							y: i_selector.getLocalY()
						}, o_rules);

						var n_col = o_coords.col - 1;

						var n_x = IceCap.util.Handler.getX(n_col, o_rules.fontScale);

						if (n_x == Math.floor(i_region.right)) {
							n_x = IceCap.util.Handler.getX(n_col - 1, o_rules.fontScale);
						}

						i_selector.setDragX(n_x);
					}
					else {
						if (!i_component.isXType("field")) {

							var i_cursor = i_self.getCursor();

							var o_click = Ext.apply({
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY()
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col - 1, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							var n_dragX = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_dragY = IceCap.util.Handler.getY(o_position.lin + 1, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.show();

							i_selector.setSelecting(true);

							i_selector.setDragX(n_dragX);
							i_selector.setDragY(n_dragY);

							i_event.stopEvent();
						}
					}
				}
			},
			{
				key: Ext.event.Event.RIGHT,
				shift: true,
				ctrl: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					var i_target = i_event.getTarget();
					var i_element = Ext.get(i_target);
					var i_component = i_element.component;

					if (!i_component) {
						i_component = i_element.getParent().component;
					}

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var i_region = i_selector.getRegion(false, true);

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_region.right,
							y: i_selector.getLocalY()
						}, o_rules);

						var n_col = o_coords.col;

						var n_x = IceCap.util.Handler.getX(n_col, o_rules.fontScale);

						if (n_x == Math.floor(i_region.right)) {
							n_x = IceCap.util.Handler.getX(n_col + 1, o_rules.fontScale);
						}

						i_selector.setDragX(n_x);
					}
					else {
						if (!i_component.isXType("field")) {

							var i_cursor = i_self.getCursor();

							var o_click = Ext.apply({
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY()
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col - 1, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							var n_dragX = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_dragY = IceCap.util.Handler.getY(o_position.lin + 1, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.show();

							i_selector.setSelecting(true);

							i_selector.setDragX(n_dragX);
							i_selector.setDragY(n_dragY);

							i_event.stopEvent();
						}
					}
				}
			},
			{
				key: Ext.event.Event.UP,
				shift: false,
				ctrl: true,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_selector.getLocalY()
						}, o_rules);

						var n_lin = o_coords.lin;

						var n_y = IceCap.util.Handler.getY(n_lin, o_rules.lineScale);

						if (n_y == i_selector.getLocalY()) {
							n_y = IceCap.util.Handler.getY(n_lin - 1, o_rules.lineScale);
						}

						i_selector.setTop(n_y);

						var i_region = i_selector.getRegion(false, true);

						i_selector.dragY = n_y;
						i_selector.setDragX(i_region.right);
					}
				}
			},
			{
				key: Ext.event.Event.DOWN,
				shift: false,
				ctrl: true,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_selector.getLocalY()
						}, o_rules);

						var n_lin = o_coords.lin + 1;

						var n_y = IceCap.util.Handler.getY(n_lin, o_rules.lineScale);

						if (n_y == i_selector.getLocalY()) {
							n_y = IceCap.util.Handler.getY(n_lin + 1, o_rules.lineScale);
						}

						i_selector.setTop(n_y);

						var i_region = i_selector.getRegion(false, true);

						i_selector.dragY = n_y;
						i_selector.setDragX(i_region.right);
					}
				}
			},
			{
				key: Ext.event.Event.UP,
				shift: true,
				ctrl: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					var i_target = i_event.getTarget();
					var i_element = Ext.get(i_target);
					var i_component = i_element.component;

					if (!i_component) {
						i_component = i_element.getParent().component;
					}

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var i_region = i_selector.getRegion(false, true);

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_region.bottom
						}, o_rules);

						var n_lin = o_coords.lin;

						var n_y = IceCap.util.Handler.getY(n_lin, o_rules.lineScale);

						if (n_y == Math.floor(i_region.bottom)) {
							n_y = IceCap.util.Handler.getY(n_lin - 1, o_rules.lineScale);
						}

						i_selector.setDragY(n_y);
					}
					else {
						if (!i_component.isXType("field")) {

							var i_cursor = i_self.getCursor();

							var o_click = Ext.apply({
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY()
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col - 1, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							var n_dragX = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_dragY = IceCap.util.Handler.getY(o_position.lin + 1, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.show();

							i_selector.setSelecting(true);

							i_selector.setDragX(n_dragX);
							i_selector.setDragY(n_dragY);

							i_event.stopEvent();
						}
					}
				}
			},
			{
				key: Ext.event.Event.DOWN,
				shift: true,
				ctrl: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					var i_target = i_event.getTarget();
					var i_element = Ext.get(i_target);
					var i_component = i_element.component;

					if (!i_component) {
						i_component = i_element.getParent().component;
					}

					if (!i_selector.isHidden()) {

						i_event.stopEvent();

						var i_region = i_selector.getRegion(false, true);

						var o_coords = IceCap.util.Handler.toColAndLine({
							x: i_selector.getLocalX(),
							y: i_region.bottom
						}, o_rules);

						var n_lin = o_coords.lin + 1;

						var n_y = IceCap.util.Handler.getY(n_lin, o_rules.lineScale);

						if (n_y == Math.floor(i_region.bottom)) {
							n_y = IceCap.util.Handler.getY(n_lin + 1, o_rules.lineScale);
						}

						i_selector.setDragY(n_y);
					}
					else {
						if (!i_component.isXType("field")) {

							var i_cursor = i_self.getCursor();

							var o_click = Ext.apply({
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY()
							});

							var o_position = IceCap.util.Handler.toColAndLine(o_click, o_rules);

							var n_x = IceCap.util.Handler.getX(o_position.col - 1, o_rules.fontScale);
							var n_y = IceCap.util.Handler.getY(o_position.lin, o_rules.lineScale);

							var n_dragX = IceCap.util.Handler.getX(o_position.col, o_rules.fontScale);
							var n_dragY = IceCap.util.Handler.getY(o_position.lin + 1, o_rules.lineScale);

							i_selector.resetPos(n_x, n_y);

							i_selector.show();

							i_selector.setSelecting(true);

							i_selector.setDragX(n_dragX);
							i_selector.setDragY(n_dragY);

							i_event.stopEvent();
						}
					}
				}
			},
			{
				key: Ext.event.Event.UP,
				shift: false,
				ctrl: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {

						if (!i_event.target.type) {

							i_event.stopEvent();

							var i_cursor = i_self.getCursor();
							var o_position = i_self.getCurrentPosition();

							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							o_position.lin--;

							if (o_position.lin < 1) {
								o_position.lin = 1;
							}

							var o_box = {
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY() - IceCap.util.Handler.getHeight(1, o_rules.lineScale),
								width: i_cursor.getWidth(),
								height: i_cursor.getHeight(),
								right: i_cursor.getLocalX() + i_cursor.getWidth(),
								bottom: i_cursor.getLocalY(),
								height: 1
							};


							Ext.Array.each(a_inputs, function (i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {
									b_intersect = true;
									i_field.focus(false, 10);
									return false;
								}
							});

							var b_intersect = false;

							Ext.Array.each(a_inputs, function(i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {

									b_intersect = true;
									i_field.focus(false, 10);

									var n_start = o_position.col - i_field.col;
									var i_inputEl = i_field.inputEl;
									i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = n_start;

									return false;
								}
							});

							if (!b_intersect) {
								i_cursor.moveCursor(o_position);
							}
							i_self.setCurrentPosition(o_position);
						}
						else {
							i_self.doNavigationKey(0);
						}
					}
				}
			},
			{
				key: Ext.event.Event.DOWN,
				shift: false,
				ctrl: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {

						if (!i_event.target.type) {

							i_event.stopEvent();

							var i_cursor = i_self.getCursor();
							var o_position = i_self.getCurrentPosition();
							var o_inputData = i_self.getInputData();

							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							o_position.lin++;

							if (o_position.lin > o_inputData.height) {
								o_position.lin = o_inputData.height;
							}

							var o_box = {
								x: i_cursor.getLocalX(),
								y: i_cursor.getLocalY() + IceCap.util.Handler.getHeight(1, o_rules.lineScale),
								width: i_cursor.getWidth(),
								height: i_cursor.getHeight(),
								right: i_cursor.getLocalX() + i_cursor.getWidth(),
								bottom: i_cursor.getLocalY() + IceCap.util.Handler.getHeight(1, o_rules.lineScale) + i_cursor.getHeight(),
								height: 1
							};

							var b_intersect = false;

							Ext.Array.each(a_inputs, function(i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {

									b_intersect = true;
									i_field.focus(false, 10);

									var n_start = o_position.col - i_field.col;
									var i_inputEl = i_field.inputEl;
									i_inputEl.dom.selectionStart = i_inputEl.dom.selectionEnd = n_start;

									return false;
								}
							});

							if (!b_intersect) {
								i_cursor.moveCursor(o_position);
							}
							i_self.setCurrentPosition(o_position);
						}
						else {
							i_self.doNavigationKey(1);
						}
					}
				}
			},
			{
				key: Ext.event.Event.LEFT,
				shift: false,
				ctrl: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {
						if (!i_event.target.type) {
							i_event.stopEvent();

							var i_cursor = i_self.getCursor();
							var o_position = i_self.getCurrentPosition();

							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							o_position.col--;

							if (o_position.col < 1) {
								o_position.col = 1;
							}

							var o_box = {
								x: i_cursor.getLocalX() - IceCap.util.Handler.getWidth(1, o_rules.fontScale),
								y: i_cursor.getLocalY(),
								width: i_cursor.getWidth(),
								height: i_cursor.getHeight(),
								right: (i_cursor.getLocalX() - IceCap.util.Handler.getWidth(1, o_rules.fontScale)) + i_cursor.getWidth(),
								bottom: i_cursor.getLocalY() + i_cursor.getHeight(),
								height: 1
							};


							var b_intersect = false;

							Ext.Array.each(a_inputs, function(i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {
									b_intersect = true;
									i_field.focus(false, 10);
									return false;
								}
							});

							if (!b_intersect) {
								i_cursor.moveCursor(o_position);
							}

							i_self.setCurrentPosition(o_position);
						}
					}
				}
			},
			{
				key: Ext.event.Event.RIGHT,
				shift: false,
				ctrl: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {
						if (!i_event.target.type) {

							i_event.stopEvent();

							var i_cursor = i_self.getCursor();
							var o_position = i_self.getCurrentPosition();
							var o_inputData = i_self.getInputData();

							var a_inputs = IceCap.util.Handler.getInputFields(i_self);

							o_position.col++;

							if (o_position.col > o_inputData.width) {
								o_position.col = o_inputData.width;
							}

							var o_box = {
								x: i_cursor.getLocalX() + IceCap.util.Handler.getWidth(1, o_rules.fontScale),
								y: i_cursor.getLocalY(),
								width: i_cursor.getWidth(),
								height: i_cursor.getHeight(),
								right: i_cursor.getLocalX() + IceCap.util.Handler.getWidth(1, o_rules.fontScale) + i_cursor.getWidth(),
								bottom: i_cursor.getLocalY() + i_cursor.getHeight(),
								height: 1
							};

							var b_intersect = false;

							Ext.Array.each(a_inputs, function(i_field) {

								var i_region = i_field.getRegion(false, true);

								if (i_region.intersect(o_box)) {
									b_intersect = true;
									i_field.focus(false, 10);
									return false;
								}
							});

							if (!b_intersect) {
								i_cursor.moveCursor(o_position);
							}

							i_self.setCurrentPosition(o_position);
						}
					}
				}
			},
			{
				key: Ext.event.Event.TAB,
				shift: false,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {
						i_event.stopEvent();
						i_event.stopPropagation();

						i_self.doNavigationKey(1, true);
					}


				}
			},
			{
				key: Ext.event.Event.TAB,
				shift: true,
				fn: function(n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;

					var i_activeComponent = Ext.ComponentManager.getActiveComponent();
					var i_content = i_self.getContent();

					if (i_content.contains(i_activeComponent) || i_content.ownerCt == i_activeComponent) {
						i_event.stopEvent();
						i_event.stopPropagation();

						i_self.doNavigationKey(0, true);
					}
				}
			},
			{
				key: Ext.event.Event.NUM_PLUS,
				fn: function(n_key, i_event) {

					i_event.stopEvent();

					var i_key = this;
					var i_self = i_key.target.component;

					var i_field = i_self.getCurrentField();

					if (i_field) {

						var n_start = i_field.inputEl.el.dom.selectionStart;

						var s_text = i_field.getValue();

						s_text = s_text.substr(0, n_start);

						i_field.setValue(s_text);

						i_self.doNavigationKey(1, true);
					}
				}
			},
			{
				key: Ext.event.Event.HOME,
				ctrl: true,
				alt: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();

					var i_key = this;
					var i_self = i_key.target.component;

					var b_markerActive = i_self.getMarkerActive();
					var i_marker = i_self.getMarker();

					i_self.setMarkerActive(!b_markerActive);

					i_marker.toggle();
				}
			},
			{
				key: Ext.event.Event.INSERT,
				ctrl: false,
				alt: false,
				fn: function (n_key, i_event) {

					var n_type = i_self.getTypeMode();
					switch (n_type) {
						case IceCap.util.Handler.typeMode.OVERWRITE:
							n_type = IceCap.util.Handler.typeMode.FOCUS;
							break;
						case IceCap.util.Handler.typeMode.FOCUS:
							n_type = IceCap.util.Handler.typeMode.INSERT;
							break;
						default:
							n_type = IceCap.util.Handler.typeMode.OVERWRITE;
							break;
					}

					i_self.setTypeMode(n_type);
				}
			},
			{
				key: Ext.event.Event.A,
				ctrl: true,
				alt: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;

					var i_target = i_event.getTarget();

					var i_element = Ext.get(i_target);

					if (!i_element.isInputField()) {
						var i_selector = i_self.getSelector();

						var o_inputData = i_self.getInputData();

						i_event.stopEvent();

						i_selector.setSelecting(true);


						i_selector.setLeft(IceCap.util.Handler.getX(1));
						i_selector.setTop(IceCap.util.Handler.getY(1));

						i_selector.setDragX(IceCap.util.Handler.getX(o_inputData.width));
						i_selector.setDragY(IceCap.util.Handler.getY(o_inputData.height + 1));

						i_selector.setSelecting(false);
					}
				}
			},
			{
				key: Ext.event.Event.C,
				ctrl: true,
				shift: true,
				alt: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (i_selector.isVisible()) {
						i_event.stopEvent();

						var i_field  = IceCap.util.Handler.getCopyArea();

						var a_inputs = IceCap.util.Handler.getInputFields(i_self);
						var a_labels = IceCap.util.Handler.getLabels(i_self);

						var i_region = i_selector.getRegion(true, true);

						var n_rows = Math.round(i_region.height / IceCap.util.Handler.getHeight(1, o_rules.lineScale));
						var n_cols = Math.round(i_region.width / IceCap.util.Handler.getWidth(1, o_rules.fontScale));

						var a_copyLabels = IceCap.util.Handler.getCopyValues(a_labels, n_rows, n_cols, i_region, o_rules, 0);
						var a_copyFields = IceCap.util.Handler.getCopyValues(a_inputs, n_rows, n_cols, i_region, o_rules, 1);

						var a_result = [];

						Ext.Array.each(a_copyLabels, function (s_label, n_index) {

							var s_result = "";

							var s_field = a_copyFields[n_index];

							var a_splitLabel = s_label.split("");
							var a_splitField = s_field.split("");

							var n_copy = a_splitLabel.length;

							for (var n_copyIndex = 0; n_copyIndex < n_copy; n_copyIndex++) {

								var s_charLabel = a_splitLabel[n_copyIndex];
								var s_charField = a_splitField[n_copyIndex];

								s_result += !Ext.isEmpty(Ext.String.trim(s_charLabel)) ? s_charLabel : s_charField;

							}

							a_result.push(s_result);
						});

						var s_result = a_result.join("\n");

						var a_values = [
							i_field.getValue(),
							s_result
						];

						a_values = Ext.Array.filter(a_values, function (s_value) {
							return s_value;
						});

						s_result = a_values.join("\n");

						i_field.setValue(s_result);

						i_field.show();

						i_field.inputEl.dom.focus();

						i_field.inputEl.dom.select();

						document.execCommand("copy");

						i_selector.hide();

						i_field.hide();

						var i_main = i_self.getMain();
						i_main.focus();
					}
				}
			},
			{
				key: Ext.event.Event.C,
				ctrl: true,
				alt: false,
				fn: function (n_key, i_event) {

					var i_key = this;
					var i_self = i_key.target.component;
					var o_rules = i_self.getCssRules();

					var i_selector = i_self.getSelector();

					if (i_selector.isVisible()) {
						i_event.stopEvent();

						var i_field = IceCap.util.Handler.getCopyArea();

						i_field.setValue("");

						var a_inputs = IceCap.util.Handler.getInputFields(i_self);
						var a_labels = IceCap.util.Handler.getLabels(i_self);

						var i_region = i_selector.getRegion(true, true);

						var n_rows = Math.round(i_region.height / IceCap.util.Handler.getHeight(1, o_rules.lineScale));
						var n_cols = Math.round(i_region.width / IceCap.util.Handler.getWidth(1, o_rules.fontScale));

						var a_copyLabels = IceCap.util.Handler.getCopyValues(a_labels, n_rows, n_cols, i_region, o_rules, 0);
						var a_copyFields = IceCap.util.Handler.getCopyValues(a_inputs, n_rows, n_cols, i_region, o_rules, 1);

						var a_result = [];

						Ext.Array.each(a_copyLabels, function (s_label, n_index) {

							var s_result = "";

							var s_field = a_copyFields[n_index];

							var a_splitLabel = s_label.split("");
							var a_splitField = s_field.split("");

							var n_copy = a_splitLabel.length;

							for (var n_copyIndex = 0; n_copyIndex < n_copy; n_copyIndex++) {

								var s_charLabel = a_splitLabel[n_copyIndex];
								var s_charField = a_splitField[n_copyIndex];

								s_result += !Ext.isEmpty(Ext.String.trim(s_charLabel)) ? s_charLabel : s_charField;

							}

							a_result.push(s_result);
						});

						var s_result = a_result.join("\n");

						i_field.setValue(s_result);

						i_field.show();

						i_field.inputEl.dom.focus();

						i_field.inputEl.dom.select();

						document.execCommand("copy");

						i_selector.hide();

						i_field.hide();

						var i_main = i_self.getMain();
						i_main.focus();
					}
				}
			}
		];

		a_bindings = a_bindings.concat(i_self.getFKeys());

		var i_keyMap = Ext.create("Ext.util.KeyMap", {
			target: i_self.getEl(),
			binding: a_bindings
		});

		i_self.setKeyHandler(i_keyMap)
	},

	getFKeys: function() {

		var i_self = this;

		var a_keys = [
			{
				key: Ext.event.Event.F1,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F1");
				}
			},
			{
				key: Ext.event.Event.F2,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F2");
				}
			},
			{
				key: Ext.event.Event.F3,
				shift: false,
				alt: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F3");
				}
			},
			{
				key: Ext.event.Event.F4,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F4");
				}
			},
			{
				key: Ext.event.Event.F5,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F5");
				}
			},
			{
				key: Ext.event.Event.F6,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F6");
				}
			},
			{
				key: Ext.event.Event.F7,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F7");
				}
			},
			{
				key: Ext.event.Event.F8,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F8");
				}
			},
			{
				key: Ext.event.Event.F9,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F9");
				}
			},
			{
				key: Ext.event.Event.F10,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F10");
				}
			},
			{
				key: Ext.event.Event.F11,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F11");
				}
			},
			{
				key: Ext.event.Event.F12,
				shift: false,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F12");
				}
			}
		];

		a_keys = a_keys.concat(i_self.getFShiftKeys());

		return a_keys;
	},

	getFShiftKeys: function() {

		var i_self = this;

		var a_keys = [
			{
				key: Ext.event.Event.F1,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F13");
				}
			},
			{
				key: Ext.event.Event.F2,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F14");
				}
			},
			{
				key: Ext.event.Event.F3,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F15");
				}
			},
			{
				key: Ext.event.Event.F4,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F16");
				}
			},
			{
				key: Ext.event.Event.F5,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F17");
				}
			},
			{
				key: Ext.event.Event.F6,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F18");
				}
			},
			{
				key: Ext.event.Event.F7,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F19");
				}
			},
			{
				key: Ext.event.Event.F8,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F20");
				}
			},
			{
				key: Ext.event.Event.F9,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F21");
				}
			},
			{
				key: Ext.event.Event.F10,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F22");
				}
			},
			{
				key: Ext.event.Event.F11,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F23");
				}
			},
			{
				key: Ext.event.Event.F12,
				shift: true,
				fn: function(n_key, i_event) {

					i_event.stopEvent();
					i_self.doKeyEvent("F24");
				}
			}
		];

		return a_keys;
	},

	createCursor: function() {

		var i_self = this;
		var o_inputData = i_self.getInputData();
		var o_rules = i_self.getCssRules();

		var i_cursor = Ext.widget("icecap-cursor", {
			theme: i_self.getTheme(),
			width: IceCap.util.Handler.getWidth(1, o_rules.fontScale),
			listeners: {
				show: {
					fn: function(i_cursor) {

						var i_marker = i_self.getMarker();
						var b_active = i_marker.getInUse();

						if (b_active) {
							i_marker.show();
						}
					}
				},
				render: {
					fn: function(i_item) {
						i_item.hide();
					}
				},
				afterrender: {
					fn: function(i_cursor) {

						var i_content = i_self.getContent();

						var a_fields = IceCap.util.Handler.getInputFields(i_content);

						if (a_fields.length === 0) {

							i_cursor.show();

							i_cursor.moveCursor({
								col: o_inputData.csrCol || 1,
								lin: o_inputData.csrLin || 1
							});
						}
					}
				}
			},
			moveCursor: function(o_position) {

				var i_cursor = this;
				var i_marker = i_self.getMarker();
				var o_rules = i_self.getCssRules();

				var n_x = IceCap.util.Handler.getX(o_position.col - 1);
				var n_y = IceCap.util.Handler.getY(o_position.lin + 1);

				i_cursor.move([
					(n_x * o_rules.fontScale) - (o_rules.fontScale < 1 ? (1/2) * o_rules.fontScale : 0),
					(n_y - 6) * o_rules.lineScale
				]);
				i_marker.move([
					n_x * o_rules.fontScale - (o_rules.fontScale < 1 ? (1/2) * o_rules.fontScale : 0),
					(n_y - 7) * o_rules.lineScale
				]);

				i_self.updateCurrentPosition(o_position);
			}
		});

		i_self.setCursor(i_cursor);

		return i_cursor;
	},

	createMarker: function() {

		var i_self = this;

		var i_marker = Ext.widget("icecap-marker", {
			hidden: true,
			active: false,
			inUse: false,
			ui: i_self.getTheme() || "default"
		});

		i_self.setMarker(i_marker);

		return i_marker;
	},

	createSelector: function() {

		var i_self = this;

		var i_content = i_self.getContent();

		var i_selector = Ext.widget("icecap-selector", {
			left: 0,
			top: 0,
			dragX: 0,
			dragY: 0,
			selecting: false,
			renderTo: i_content.getEl(),
			shadow:false,
		});

		i_self.setSelector(i_selector);

		return i_selector;
	},

	findFocus: function() {

		var i_self = this;
		var i_main = i_self.getMain();
		var i_content = i_self.getContent();

		var i_focus = i_main;

		var a_fields = IceCap.util.Handler.getInputFields(i_content);

		if (a_fields.length > 0) {
			i_focus = Ext.Array.findBy(a_fields, function (i_field) {
				return i_field.getTabIndex() === i_self.getNeedFocus();
			});

			if (!i_focus) {
				i_focus = a_fields[0];
			}
		}

		var f_delay = Ext.Function.createDelayed(function() {
			i_focus.focus(false, 10);
		}, 10);

		f_delay.call();

	},

	doTimer: function() {

		var i_self = this;
		var s_message = i_self.getMessageText();

		var i_timer = i_self.getTimer();
		if (!i_timer) {
			i_timer = new Ext.util.DelayedTask(function() {

				i_self.setLoading(s_message ? s_message :true);
			});

			i_self.setTimer(i_timer);

			i_timer.delay(1000);
		}
	},

	cancelTimer: function() {

		var i_self = this;

		var i_timer = i_self.getTimer();

		if (i_timer) {
			i_timer.cancel();
			i_self.setTimer(null);
		}
	},

	doTitleUpdate: function(s_value) {

		var i_self = this;
		var i_window = i_self.up("window");
		i_self.setTitle("");

		if (i_window && !i_window.isXType("ip2DomainModelEntityManager", false)) {

			if (!i_self.getIgnoreTitle()) {
				i_window.setTitle(s_value);
			}
		}
		else {
			if (!i_self.getIgnoreTitle()) {
				i_self.setTitle(s_value);
			}
		}
	},

	onError: function(o_inputData) {

		var i_self = this;

		IceCap.util.Handler.messageBox({
			title: "Server Message",
			msg: o_inputData.msgBox.text,
			yesText: "OK",
			yesFn: function(btn) {
				i_self.findFocus();
			}
		});
	},

	updateMessage: function(o_inputData) {

		var i_self = this;
		var o_rules = i_self.getCssRules();
		var i_statusbar = i_self.getStatusBar();

		var a_messages = Ext.Array.from(o_inputData.message);

		var a_result = [];

		if (a_messages.length > 1) {

			a_result.push(a_messages[0].text);
		}
		else {
			Ext.Array.each(a_messages, function(o_message) {
				a_result.push(o_message.text);
			});
		}

		var i_messageLabel = i_statusbar.getComponent("icecap-message");
		var i_languageButton = i_statusbar.getComponent("icecap-language");
		var i_translatorButton = i_statusbar.getComponent("icecap-translator");
		var i_position = i_statusbar.getComponent("icecap-position");
		var i_type = i_statusbar.getComponent("icecap-typemode");

		var s_message = a_result.join(" ");

		if (Ext.String.startsWith(s_message.toLowerCase(), "(c)")) {
			i_messageLabel.removeCls("icecap-statusbar-error");

		}
		else {
			i_messageLabel.addCls("icecap-statusbar-error")
		}

		i_messageLabel.setText(s_message);

		i_messageLabel.setStyle("font-size", "calc(1em * " + o_rules.fontScale);
		i_languageButton.setStyle("font-size", "calc(1em * " + o_rules.fontScale);
		i_translatorButton.setStyle("font-size", "calc(1em * " + o_rules.fontScale);
		i_position.setStyle("font-size", "calc(1em * " + o_rules.fontScale);
		i_type.setStyle("font-size", "calc(1em * " + o_rules.fontScale);

	},

	applyFFW: function(o_config) {

		var i_self = this;
		var s_hex = o_config.ffw;
		var b_fixed = IceCap.util.Handler.getFixed();

		var o_field = {
			xtype: "icecap-input"
		};

		var o_fieldStyle = {
		};

		if (o_config.ta) {

			Ext.apply(o_fieldStyle, {
				"text-align": o_config.ta
			});
		}

		if (s_hex) {

			var n_hex = parseInt(s_hex);

			var n_sanHex = IceCap.util.Handler.createIndicators(s_hex);

			if (n_sanHex & IceCap.util.Handler.FFW.BYPASS) {

				Ext.apply(o_field, {
					readOnly: true,
					tabIndex: -1,
					unselected: true
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.IO_FEATURE) {

				Ext.apply(o_field, {
					readOnly: true,
					selectOnFocus: true
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.ALPHA_ONLY) {

				Ext.apply(o_field, {
					maskRe: new RegExp("[a-z A-Z ,.-]")
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.NUMERIC_ONLY) {

				Ext.apply(o_field, {
					validator: function(value) {

						var b_valid = true;

						if (value) {
							var i_regex = new RegExp("^(?:\\+|\\-){0,1}[0-9]+(?:(,|\\.)[0-9]+){0,1}$");
							b_valid = i_regex.test(value);
						}
						
						return b_valid ? "" : "Must be pattern <strong>(+ or -) xxx ( , or . xxx)</strong> where x is <strong>0-9</strong><br>Anything in Parentheses is optinal";
					},
					maskRe: new RegExp("[\\+\\-,\\.0-9]")
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.DIGITS_ONLY) {

				Ext.apply(o_field, {
					maskRe: new RegExp("[0-9]")
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.MOD_DATA) {

				Ext.apply(o_field, {
					listeners: {
						afterrender: {
							fn: function(i_field) {

								i_field.originalValue = 0xFF;
							},
							single: true
						}
					}
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.AUTO_ENTER) {

				// THIS WE DONT NEED IN THE MODERN WORLD...

				// Ext.apply(o_field, {
				// 	listeners: {
				// 		blur: {
				// 			fn: function(i_field) {
				// 				i_self.doKeyEvent("ENTER");
				// 			}
				// 		}
				// 	}
				// });
			}

			if (n_sanHex & IceCap.util.Handler.FFW.MONOCASE) {

				// Ext.apply(o_fieldStyle, {
				// 	"text-transform": "uppercase"
				// });
			}

			if (n_sanHex & IceCap.util.Handler.FFW.MAND_ENTER) {

				Ext.apply(o_field, {
					allowBlank: false
				});
			}

			if (n_sanHex & IceCap.util.Handler.FFW.RA_ZEROFILL ||
				n_sanHex & IceCap.util.Handler.FFW.RA_BLANKFILL ||
				n_sanHex & IceCap.util.Handler.FFW.RA_MANDATORY) {

				Ext.apply(o_fieldStyle, {
					"text-align": "right"
				});
			}

			if (o_config.atr == "27" && n_hex & (1 << 13)) {

				Ext.apply(o_field, {
					hidden: true,
					disabled: true
				});
			}
		}

		Ext.apply(o_field, {
			fieldStyle: o_fieldStyle
		});

		return o_field;
	},

	getState: function() {

		var i_self = this;

		var o_inputData = i_self.getInputData();
		var s_sessionValue = i_self.getSessionValue();

		var o_result = {
			appConfig: {
				inputData: o_inputData,
				sessionValue: s_sessionValue,
				typeMode: i_self.getTypeMode(),
				resizeMode: i_self.getResizeMode(),
				currentPosition: i_self.getCurrentPosition()
			}
		};

		return o_result;
	},

	updateCurrentPosition: function(o_position) {

		var i_self = this;
		var i_statusbar = i_self.getStatusBar();

		if (i_statusbar) {
			var i_position = i_statusbar.getComponent("icecap-position");

			if (i_position) {

				var a_result = [
					o_position.lin,
					o_position.col
				];

				i_position.setText(a_result.join(" / "));
			}
			i_self.updateTypeMode(i_self.getTypeMode())
		}
	},

	updateTypeMode: function (n_type) {

		var i_self = this;

		var i_statusbar = i_self.getStatusBar();

		if (i_statusbar) {

			var i_typeLabel = i_statusbar.getComponent("icecap-typemode");

			var a_mode = [
			];

			if (i_typeLabel) {

				switch (n_type) {
					case IceCap.util.Handler.typeMode.OVERWRITE:
						a_mode.push("DEL");
						break;
					case IceCap.util.Handler.typeMode.FOCUS:
						a_mode.push("WEB");
						break;

					default:
						a_mode.push("INS");
						break;
				}

				i_typeLabel.setHtml(a_mode.join(" "));
			}
		}
	},

	updateResizeMode: function(n_mode) {

		var i_self = this;
		var i_content = i_self.getContent();
		var o_inputData = i_self.getInputData()

		if (n_mode == 2 && o_inputData) {

			i_content.setSize({
				width: IceCap.util.Handler.getWidth(o_inputData.width + 7 || 87),
				height: IceCap.util.Handler.getHeight(o_inputData.height || 24)
			});
		}
	},

	updateEdit: function(value) {

		var i_self = this;

		if (i_self.rendered) {

			IceCap.util.Handler.getData({
				func: "",
				i18nLearning: false,
				session: i_self.getSessionValue(),
				translateMode: value,
				language: i_self.getActiveLanguage(),
			}, {}, function (o_inputData) {

				o_inputData = o_inputData || {};

				i_self.setInputData(o_inputData);

				i_self.redraw();
			});
		}
	},

	updateActiveLanguage: function(value) {

		var i_self = this;

		if (i_self.rendered) {

			IceCap.util.Handler.getData({
				func: "",
				i18nLearning: false,
				session: i_self.getSessionValue(),
				translateMode: value,
				language: value,
			}, {}, function (o_inputData) {

				o_inputData = o_inputData || {};

				i_self.setInputData(o_inputData);

				i_self.redraw();
			});
		}
	},

	focus: function() {

		var i_self = this;
		i_self.findFocus();
	},

	redraw: function() {

		var i_self = this;
		var o_inputData = i_self.getInputData();

		IceCap.util.Handler.setChanged(false);

		if (o_inputData) {
			var i_content = i_self.getContent();

			var o_values = {};
			var i_form = i_content.getForm();
			var i_fieldCollection = i_form.getFields();
			var a_fields = i_fieldCollection.getRange();

			Ext.Array.each(a_fields, function (i_field) {
				o_values[i_field.itemId] = i_field.getValue();
			});

			i_self.doCreateFromData(o_inputData);

			i_content = i_self.getContent();

			i_fieldCollection = i_form.getFields();
			a_fields = i_fieldCollection.getRange();

			Ext.Object.each(o_values, function (s_key, value) {

				var i_field = i_form.getFields().findBy(function (i_search) {
					return i_search.itemId == s_key;
				});

				if (i_field) {
					i_field.setValue(value);
				}
			});

			i_self.findFocus();
		}
	},

	redrawFull: function (o_values) {

		var i_self = this;

		var i_content = i_self.getContent();
		var o_inputData = i_self.getInputData();

		var i_controller = i_self.getController();

		i_self.splitFields();

		var b_fixed = o_inputData.hasOwnProperty("fixed") ? o_inputData.fixed : true;

		IceCap.util.Handler.setFixed(b_fixed);

		var a_fields = [];
		var i_content;

		Ext.suspendLayouts();

		if (i_self.rendered) {
			i_self.unmask();
		}

		if (o_inputData.title) {
			i_self.doTitleUpdate(o_inputData.title);
		}

		i_content = i_self.getContent();

		if (i_self.getResizeMode() == 2) {

			i_content.setSize({
				width: IceCap.util.Handler.getWidth(o_inputData.width + 7 || 87),
				height: IceCap.util.Handler.getHeight(o_inputData.height || 24)
			});
		}

		var i_keyArea = i_self.getKeyArea();

		if (i_content.rendered) {
			i_content.removeAll(true);
		}

		if (i_keyArea.rendered) {
			i_keyArea.removeAll(true);
		}

		i_self.setCursor(null);
		i_self.setMarker(null);
		i_self.setSelector(null);

		var a_created = [];
		a_created = a_created.concat(i_self.createLabels());
		a_created = a_created.concat(i_self.createFields(a_created));
		a_created = a_created.concat(i_self.createMetaFields());

		a_created.push(i_self.createCursor());
		a_created.push(i_self.createMarker());
		a_created.push(i_self.createSelector());

		if (o_inputData.processedFields) {

			var a_toAdd = Ext.Array.slice(a_created);

			var n_inputWidth = o_inputData.width || 80;
			var n_inputHeight = o_inputData.height || 24;

			var i_container = Ext.widget("container", {
				layout: "anchor",
				width: IceCap.util.Handler.getWidth(n_inputWidth),
				height: IceCap.util.Handler.getHeight(n_inputHeight),
				focusable: false,
				tabIndex: -1,
				defaults: {
					margin: "5 0 0 0"
				},
				items: a_toAdd
			});

			a_created = [i_container];
		}

		i_content.add(a_created);

		i_self.updateMessage(o_inputData);

		var a_keys = i_self.createKeys();
		i_keyArea.add(a_keys);

		i_keyArea[a_keys.length === 0 ? "hide" : "show"]();

		if (o_inputData.cmd) {

			i_controller.onPCO(o_inputData);
			i_controller.doKeyEvent("ENTER");
		}

		var i_marker = i_self.getMarker();
		i_marker.setInUse(i_self.getMarkerActive());

		IceCap.util.Handler.setFixed(true);

		Ext.resumeLayouts(true);

		var a_metafields = o_inputData.metaFields || [];

		i_content = i_self.getContent();
		var i_form = i_content.getForm();
		var i_fieldCollection = i_form.getFields();
		var a_fields = i_fieldCollection.getRange();

		Ext.Object.each(o_values, function (s_key, value) {

			var i_field = i_form.getFields().findBy(function (i_search) {
				return i_search.itemId == s_key;
			});

			if (i_field) {
				i_field.setValue(value);
			}
		});
	},

	createEditor: function (o_config, o_data, f_callback, b_split) {

		var i_self = this;
		var o_rules = i_self.getCssRules();

		var s_active = i_self.getActiveLanguage();

		f_callback = f_callback || Ext.emptyFn;

		var o_value = o_data.translation || {};

		var s_original = o_data.text || o_config.dta;
		var s_dta = s_original;

		var a_split = s_original.split("=");

		if (a_split.length > 1 && b_split) {
			s_dta = a_split.pop();
		}

		var i_editor = new Ext.Editor({
			updateEl: false,
			alignment: "l-l",
			hideEl: false,
			ignoreNoChange: true,
			allowBlur: true,
			field: {
				xtype: "icecap-i18n-textfield",
				ui: "icecap-field",
				enforceMaxLength: true,
				languages: i_self.getLanguages(),
				languageActive: s_active ? true : false,
				language: s_active,
				value: o_value,
				global: o_data.general,
				originalText: s_dta
			},
			getValue: function () {

				var i_editor = this;
				var i_field = i_editor.field;
				var value = i_field.getValue();

				return value;
			},
			listeners: {
				beforecomplete: {
					fn: function (i_editor) {

						var i_field = i_editor.field;
						var s_value = i_field.getValue();

						if (Ext.isObject(s_value)) {

							Ext.Object.each(s_value, function (s_key, value) {
								value = value.padEnd(i_field.maxLength);
								s_value[s_key] = value;
							});
						}
						else {
							s_value = s_value.padEnd(i_field.maxLength);
							i_field.setValue(s_value);
						}

						return !Ext.isEmpty(s_value);
					}
				},
				complete: {
					fn: function (i_editor, i_element) {

						var i_editorField = i_editor.field;
						var value = i_editorField.getValue();

						if (i_editorField.isDirty()) {

							var i_menu = i_editorField.getSelections();
							var i_check = i_menu.items.get("check-global");
							var b_check = i_check.checked;

							IceCap.util.Handler.doUpsertTranslation({
								screen_id: i_self.getOriginalTitle(),
								linno: o_config.lin,
								colno: o_config.col,
								maxLen: i_editorField.maxLength,
								tolinno: o_config.lin,
								text: o_config.originalValue,
								txtId: o_config.txtId || 0,
								general: b_check,
								translation: i_editorField.getValue()
							}, f_callback);
						}
					}
				},
				globalchange: {
					fn: function (i_editorField, b_checked) {

						if (i_editorField.isDirty()) {

							var i_menu = i_editorField.getSelections();
							var i_check = i_menu.items.get("check-global");
							var b_check = b_checked;

							IceCap.util.Handler.doUpsertTranslation({
								screen_id: i_self.getOriginalTitle(),
								linno: o_config.lin,
								colno: o_config.col,
								maxLen: i_editorField.maxLength,
								tolinno: o_config.lin,
								text: o_config.originalValue,
								txtId: o_config.txtId || 0,
								general: b_check,
								translation: i_editorField.getValue()
							}, f_callback);
						}
					}
				},
				selectionopen: {
					fn: function (i_editorField) {
						i_editor.allowBlur = false;
					}
				},
				selectionclose: {
					fn: function (i_editorField) {
						i_editor.allowBlur = true;
					}
				},
				canceledit: {
					fn: function (i_editor) {
						var i_field = i_editor.field;
						var i_menu = i_field.getSelections();
						i_menu.hide();
					}
				}
			}
		});


		var n_width = (IceCap.util.Handler.getWidth(o_config.len, o_rules.fontScale) + (IceCap.util.Handler.getWidth(1, o_rules.fontScale) / 2)) + 45;
		var i_editorField = i_editor.field;
		i_editor.setWidth(n_width);
		i_editorField.setWidth(n_width);
		i_editorField.maxLength = o_config.len;
		i_editorField.focus(false, 50);

		return i_editor;
	},

	detach: function() {

		var i_self = this

		i_self.setResizeMode(2);

		var a_windows = i_self.getWindows();

		Ext.Array.each(a_windows, function(i_window) {
			i_window.hide();
		});

		var f_delay = Ext.Function.createDelayed(function() {

			Ext.Array.each(a_windows, function (i_window) {
				i_window.show();
				i_window.center();

				i_self.focus();

			});

		}, 100);

		f_delay.call(i_self);
	}
});
