Source: directives/timeline/timeline.js

/**
 * @ngdoc directives
 * @name Timeline
 * @module s4c.directives.timeline.Timeline
 *
 * @description
 * `Timeline` Controller do módulo de Timeline
 * 
 * 
 */
(function () {
    'use strict';

    //angular.module('s4c.components.timeline', ['s4c_components_incidentes',])
    angular.module('s4c.components.timeline', ['s4c.components.incidentes',])
        .directive('s4cTimeline', s4cTimeline);

    s4cTimeline.$inject = ['IncidentesService', '$timeout', '$rootScope', '$q', 'IncidenteFilter',
        'LegendaIncidenteFilter', 'CommService', 'localize'];

    function s4cTimeline(IncidentesService, $timeout, $rootScope, $q, IncidenteFilter, LegendaIncidenteFilter,
        CommService, localize, MapaManager) {
        return {
            templateUrl: 'app/directives/timeline/timeline.html',
            restrict: 'EA',
            scope: {
                edicao: '=edicao',
                agencias: '=agencias',
                agencia: '=agencia'
            },
            transclude: true,
            link: function ($scope, $elem) {

                $scope.res = $rootScope.res;

                CommService.on('incidentes_', function (incidente) {
                    $scope.$apply(function () {
                        $scope.incidentes.push(incidente);
                    });
                });

                IncidenteFilter.getInstance('filtro-timeline').on('filterChanged', _reloadIncidentes);
                LegendaIncidenteFilter.getInstance('legenda-incidente-timeline').on('filterChanged', _reloadIncidentes);

                _reloadIncidentes();

                var resizeTimerID = null,
                    timeline,
                    eventSource;

                $scope.$watch('edicao', function (newVal) {
                    // Não está no modo de edição, redimensionar:
                    if (!newVal) {
                        resize().then(centerTimeline);
                    }
                });

                $rootScope.$on('s4c:windowResize', function (e, data) {
                    $timeout(function () {
                        resize().then(centerTimeline);
                    }, 1200);
                });

                /**
                 * @method adicionarZoom
                 */
                function adicionarZoom() {
                    if (timeline._bandInfos[0].ether._pixelsPerInterval - 40 <= 0) {
                        timeline._bandInfos[0].ether._pixelsPerInterval = 0;
                        return;
                    }
                    timeline._bandInfos[0].ether._pixelsPerInterval -= 40;
                    timeline._bandInfos[0]._interval -= 400;
                    timeline.layout();
                }

                /**
                 * @method removerZoom
                 */
                function removerZoom() {
                    if (timeline._bandInfos[0].ether._pixelsPerInterval + 40 >= 400) {
                        timeline._bandInfos[0].ether._pixelsPerInterval = 400;
                        return;
                    }
                    timeline._bandInfos[0].ether._pixelsPerInterval += 40;
                    timeline._bandInfos[0]._interval += 400;
                    timeline.layout();
                }

                $scope.adicionarZoom = adicionarZoom;
                $scope.removerZoom = removerZoom;

                /**
                 * @method _validEventDates
                 * @param {*} startDate 
                 * @param {*} endDate 
                 */
                function _validEventDates(startDate, endDate) {
                    if (endDate && (startDate !== endDate)) {
                        if ((moment().range(startDate, endDate).diff() > 0)) {
                            return true;
                        };
                    };

                    return false;
                }

                /**
                 * @method resize
                 */
                function resize() {
                    var deferred = $q.defer();
                    if (resizeTimerID == null) {
                        resizeTimerID = window.setTimeout(function () {
                            resizeTimerID = null;
                            timeline.layout();
                            deferred.resolve();
                        }, 500);
                    }

                    return deferred.promise;
                }

                /**
                 * @method voarParaIncidente
                 * @param {*} incidenteId
                 */
                window.voarParaIncidente = function (incidenteId) {
                    var incidente = _.find($scope.incidentes, function (incidenteDaLista) {
                        return incidenteDaLista.id === incidenteId;
                    });
                    MapaManager.voarParaObjeto(incidente);
                };

                /**
                 * @method _formatData
                 * @param {*} incidentes 
                 */
                function _formatData(incidentes) {
                    var json = {};
                    json.events = _.map(incidentes, function (incidente) {

                        var imagemIncidente = $('<img style="width: 48px;"/>');

                        $(imagemIncidente).attr('src', incidente.urlIcone);

                        var wrapper = $('<div class="bubble-content-wrapper">');
                        var gotoIncidente = $('<a>', {
                            'class': 'anchor-gotoIncidente'
                        })
                            .attr('href', 'javascript:voarParaIncidente(' + incidente.id + ')');

                        moment.locale('pt-br', {
                            weekdaysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"]
                        });

                        var msgInicio = localize.getLocalizedString('COMUM_INICIO');
                        var msgFim = localize.getLocalizedString('COMUM_FIM');

                        var descricao = $('<div>')
                            .append($('<p class="bubble-description-content">').html(incidente.descricao))
                            .append($('<br>'))
                            .append($('<strong>').html('Status: '))
                            .append(incidente.status)
                            .append($('<br>'))
                            .append($('<strong>', { text: + msgInicio + ': ' }))
                            .append(moment(incidente.inicio).format('ddd, DD/MM/YYYY - hh:mm'))
                            .append($('<br>'))
                            .append($('<strong>', { text: + msgFim + ': ' }));

                        if (incidente.fim) {
                            descricao
                                .append(moment(incidente.fim).format('ddd, DD/MM/YYYY - hh:mm'));
                        }

                        wrapper.append(descricao);

                        var img = $('<img>', {
                            'class': 'event-icon'
                        })
                            .attr('src', incidente.urlIcone);
                        var wrapperGeral = $('<div>', {
                            'class': 'wrapper-geral'
                        });

                        wrapperGeral
                            .append(img)
                            .append(wrapper);

                        wrapperGeral = $(gotoIncidente).append(wrapperGeral);

                        moment.locale('en');

                        var timelineEvent = {
                            'start': moment(incidente.inicio).format('MMM DD YYYY HH:mm:ss'),
                            'title': incidente.nome,
                            'durationEvent': true,
                            'description': wrapperGeral[0].outerHTML
                        };

                        if (_validEventDates(incidente.inicio, incidente.fim)) {
                            timelineEvent.end = moment(incidente.fim).format('MMM DD YYYY HH:mm:ss');
                        }

                        if (incidente.status === "FECHADO") {

                            timelineEvent.icon = '/assets/icons/green_ball.png';
                            timelineEvent.color = "#8AC249"; // verde
                            timelineEvent.classname = "closed-event";

                        } else {
                            timelineEvent.icon = '/assets/icons/red_ball.png';
                            timelineEvent.color = "#F34235"; //vermelho
                            timelineEvent.classname = "opened-event";
                        };

                        // Se o status do incidente está fechado e não tem data de fim deve mostrar como uma bolinha
                        if (incidente.status === "FECHADO" && !incidente.fim) {
                            timelineEvent.end = null;
                        }

                        if (incidente.status === "ABERTO" && !incidente.fim) {
                            timelineEvent.end = moment().format('MMM DD YYYY HH:mm:ss');
                        }

                        return timelineEvent;
                    });

                    return json;
                }

                /**
                 * @method voarParaIncidente
                 * @param {*} incidenteId
                 */                
                window.voarParaIncidente = function (incidenteId) {
                    var incidente = _.find($scope.incidentes, { 'id': incidenteId });
                    MapaManager.voarParaObjeto(incidente);
                }

                /**
                 * @method centerTimeline
                 */
                function centerTimeline() {
                    timeline.getBand(0).setCenterVisibleDate(new Date());
                }

                /**
                 * @method _reloadIncidentes
                 */
                function _reloadIncidentes() {
                    IncidentesService.findByFilter()
                        .then(function (incidentes) {

                            incidentes = incidentes;

                            $scope.incidentes = incidentes;
                            var events_json = _formatData(incidentes);
                            eventSource = new Timeline.DefaultEventSource(0);
                            var theme = Timeline.ClassicTheme.create();

                            theme.event.highlightLabelBackground = true;
                            theme.event.bubble.width = 320;

                            var zones = [{
                                start: moment().startOf('year').format('MMM DD YYYY HH:mm:ss'),
                                end: moment().startOf('year').format('MMM DD YYYY HH:mm:ss'),
                                magnify: 5,
                                unit: Timeline.DateTime.DAY
                            }];

                            var d = Timeline.DateTime.parseGregorianDateTime(moment().format('MMM DD YYYY'));
                            var bandInfos = [
                                Timeline.createHotZoneBandInfo({
                                    width: '90%',
                                    intervalUnit: Timeline.DateTime.HOUR,
                                    intervalPixels: 80,
                                    zones: zones,
                                    eventSource: eventSource,
                                    date: d,
                                    timeZone: -3,
                                    trackGap: 0.2,
                                    theme: theme,
                                    layout: 'original'
                                }),
                                Timeline.createHotZoneBandInfo({
                                    width: '10%',
                                    intervalUnit: Timeline.DateTime.DAY,
                                    intervalPixels: 150,
                                    zones: zones,
                                    eventSource: eventSource,
                                    date: d,
                                    timeZone: -3,
                                    overview: true,
                                    theme: theme
                                })
                            ];

                            bandInfos[0].decorators = [
                                new Timeline.SpanHighlightDecorator({
                                    startDate: moment().format('MMM DD YYYY HH:mm:ss'),
                                    endDate: moment()
                                        .add(5, 'minutes')
                                        .format('MMM DD YYYY HH:mm:ss'),
                                    color: "Yellow",
                                    opacity: 20,
                                    startLabel: localize.getLocalizedString('COMUM_AGORA'),
                                    cssClass: 't-estado'
                                })
                            ];

                            bandInfos[1].syncWith = 0;
                            bandInfos[1].highlight = true;

                            timeline = Timeline.create($elem.find('#timeline')[0],
                                bandInfos, Timeline.HORIZONTAL);

                            eventSource.loadJSON(events_json, '');

                            timeline.finishedEventLoading();
                            centerTimeline();
                        });
                }
            },
        };
    }

}());