Source: directives/detalhamento_rotas_olimpicas/detalhamento_rotas.js

    /**
     * @ngdoc directives
     * @name detalhamentoRotas
     * @module s4c.directives.detalhamentorotas.detalhamentoRotas
     *
     * @description
     * `detalhamentoRotasOlimpicasCtrl` exibe informações sobre um ponto de interesse
     *
     *@example
     *   <s4c-detalhamento-rotas-olimpicas>
     *   </s4c-detalhamento-rotas-olimpicas>
     */
(function () {
    'use strict';

    detalhamentoRotasOlimpicasCtrl.$inject = [
        '$scope',
        'DetalhamentoManager',
        'MainState',
        'RotasOlimpicasService',
        'MapaService',
        'CamadasService',
        'DetalhamentoRotasOlimpicasManager',
        '$state',
        'RotasOlimpicas'
    ];

    function detalhamentoRotasOlimpicasCtrl($scope, DetalhamentoManager, MainState,
        RotasOlimpicasService, MapaService, CamadasService, DetalhamentoRotasOlimpicasManager, $state, RotasOlimpicas) {
        $scope.data = {
            nome: ''
        };

        $scope.res = $scope.$root.res;

	   /**
	    * Voa para um objeto 
	    *
	    * @method voarPara
		*        
	    * @param obj {Object} Poi 
		*               
	    */
        function voarPara(obj) {
            DetalhamentoManager.voarParaObjeto(obj);
        }

	   /**
	    * Voa para um item que está dentro de um detalhamento 
	    *
	    * @method voarParaSubItem
		*        
	    * @param obj {Object} Poi 
		*               
	    */
        function voarParaSubItem(obj) {
            DetalhamentoManager.voarParaSubItem($scope.data, obj);
        }

	   /**
	    * Fecha o detalhamento
	    *
	    * @method fechar
		*        
	    * 
		*               
	    */
        function fechar() {
            DetalhamentoManager.fechar();
        }

	   /**
	    * Busca os pois que estão próximos de um ponto de interesse
	    *
	    * @method pegarPois
		*        
	    * @param ponto {Object} Poi
	    * @param id {Integer} Poi  
		*               
	    */
        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);
                    });

                    DetalhamentoManager.poisProximos = poisProximos;

                    $scope.poisProximos = poisProximos;

                }, function () {
                });
        }

	   /**
	    * Salva as alterações feitas na Rota
	    *
	    * @method save
		*        
	    */
        $scope.save = function () {

            $scope.data.inicio = moment($scope.data.formatDtinicio, 'DD/MM - HH:mm').format();
            $scope.data.fim = moment($scope.data.formatDtfim, 'DD/MM - HH:mm').format();

            RotasOlimpicasService.detalhamentoUpdate($scope.data).then(function (resp) {

                $scope.data.inicio = moment(resp.inicio).format('DD/MM/YYYY HH:mm');
                $scope.data.fim = moment(resp.fim).format('DD/MM/YYYY HH:mm');
            });
        };

	   /**
	    * Voa para o Incidente e atualiza as informações dele
	    *
	    * @method selecionarIncidente
		*
		* @param incidente {Object} Incidente        
	    */
        function selecionarIncidente(incidente) {

            CamadasService.reloadIncidentes(true);
            DetalhamentoManager.voarParaObjeto(incidente);

        }

	   /**
	    * Voa para a camara e atualiza as informações dela
	    *
	    * @method selecionarCamera
		*
		* @param camera {Object} Camera        
	    */
        function selecionarCamera(camera) {

            CamadasService.ativarMenuDaCamera(camera);
            DetalhamentoManager.voarParaObjeto(camera);
        }

	   /**
	    * Marca a rota como ativa
	    *
	    * @method selecionarRota
		*
		* @param rota {Object} Rota        
	    */
        function selecionarRota(rota) {

            RotasOlimpicas.setActive(rota);
        }

	   /**
	    * Abre as cameras no mosaico de camera
	    *
	    * @method abrirCamerasMosaico
		*
		* @param cameras {Object} 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');
        }


	   /**
	    * Abre o detalhamento da rota e busca os pontos próximos a ela
	    *
	    * @method abrir
		*
		* @param rota {Object} Rota        
	    */
        function abrir(rota) {

            $scope.data = rota;
            $scope.data.inicio = moment(rota.inicio).format('DD/MM/YYYY HH:mm');
            $scope.data.fim = moment(rota.fim).format('DD/MM/YYYY HH:mm');

            RotasOlimpicasService.pegarIncidentesProximos(rota.id)
                .then(function (incidentes) {

                    $scope.data.incidentes = incidentes;
                });

            RotasOlimpicasService.pegarCamerasProximas(rota.id)
                .then(function (cameras) {

                    $scope.data.cameras = cameras;
                });

            RotasOlimpicasService.pegarRotasProximas(rota.id)
                .then(function (rotas) {

                    $scope.data.rotas = rotas;
                });
        }

        angular.extend($scope, {
            apiRotasOlimpicas: {
                abrir: abrir,
                selecionarIncidente: selecionarIncidente,
                selecionarCamera: selecionarCamera,
                selecionarRota: selecionarRota,
                abrirCamerasMosaico: abrirCamerasMosaico
            }
        });

        MainState.registerDirective('detalhamentoRotasOlimpicas', $scope.apiRotasOlimpicas);

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

    function s4cDetalhamentoRotasOlimpicas() {
        return {
            restrict: 'E',
            replace: true,
            scope: {},
            templateUrl: 'app/directives/detalhamento_rotas_olimpicas/detalhamento_rotas.html',
            controller: detalhamentoRotasOlimpicasCtrl
        };
    }

    /**
     * @ngdoc overview
     * @name s4c.components.detalhamento
     */
    angular.module('s4c.components.detalhamentoRotasOlimpicas', [])
        .directive('s4cDetalhamentoRotasOlimpicas', s4cDetalhamentoRotasOlimpicas);
}());