var InlineHint = (function() {
    var onFocus, onBlur;

    function addEvents(input) {
        /* Неприятный хак для компенсации странного поведения addEvent.
         * На самом деле должно быть так:
         * input.addEvent("focus", onFocus);
         * input.addEvent("blur", onBlur);
         */
        input.addEvent("focus", function(event) {onFocus.call(this, event);});
        input.addEvent("blur", function(event) {onBlur.call(this, event);});
    }

    /**
     * Изменяет тип элемента <input /> — создаёт новый input с новым типом, заменяет ним старый и возвращает новый
     * @param HTMLInputElement oldObject старый input
     * @param String oType новый тип
     * @return HTMLInputElement новый input
     */
    function changeInputType(oldObject, oType) {
        if (Browser.Engine.gecko || Browser.Engine.webkit ) {
            oldObject.type = oType;
            return oldObject;
        }
        var newObject = $(document.createElement('input'));
        newObject.defaultType   = oldObject.defaultType;
        newObject.type          = oType;
        newObject.defaultValue  = oldObject.defaultValue;
        newObject.value         = oldObject.value;
        newObject.getValue      = getValue;
        newObject.size          = oldObject.size;
        newObject.name          = oldObject.name;
        newObject.id            = oldObject.id;
        newObject.className     = oldObject.className;
        if (oldObject.maxLength > 0) {
            newObject.maxLength = oldObject.maxLength;
        }
        newObject.tabIndex      = oldObject.tabIndex;
        newObject.replaces(oldObject);
        addEvents(newObject);
        return newObject;
    }

    /**
     * Обработчик события onfocus для input’ов
     * this — HTMLInputElement
     */
    onFocus = function(event) {
        if (this.value == this.defaultValue) {
            $(this).removeClass("hint");
            this.value = "";
            if (this.defaultType && this.type != this.defaultType) {
                event.stop();
                var new_input = changeInputType(this, this.defaultType);
                new_input.focus();
                new_input.focus(); // не удаляйте повторную строку. Без неё не работает в IE6…
            }
        }
    }

    /**
     * Обработчик события onblur для input’ов
     * this — HTMLInputElement
     */
    onBlur = function(event) {
        if ("" == this.value) {
            $(this).addClass("hint");
            this.value = this.defaultValue;
            if ("text" != this.type) {
                changeInputType(this, "text");
            }
        }
    }

    /**
     * Получает значение, введённое пользователем в input
     * this — HTMLInputElement
     */
    function getValue() {
        return (this.value == this.defaultValue) ? "" : this.value;
    }

    return {
        /**
         * Присоединяет к полю hint
         * @param HTMLInputElement input <input type='text' /> или <input type='password' />
         * @param String hint текст подсказки
         */
        appendTo: function(input, hint) {
            var current_value = input.value;
            input.defaultValue = hint;
            input.defaultType = input.type;
            input.getValue = getValue;
            addEvents(input);
            if (current_value) {
                input.value = current_value;
            } else {
                input.value = "";
                onBlur.call(input);
            }
        }
    };
})();