window.cmu = window.cmu || {};

(function (ns) {

    ns.userMessaging = function (spec, my) {
        var that;
        // var container = '#content';
        var container = '#messageCenter';
        var messageClassName = 'userMessage';

        that = gj.logging.handler(spec, my);

        that.flush = function () {
            $(container).empty();
        };

        that.emit = function (record) {
            var arguments = [];
            var levelName = gj.logging.getLevelName(record.level).toLowerCase();
            var msg = ''

            // msg += levelName + ' - ';
            msg += record.name + ': ';
            msg += record.messages[0];

            $(container).prepend(
                $('<div/>').addClass(messageClassName).addClass(levelName).text(msg).slideDown(500)
            );

            $('html, body').animate({scrollTop:0}, 'slow');
        };

        $(container + ' .' + messageClassName).live('click', function () {
            $(this).slideUp(500, function () {
                $(this).remove()
            });
        });

        return that;
    };

    /**
     * Communication Controller.
     *
     * Thin wrapper around jQuery.ajax(), providing:
     * - a standard error handling mechanism.
     */
    ns.communicationController = function (spec, my) {
        var that;

        // ------------------------------------------------------------------
        // Shared properties
        // ------------------------------------------------------------------

        my = my || {};

        my.logger = gj.logging.getLogger('cmu.communicationController');
        my.logger.addHandler(ns.userMessaging({
            level: gj.logging.WARNING
            // level: gj.logging.DEBUG
        }));

        my.lastUrl = null;

        // ------------------------------------------------------------------
        // Shared methods
        // ------------------------------------------------------------------

        that = {};

        // ------------------------------------------------------------------
        // Private methods
        // ------------------------------------------------------------------

        var handleError = function (xhr, textStatus, errorThrown) {
            if (textStatus === 'abort') {
                // my.logger.info('Ignoring error resulting from aborted request');
                return;
            }
            // FIXME (yvdm): this my.lastUrl approach doesn't work well with the asynchronous nature of Ajax loading
            var msg = 'An error occured: ' + xhr.status + ' (' + xhr.statusText + ') while loading "' + my.lastUrl + '".' ;
            my.logger.warning(msg);
        };

        // ------------------------------------------------------------------
        // Public methods
        // ------------------------------------------------------------------

        that.load = function (url, options) {
            options = options || {};
            options.url = cmu.urls[url]; // Reverse URL lookup
            that.ajax(options);
        };

        that.ajax = function (options) {
            options = options || {};
            options.error = options.error || handleError;

            if (!options.url) {
                my.logger.warning('No URL specified');
                return;
            }
            my.logger.debug('Loading "' + options.url + '"');
            my.lastUrl = options.url; // Remember the last URL loaded (used in handleError())
            return $.ajax(options);
        };

        return that;
    };
    ns.communicationController = ns.communicationController(); // Singleton

})(cmu);

