coreFramework.service('Message', function($rootScope, $compile, $timeout) {
    
    var scope;
    
    function init() {
        scope = $rootScope.$new();
        scope.messageList = [];
        scope.lastMessageId = 0;

        scope.icons = {
            'info':        'fa-info-circle',
            'success':     'fa-check-circle',
            'error':       'fa-times-circle',
            'warn':        'fa-exclamation-circle',
            'log':         'fa-arrow-circle-down',
            'debug':       'fa-chevron-circle-right',
            'wait':         ['fa-cog', 'fa-spin']
        };
        scope.getIcon = function (type) {
            return scope.icons[type];
        };

        scope.messageRemove = function(id) {
            scope.messageList.splice(scope.getMessageIndexById(id), 1);
        };
        
        scope.getMessageIndexById = function(id) {
            for (var i = 0; i < scope.messageList.length; i++) {
                if (scope.messageList[i].id == id) {
                    return i;
                }
            }
            return -1;
        };
        
        scope.getMessagesByType = function(type) {
            var list = [];
            for (var i = 0; i < scope.messageList.length; i++) {
                if (scope.messageList[i].type == type) {
                    list.push(scope.messageList[i]);
                }
            }
            return list;
        };
        
        var template =  '<div id="cf-message-center">' +
                            '<div class="cf-message" ng-class="{\'cf-message-{{message.type}}\': message.type}" ng-repeat="message in messageList" data-id="{{message.id}}">' +
                                '<span class="cf-message-wrapper">' +
                                    '<i class="Flash-icon fa" ng-class="getIcon(message.type)"></i>' +
                                    '<span class="cf-message-text" ng-bind-html="message.text"></span>' +
                                    '<a class="cf-message-close" href="#" ng-if="message.hold" ng-click="messageRemove(message.id)">x</a>' +
                                '</span>' +
                            '</div>' +
                        '</div>';
        var element = $compile(template)(scope);
        $('body').append(element);
    }

    this.info = function(message, holdFor) {

        this.send(message, 'info', holdFor);

    };

    this.success = function(message, holdFor) {

        this.send(message, 'success', holdFor);

    };

    this.error = function(message, holdFor) {

        this.send(message, 'error', holdFor);

    };

    this.warn = function(message, holdFor) {

        this.send(message, 'warn', holdFor);

    };

    this.log = function(message, holdFor) {

        this.send(message, 'log', holdFor);

    };

    this.debug = function(message, holdFor) {

        this.send(message, 'debug', holdFor);

    };

    this.waitStart = function(message) {

        this.waitEnd();
        this.send(message, 'wait', 3600);

    };

    this.waitEnd = function() {

        $timeout(function() {
            angular.forEach(scope.getMessagesByType('wait'), function (item) {
                scope.messageRemove(item.id);
            });
        });

    };
    
    this.send = function(message, classType, holdFor) {
        
        if (angular.isUndefined(scope)) {
            init();
        }
        if (angular.isUndefined(classType)) {
            classType = null;
        }
        if (angular.isUndefined(holdFor)) {
            holdFor = 5;
        }
        
        var id = scope.lastMessageId += 1;
        
        $timeout(function() {
            scope.messageList.unshift({
                id: id,
                text: message,
                type: classType,
                hold: holdFor === 0
            });
        });
        
        if (holdFor > 0) {
            $timeout(function() {
                scope.messageRemove(id);
            }, holdFor * 1000);
        }

        return message;
    };
    
});

coreFramework.animation('.cf-message', function() {
    return {
        leave: function(element, done) {
            TweenMax.to(element[0], .1, {height: 0, ease:Power1.easeInOut, onComplete: done});
        },
        enter: function(element, done) {
            TweenMax.fromTo(element[0], .1, {height: 0, top: '-2'}, {height: element.outerHeight(true), top: 0, onComplete: done});
        }
    }
});
