/*global UNIFACE */

/**
 * Busy indicator.
 * Has separate busy indicators for synchronous and asynchronous busy-ness.
 * For the synchronous case the indicator is shown immediately, and turned off
 * as soon as setBusy(false,true) is called.
 * For the asynchronous case the indicator is only shown after a short delay.
 * This takes care that the indicator is only shown for cases that take a
 * relatively long time.
 * For the asynchronous case this busyIndicator also counts the number of
 * open setBusy(true,false) calls.  The indicator is only turned off after all
 * open calls have been closed, by setBusy(false,false) calls.
 */
UNIFACE.busyIndicator = (function() {

    // Private members:
    var _DELAY = 750;
    var _busy = 0;
    var _syncBusyIndicator;
    var _asyncBusyIndicator;

    function _appendElement(node, tag, id, className) {
        var elem = document.createElement(tag);
        if (id) {
            elem.id = id;
        }
        node.appendChild(elem);
        elem.className = className;
        return elem;
    }
    function _setVisibility(node, isVisible) {
        if (isVisible) {
            // Make visible.
            node.style.visibility = "visible";
        } else {
            // Make invisible.
            node.style.visibility = "hidden";
        }
    }
    function _getBusyIndicatorElement(busyIndicatorCSSClass) {
    	var id = "UNIFACE." + busyIndicatorCSSClass;
        var elem = document.getElementById(id);
        if (elem == undefined) { // pragma(allow-loose-compare)
            // The element does not exist yet; create one here.
            elem = _appendElement(document.body, "div", id, busyIndicatorCSSClass);
        }
        return elem;
    }
    function _getSyncBusyIndicator() {
        if (_syncBusyIndicator == undefined) { // pragma(allow-loose-compare)
            _syncBusyIndicator = _getBusyIndicatorElement("ubusysync");
        }
        return _syncBusyIndicator;
    }
    function _getAsyncBusyIndicator() {
        if (_asyncBusyIndicator == undefined) { // pragma(allow-loose-compare)
            _asyncBusyIndicator = _getBusyIndicatorElement("ubusyasync");
        }
        return _asyncBusyIndicator;
    }
    function _showSync(aBusy) {
    	_setVisibility(_getSyncBusyIndicator(), aBusy);
    }
    function _showAsync() {
        _setVisibility(_getAsyncBusyIndicator(), _busy  > 0);
    }

    // Public:
    return {
        setBusySync : function(isBusy) {
            // Immediately show the indicator.
            _showSync(isBusy);
        },
        setBusyAsync : function(isBusy) {
            if (isBusy) {
                if (++_busy == 1) {
                    // Wait a little while before showing.
                    window.setTimeout(_showAsync, _DELAY);
                }
            } else {
                // Decrease async-busy counter.
                // If counted down to zero then immediately show.
                if (--_busy <= 0) {
                    _showAsync();
                    _busy = 0; // Reset to zero, just in case it was even less...
                }
            }
        }
    };
})();

UNIFACE.extension.register("busyIndicator", UNIFACE.busyIndicator);

