/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

var Guacamole = Guacamole || {};

/**
 * A hidden input field which attempts to keep itself focused at all times,
 * except when another input field has been intentionally focused, whether
 * programatically or by the user. The actual underlying input field, returned
 * by getElement(), may be used as a reliable source of keyboard-related events,
 * particularly composition and input events which may require a focused input
 * field to be dispatched at all.
 *
 * @constructor
 */
Guacamole.InputSink = function InputSink() {

    /**
     * Reference to this instance of Guacamole.InputSink.
     *
     * @private
     * @type {Guacamole.InputSink}
     */
    var sink = this;

    /**
     * The underlying input field, styled to be invisible.
     *
     * @private
     * @type {Element}
     */
    var field = document.createElement('textarea');
    field.style.position   = 'fixed';
    field.style.outline    = 'none';
    field.style.border     = 'none';
    field.style.margin     = '0';
    field.style.padding    = '0';
    field.style.height     = '0';
    field.style.width      = '0';
    field.style.left       = '0';
    field.style.bottom     = '0';
    field.style.resize     = 'none';
    field.style.background = 'transparent';
    field.style.color      = 'transparent';

    // Keep field clear when modified via normal keypresses
    field.addEventListener("keypress", function clearKeypress(e) {
        field.value = '';
    }, false);

    // Keep field clear when modofied via composition events
    field.addEventListener("compositionend", function clearCompletedComposition(e) {
        if (e.data)
            field.value = '';
    }, false);

    // Keep field clear when modofied via input events
    field.addEventListener("input", function clearCompletedInput(e) {
        if (e.data && !e.isComposing)
            field.value = '';
    }, false);

    // Whenever focus is gained, automatically click to ensure cursor is
    // actually placed within the field (the field may simply be highlighted or
    // outlined otherwise)
    field.addEventListener("focus", function focusReceived() {
        window.setTimeout(function deferRefocus() {
            field.click();
            field.select();
        }, 0);
    }, true);

    /**
     * Attempts to focus the underlying input field. The focus attempt occurs
     * asynchronously, and may silently fail depending on browser restrictions.
     */
    this.focus = function focus() {
        window.setTimeout(function deferRefocus() {
            field.focus(); // Focus must be deferred to work reliably across browsers
        }, 0);
    };

    /**
     * Returns the underlying input field. This input field MUST be manually
     * added to the DOM for the Guacamole.InputSink to have any effect.
     *
     * @returns {Element}
     */
    this.getElement = function getElement() {
        return field;
    };

    // Automatically refocus input sink if part of DOM
    document.addEventListener("keydown", function refocusSink(e) {

        // Do not refocus if focus is on an input field
        var focused = document.activeElement;
        if (focused && focused !== document.body) {

            // Only consider focused input fields which are actually visible
            var rect = focused.getBoundingClientRect();
            if (rect.left + rect.width > 0 && rect.top + rect.height > 0)
                return;

        }

        // Refocus input sink instead of handling click
        sink.focus();

    }, true);

};
