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");
        }
    }

});
