Source: directives/detalhamento/detalhamento.js

/**
 * @ngdoc directives
 * @name Detalhamento
 * @module s4c.directives.detalhamento.Detalhamento
 *
 * @description `detalhamentoCtrl` Controller do módulo de detalhamento
 *              
 *
 * @example <s4c-detalhamento> </s4c-detalhamento>
 *
 */
(function () {
    'use strict';

    detalhamentoCtrl.$inject = [
        '$scope',
        '$q',
        'DetalhamentoService',
        'VideoChamadaService',
        'ZonaObservacaoService',
        '$state',
        'AuthService',
        'ParametrosS4C',
        '$mdDialog',
        'CommService',
        'MainState',
        'IncidentesService',
        'MapaService',
        'BotoesManager',
        'DetalhamentoManager',
        'ZonaDeObservacaoManager',
        'IncidentesManager',
        'FileUploader',
        'RotasUnificadasManager',
        'RotasUnificadasService',
        '$http',
        'BuscaUsuariosTelegramManager',
        'TelegramService',
        'PermissoesService',
        'LegendaIncidenteFilter',
        'CamadasService',
        'toasty',
        'BlackList',
        'Validate',
        'localize',
        'AreaAtuacaoManager',
        'Base',
        'MensageriaChatUsuario',
        'RepresentacaoService',
        'VoipManager',
        'MsiFilter',
        '$timeout',
        'VideoStreamService'
    ];

    function detalhamentoCtrl($scope,
        $q,
        DetalhamentoService,
        VideoChamadaService,
        ZonaObservacaoService,
        $state,
        AuthService,
        ParametrosS4C,
        $mdDialog,
        CommService,
        MainState,
        IncidentesService,
        MapaService,
        BotoesManager,
        DetalhamentoManager,
        ZonaDeObservacaoManager,
        IncidentesManager,
        FileUploader,
        RotasUnificadasManager,
        RotasUnificadasService,
        $http,
        BuscaUsuariosTelegramManager,
        TelegramService,
        PermissoesService,
        LegendaIncidenteFilter,
        CamadasService,
        toasty,
        BlackList,
        Validate,
        localize,
        AreaAtuacaoManager,
        Base,
        MensageriaChatUsuario,
        RepresentacaoService,
        VoipManager,
        MsiFilter, $timeout, VideoStreamService) {

        DetalhamentoService.on('openOptionShare', function () {
            $scope.openShare = !$scope.openShare;
            //MensageriaChatUsuario.trigger('obterInformacoes');
        });

        var usuarios = [];

        $scope.hasError = Validate.hasError;
        $scope.formDeleteIncidenteSubmitted;
        $scope.justDel = {
            isOpen: false,
            isDeleting: false,
            motivo: ""
        };

	   /**
	    * Envia um comando de restart para o Multivis 
	    *
	    * @method restart
		*        
	    * @param poi {obj} Poi com as informações do Multivis 
		*               
	    */
        $scope.restart = function (poi) {
            if ($scope.isMultivisManager(poi)) {
                for (var index in poi.extras.informacoes) {
                    if (poi.extras.informacoes[index].label == 'Status' && poi.extras.informacoes[index].valor == 'Online') {
                        var confirm = $mdDialog.confirm()
                            .title(localize.res('COMUM_AVISO'))
                            .content(localize.res('MULTIVIS_RESTART'))
                            .ariaLabel(localize.res('MULTIVIS_RESTART'))
                            .ok(localize.res('COMUM_SIM'))
                            .cancel(localize.res('COMUM_CANCELAR'));

                        $mdDialog
                            .show(confirm)
                            .then(function () {
                                Base.obterDoManager('multivis/restart/' + poi.chave_estrangeira).then(function (rep) {
                                    multivisOffLine = false;
                                    $mdDialog.show(
                                        $mdDialog.alert()
                                            .title(localize.res('COMUM_SUCESSO'))
                                            .content(localize.res('COMANDO_ENVIADO'))
                                            .ariaLabel(localize.res('COMANDO_ENVIADO'))
                                            .ok(localize.res('COMUM_OK'))
                                    );
                                });
                            });

                    } else if (poi.extras.informacoes[index].label == 'Status' && poi.extras.informacoes[index].valor == 'Offline') {
                        $mdDialog.show(
                            $mdDialog.alert()
                                .title(localize.res('COMUM_ERRO'))
                                .content(localize.res('COMANDO_NAO_ENVIADO'))
                                .ariaLabel(localize.res('COMANDO_NAO_ENVIADO'))
                                .ok(localize.res('COMUM_OK'))
                        );
                    }

                }
            }

        };

	   /**
	    * Verifica atualizações para os aplicativos do multivis (Apenas POC) 
	    *
	    * @method CheckUpdate
		*        
		*               
	    */
        $scope.CheckUpdate = function () {
            document.getElementById("check").innerHTML = "<i class='far fa-calendar'></i> Schedule Update";
            document.getElementById("check").className = "schedule-link";
            document.getElementById("check").setAttribute("onClick", "schedule();");


            var ok = document.getElementsByName("ok");
            var i;
            for (i = 0; i < ok.length; i++) {
                ok[i].innerHTML = "<i class='fas fa-check-circle'></i> System up to date";
                ok[i].className = "result-ok"
            }
            var nok = document.getElementsByName("nok");
            var i;
            for (i = 0; i < nok.length; i++) {
                nok[i].innerHTML = "<i class='fas fa-exclamation-triangle'></i> Pending update";
                nok[i].className = "result-nok"

            }
        }

	   /**
	    * faz o agendamento de atualizações para os aplicativos do multivis (Apenas POC) 
	    *
	    * @method schedule
		*        
		*               
	    */
        $scope.schedule = function () {
            document.getElementById("check").innerHTML = "<i class='far fa-calendar'></i> Scheduled";
            document.getElementById("check").className = "scheduled";

            var nok = document.getElementsByName("nok");
            var i;
            for (i = 0; i < nok.length; i++) {
                nok[i].innerHTML = "<i class='fas fa-calendar-check'></i> scheduled";
                nok[i].className = "schedule"

            }
        }


        //CORRIGIR AS URLS
       /**
	    * Monta uma url de acesso ao multivis no detalhamento 
	    *
	    * @method acessarMultivis
		*        
	    * @param data {obj} Poi com as informações do Multivis 
		*               
	    */
        $scope.acessarMultivis = function (data) {
            if (data.urlMultivis && $scope.isMultivisManager(data)) {
                window.open("https://" + data.urlMultivis + ":9090/index.html", "Multivis", "height=600,width=800");
            }
        }

        //CORRIGIR AS URLS
       /**
	    * Monta uma url de acesso ao multivis (porta 10000 administração) no detalhamento 
	    *
	    * @method acessarMultivis10000
		*        
	    * @param data {obj} Poi com as informações do Multivis 
		*               
	    */        
        $scope.acessarMultivis10000 = function (data) {
            if (data.urlMultivis && $scope.isMultivisManager(data)) {
                Base.obterDoManager('multivis/find/' + data.chave_estrangeira).then(function (response) {
                    window.open("http://" + data.urlMultivis + ":10000/?token=" + response.token, "Multivis", "height=600,width=800");
                });
            }
        }

        //CORRIGIR AS URLS
       /**
	    * Monta uma url de acesso ao multivis meeting(porta 8080) no detalhamento 
	    *
	    * @method acessarMultivis10000
		*        
	    * @param data {obj} Poi com as informações do Multivis 
		*               
	    */          
        $scope.acessarMultivisMeeting = function (data) {
            if (data.urlMultivis && $scope.isMultivisManager(data)) {
                window.open("http://" + data.urlMultivis + ":8080/config?password=meeting", "Multivis", "height=600,width=800");
            }
        }

       /**
	    * Monta uma url de acesso ao multivis na página de performance (porta 9292) no detalhamento 
	    *
	    * @method acessarPerformanceMultivis
		*        
	    * @param data {obj} Poi com as informações do Multivis 
		*               
	    */  
        $scope.acessarPerformanceMultivis = function (data) {
            if (data.urlMultivis && $scope.isMultivisManager(data)) {
                window.open("http://" + data.urlMultivis + ":9292/admin/performance.html", "Multivis", "height=600,width=800");
            }
        }

       /**
	    * Verifica atualizações para os aplicativos do multivis (Apenas POC)  
	    *
	    * @method checkUpdates
		*        
	    * @param data {obj} Poi com as informações do Multivis 
		*               
	    */  
        $scope.checkUpdates = function (data) {
            if (data.urlMultivis && $scope.isMultivisManager(data)) {
                $mdDialog.show(
                    $mdDialog.alert()
                        .title(localize.res('COMUM_SUCESSO'))
                        .content(localize.res('VERIFICAR_UPDATES'))
                        .ariaLabel(localize.res('VERIFICAR_UPDATES'))
                        .ok(localize.res('COMUM_OK'))
                );
            }
        }

       /**
	    * Agenda atualizações para os aplicativos do multivis (Apenas POC)  
	    *
	    * @method scheduleUpdates
		*        
	    * @param data {obj} Poi com as informações do Multivis 
		*               
	    */  
        $scope.scheduleUpdates = function (data) {
            if (data.urlMultivis && $scope.isMultivisManager(data)) {
                $mdDialog.show(
                    $mdDialog.alert()
                        .title(localize.res('COMUM_SUCESSO'))
                        .content(localize.res('AGENDAMENTO_EFETUADO'))
                        .ariaLabel(localize.res('AGENDAMENTO_EFETUADO'))
                        .ok(localize.res('COMUM_OK'))
                );
            }
        }

       /**
	    * Faz o download dos logs do multivis
	    *
	    * @method downloadLog
		*        
	    * @param data {obj} Poi com as informações do Multivis 
		*               
	    */  
        $scope.downloadLog = function (data) {
            if (data.urlMultivis && $scope.isMultivisManager(data) && data.chave_estrangeira != null) {
                Base.obterDoManager('multivis/getLog/' + data.chave_estrangeira).then(function (response) {

                    var a = document.createElement("a");
                    document.body.appendChild(a);
                    a.style = "display: none";

                    var file = new Blob([response], { type: 'application/octet-stream' });
                    var fileURL = URL.createObjectURL(file);

                    a.href = fileURL;
                    a.download = 'multivisLog.txt';
                    a.click();
                });
            }
        }

        $scope.my_id = AuthService.user.info.id;

        BlackList.obter()
            .then(function (blacklist) {
                $scope.blackList = blacklist;
            })

       /**
	    * Verifica se a funcionalidade está na blacklist 
	    *
	    * @method isToShow
		*        
	    * @param label {String} nome da funcionalidade 
		*               
	    */ 
        $scope.isToShow = function (label) {
            return MainState.isToShow(label);
        }

       /**
	    * Verifica as permissões para visualizar o conteúdo
	    *
	    * @method hasPermission
		*        
	    * @param informacao {Object} Extras do Poi 
		*               
	    */ 
        $scope.hasPermission = function (informacao) {
            if (informacao.VISIBILIDADE != null) {
                if (typeof informacao.VISIBILIDADE === "boolean") {
                    return informacao.VISIBILIDADE;
                } else if (typeof informacao.VISIBILIDADE === "object") {
                    for (var index in AuthService.user.info.Perfils) {
                        for (var index_y in informacao.VISIBILIDADE) {
                            if (AuthService.user.info.Perfils[index].id == informacao.VISIBILIDADE[index_y]) {
                                return true;
                            }
                        }
                    }
                    return false;
                }
            }
            return true;
        }

       /**
	    * Verifica se o POI é do tipo Multivis 
	    *
	    * @method isMultivisManager
		*        
	    * @param data {Object} Poi
		*               
	    */ 
        $scope.isMultivisManager = function (data) {
            var isMultivisManager_ = false;
            if ($scope.data.extras && $scope.data.extras.informacoes) {
                for (var index in $scope.data.extras.informacoes) {
                    if ($scope.data.extras.informacoes[index].tipo == 'MULTIVIS_MANAGER') {
                        return true;
                    }
                }
            }

        }


        PermissoesService.getPermissoes().then(function (perms) {
            $scope.permissoesVisualizacao = perms.permissoesVisualizacao;
            $scope.permissoesCriacao = perms.permissoesCriacao;
            $scope.permissoesEdicao = perms.permissoesEdicao;
            $scope.permissoesRemocao = perms.permissoesRemocao;
            $scope.permissoesExtras = perms.permissoesExtras;
        });

        IncidentesService.getIncidenteGravidades()
            .then(function (gravidades) {
                $scope.incidenteGravidades = gravidades;
            });

        var uploader = $scope.uploader = new FileUploader(),
            uploadCallbackQueue = [];

        $scope.comentarioFormData = {};
        $scope.buscaUsuariosTelegram = BuscaUsuariosTelegramManager;

       /**
	    * Listener do atributo selecaoConcluida do formulário buscaUsuariosTelegram
	    *
	    * @method watch
		*        
	    * @param newVal {Object} Novo valor
	    * @param oldVal {Object} Valor antigo
		*               
	    */ 
        $scope.$watch('buscaUsuariosTelegram.selecaoConcluida', function (newVal, oldVal) {
            if (newVal == true && oldVal == false) {
                var geometry;

                if (typeof $scope.data.geojson == 'string') {
                    geometry = JSON.parse($scope.data.geojson)
                } else {
                    geometry = $scope.data.geojson;
                }

                var template = '';
                var gravidade = ($scope.data.GravidadeIncidente || {}).nome;
                var responsavel = ($scope.data.Responsavel || {}).nome;
                var dataHora = moment($scope.data.inicio).format('DD/MM/YYYY HH:mm');
                var localizacao = _.template('http://maps.google.com/maps?q=${latitude},${longitude}')({
                    latitude: geometry.coordinates[1],
                    longitude: geometry.coordinates[0]
                });
                var users = BuscaUsuariosTelegramManager.usuariosSelecionados;
                var groups = BuscaUsuariosTelegramManager.gruposSelecionados;

                var cronologia = _.map($scope.data.extras.observacoes, function (cronologia) {
                    var texto = cronologia.split('||')[0];
                    var data = cronologia.split('||')[1];

                    return data + '\\n' + texto + '\\n';
                }).join('\\n');


                template += '<ID: ${incidente.id}>\\n'
                template += localize.res('COMUM_TIPO') + ': ${incidente.TipoIncidente.nome}\\n';
                template += localize.res('COMUM_TITULO') + ': ${incidente.nome}\\n';
                template += localize.res('INCIDENTE_RESPONSAVEL') + ': ${responsavel}\\n';
                template += localize.res('INCIDENTE_GRAVIDADE') + ': ${gravidade}\\n';
                template += localize.res('COMUM_DESCRICAO') + ': ${incidente.descricao}\\n';
                template += localize.res('COMUM_LOCALIZACAO') + ': ${localizacao}\\n';
                template += localize.res('DETALHAMENTO_DATAHORA') + ': ${dataHora}\\n';
                template += '\\n' + localize.res('DETALHAMENTO_CRONOLOGIAFATOS') + ':\\n${cronologia}\\n\\n';
                template += localize.res('COMUM_MENSAGEM') + ': ${messageOptional}\\n';

                if (users.length) {
                    TelegramService.sendMessageBulk({
                        message: _.template(template)({
                            incidente: $scope.data,
                            gravidade: gravidade,
                            responsavel: responsavel,
                            localizacao: localizacao,
                            dataHora: dataHora,
                            cronologia: cronologia,
                            messageOptional: BuscaUsuariosTelegramManager.messageOptional
                        }),
                        users: users,
                        notAvisoOperacional: true
                    });
                }

                if (groups.length) {
                    TelegramService.sendGroupMessageBulk({
                        message: _.template(template)({
                            incidente: $scope.data,
                            gravidade: gravidade,
                            responsavel: responsavel,
                            localizacao: localizacao,
                            dataHora: dataHora,
                            cronologia: cronologia,
                            messageOptional: BuscaUsuariosTelegramManager.messageOptional
                        }),
                        groups: groups,
                        notAvisoOperacional: true
                    });
                }
            }
        });

        $scope.$botoes = BotoesManager;

        if (MainState.isToShow('mensageria_externa')) {
            $scope.botoesItems = [{
                title: 'Twitter',
                icon: '/assets/images/Incidentes/ic_social_twitter_color_24px.svg',
                action: function () {
                    $scope.data.tipoObjeto = 'incidente';

                    var geojson = JSON.parse($scope.data.geojson);
                    var lat = geojson.coordinates[1];
                    var long = geojson.coordinates[0];

                    var info = { latitude: lat, longitude: long };

                    $scope.$botoes.abrirTwitter(info);
                }
            }, {
                title: localize.res('MAIN_MENU_MENSAGERIA'),
                icon: '/assets/images/Incidentes/ic_social_telegram_color_24px.svg',
                action: function () {
                    $scope.data.tipoObjeto = 'incidente';
                    $scope.$botoes.abrirMensageria(true, $scope.data);
                }
            }, {
                title: localize.res('TELEGRAM_MENSAGEMNAOLIDA'),
                icon: '/assets/images/Incidentes/ic_social_telegram_color_24px2.svg',
                action: function () {
                    var gruposIncidente = $scope.data.GruposUsuarios.concat($scope.data.Responsavel.GrupoUsuarios)
                    BuscaUsuariosTelegramManager.abrir(function (usuario) {
                        return _.intersectionBy(usuario.GrupoUsuarios, gruposIncidente, 'id').length;
                    });

                }
            }];
        } else {
            $scope.botoesItems = [{
                title: localize.res('MAIN_MENU_TWITTER'),
                icon: '/assets/images/Incidentes/ic_social_twitter_color_24px.svg',
                action: function () {
                    $scope.data.tipoObjeto = 'incidente';

                    var geojson = JSON.parse($scope.data.geojson);
                    var lat = geojson.coordinates[1];
                    var long = geojson.coordinates[0];

                    var info = { latitude: lat, longitude: long };

                    $scope.$botoes.abrirTwitter(info);
                }
            }, {
                title: localize.res('MAIN_MENU_MENSAGERIA'),
                icon: '/assets/images/Incidentes/ic_social_telegram_color_24px.svg',
                action: function () {
                    $scope.data.tipoObjeto = 'incidente';
                    $scope.$botoes.abrirMensageria(true, $scope.data);
                }
            }];
        }

        $scope.openShare = false;

        $scope.enviadosComSucesso = [];
        $scope.enviadosComFalha = [];

        $scope.uploader.onCompleteItem = function (item, response) {

            if (response.status == 403) {
                toasty({
                    msg: response.message
                });
                return;
            }

            if (item.uploader.queue.length > 0) {
                if (item.isSuccess) {
                    $scope.enviadosComSucesso.push(item);
                }
                else {
                    $scope.enviadosComFalha.push(item);
                }
            }
            else {
                if (item.isSuccess) {
                    $scope.enviadosComSucesso.push(item);
                }
                else {
                    $scope.enviadosComFalha.push(item);
                }

                $scope.data = response;
            }

        };

       /**
	    * Função chamada após os arquivos serem adicionados na fila de envio
	    *
	    * @method onAfterAddingFile
		*        
	    * @param item {Object} Arquivo
	    *
		*               
	    */ 
        $scope.uploader.onAfterAddingFile = function (item) {
            item.novoNome = item.file.name;
            $scope.arquivosPraSubir = true;
            if ($scope.arquivosHidden)
                $scope.arquivosHidden = false;
        }

       /**
	    * Função chamada antes dos arquivos serem adicionados na fila de envio
	    *
	    * @method onBeforeUploadItem
		*        
	    * @param item {Object} Arquivo
	    *
		*               
	    */ 
        $scope.uploader.onBeforeUploadItem = function (item) {
            item.url = uploader.url;

            var token = window.sessionStorage.getItem('s4cToken');
            var tokenObj = JSON.parse(token);
            item.headers = {
                'Authorization': 'Bearer ' + tokenObj.access_token
            };
            item.file.name = item.novoNome + ext(item.file.name);
        };

       /**
	    * Mostra o processo de envio dos arquivos
	    *
	    * @method onProgressItem
		*        
	    * @param fileItem {Object} Arquivo
	    * @param progress {Object} 
	    *               
	    */ 
        $scope.uploader.onProgressItem = function (fileItem, progress) {
            console.info('onProgressItem', fileItem, progress);
        };
        
       /**
	    * Função chamada ao finalizar o envio dos arquivos
	    *
	    * @method onCompleteAll
		*        
	    * @param result {Object}
	    *
		*               
	    */ 
        $scope.uploader.onCompleteAll = function (result) {
            _.each(uploadCallbackQueue, function (callback) {
                callback();
            });

            var content = $scope.enviadosComSucesso.length + localize.res('ARQUIVOS_ENVIADOS_SUCESSO') + '.<br/>';

            if ($scope.enviadosComFalha.length > 0) {
                content += $scope.enviadosComFalha.length + localize.res('ARQUIVOS_NAO_ENVIADOS_SUCESSO') + '.<br/>';
                content += '<br/>' + localize.res('ARQUIVOS_NAO_ENVIADOS_SUCESSO') + ':<br/>';
                _.each($scope.enviadosComFalha, function (item) {
                    content += '- ' + item.novoNome + '<br/>';
                })
            }

            $mdDialog.show({
                template: '<md-dialog>' +
                    '<md-title style="padding: 20px 0px 0px 20px;">' + localize.res('RESUMO_ENVIO_ARQUIVOS') + '</md-title>' +
                    '  <md-content>' + content + '</md-content>' +
                    '  <div class="md-actions">' +
                    '    <md-button ng-click="fechar()">' + localize.res('COMUM_OK') + '</md-button>' +
                    '  </div>' +
                    '</md-dialog>',
                controller: function ($scope, $mdDialog) {
                    $scope.fechar = function () {
                        $mdDialog.hide();
                    }
                }
            });

            $scope.enviadosComSucesso = [];
            $scope.enviadosComFalha = [];
        };

        $scope.openOptionShare = function () {
            $scope.openShare = !$scope.openShare;
        };
        $scope.res = $scope.$root.res;

       /**
	    * Retorna a extensão dos arquivos
	    *
	    * @method ext
		*        
	    * @param filename {String}
	    *
		*               
	    */ 
        function ext(filename) {
            var index = _.lastIndexOf(filename, '.');
            return filename.substring(index, filename.length);
        }

       /**
	    * Faz o envio dos arquivos que estão na fila 
	    *
	    * @method enviarArquivos
		*        
	    * @param data {Object}
	    *
		*               
	    */ 
        function enviarArquivos(data) {

            $scope.isUploading = true;
            uploader.url = '/pois/arquivo/' + data.id;
            uploader.uploadAll();

            uploadCallbackQueue.push(function () {
                $scope.isUploading = false;
                $scope.arquivosPraSubir = false;

                var latlng = {
                    lat: data.latitude,
                    lng: data.longitude
                };

                DetalhamentoManager.abrirPoi(data.id, latlng);
            });

        };

       /**
	    * Encerra o incidente
	    *
	    * @method encerrarIncidente
		*        
	    * @param data {Object} Dados do Incidente
	    *
		*               
	    */
        $scope.encerrarIncidente = function (data) {
            var confirm = $mdDialog.confirm()
                .title(localize.res('DESEJA_ENCERRAR_INCIDENTE'))
                .content(localize.res('PRESET_CONFIRMAR_SALVAR_MENSAGEM'))
                .ariaLabel(localize.res('ENCERRAR_INCIDENTE'))
                .ok(localize.res('COMUM_SIM'))
                .cancel(localize.res('COMUM_CANCELAR'));

            $mdDialog
                .show(confirm)
                .then(function () {
                    var UserInfo = MainState.getManager('UserInfo');
                    var mensagem = UserInfo.nome + ' (' + UserInfo.Perfils[0].nome + ') ' + localize.res('COMUM_EM') + ' ' + moment().format('DD/MM/YYYY HH:mm:ss');
                    data.status = 'FECHADO';
                    data.extras.informacoes.push({
                        'label': localize.res('ENCERRADO_POR'),
                        'valor': mensagem
                    });
                    IncidentesService.saveIncidente(data)
                        .then(function () {
                            $mdDialog.show(
                                $mdDialog.alert()
                                    .title(localize.res('INCIDENTE_ENCERRADO'))
                                    .content(localize.res('INCIDENTE_ENCERRADO_SUCESSO'))
                                    .ariaLabel(localize.res('INCIDENTE_ENCERRADO_SUCESSO'))
                                    .ok(localize.res('COMUM_OK'))
                            );
                        });
                });
        };

       /**
	    * Remove arquivos da fila
	    *
	    * @method removerItem
		*        
	    * @param item {Object} 
	    *
		*               
	    */
        function removerItem(item) {
            uploader.removeFromQueue(item);
        }

       /**
	    * Atualiza a quantidade de comentários que o Incidente possui
	    *
	    * @method updateIconCount
		*        
	    * 
	    *
		*               
	    */
        function updateIconCount() {
            var incidente = $scope.data;
            MapaService.updateIconeIncidente($scope.marker, incidente, incidente.Comentarios.length);
        }

       /**
	    * Atualiza a lista de comentários que o Incidente possui
	    *
	    * @method updateComentariosList
		*        
	    * 
	    *
		*               
	    */
        function updateComentariosList(comentario) {
            if ($scope.tipoItem === 'Incidente') {

                var incidente = $scope.data;
                var usuario = _.find(usuarios, function (usuario) {
                    return usuario.id === comentario.UsuarioId;
                });

                comentario.cor = (usuario && usuario.cor) || getRandomColor();

                if ($scope.tipoItem === 'Incidente') {
                    if (!_.find(incidente.Comentarios, {
                        'id': comentario.id
                    })) {
                        incidente.Comentarios.push(comentario);
                        usuarios.push({
                            id: AuthService.user.info.id,
                            cor: comentario.cor
                        });
                    }
                }
            }

            if ($scope.tipoItem === 'Poi') {

                var poi = $scope.data;
                var usuario = _.find(usuarios, function (usuario) {
                    return usuario.id === comentario.UsuarioId;
                });

                comentario.cor = (usuario && usuario.cor) || getRandomColor();

                if (!_.find(poi.Comentarios, {
                    'id': comentario.id
                })) {
                    poi.Comentarios.push(comentario);
                    usuarios.push({
                        id: AuthService.user.info.id,
                        cor: comentario.cor
                    });
                }
            }
        }

       /**
	    * Listener do Websocket updateIncident
	    *
	    * @method updateIncident
		*        
	    * 
	    *
		*               
	    */
        CommService.on('updateIncident', function (incidente) {
            if ($scope.data.id == incidente.id) {
                $scope.data.extras = incidente.extras;
            }
        });

       /**
	    * Listener do Websocket incidenteNewNota
	    *
	    * @method incidenteNewNota
		*        
	    * 
	    *
		*               
	    */
        CommService.on('incidenteNewNota', function (comentario) {
            if (comentario.IncidenteId === $scope.data.id) {
                updateComentariosList(comentario);
            }
        });

       /**
	    * Listener do Websocket incidentes
	    *
	    * @method incidentes
		*        
	    * 
	    *
		*               
	    */
        CommService.on('incidentes', function (data) {
            if (data == null || data == undefined) {
                return;
            }

            if (data.id === $scope.data.id) {
                buscarIncidente(data.id, {
                    lat: data.geometry.coordinates[1],
                    lng: data.geometry.coordinates[0]
                });
            }
            var status = LegendaIncidenteFilter.getInstance('legenda-incidente-incidentes').statuses;
            LegendaIncidenteFilter.getInstance('legenda-incidente-incidentes').trigger('filterChanged', 'filtro');
        });

      /**
	    * Gera um excel com os dados do incidente
	    *
	    * @method salvarIncidenteExcel
		*        
	    * @param incidente {Object} Dados do Incidente
	    *
		*               
	    */
        function salvarIncidenteExcel(incidente) {
            window.open('/incidentes/' + incidente.id + '/excel');
        }

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

      /**
	    * Faz um solicitação de videoChamada para a camera cadastrada no POI
	    *
	    * @method solicitarVideoChamada
		*        
	    * @param informacao {String} Dados da camera
	    *
		*               
	    */
        function solicitarVideoChamada(informacao) {

            var url_ = ParametrosS4C.wowzaUrl + '/live/' + informacao.valor + '.stream/playlist.m3u8';

            if (informacao.tipo == "CAMERA_WOWZA") {
                var url = ParametrosS4C.wowzaUrl + '/live/' + informacao.valor + '.stream/playlist.m3u8';
                window.open("/Cam/rtsp/?url=" + url, '_blank', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=false,resizable=false,width=' + 670 + ',height=' + 400);
                return;
            }

            if (informacao.tipo == "CAMERA") {

                var id = Math.random().toString(36).substring(2, 15);
                vModal('id' + id, informacao.label,
                    '<video id="' + id + '" controls autoplay style="width:100%; height:100%;"></video>', function () {
                        VideoStreamService.close(id);
                    });
                VideoStreamService.open(id, informacao.valor);
                return;
            }

            VideoChamadaService.iniciarVideo(informacao.valor).then(function (url) {
                window.open("/assets/html/conectarVideoChamada.html?terminal=" + informacao.valor + "&url=" + url_, '_blank', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=false,resizable=false,width=' + 670 + ',height=' + 400);
            }, function (err) {
                console.log("Erro na solicitação de conexão de vídeo chamada");
            });
        }


      /**
	    * Faz o envio do comentário para o poi ou incidente
	    *
	    * @method enviarComentario
		*        
	    * @param valido {Boolean}
	    *
		*               
	    */
        function enviarComentario(valido) {
            if (valido) {

                $scope.comentarioFormData.UsuarioId = $scope.user.id;

                DetalhamentoService
                    .enviarComentario($scope.comentarioFormData)
                    .then(function (comentario) {

                        $scope.comentarioFormData.corpo = '';
                        updateComentariosList(comentario);

                        if ($scope.tipoItem === 'Incidente') {
                            updateIconCount();
                            $scope.comentarioFormData = {
                                IncidenteId: $scope.data.id,
                                corpo: ''
                            };
                        }
                        ;

                        if ($scope.tipoItem === 'Poi') {
                            $scope.comentarioFormData = {
                                PoiId: $scope.data.id,
                                corpo: ''
                            };
                        }
                        ;

                    }, function (err) {
                        toasty({
                            msg: err.data.message
                        });
                    });
            } 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'))
                );
            }
        }

      /**
	    * Faz o envio da cronologia
	    *
	    * @method enviarCronologia
		*        
	    * @param valido {Boolean}
	    *
		*               
	    */
        function enviarCronologia(valido) {
            if (valido) {
                // adicionando 3 horas à cronologia por que na hora da leitura
                // ele diminui esse tempo devido à gambiarra pro integrador
                var cronologia = $scope.cronologiaFormData.corpo + '||' + moment().add(3, 'hours').format('YYYY-MM-DD HH:mm');
                DetalhamentoService
                    .enviarCronologia($scope.data.id, {
                        cronologia: cronologia
                    })
                    .then(function (result) {
                        if (!$scope.data.extras) {
                            $scope.data.extras = {
                                observacoes: []
                            }
                        } else if (!$scope.data.extras.observacoes) {
                            $scope.data.extras.observacoes = []
                        }

                        $scope.data.extras.observacoes = _.filter($scope.data.extras.observacoes, function (obs) {
                            return obs != result;
                        });

                        $scope.data.extras.observacoes.push(result);
                        $scope.cronologiaFormData.corpo = '';
                    });
            } else {
                $mdDialog.show(
                    $mdDialog.alert()
                        .title(localize.res('COMUM_ERRO'))
                        .content(localize.res('TEXT_CRONOLOGIA_OBRIGATORIO'))
                        .ariaLabel(localize.res('TEXT_CRONOLOGIA_OBRIGATORIO'))
                        .ok(localize.res('COMUM_OK'))
                );
            }
        }

      /**
	    * Gera uma cor aleatória
	    *
	    * @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;
        }

      /**
	    * Voa para as coordenadas recebidas por parâmetro
	    *
	    * @method voarPara
		*        
		* @param obj {Object} Coordenadas               
	    */
        function voarPara(obj) {
            DetalhamentoManager.voarParaObjeto(obj);
        }

      /**
	    * Voa para as coordenadas recebidas por parâmetro
	    *
	    * @method voarParaSubItem
		*        
		* @param obj {Object} Coordenadas               
	    */
        function voarParaSubItem(obj) {

            DetalhamentoManager.voarParaSubItem($scope.data, obj);
        }

      /**
	    * Remove arquivo do Poi
	    *
	    * @method removerArquivo
		*        
		* @param arquivo {Object} Arquivo               
	    */
        function removerArquivo(arquivo) {
            $http.delete('/pois/arquivo/' + arquivo.id)
                .then(function (response) {
                    var index = $scope.data.Arquivos.indexOf(arquivo);
                    $scope.data.Arquivos.splice(index, 1);
                },
                    function (err) {
                        toasty({
                            msg: err.data.message
                        });
                    });
        }

      /**
	    * Remove incidente
	    *
	    * @method removerIncidente
		*        
		*      
	    */
        function removerIncidente() {

            var idIncidente = $scope.data.id;
            var confirm = $mdDialog.confirm()
                .title(localize.res('CERTEZA_REMOVER_INCIDENTE'))
                .ok(localize.res('COMUM_SIM'))
                .cancel(localize.res('COMUM_NAO'));

            $mdDialog.show(confirm).then(function () {
                DetalhamentoService.removerIncidente(idIncidente)
                    .then(function (data) {
                        MainState.getDirective('filtro-msi').refreshIncidentes('clearIncidentes', $scope.data);
                    });
            });
        };

     /**
	    * Remove incidente informando um motivo
	    *
	    * @method removerIncidenteComMotivo
		*        
		*      
	    */
        function removerIncidenteComMotivo() {
            $scope.formDeleteIncidenteSubmitted = true;
            if (!$scope.formDeleteIncidente.$valid) {
                return;
            }

            var idIncidente = $scope.data.id;
            DetalhamentoService.removerIncidente(idIncidente, { motivo: $scope.justDel.motivo })
                .then(function (data) {
                    fechar();
                }).finally(function () {
                    $scope.formDeleteIncidenteSubmitted = false;
                    MainState.getDirective('filtro-msi').refreshIncidentes('clearIncidentes', $scope.data);
                })
        }

     /**
	    * Função chamada no cancelar do delete
	    *
	    * @method cancelarDelete
		*        
		*      
	    */
        function cancelarDelete() {
            $scope.justDel = {
                isOpen: false,
                isDeleting: false,
                motivo: ""
            };
            $scope.formDeleteIncidenteSubmitted = false;
        }

       /**
	    * Abre a janela pra incluir arquivos
	    *
	    * @method abrirUpload
		*        
		*      
	    */
        function abrirUpload() {
            $scope.input.click();
        }

       /**
	    * Fecha o detalhamento
	    *
	    * @method fechar
		*        
		*      
	    */
        function fechar() {
            $scope.justDel = {
                isOpen: false,
                isDeleting: false,
                motivo: ""
            };
            DetalhamentoManager.fechar();
            CamadasService.reloadIncidentes();
            $scope.enableButton = true;
        }

       /**
	    * Busca um planejamento
	    *
	    * @method buscarPlanejamento
		*        
		* @param id {Integer} Indentificador
		* @param latlng {Object} Coordenadas
		*       
	    */
        function buscarPlanejamento(id, latlng) {
            DetalhamentoManager.titulo = localize.res('PLANEJAMENTO_TITULO');

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

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

      /**
	    * Busca uma zona de observação
	    *
	    * @method buscarZonaDeObservacao
		*        
		* @param data {Object} 
		*       
	    */
        function buscarZonaDeObservacao(data) {

            var id = data.zonaDeObservacao ? data.zonaDeObservacao.id : data

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

      /**
	    * Abre o detalhamento da rota
	    *
	    * @method abrirRota
		*        
		* @param rota {Object} 
		*       
	    */
        function abrirRota(rota) {
            RotasUnificadasService.pegarRota(rota.id).then(function (rotaUnficada) {
                RotasUnificadasManager.editar(rotaUnficada);
            });
        }

     /**
	    * Fecha o detalhamento da rota
	    *
	    * @method fecharRota
		*        
		* 
		*       
	    */
        function fecharRota() {
            MapaService.removerRouter();
        }

     /**
	    * Busca os dados do Incidente
	    *
	    * @method buscarIncidente
		*        
		* @param id {Integer} 
		* @param latlng {Object}
		* @param marker {Object} 
		*        
	    */
        function buscarIncidente(id, latlng, marker) {
            $scope.incidentesProximos = [];
            $scope.basesProximas = [];
            $scope.poisProximos = [];
            $scope.viaturasProximas = [];
            $scope.areaAtuacao = {};
            $scope.tipoItem = 'Incidente';
            $scope.marker = marker;
            $scope.comentarioFormData = {
                IncidenteId: $scope.data.id,
                corpo: ''
            };
            $scope.cronologiaFormData = {
                corpo: ''
            };

            $scope.incidente;
            DetalhamentoService
                .pegarIncidente(id)
                .then(function (incidente) {

                    $scope.incidente = incidente;
                    $scope.user = AuthService.user.info;
                    incidente.Comentarios = incidente.Comentarios.reverse();

                    usuarios = _.chain(incidente.Comentarios) // O chain
                        // encadeia os
                        // métodos
                        .map('UsuarioId') // 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,
                            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;

                    DetalhamentoManager.titulo = (!incidente.nome) ? incidente.TipoIncidente.nome : incidente.nome;
                    DetalhamentoManager.data = incidente;
                    updateIconCount();

                    if (!!MainState.getDirective('incidentes') && angular.element('#modulo-incidentes')) {
                        try {
                            angular.element('#modulo-incidentes').scrollTo(angular.element('#incidente-' + incidente.id));
                        } catch (err) {
                            console.log("Não foi possível encontrar o incidente na lista para marca-lo.");
                        }
                    }

                    IncidentesManager.incidenteAtivo = incidente;
                    if (incidente.CategoriaIncidente) {
                        DetalhamentoManager.data.categoria = incidente.CategoriaIncidente.nome;
                    }

                    $scope.GruposParticipantes = _.map(incidente.GruposUsuarios, 'nome').join(', ');
                    $scope.UsuariosParticipantes = _.map(incidente.Usuarios, 'nome').join(', ');

                    $scope.Usuarios = incidente.Usuarios;
                    $scope.GruposUsuarios = incidente.GruposUsuarios;

                    pegarBases(latlng, id);
                    pegarIncidentes(latlng, id);
                    pegarPois(latlng, id); // HERE
                    pegarViaturas(latlng);
                    pegarAreaAtuacao(undefined, latlng, 'Incidente');


                    // Pega cameras próximas, se existirem cameras, marca as 3
                    // mais próximas e dá fit bounds, se não existire, voa para
                    // a posição do incidente
                    pegarCameras(latlng)
                        .then(function (cameras) {
                            if (cameras.length > 0) {
                                IncidentesManager.abrirMosaicoCameras(latlng, cameras);
                            }
                        });
                });

            return $scope.incidente;
        }

        $scope.runningVideo = false;
        
     /**
	    * Busca os dados do Poi
	    *
	    * @method buscarPoi
		*        
		* @param id {Integer} 
		* @param latlng {Object}
		* @param tipo {Object} 
		*        
	    */        
        function buscarPoi(id, latlng, tipo) {

            $scope.titulo = '';
            $scope.incidentesProximos = [];
            $scope.basesProximas = [];
            $scope.poisProximos = [];
            $scope.areaAtuacao = {};
            $scope.tipoItem = 'Poi';
            $scope.temCameras = false;
            $scope.comentarioFormData = {
                PoiId: id,
                corpo: ''
            };
            DetalhamentoService
                .pegarPoi(id)
                .then(function (data) {

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

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

                    usuarios = _.chain(data.Comentarios)
                        .map('Usuario')
                        .uniq()
                        .value();

                    usuarios = _.map(usuarios, function (u) {
                        return {
                            id: u.id,
                            cor: getRandomColor()
                        };
                    });

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

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

                    $scope.data = data;
                    if ($scope.isMultivisManager(data)) {
                        $("#carregando").show();
                        $("#informacoes").hide();

                        $scope.data.license_html = "<p>License Status:<span class=\"d-info\"> Active</span></p><p>Number:<span class=\"d-info\"> ####-####-####-v291</span></p>";


                        Base.obterDoManager('multivis/getFullVersion/' + data.chave_estrangeira).then(function (response) {
                            $scope.data.multivis_version = response;
                        });
                        Base.obterDoManager('multivis/systeminformation/' + data.chave_estrangeira).then(function (response) {
                            $scope.data.systeminformation = response;
                            $("#carregando").hide();
                            $("#informacoes").show();
                            $scope.data.systeminformation.time = new Date().toLocaleString();
                        });

                        $("#modo_meeting").hide();
                        Base.obterDoManager('multivis/getTokenMeeting/' + data.chave_estrangeira).then(function (response) {
                            if (response.modo_meeting) {
                                $("#modo_meeting").show();
                                $scope.data.token_meeting = response.token;
                            }
                        });

                        if ($scope.data.extras && $scope.data.extras.informacoes) {
                            for (var index in $scope.data.extras.informacoes) {
                                if ($scope.data.extras.informacoes[index].label == 'IP') {
                                    $scope.data.urlMultivis = $scope.data.extras.informacoes[index].valor;
                                }
                            }
                        }
                    }

                    DetalhamentoManager.data = data;

                    pegarBases(latlng.lat != null ? latlng : data.geometry, id);
                    pegarIncidentes(latlng.lat != null ? latlng : data.geometry, id, data.chave_estrangeira);
                    pegarPois(latlng.lat != null ? latlng : data.geometry, id);
                    pegarViaturas(latlng.lat != null ? latlng : data.geometry);
                    pegarAreaAtuacao(id, latlng.lat != null ? latlng : data.geometry);
                    pegarCameras(latlng.lat != null ? latlng : data.geometry);
                    pegarRotasProximas(latlng.lat != null ? latlng : data.geometry, id);
                    pegarPoisContidos(id);
                    //pegarEventosPlanejados(data.chave_estrangeira);
                    //pegarEventosContidos(id);
                    totalizarPoisRelacionadosPorCategoria(data);

                    temCameras();

                    var url1;
                    var url2;
                    for (var index in $scope.data.extras.informacoes) {
                        if ($scope.data.extras.informacoes[index].label == 'url1') {
                            url1 = $scope.data.extras.informacoes[index].valor;
                        } else if ($scope.data.extras.informacoes[index].label == 'url2') {
                            url2 = $scope.data.extras.informacoes[index].valor;
                        }
                    }

                    if (!url1) {
                        return;
                    }

                    $scope.data.extras.url1 = url1;
                    $scope.data.extras.url2 = url2;

                    if ($scope.runningVideo) {
                        return;
                    }

                    $timeout(function () {
                        if (flvjs.isSupported()) {
                            var videoElement1 = document.getElementById('videoElement1');
                            var flvPlayer1 = flvjs.createPlayer({
                                type: 'flv',
                                url: url1
                            });
                            flvPlayer1.attachMediaElement(videoElement1);
                            flvPlayer1.load();
                            flvPlayer1.play();

                            var videoElement2 = document.getElementById('videoElement2');
                            var flvPlayer2 = flvjs.createPlayer({
                                type: 'flv',
                                url: url2
                            });
                            flvPlayer2.attachMediaElement(videoElement2);
                            flvPlayer2.load();
                            flvPlayer2.play();

                            $scope.runningVideo = true;
                        }
                    }, 1000);
                });
        }

     /**
	    * Carrega os dados da viatura
	    *
	    * @method carregarViatura
		*        
		* @param viatura {Object}
		*        
	    */  
        function carregarViatura(viatura) {

            if (!viatura.nome) {
                viatura.nome = viatura.chave_estrangeira;
            }

            $scope.titulo = '';
            $scope.incidentesProximos = [];
            $scope.basesProximas = [];
            $scope.poisProximos = [];
            $scope.areaAtuacao = {};
            $scope.tipoItem = 'Viatura';
            $scope.data = viatura;
            DetalhamentoManager.data = viatura;
            if (!viatura.agencia) {
                DetalhamentoManager.titulo = viatura.nome;
            } else {
                DetalhamentoManager.titulo = viatura.agencia + ' - ' + viatura.chave_estrangeira;
            }

            var latlng = {
                lat: viatura.posicao.latitude,
                lng: viatura.posicao.longitude
            };

            viatura.geojson = turf.point([latlng.lng, latlng.lat]).geometry;

            viatura.viatura = true;

            pegarBases(latlng);
            pegarIncidentes(latlng);
            pegarPois(latlng);
            pegarViaturas(latlng);
            pegarAreaAtuacao(undefined, latlng);
            pegarCameras(latlng);

        }

     /**
	    * Carrega os dados da Area de Atuação
	    *
	    * @method pegarAreaAtuacao
		*
		* @param id {Identificador}        
		* @param obj {Object}
		*        
	    */  
        function pegarAreaAtuacao(id, obj) {

            DetalhamentoService
                .findAreaAtuacao(id, obj)
                .then(function (data) {
                    $scope.areasAtuacao = data;
                });


            return;
        }

     /**
	    * Executa o filtro de incidentes ou busca indentes próximos 
	    *
	    * @method pegarIncidentes
		*
		* @param obj {Object}
		* @param id {Identificador}        
		* @param chaveEstrangeira {String}
		*        
	    */ 
        function pegarIncidentes(obj, id, chaveEstrangeira) {

            if (!chaveEstrangeira) {
                DetalhamentoService
                    .pegarIncidentesProximos(obj)
                    .then(function (data) {
                        afterThen(data, id);
                    });
            } else {

                var query = MsiFilter.getInstance('filtro-msi').lastTableQueryFilter;
                if (!query) {
                    MainState.getDirective('filtro-msi').refreshIncidentes();
                    query = MsiFilter.getInstance('filtro-msi').lastTableQueryFilter;
                }
                query.chaveEstrangeira = chaveEstrangeira;

                IncidentesService.findSimpleByFilter(query).then(function (incidentes) {
                    $scope.incidentesPoi = incidentes;
                });
            }
        }

  	  /**
	    * Executado após obter os dados dos indentes próximos 
	    *
	    * @method afterThen
		*
		* @param data {Object}
		* @param id {Identificador}        
		*        
	    */ 
        function afterThen(data, id) {

            $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 = 0;
                var geom = [];
                if (!obj.geometry) {
                    distance = turf.distance(
                        turf.point([obj.lat, obj.lng]),
                        turf.point([leafletCoords.lat, leafletCoords.lng]),
                        'kilometers');
                } else {

                    if (obj.geometry.type == 'Polygon' || obj.geometry.type == 'MultiPolygon') {

                        var polygon = turf.polygon(obj.geometry.coordinates);
                        geom.push(turf.centroid(polygon).geometry.coordinates[1]);
                        geom.push(turf.centroid(polygon).geometry.coordinates[0]);

                    } else {

                        var line = turf.linestring(obj.geometry.coordinates);
                        var center = turf.center(line);
                        geom.push(center.geometry.coordinates[1]);
                        geom.push(center.geometry.coordinates[0]);

                    }

                    distance = data[key].distance;
                }

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

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

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

            _.remove($scope.incidentesProximos, function (incidente) {
                return _.chain($scope.data.Incidentes)
                    .map('id')
                    .includes(incidente.id)
                    .value();
            });
        }

 	  /**
	    * Carrega os dados das cameras 
	    *
	    * @method pegarCameras
		*
		* @param obj {Object}
		*        
	    */ 
        function pegarCameras(obj) {
            var deferred = $q.defer();
            DetalhamentoService
                .pegarCamerasProximas(obj)
                .then(function (data) {
                    if (data.length) {
                        // Mosaico de cameras:
                        // DetalhamentoManager.abrirMosaicoCameras(ponto, data);
                    }

                    var camerasProximas = _.sortBy(data, function (c) {

                        var coords = JSON.parse(c.geojson);
                        var distancia;

                        if (!obj.geometry) {
                            distancia = turf.distance(
                                turf.point([coords.coordinates[1], coords.coordinates[0]]),
                                turf.point([obj.lat, obj.lng]),
                                'miles');
                        } else {

                            var tipo = obj.geometry.type;
                            if (tipo == 'Polygon') {
                                var polygon = turf.polygon(obj.geometry.coordinates);
                                var centroid = turf.centroid(polygon);
                                distancia = turf.distance(
                                    turf.point([coords.coordinates[1], coords.coordinates[0]]),
                                    turf.point([centroid.geometry.coordinates[1], centroid.geometry.coordinates[0]]),
                                    'meters');
                            } else {

                                distancia = turf.distance(
                                    turf.point([coords.coordinates[1], coords.coordinates[0]]),
                                    turf.point([obj.geometry.coordinates[0][1], obj.geometry.coordinates[0][0]]),
                                    'meters');
                            }
                        }

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

                        return distancia;
                    });

                    $scope.camerasProximas = camerasProximas;
                    deferred.resolve(camerasProximas);
                });

            return deferred.promise;
        }

        /*
		 * Abre cameras do detalhamento no Mosaico de cameras.
		 */
 	  /**
	    * Abre cameras do detalhamento no Mosaico de cameras.
	    *
	    * @method abrirCamerasMosaico
		*
		* @param cameras {Object}
		*        
	    */ 		 
        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');
        }

 	  /**
	    * Busca pois próximos.
	    *
	    * @method pegarPois
		*
		* @param obj {Object}
		* @param id {Integer}        
	    */ 	
        function pegarPois(obj, id) {

            DetalhamentoService
                .pegarPoisProximos(obj)
                .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;
                            var geom = [];
                            if (!obj.geometry && leafletCoords != null && leafletCoords.lat != null && leafletCoords.lng != null) {
                                distance = turf.distance(
                                    turf.point([obj.lat, obj.lng]),
                                    turf.point([leafletCoords.lat, leafletCoords.lng]),
                                    'kilometers');
                            } else if (obj.geometry != null) {

                                if (obj.geometry.type == 'Polygon' || obj.geometry.type == 'MultiPolygon') {

                                    var polygon = turf.polygon(obj.geometry.coordinates);
                                    geom.push(turf.centroid(polygon).geometry.coordinates[1]);
                                    geom.push(turf.centroid(polygon).geometry.coordinates[0]);

                                } else {

                                    var line = turf.linestring(obj.geometry.coordinates);
                                    var center = turf.center(line);
                                    geom.push(center.geometry.coordinates[1]);
                                    geom.push(center.geometry.coordinates[0]);

                                }

                                distance = data[key].distance;
                            }

                            var urlIcone;
                            if (data[key].representacao && data[key].extras) {
                                data[key].properties = { extras: data[key].extras };
                                urlIcone = RepresentacaoService.getFunctionResult(data[key], data[key].representacao.json.pointLayout[0].circulo.centro.funcao);
                            } else {
                                urlIcone = data[key].urlIcone;
                            }
                            poisProximos.push({
                                id: data[key].id,
                                nome: data[key].nome,
                                cat: data[key],
                                icone: urlIcone,
                                geojson: data[key].geojson,
                                distancia: (distance * 1000).toFixed(0),
                                tipo: 'poi'
                            });

                        }
                    });

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

                    DetalhamentoManager.poisProximos = poisProximos;

                    $scope.poisProximos = poisProximos;

                }, function () {
                });
        }

 	  /**
	    * Busca viaturas próximas.
	    *
	    * @method pegarViaturas
		*
		* @param ponto {Object}
	    */ 	
        function pegarViaturas(ponto) {
            DetalhamentoService.pegarViaturasProximas(ponto).then(function (viaturas) {
                if ($scope.tipoItem == 'Viatura') {
                    _.remove(viaturas, { chave_estrangeira: $scope.data.chave_estrangeira });
                }

                _.each(viaturas, function (viatura) {
                    viatura.geojson = turf.point([viatura.posicao.longitude, viatura.posicao.latitude]).geometry;
                    viatura.tipo = "viatura";
                });
                $scope.viaturasProximas = viaturas;
            });
        }

 	  /**
	    * Busca Bases de Conhecimento próximas.
	    *
	    * @method pegarBases
		*
		* @param ponto {Object}
		* @param id {Integer}  
	    */ 	
        function pegarBases(obj, id) {

            DetalhamentoService
                .pegarBasesProximas(obj)
                .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) {
                        DetalhamentoManager.drawBasesLines(ponto, $scope.basesProximas);
                    }
                });
        }

 	  /**
	    * Faz o download de arquivos anexados
	    *
	    * @method download
		*
		* @param id {Integer}
		* @param fileName {String}  
	    */ 	
        function download(id, fileName) {

            Base.obter('filemanager/checkexistence/' + id)
                .then(function (response) {
                    if (response.status == 200 || response.data) {
                        DetalhamentoService.getAttachedFile(id)
                            .then(function (data) {

                                var a = document.createElement("a");
                                document.body.appendChild(a);
                                a.style = "display: none";

                                var file = new Blob([data], { type: 'application/octet-stream' });
                                var fileURL = URL.createObjectURL(file);

                                a.href = fileURL;
                                a.download = fileName;
                                a.click();

                            });
                    }
                    else {
                        $mdDialog
                            .show($mdDialog.alert()
                                .title(localize.res('COMUM_SUCESSO'))
                                .content(response.data.message)
                                .ok(localize.res('COMUM_OK')));
                    }
                }, function (err) {
                    $mdDialog
                        .show($mdDialog.alert()
                            .title(localize.res('COMUM_SUCESSO'))
                            .content(err.data.message)
                            .ok(localize.res('COMUM_OK')));
                });

        }

 	  /**
	    * Abre o detalhamento do Incidente
	    *
	    * @method abrirIncidente
		*
		* @param incidente {Object}
	    */ 
        function abrirIncidente(incidente) {
            DetalhamentoManager.abrirIncidente(incidente.id, {
                lat: incidente.geojson.coordinates[1],
                lng: incidente.geojson.coordinates[0]
            })
        }

 	  /**
	    * Abre o detalhamento do Incidente
	    *
	    * @method abrirIncidentePoi
		*
		* @param incidente {Object}
	    */ 
        function abrirIncidentePoi(incidente) {
            DetalhamentoManager.abrirIncidente(incidente.id, {
                lat: incidente.geometry.coordinates[1],
                lng: incidente.geometry.coordinates[0]
            })
        }

 	  /**
	    * Busca as rotas próximas
	    *
	    * @method pegarRotasProximas
		*
		* @param ponto {Object}
		* @param id {Integer}
	    */ 
        function pegarRotasProximas(ponto, id) {

            DetalhamentoService.pegarRotasProximas(id)
                .then(function (data) {
                    $scope.rotasProximas = [];
                    _.each(Object.keys(data), function (key) {
                        data[key].tipo = 'rota';
                        $scope.rotasProximas.push(data[key]);
                    });

                    if (false) {
                        DetalhamentoManager.drawBasesLines(ponto, $scope.rotasProximas);
                    }
                })
        }

 	  /**
	    * Busca os Eventos Planejados
	    *
	    * @method pegarEventosPlanejados
		*
		* @param chave_estrangeira {String}
	    */ 
        function pegarEventosPlanejados(chave_estrangeira) {
            DetalhamentoService.pegarEventosPlanejados(chave_estrangeira)
                .then(function (data) {

                    $scope.eventosPlanejados = [];

                    _.each(Object.keys(data), function (key) {
                        data[key].dataHora = moment(data[key].dataHora).format('DD/MM/YYYY hh:mm');
                    });

                    $scope.tiposDeEvento = _(data).chain().map('tipo').uniq().value();

                    _.each($scope.tiposDeEvento, function (t) {
                        $scope.eventosPlanejados.push(_.filter(data, function (ev) {
                            if (ev.tipo == t) {
                                return ev;
                            }
                        }))
                    });
                })
        }

	  /**
	    * Busca os pois contidos numa area
	    *
	    * @method pegarPoisContidos
		*
		* @param id {Integer}
	    */ 
        function pegarPoisContidos(id) {
            DetalhamentoService.pegarPoisContidos(id)
                .then(function (data) {
                    $scope.instalacoesOlimpicas = [];

                    _.each(Object.keys(data), function (key) {
                        data[key].tipoItem = 'instalacaoOlimpica';
                    });

                    _.each(data, function (poi) {
                        $scope.instalacoesOlimpicas.push(poi);
                    });
                }, function (err) {
                    console.log(err);
                })
        }

	  /**
	    * Busca os Eventos contidos numa area
	    *
	    * @method pegarEventosContidos
		*
		* @param id {Integer}
	    */ 
        function pegarEventosContidos(id) {
            DetalhamentoService.pegarEventosContidos(id)
                .then(function (data) {
                    $scope.competicoesOlimpicas = [];

                    _.each(Object.keys(data), function (key) {
                        data[key].tipoItem = 'competicaoOlimpica';
                    });

                    _.each(data, function (poi) {
                        $scope.competicoesOlimpicas.push(poi);
                    });
                }, function (err) {
                    console.log(err);
                })
        }


	  /**
	    * Fecha o Incidente
	    *
	    * @method fecharIncidente
		*
		* @param dataId {Integer}
		* @param incidente {Object}
	    */ 
        function fecharIncidente(dataId, incidente) {
            $mdDialog.show({
                templateUrl: 'app/directives/detalhamento/motivo-fechamento-incidente.html',
                controller: function ($scope, $mdDialog) {
                    $scope.res = $scope.$root.res;
                    if (!incidente.extras) {
                        incidente.extras = {};
                    }

                    $scope.salvar = function () {
                        $scope.tentouEnviar = true;
                        incidente.fim = moment().format('MM/DD/YYYY HH:mm:ss');
                        incidente.extras.motivoFechamento = $scope.motivoFechamento;
                        if (incidente.extras.motivoFechamento) {
                            salvarAlteracaoIncidente(dataId, incidente);
                        }
                    };

                    $scope.cancelar = function () {
                        $mdDialog.hide();
                        alterarIncidente();
                    };
                }
            });
        }

	  /**
	    * Salva as alterações no Incidente
	    *
	    * @method salvarAlteracaoIncidente
		*
		* @param dataId {Integer}
		* @param incidente {Object}
	    */ 
        function salvarAlteracaoIncidente(dataId, incidente) {
            IncidentesService.
                atualizarIncidente(dataId, incidente)
                .then(function (result) {
                    $mdDialog.hide();
                    MainState.getDirective('filtro-msi').atualizaIncidente(incidente);
                    $scope.enableButton = true;
                });
        }

	  /**
	    * Salva o Incidente
	    *
	    * @method salvarIncidente
		*
		* @param incidente {Object}
	    */
        function salvarIncidente(incidente) {

            if ($scope.enableButton == false) {
                return;
            }

            $scope.enableButton = false;
            IncidentesService.
                atualizarIncidente(incidente.id, incidente).then(_onIncidenteSuccess).then(fechar);
        }

	  /**
	    * Função chamada caso o incidente seja salvo sem erros
	    *
	    * @method _onIncidenteSuccess
		*
		* @param incidente {Object}
	    */
        function _onIncidenteSuccess(incidente) {
            $scope.tentouEnviar = false;

            $mdDialog.show(
                $mdDialog.alert()
                    .title(localize.res('COMUM_SUCESSO'))
                    .content(localize.res('INCIDENTE_ALTERADO_SUCESSO'))
                    .ariaLabel(localize.res('INCIDENTE_ALTERADO_SUCESSO'))
                    .ok(localize.res('COMUM_OK'))
            );
        }

        $scope.enableButton = true;
      /**
	    * Controller da tela de alteração de incidentes
	    *
	    * @method alterarIncidente
		*
	    */
        function alterarIncidente() {
            $mdDialog.show({
                templateUrl: 'app/directives/detalhamento/alterar-incidente.html',
                locals: {
                    data: $scope.data,
                    incidenteGravidades: $scope.incidenteGravidades
                },
                controller: function ($scope, $mdDialog, data, incidenteGravidades, $rootScope) {
                    $scope.res = $rootScope.res
                    $scope.enableButton = true;

                    $scope.incidenteGravidades = _.filter(incidenteGravidades, function (gravidade) {
                        return gravidade.status == 1;
                    });

                    $scope.statuses = [{
                        label: localize.res('COMUM_ABERTO'),
                        value: 'ABERTO'
                    }, {
                        label: localize.res('COMUM_FECHADO'),
                        value: 'FECHADO'
                    }];

                    $scope.incidente = data;

                    if (data.extras != null && data.extras.motivoFechamento) {
                        $scope.incidente.motivoFechamento = data.extras.motivoFechamento;
                    }

                    $scope.cancelar = function () {
                        $mdDialog.hide();
                    };

                    $scope.salvar = function () {

                        if ($scope.enableButton == false) {
                            return;
                        }

                        $scope.enableButton = false;
                        if ($scope.incidente.status === 'FECHADO' && !$scope.incidente.motivoFechamento) {
                            fecharIncidente(data.id, $scope.incidente);
                        } else {
                            salvarAlteracaoIncidente(data.id, $scope.incidente);
                        }
                    }
                }
            });
        }

      /**
	    * Abre a área de atuação
	    *
	    * @method abrirAreaAtuacao
	    *
		* @param id {Integer}
	    */
        function abrirAreaAtuacao(id) {
            AreaAtuacaoManager.abrirAreaAtuacao(id);
        }

     /**
	    * Verifica se há cameras no extra do objeto que está no detalhamento
	    *
	    * @method temCameras
	    *
	    */
        function temCameras() {
            if ($scope.data != null && $scope.data.extras != null && $scope.data.extras.informacoes != null) {
                angular.forEach($scope.data.extras.informacoes, function (informacao) {
                    if (informacao.tipo == "CAMERA") {
                        $scope.temCameras = true;
                    }
                });
            } else {
                $scope.temCameras = false;
            }
        }

     /**
	    * Limpa o detalhamento
	    *
	    * @method apagarDetalhamento
	    *
	    */
        function apagarDetalhamento() {
            $scope.data = {};
        }

     /**
	    * Carrega os Pois relacionados
	    *
	    * @method carregarPoisRelacionados
	    *
	    * @param id {Integer}
	    * @param categoriaId {Integer}
	    */
        function carregarPoisRelacionados(id, categoriaId) {

            CamadasService.carregarPoisRelacionados(id, categoriaId);
        }

     /**
	    * remove os Pois relacionados
	    *
	    * @method carregarPoisRelacionados
	    *
	    * @param categoriaId {Integer}
	    */
        function removerPoisRelacionados(categoriaId) {

            CamadasService.removerPoisRelacionados(categoriaId);
        }

        angular.extend($scope, {
            data: {},
            voarPara: voarPara,
            salvarIncidenteExcel: salvarIncidenteExcel,
            voarParaSubItem: voarParaSubItem,
            atualizandoCronologia: false,
            fechar: fechar,
            abrirCamerasMosaico: abrirCamerasMosaico,
            abrirPopup: abrirPopup,
            solicitarVideoChamada: solicitarVideoChamada,
            abrirUpload: abrirUpload,
            enviarComentario: enviarComentario,
            enviarCronologia: enviarCronologia,
            abrirIncidente: abrirIncidente,
            abrirIncidentePoi: abrirIncidentePoi,
            abrirRota: abrirRota,
            fecharRota: fecharRota,
            removerIncidente: removerIncidente,
            removerIncidenteComMotivo: removerIncidenteComMotivo,
            cancelarDelete: cancelarDelete,
            $apiDetalhamento: {
                apagarDetalhamento: apagarDetalhamento,
                buscarPoi: buscarPoi,
                buscarIncidente: buscarIncidente,
                buscarPlanejamento: buscarPlanejamento,
                buscarZonaDeObservacao: buscarZonaDeObservacao,
                carregarViatura: carregarViatura,
                removerPoisRelacionados: removerPoisRelacionados,
                totalizarPoisRelacionadosPorCategoria: totalizarPoisRelacionadosPorCategoria
            },
            removerItem: removerItem,
            removerArquivo: removerArquivo,
            enviarArquivos: enviarArquivos,
            download: download,
            alterarIncidente: alterarIncidente,
            salvarIncidente: salvarIncidente,
            abrirAreaAtuacao: abrirAreaAtuacao,
            carregarPoisRelacionados: carregarPoisRelacionados
        });

        $scope.uploader.alias = 'arquivo';
        $scope.uploader.removeAfterUpload = true;

        MainState.registerDirective('detalhamento', $scope.$apiDetalhamento);

        $scope.$on('$destroy', function () {
            MainState.unregisterDirective('detalhamento');
        });

        $scope.poisRelacionadosPorCategoria = {};

      /**
	    * Totaliza a quantidade de Pois relacionados por Categoria
	    *
	    * @method totalizarPoisRelacionadosPorCategoria
	    *
	    * @param data {Object}
	    */
        function totalizarPoisRelacionadosPorCategoria(data) {

            var poi;
            var totalizador = {};
            var item;

            if (!data || !data.poisRelacionados) {
                return totalizador;
            }

            for (var i = 0; i < data.poisRelacionados.length; i++) {
                poi = data.poisRelacionados[i];

                if (totalizador[poi.CategoriumId] == null || totalizador[poi.CategoriumId] == undefined) {
                    item = {};
                    item.qtd = 1;
                    item.categoriaNome = poi.categoriaNome;
                    item.CategoriumId = poi.CategoriumId;
                    totalizador[poi.CategoriumId] = item;

                } else {
                    item = totalizador[poi.CategoriumId];
                    item.qtd++;
                    totalizador[poi.CategoriumId] = item;
                }
            }

            $scope.poisRelacionadosPorCategoria = totalizador;
        }
    }

    function s4cDetalhamento() {
        return {
            restrict: 'EA',
            replace: true,
            scope: {},
            templateUrl: 'app/directives/detalhamento/detalhamento.html',
            controller: detalhamentoCtrl,
            link: function ($scope, $elem) {
                $scope.res = $scope.$root.res;
                $scope.input = $elem.find('input.uploadArquivo');
            }
        };
    }

   /**
    * Verifica se a data é válida  
    *
    * @method _isDate
	*        
    * @param date {Object} Arquivo
    * @param callback {Function} Função que será chamada no final da execução deste método 
    *  
	*               
    */
    function _isDate(date) {
        return (new Date(date) !== "Invalid Date" && !isNaN(new Date(date))) ? true : false;
    }

   /**
    * Monta o texto na cronologia  
    *
    * @method cronologiaTexto
	*        
    *  
	*               
    */
    function cronologiaTexto() {
        return function (texto) {
            if (texto.indexOf('||') > -1) {
                var temp = texto.split('||');
                var datahora = temp[1];
                var motivo = temp[2] || '';

                if (_isDate(datahora)) {
                    datahora = moment(temp[1]).format('DD/MM/YYYY - HH:mm');
                } else {
                    datahora = moment(parseInt(temp[1], 10)).format('DD/MM/YYYY - HH:mm');
                }

                return '<b class="datahora-cronologia">' + datahora + '</b><br/>' + ' ' + temp[0] + motivo;
            }

            return texto;
        };
    }

   /**
    * Monta o status na cronologia 
    *
    * @method cronologiaStatus
	*        
    *  
	*               
    */
    function cronologiaStatus() {
        return function (texto) {
            return _.startCase(texto.toLowerCase());
        };
    }

   /**
    * Monta o endereço na cronologia 
    *
    * @method cronologiaEndereco
	*        
    *  
	*               
    */
    function cronologiaEndereco() {

        return function (texto) {

            return _.chain(_.words(texto))
                .map(function (w) {
                    return _.startCase(w.toLowerCase());
                })
                .value()
                .join(' ');

        };
    }

    /**
	 * @ngdoc overview
	 * @name s4c.components.detalhamento
	 */
    angular.module('s4c.components.detalhamento', ['angularMoment'])
        .directive('s4cDetalhamento', s4cDetalhamento)
        .filter('cronologiaTexto', cronologiaTexto)
        .filter('cronologiaEndereco', cronologiaEndereco)
        .filter('cronologiaStatus', cronologiaStatus)
        .filter('sanitize', ['$sce', function ($sce) {
            return function (htmlCode) {
                return $sce.trustAsHtml(htmlCode);
            }
        }]);
}());