Source: directives/subdetalhamento/subdetalhamento.js

    /**
     * @ngdoc directives
     * @name SubDetalhamento
     * @module s4c.directives.subdetalhamento.SubDetalhamento
     *
     * @description
     * `SubDetalhamento` Controller da funcionalidade de SubDetalhamento
     *
     *@example
     *   <s4c-subdetalhamento>
     *   </s4c-subdetalhamento>
     */
(function () {
    'use strict';

    subDetalhamentoCtrl.$inject = [
        '$scope',
        'DetalhamentoService',
        'ZonaObservacaoService',
        'MapaService',
        '$state',
        'AuthService',
        'ParametrosS4C',
        '$mdDialog',
        'MainState',
        'SubDetalhamentoManager',
        'ZonaDeObservacaoManager',
        'localize'
    ];

    angular.module('s4c.components.detalhamento')
        .directive('s4cSubdetalhamento', s4cSubdetalhamento);


    function s4cSubdetalhamento() {
        return {
            restrict: 'E',
            replace: true,
            scope: {},
            templateUrl: 'app/directives/subdetalhamento/subdetalhamento.html',
            controller: subDetalhamentoCtrl
        };
    }

    function subDetalhamentoCtrl($scope, DetalhamentoService, ZonaObservacaoService, MapaService, $state,
        AuthService, ParametrosS4C, $mdDialog, MainState, SubDetalhamentoManager,
        ZonaDeObservacaoManager, localize) {

            /**
             * @method atualizandoCronologia
             */
        function atualizarCronologia() {
            $scope.atualizandoCronologia = true;

            setTimeout(function () {
                $scope.atualizandoCronologia = false;
            }, 800);
        }

        /**
         * @method salvarIncidenteExcel
         * @param {*} incidente 
         */
        function salvarIncidenteExcel(incidente) {
            window.open('/incidentes/' + incidente.id + '/excel');
        }

        /**
         * @method abrirPopup
         * @param {*} url 
         */
        function abrirPopup(url) {
            window.open(url, '_blank', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=false,resizable=false,width=' + 420 + ',height=' + 300);
        }

        var usuarios = [];
        $scope.comentarioFormData = {};

        /**
         * @method enviarComentario
         * @param {*} valido 
         */
        function enviarComentario(valido) {
            if (valido) {
                DetalhamentoService
                    .enviarComentario($scope.comentarioFormData)
                    .then(function (comentario) {
                        var incidente = $scope.data;
                        var usuario = _.find(usuarios, function (usuario) {
                            return usuario.id === comentario.UsuarioId;
                        });

                        comentario.cor = (usuario && usuario.cor) || getRandomColor();
                        incidente.Comentarios.push(comentario);

                        usuarios.push({
                            id: AuthService.user.info.id,
                            cor: comentario.cor
                        });

                        $scope.comentarioFormData = {
                            IncidenteId: $scope.data.id,
                            corpo: ''
                        };

                        MapaService.updateIconeIncidente($scope.marker, incidente, incidente.Comentarios.length);
                    });
            } else {
                $mdDialog.show(
                    $mdDialog.alert()
                        .title(localize.res('COMUM_ERRO'))
                        .content(localize.res('TEXTO_COMENTARIO_OBRIGATORIO'))
                        .ariaLabel(localize.res('TEXTO_COMENTARIO_OBRIGATORIO'))
                        .ok(localize.res('COMUM_OK'))
                );
            }
        }

        /**
         * @method getRandomColor
         */
        function getRandomColor() {
            var letters = '0123456789ABCDEF'.split('');
            var color = '#';
            for (var i = 0; i < 6; i++) {
                color += letters[Math.floor(Math.random() * 16)];
            }

            return color;
        }

        /**
         * @method voarPara
         * @param {*} obj 
         */
        function voarPara(obj) {
            SubDetalhamentoManager.voarParaObjeto(obj);
        }

        /**
         * @method voarParaSubItem
         * @param {*} obj 
         */
        function voarParaSubItem(obj) {
            SubDetalhamentoManager.voarParaSubItem($scope.data, obj);
        }

        /**
         * @method fechar
         */
        function fechar() {
            SubDetalhamentoManager.fechar();
        }

        /**
         * @method buscarPlanejamento
         * 
         * @param {*} id 
         * @param {*} latlng 
         */
        function buscarPlanejamento(id, latlng) {
            $scope.$parent.SubSubDetalhamentoManager.titulo = 'Planejamento';

            $scope.incidentesProximos = [];
            $scope.basesProximas = [];
            $scope.poisProximos = [];
            $scope.areaAtuacao = {};

            DetalhamentoService
                .pegarPlanejamento(id)
                .then(function (data) {
                    $scope.data = data;
                    SubDetalhamentoManager.data = data;
                });
        }

        /**
         * @method buscarZonaDeObservacao
         * @param {*} id 
         */
        function buscarZonaDeObservacao(id) {

            ZonaObservacaoService
                .pegarZona(id)
                .then(function (data) {
                    $scope.data = data;
                    ZonaDeObservacaoManager.abrirExistente(data);
                });
        }

        /**
         * @method buscarIncidente
         * 
         * @param {*} id 
         * @param {*} latlng 
         * @param {*} marker 
         */
        function buscarIncidente(id, latlng, marker) {
            $scope.incidentesProximos = [];
            $scope.basesProximas = [];
            $scope.poisProximos = [];
            $scope.areaAtuacao = {};
            $scope.tipoItem = 'Incidente';
            $scope.marker = marker;

            DetalhamentoService
                .pegarIncidente(id)
                .then(function (incidente) {
                    $scope.user = AuthService.user.info;
                    incidente.Comentarios = incidente.Comentarios.reverse();

                    usuarios = _.chain(incidente.Comentarios) // O chain encadeia os métodos
                        .map('Usuario') // Pega a propriedade Usuário de cada Comentário
                        .uniq() // Remove os repetidos da lista
                        .value(); // Finaliza o chain

                    // Gera as cores para os usuários e gera uma lista com id e a cor randômica
                    usuarios = _.map(usuarios, function (u) {
                        return {
                            id: u.id,
                            cor: getRandomColor()
                        };
                    });

                    // Gera uma lista de Comentários com cores únicas
                    incidente.Comentarios = _.map(incidente.Comentarios, function (comentario) {

                        var cor = _.find(usuarios, function (usuario) {
                            return usuario.id === comentario.UsuarioId;
                        }).cor;

                        comentario.cor = cor;
                        return comentario;
                    });

                    $scope.data = incidente;
                    $scope.comentarioFormData.IncidenteId = incidente.id;
                    $scope.comentarioFormData.UsuarioId = $scope.user.id;


                    // Titulo da janela é o nome do incidente
                    SubDetalhamentoManager.titulo = incidente.nome;
                    SubDetalhamentoManager.data = incidente;

                    pegarBases(latlng, id);
                    pegarIncidentes(latlng, id);
                    pegarPois(latlng, id);
                    pegarAreaAtuacao(latlng);
                    pegarCameras(latlng);
                });
        }

        /**
         * @method buscarPoi
         * 
         * @param {*} id 
         * @param {*} latlng 
         * @param {*} tipo 
         */
        function buscarPoi(id, latlng, tipo) {

            $scope.titulo = '';
            $scope.incidentesProximos = [];
            $scope.basesProximas = [];
            $scope.poisProximos = [];
            $scope.areaAtuacao = {};
            $scope.tipoItem = 'Poi';

            DetalhamentoService
                .pegarPoi(id)
                .then(function (data) {

                    if (data.status === 'NULL') {
                        data.status = undefined;
                    }

                    DetalhamentoService
                        .pegarAcervo(data.AcervoId)
                        .then(function (data) {
                            SubDetalhamentoManager.titulo = data.nome;
                            //SubDetalhamentoManager.data = data;
                        });

                    $scope.data = data;
                    SubDetalhamentoManager.data = data;

                    pegarBases(latlng, id);
                    pegarIncidentes(latlng, id);
                    pegarPois(latlng, id);
                    pegarAreaAtuacao(latlng, tipo);
                    pegarCameras(latlng);
                });
        }

        /**
         * @method carregarViatura
         * 
         * @param {*} viatura 
         */
        function carregarViatura(viatura) {
            $scope.data = viatura;
        }

        /**
         * @method pegarAreaAtuacao
         * 
         * @param {*} ponto 
         */
        function pegarAreaAtuacao(ponto) {

            DetalhamentoService
                .pegarAreasAtuacao(ponto)
                .then(function (data) {
                    $scope.areaAtuacao['bairro'] = data.DATA[0][0];
                    $scope.areaAtuacao['subprefeitura'] = data.DATA[0][1];
                    $scope.areaAtuacao['RA'] = data.DATA[0][3];
                    $scope.areaAtuacao['AP'] = data.DATA[0][5];
                    $scope.areaAtuacao['inspetoria_gm'] = data.DATA[0][7];
                    $scope.areaAtuacao['agua'] = data.DATA[0][9];
                    $scope.areaAtuacao['esgoto'] = data.DATA[0][11];
                    $scope.areaAtuacao['iluminacao'] = data.DATA[0][15];
                });

            DetalhamentoService
                .findAreaAtuacao(ponto.lat, ponto.lng)
                .then(function (data) {
                    $scope.areaAtuacao['extras'] = data;
                });
        }

        /**
         * @method pegarIncidentes
         * 
         * @param {*} ponto 
         * @param {*} id 
         */
        function pegarIncidentes(ponto, id) {
            DetalhamentoService
                .pegarIncidentesProximos(ponto)
                .then(function (data) {
                    $scope.incidentesProximos = [];
                    _.each(Object.keys(data), function (key) {
                        var coords = JSON.parse(data[key].geojson).coordinates;
                        var leafletCoords = L.latLng(coords[1], coords[0]);

                        var distance = turf.distance(
                            turf.point([ponto.lat, ponto.lng]),
                            turf.point([leafletCoords.lat, leafletCoords.lng]),
                            'miles');

                        angular.extend(data[key], {
                            distancia: (distance * 1609).toFixed(0),
                            tipo: 'incidente'
                        });

                        if (id !== data[key].id) {
                            $scope.incidentesProximos.push(data[key]);
                        }

                        SubDetalhamentoManager.incidentesProximos = _.clone($scope.incidentesProximos);
                    });
                });
        }

        /**
         * @method pegarCameras
         * 
         * @param {*} ponto 
         */
        function pegarCameras(ponto) {
            DetalhamentoService
                .pegarCamerasProximas(ponto)
                .then(function (data) {
                    if (data.length) {
                        $scope.$parent.DetalhamentoManager.abrirMosaicoCameras(ponto, data);
                    }

                    var camerasProximas = _.sortBy(data, function (c) {
                        var coords = JSON.parse(c.geojson);

                        var distancia = turf.distance(
                            turf.point([coords.coordinates[1], coords.coordinates[0]]),
                            turf.point([ponto.lat, ponto.lng]),
                            'miles');

                        c.distancia = distancia;
                        c.tipo = 'camera';

                        return distancia;
                    });

                    var camerasMaisProximas = camerasProximas.slice(0, 3);

                    camerasProximas = _.filter(camerasProximas, function (c) {
                        // Convertendo para kilometros:
                        return c.distancia <= (ParametrosS4C.parametros.detalhamento.raio * 0.000621371);
                    });

                    _.each(camerasMaisProximas, function (camera) {
                        if (!_.find(camerasProximas, { 'id': camera.id })) {
                            camerasProximas.push(camera);
                        }
                    });

                    $scope.camerasProximas = camerasProximas;
                });
        }

        /*
        * Abre cameras do detalhamento no
        * Mosaico de cameras.
        */
       /**
        * @method abrirCamerasMosaico
        * @param {*} cameras 
        */
        function abrirCamerasMosaico(cameras) {
            cameras = cameras.filter(function (camera) {
                return camera.numero > 0;
            });

            if (cameras.length <= 0) {
                return;
            }

            var url = $state.href('mosaico', {
                cameras: JSON.stringify(cameras)
            }, {
                absolute: true
            });

            window.open(url, 'Mosaico', 'menubar=no,location=no,resizable=no,scrollbars=no,status=yes,width=1024,height=600');
        }

        /**
         * @method pegarPois
         * 
         * @param {*} ponto 
         * @param {*} id 
         */
        function pegarPois(ponto, id) {
            DetalhamentoService
                .pegarPoisProximos(ponto)
                .then(function (data) {

                    var poisProximos = [];
                    _.each(Object.keys(data), function (key) {
                        if (id !== data[key].id) {

                            var coords = JSON.parse(data[key].geojson).coordinates;
                            var leafletCoords = L.latLng(coords[1], coords[0]);

                            var distance = turf.distance(
                                turf.point([ponto.lat, ponto.lng]),
                                turf.point([leafletCoords.lat, leafletCoords.lng]),
                                'miles');

                            poisProximos.push({
                                id: data[key].id,
                                nome: data[key].nome,
                                cat: data[key],
                                icone: data[key].urlIcone,
                                geojson: data[key].geojson,
                                distancia: (distance * 1609).toFixed(0),
                                tipo: 'poi'
                            });
                        }
                    });

                    poisProximos = _.sortBy(poisProximos, function (a) {
                        return parseInt(a.distancia, 10);
                    });

                    SubDetalhamentoManager.poisProximos = poisProximos;

                    $scope.poisProximos = poisProximos;

                }, function () {
                });
        }

        /**
         * @method pegarBases
         * 
         * @param {*} ponto 
         * @param {*} id 
         */
        function pegarBases(ponto, id) {
            DetalhamentoService
                .pegarBasesProximas(ponto)
                .then(function (data) {
                    $scope.basesProximas = [];
                    _.each(Object.keys(data), function (key) {
                        if (id !== data[key].id) {
                            data[key].tipo = 'base';
                            $scope.basesProximas.push(data[key]);
                        }
                    });

                    if (false) {
                        SubDetalhamentoManager.drawBasesLines(ponto, $scope.basesProximas);
                    }
                });
        }

        angular.extend($scope, {
            data: {},
            voarPara: voarPara,
            salvarIncidenteExcel: salvarIncidenteExcel,
            voarParaSubItem: voarParaSubItem,
            atualizandoCronologia: false,
            fechar: fechar,
            abrirCamerasMosaico: abrirCamerasMosaico,
            abrirPopup: abrirPopup,
            enviarComentario: enviarComentario,
            atualizarCronologia: atualizarCronologia,
            $apiDetalhamento: {
                buscarPoi: buscarPoi,
                buscarIncidente: buscarIncidente,
                buscarPlanejamento: buscarPlanejamento,
                buscarZonaDeObservacao: buscarZonaDeObservacao,
                carregarViatura: carregarViatura
            }
        });

        MainState.registerDirective('subdetalhamento', $scope.$apiDetalhamento);
        $scope.$on('$destroy', function () {
            MainState.registerDirective('subdetalhamento');
        });
    }
}());