Source: directives/poi/poi.js

/**
 * @ngdoc directives
 * @name Poi
 * @module s4c.directives.poi.Poi
 *
 * @description
 * 'Poi' Exibe os principais pois cadastrados no S4C
 *
 * @example  <s4c-poi></s4c-poi>
 * 
 */
(function () {
    'use strict';

    poiCtrl.$inject = [
        '$scope',
        'PermissoesService',
        'CommService',
        'Menu',
        'CamadasService',
        '$http',
        'API_ENDPOINT',
        'RepresentacaoService',
        '$timeout',
        'MapaService',
        'Preset',
        'MainState',
        'DetalhamentoManager',
        '$mdDialog'
    ];

    function poiCtrl($scope, PermissoesService, CommService, Menu, CamadasService, $http,
        API_ENDPOINT, RepresentacaoService, $timeout, MapaService, Preset, MainState, DetalhamentoManager, $mdDialog) {

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

        $scope.categorias = [];
        $scope.categoriasCopy = [];
        $scope.categorias.unshift({ id: '', nome: $scope.res('COMUM_TODOS') });

        $scope.res = $scope.$root.res;
        $scope.nameToSearch = '';
        $scope.pageNumber = 0;
        $scope.pois = [];
        $scope.selectedCategories = [];

        $scope.moduloPoi = undefined;
        $scope.presetId = undefined;
        $scope.loading = false;

        /**
         * @method carregarConfiguracao
         */
        function carregarConfiguracao() {

            var modulos = Preset.obter().PresetModulos;
            $scope.presetId = Preset.obter().id;

            for (var index in modulos) {
                if ((modulos[index].name == $scope.res('PONTOSDEINTERESSE_TITULO') || (modulos[index].Face
                    && modulos[index].Face.name == 'PONTOSDEINTERESSE_TITULO')) && !modulos[index].usado) {

                    modulos[index].usado = true;
                    $scope.moduloPoi = modulos[index];

                    //Marcar na árvore as categorias e executar a busca de pois
                    if ($scope.moduloPoi.extras) {

                        $scope.loading = true;
                        $scope.ordenacao = $scope.moduloPoi.extras.ordenacao || 'nome';
                        $scope.nameToSearch = $scope.moduloPoi.extras.nome;
                        $scope.nome = $scope.moduloPoi.extras.nome;
                        if ($scope.moduloPoi.extras.fields) {
                            $scope.fields = angular.copy($scope.moduloPoi.extras.fields);
                        }

                        var ok = markCategories();
                        if(ok){
                            $scope.applyFilter();
                        }
                        return true;
                    }

                    break;
                }
            }
        }

        /**
         * @method markCategories
         */
        function markCategories() {

            $scope.selectedCategories = [];
            $scope.categorias = [];
            $scope.categorias.unshift({ id: '', nome: $scope.res('COMUM_TODOS') });

            if ($scope.gruposPois) {
                for (var index in $scope.gruposPois) {
                    selectNode($scope.gruposPois[index]);
                }

                $scope.savedCategories = angular.copy($scope.selectedCategories);
                return true;
            } else {
                Menu.obter()
                .then(function (menus) {

                    var _grupos = [];

                    for (var index in menus) {
                        if (menus[index].subMenus != null && menus[index].subMenus.length > 0
                            && !menus[index].texto.includes("0") && !menus[index].texto.includes("COMUM_OPERACAO")) {
                            _grupos.push(_.cloneDeep(menus[index]));
                        }
                    }

                    $scope.gruposPois = _.each(_grupos, function (menu) {
                        menu.subMenus = _.sortBy(menu.subMenus, 'texto');
                    });

                    for (var index in $scope.gruposPois) {
                        selectNode($scope.gruposPois[index]);
                    }

                    $scope.savedCategories = angular.copy($scope.selectedCategories);
                    $scope.applyFilter();

                });
            }
        }

        /**
         * @method getCategoryName
         * @param {*} categoria
         */
        $scope.getCategoryName = function (categoria) {

            var count = 0;
            var nome;

            for (var index1 in $scope.categorias) {
                if (index1 != 0 && $scope.categorias[index1].nome == categoria.nome) {

                    count++;
                    if (categoria.categoriaId == $scope.categorias[index1].categoriaId) {
                        nome = $scope.categorias[index1].nome + ' (' + $scope.categorias[index1].acervoNome + ')';
                    }
                }
            }

            if (count > 1) {
                return nome;
            }

            return categoria.nome;
        }

        /**
         * @method selectNode
         * @param {*} node 
         */
        function selectNode(node) {

            if ((!node.subMenus || node.subMenus.length == 0) && containsCategory(node)) {
                $scope.selectedCategories.push(node.categoriaId);
                $scope.categorias.push({ nome: node.texto, categoriaId: node.categoriaId, acervoNome: node.parentNode ? node.parentNode.texto : '' });
                node.ativo = true;
                return;
            }

            if (!node.subMenus || node.subMenus.length == 0) {
                return;
            }

            for (var index in node.subMenus) {
                selectNode(node.subMenus[index]);
            }

            if (allSelected(node)) {
                node.ativo = true;
            }
        }

        /**
         * @method allSelected
         * @param {*} node 
         */
        function allSelected(node) {

            if (!node.subMenus || node.subMenus.length == 0) {
                return false;
            }

            for (var index in node.subMenus) {
                if (!node.subMenus[index].ativo) {
                    return false;
                }
            }

            return true;
        }

        /**
         * @method deselectAllGroups
         * @param {*} node 
         */
        function deselectAllGroups(node) {
            node.ativo = false;

            if (!node.subMenus || node.subMenus.length == 0) {
                return false;
            }

            for (var index in node.subMenus) {
                deselectAllGroups(node.subMenus[index]);
            }
        }

        /**
         * @method containsCategory
         * @param {*} node 
         */
        function containsCategory(node) {

            if (!$scope.moduloPoi.extras) {
                return false;
            }

            for (var index in $scope.moduloPoi.extras.categorias) {
                if ($scope.moduloPoi.extras.categorias[index] == node.id) {
                    return true;
                }
            }

            return false;
        }

        $scope.ordenacao = 'nome';
        /**
         * @method selecionarOrdem
         * @param {*} ordenacao 
         */
        function selecionarOrdem(ordenacao) {
            $scope.ordenacao = ordenacao.field;
        }

        $scope.hasResults = true;
        /**
         * @method applyFilter
         */
        $scope.applyFilter = function () {
            $scope.filtroAtivo = false;

            if ($scope.selectedCategories && $scope.selectedCategories.length == 0) {
                $scope.cancelado = true;
            }

            if (!$scope.moduloPoi || !$scope.moduloPoi.id) {
                if (carregarConfiguracao()) {
                    return;
                }
            }

            $scope.selectedCategories = _.filter($scope.selectedCategories, function (category) {
                return category != null;
            });

            if (!$scope.moduloPoi.extras) {
                $scope.moduloPoi.extras = {};
            }

            $scope.moduloPoi.extras.categorias = angular.copy($scope.selectedCategories);
            $scope.moduloPoi.extras.fields = angular.copy($scope.fields);
            $scope.presetId = Preset.obter().id;

            $http.post(API_ENDPOINT + 'pois/categorias/simple', {

                nome: $scope.nameToSearch,
                categorias: $scope.selectedCategories,
                pageNumber: $scope.pageNumber,
                ordenacao: $scope.ordenacao.field || $scope.ordenacao,
                moduloId: $scope.moduloPoi.id,
                presetId: $scope.presetId,
                fields: _.filter($scope.fields, function (field) {
                    return field.active == true;
                })

            }).then(function (result) {

                $scope.loading = false;
                if (!result || !result.data || result.data.pois.length == 0) {
                    $scope.hasResults = false;
                }

                $scope.pois = $scope.pois.concat(result.data.pois);
                $scope.pois.representacoes = result.data.representacoes;

                for (var index in $scope.pois) {
                    if ($scope.pois[index] != null && $scope.pois[index].extras != null) {
                        for (var index2 in $scope.pois[index].extras.informacoes) {
                            if (!containsExtra($scope.pois[index].extras.informacoes[index2]) && $scope.pois[index].extras.informacoes[index2].tipo != "INVISIVEL" && $scope.pois[index].extras.informacoes[index2].tipo != "INDICADOR") {
                                var column = {
                                    active: true,
                                    name: $scope.pois[index].extras.informacoes[index2].label,
                                    field: $scope.pois[index].extras.informacoes[index2].label,
                                    width: 250,
                                    enableColumnMenu: false,
                                    headerCellClass: 'tableHeader',
                                    cellClass: 'tableRow',
                                    tipo: 'extra'
                                }
                                $scope.fields.push(column);
                                $scope.moduloPoi.extras.fields.push(column);
                            }
                        }
                    }
                }

                //Jamais remova esta linha. Necessária para carregar a tabela e já filtrar por abas.
                updateModule();
                Preset.salvar();

            }, function (err) {

            });
        }

        /**
         * @method camadas
         * @param {*} poi
         */
        CommService.on('camadas', function (poi) {

            if (poi.poisUpdate == 'remove') {
                $scope.pois = _.filter($scope.pois, function (p) {
                    return p.id != poi.pois[0].id;
                });

                updateModule();
                return;
            }

            var hasPoi = false;
            for (var index in $scope.pois) {
                if ($scope.pois[index].id == poi.pois[0].id) {

                    $scope.pois[index].nome = poi.pois[0].nome;
                    $scope.pois[index].geometry = poi.pois[0].geometry;
                    $scope.pois[index].extras = poi.pois[0].extras;
                    $scope.pois[index].latitude = poi.pois[0].latitude;
                    $scope.pois[index].longitude = poi.pois[0].longitude;

                    if ($scope.pois[index].extras) {
                        for (var index2 in $scope.pois[index].extras.informacoes) {
                            if (!containsExtra($scope.pois[index].extras.informacoes[index2]) && $scope.pois[index].extras.informacoes[index2].tipo != "INVISIVEL" && $scope.pois[index].extras.informacoes[index2].tipo != "INDICADOR") {
                                var column = {
                                    active: true,
                                    name: $scope.pois[index].extras.informacoes[index2].label,
                                    field: $scope.pois[index].extras.informacoes[index2].label,
                                    width: 150,
                                    enableColumnMenu: false,
                                    headerCellClass: 'tableHeader',
                                    cellClass: 'tableRow',
                                    tipo: 'extra'
                                }
                                $scope.fields.push(column);
                                $scope.moduloPoi.extras.fields.push(column);
                            }
                        }
                    }

                    hasPoi = true;
                    break;
                }
            }

            if (!hasPoi && hasCategory(poi.CategoriumId || poi.categoriaId || poi.pois[0].CategoriumId) && $scope.nameToSearch.length == 0 && !hasSearched) {

                $scope.pois.push(poi.pois[0]);
                if (poi.pois[0].extras) {
                    for (var index2 in poi.pois[0].extras.informacoes) {
                        if (!containsExtra(poi.pois[0].extras.informacoes[index2]) && poi.pois[0].extras.informacoes[index2].tipo != "INVISIVEL" && poi.pois[0].extras.informacoes[index2].tipo != "INDICADOR") {
                            var column = {
                                active: true,
                                name: poi.pois[0].extras.informacoes[index2].label,
                                field: poi.pois[0].extras.informacoes[index2].label,
                                width: 150,
                                enableColumnMenu: false,
                                headerCellClass: 'tableHeader',
                                cellClass: 'tableRow',
                                tipo: 'extra'
                            }
                            $scope.fields.push(column);
                            $scope.moduloPoi.extras.fields.push(column);
                        }
                    }
                }
            }

            updateModule();
        });

        /**
         * @method hasCategory
         * @param {*} categoriaId 
         */
        function hasCategory(categoriaId) {

            for (var index in $scope.categorias) {
                if ($scope.categorias[index].categoriaId == categoriaId) {
                    return true;
                }
            }

            return false;
        }

        /**
         * @method containsExtra
         * @param {*} extra 
         */
        function containsExtra(extra) {

            for (var index in $scope.fields) {
                if ($scope.fields[index].name == extra.label) {
                    return true;
                }
            }

            return false;
        }

        /**
         * @method filterPois
         */
        $scope.filterPois = function (isCategory) {

            $scope.pageNumber = 0;
            $scope.pois = [];
            $scope.hasResults = true;
            maxVerticalScroll = 0;
            $scope.applyFilter();
            $scope.savedCategories = angular.copy($scope.selectedCategories);
        }

        /**
         * @method clearAndApplyFilter
         */
        $scope.clearAndApplyFilter = function () {
            $scope.pageNumber++;
            $scope.applyFilter();
        }

        /**
         * @method updateModule
         */
        function updateModule() {

            for (var index in $scope.fields) {
                if ($scope.moduloPoi.extras && $scope.fields[index].field == $scope.moduloPoi.extras.ordenacao && !$scope.ordenacao.field) {
                    $scope.ordenacao = $scope.fields[index];
                    break;
                }
            }

            if (!$scope.ordenacao) {
                $scope.ordenacao = 'nome';
            }

            loadTable($scope.pois);
            $scope.toggleFieldSelection();
            $scope.searchTable($scope.moduleFilter);
        }

        $scope.nome;
        var hasSearched = false;
        /**
         * @method searchByField
         * @param {*} nome
         */
        $scope.searchByField = function (nome) {
            $scope.nameToSearch = nome;

            if (nome && nome.length > 0) {
                hasSearched = true;
            } else {
                hasSearched = false;
            }

            $scope.filterPois(false);
        }

        /**
         * @method searchTable
         * @param {*} filter
         */
        $scope.searchTable = function (filter) {

            if ($scope.pois.length == 0) {
                return;
            }

            var poisFiltered = _.filter($scope.pois, function (poi) {

                if (!poi) {
                    return false;
                }
                return (poi.CategoriumId == filter.categoriaId || filter.categoriaId == '');
            });

            poisFiltered = _.map(poisFiltered, function (poi) {
                return parseToGrid(poi);
            });

            $scope.poisGrid.data = poisFiltered;
        };

        $scope.savedFilter = {};
        /**
         * @method searchByTab
         * @param {*} filter
         */
        $scope.searchByTab = function (filter) {

            $scope.pageNumber = 0;
            $scope.hasResults = true;
            $scope.pois = [];
            $scope.savedFilter = filter;
            if (filter.categoriaId == '') {

                $scope.selectedCategories = angular.copy($scope.savedCategories);
                $scope.applyFilter();
                return;
            }

            $scope.selectedCategories = [];
            $scope.selectedCategories.push(filter.categoriaId);
            $scope.applyFilter();
        };


        $scope.cancelado = true;
        /**
         * @method cancelFilter
         */
        $scope.cancelFilter = function () {

            for (var index in $scope.gruposPois) {
                deselectAllGroups($scope.gruposPois[index]);
            }

            markCategories();
            $scope.$digest;

            $timeout(function () {
                $scope.cancelado = true;
                $scope.filtroAtivo = false;
            }, 200);
        }

        $scope.filtroAtivo = false;
        /**
         * @method activateFilter
         */
        $scope.activateFilter = function () {
            $scope.filtroAtivo = true;
            $scope.cancelado = false;
        }

        /**
         * @method isIndeterminate
         * @param {*} node 
         */
        function isIndeterminate(node) {
            return CamadasService.isIndeterminate(node);
        }

        /**
         * @method toggleMenu
         * @param {*} node 
         */
        function toggleMenu(node) {
            node.ativo = !node.ativo;

            if (node.ativo) {
                if (!node.subMenus || node.subMenus.length == 0) {
                    $scope.selectedCategories.push(node.categoriaId);
                    $scope.categorias.push({ nome: node.texto, categoriaId: node.categoriaId });
                    return;
                }

                addCategories(node);
            }

            deselectAll(node);
        }

        $scope.expanded = false;
        /**
         * @method expandCollapse
         */
        $scope.expandCollapse = function () {
            $scope.expanded = !$scope.expanded;

            if ($scope.expanded) {
                angular.element(document.getElementById("tree-root")).scope().expandAll();
            } else {
                angular.element(document.getElementById("tree-root")).scope().collapseAll();
            }
        }

        /**
         * @method deselectAll
         * @param {*} node 
         */
        function deselectAll(node) {

            if (!node.ativo && (!node.subMenus || node.subMenus.length == 0)) {
                $scope.selectedCategories = _.filter($scope.selectedCategories, function (catId) {
                    return catId != node.categoriaId;
                });

                $scope.categorias = _.filter($scope.categorias, function (cat) {
                    return cat.categoriaId != node.categoriaId || cat.id == '';
                });
            }

            _.each(node.subMenus, function (subMenu) {

                subMenu.ativo = node.ativo;
                if (subMenu.subMenus && subMenu.subMenus.length > 0) {
                    deselectAll(subMenu);
                } else {

                    if (!subMenu.ativo) {
                        $scope.selectedCategories = _.filter($scope.selectedCategories, function (catId) {
                            return catId != subMenu.categoriaId;
                        });

                        $scope.categorias = _.filter($scope.categorias, function (cat) {
                            return cat.categoriaId != subMenu.categoriaId || cat.id == '';
                        });
                    }
                }
            });
        }

        /**
         * @method addCategories
         * @param {*} node 
         */
        function addCategories(node) {

            _.each(node.subMenus, function (subMenu) {

                if ((!subMenu.subMenus || subMenu.subMenus.length == 0) && subMenu.categoriaId) {
                    $scope.selectedCategories.push(subMenu.categoriaId);
                    $scope.categorias.push({ nome: subMenu.texto, categoriaId: subMenu.categoriaId, acervoNome: subMenu.parentNode ? subMenu.parentNode.texto : '' });
                } else {

                    if (subMenu.subMenus && subMenu.subMenus.length > 0) {
                        addCategories(subMenu);
                    }
                }
            });
        }

        /**
         * @method isChecked
         * @param {*} node 
         */
        function isChecked(node) {
            return node.ativo;
        }

        $scope.gruposPois;
        /**
         * @method loadCategoriesTree
         */
        function loadCategoriesTree() {

            Menu.obter()
                .then(function (menus) {

                    var _grupos = [];

                    for (var index in menus) {
                        if (menus[index].subMenus != null && menus[index].subMenus.length > 0
                            && !menus[index].texto.includes("0") && !menus[index].texto.includes("COMUM_OPERACAO")) {
                            _grupos.push(_.cloneDeep(menus[index]));
                        }
                    }

                    $scope.gruposPois = _.each(_grupos, function (menu) {
                        menu.subMenus = _.sortBy(menu.subMenus, 'texto');
                    });

                    carregarConfiguracao();

                });
        }

        $scope.poisGrid = [];
        $scope.moduleFilter = {
            categoriaId: ''
        };
        var dateFormat = 'DD/MM/YYYY - HH:mm';
        $scope.fields = [
            {
                active: true,
                pinnedLeft: true,
                enableFiltering: false,
                name: '',
                field: 'statusIcon',
                width: 40,
                headerCellClass: 'tableHeader',
                enableColumnMenu: false,
                cellClass: 'tableRow',
                headerCellTemplate: '<md-icon md-svg-icon="settings:engine" class="settings" ng-click="grid.appScope.toggleFieldSelection()"></md-icon>',
                cellTemplate: '<img ng-src="{{grid.appScope.setIconUrl(row)}}" ng-click="grid.appScope.openDetalhamentoFromRow(row)" width="18" height="18" style="margin-left: 4px; margin-top: 6px;"/>'
            }, {
                active: true,
                name: $scope.res('COMUM_NOME'),
                field: 'nome',
                enableColumnMenu: false,
                width: 250,
                headerCellClass: 'tableHeader',
                cellClass: 'tableRow'
            }, {
                active: false,
                name: $scope.res('COMUM_CATEGORIA'),
                field: 'CategoriaNome',
                width: 150,
                enableColumnMenu: false,
                headerCellClass: 'tableHeader',
                cellClass: 'tableRow'
            }
        ];
        $scope.ordenacao = $scope.fields[1];

        /**
         * @method openDetalhamentoFromRow
         * @param {*} row
         */
        $scope.openDetalhamentoFromRow = function (row) {

            if (!row.entity) {
                return;
            }

            var poi = row.entity;
            $scope.abrirDetalhamento(poi);
        };

        /**
         * @method abrirDetalhamento
         * @param {*} poi
         */
        $scope.abrirDetalhamento = function (poi) {
            DetalhamentoManager.abrirPoi(poi.id, {
                lat: poi.geometry.coordinates[1],
                lng: poi.geometry.coordinates[0]
            });
        };

        /**
         * @method setIconUrl
         * @param {*} row
         */
        $scope.setIconUrl = function (row) {

            if (!row.entity) {
                return;
            }

            var poi = row.entity;
            poi.properties = { extras: poi.extras };

            if (poi.geometry && poi.geometry.geometry) {
                poi.geometry = poi.geometry.geometry;
            }

            if (!$scope.pois.representacoes || !$scope.pois.representacoes[poi.CategoriumId] ||
                !$scope.pois.representacoes[poi.CategoriumId].json || (poi.geometry && poi.geometry.type != 'Point')) {
                return '/assets/images/ic_geometria.svg';
            }

            var result = RepresentacaoService.getFunctionResult(poi, $scope.pois.representacoes[poi.CategoriumId].json.pointLayout[0].circulo.centro.funcao);
            if (result) {
                if (row.entity.urlIcone != result) {
                    row.entity.urlIcone = result;
                    CamadasService.getInstance('camadas-service').trigger('reloadPoi', poi);
                }

                if ($scope.pois.representacoes[poi.CategoriumId].json.pointLayout[0].circulo.centro.tipo == 'icon') {
                    return result;
                }

            }

            return '/assets/images/ic_geometria.svg';
        };

        $scope.fieldSelection = false;
        /**
         * @method toggleFieldSelection
         */
        $scope.toggleFieldSelection = function () {
            $scope.poisGrid.columnDefs = $scope.fields.filter(function (column) {
                return column.active === true;
            });
            $scope.fieldSelection = !$scope.fieldSelection;
        };

        /**
         * @method loadTable
         * @param {*} pois 
         */
        function loadTable(pois) {
            var parsedPois = _.map(pois, function (poi) {
                return parseToGrid(poi);
            });

            $scope.poisGrid.data = parsedPois;

            /*
             * When Row of Table is clicked, rowSelectionChanged is invoked
            */
            if ($scope.gridApi) {
                $scope.gridApi.selection.on.rowSelectionChanged(null, function (row) {
                    $scope.voarPoi(row.entity);
                });

                resizeTable();
            }

            $scope.toggleFieldSelection();
        }

        // Watch the Module Size
        /**
         * @method $watch
         */
        $scope.$watch(
            function () {
                if (angular.element('#modulo-poi')[0] != null) {
                    return angular.element('#modulo-poi')[0].offsetHeight
                }
            },
            function (value) {
                resizeTable();
                resizeFilter();
            }
        );


        /**
         * @method resizeTable
         */
        function resizeTable() {
            if ($scope.gridApi) {

                if (angular.element('#modulo-poi')[0] && angular.element('.poi-tabs')[0]) {
                    var gridSize = $scope.gridApi.grid.gridHeight;
                    var moduleHeight = angular.element('#modulo-poi')[0].clientHeight;
                    var tabsHeight = angular.element('.poi-tabs')[0].clientHeight;

                    var gridHeight = moduleHeight - tabsHeight - 60;
                    $scope.uiGridHeight = { height: gridHeight + 'px' };
                    $scope.uiFilterHeight = { height: (gridHeight - 56) + 'px' };
                }
            }
        }

        resizeFilter();

        /**
         * @method resizeFilter
         */
        function resizeFilter() {

            if (angular.element('#modulo-poi')[0] && angular.element(document.querySelector('#poi-tree'))[0]) {
                var moduleHeight = angular.element('#modulo-poi')[0].clientHeight;
                var treeHeight = angular.element(document.querySelector('#poi-tree'))[0].clientHeight;

                $scope.uiTreeHeight = { height: (moduleHeight - 110) + 'px' };
            }
        }

        /**
         * @method filterTab
         * @param {*} categoria
         */
        $scope.filterTab = function (categoria) {
            $scope.moduleFilter.categoriaId = (categoria.nome === $scope.res('COMUM_TODOS')) ? '' : categoria.categoriaId;
            $scope.searchByTab($scope.moduleFilter);
        };

        $scope.poisGrid = {
            enableRowSelection: true,
            enableRowHeaderSelection: false,
            multiSelect: false,
            flatEntityAccess: true,
            fastWatch: true,
            noUnselect: true,
            enableSorting: false,
            columnDefs: $scope.fields
        };

        $scope.poisGrid.onRegisterApi = function (gridApi) {
            $scope.gridApi = gridApi;
        };


        /**
         * Cuidado ao mexer neste código.
         */
        var maxVerticalScroll = 0;
        var lastMaxVerticalScroll = 1;
        $timeout(function () {

            $('#poi-rows div.ui-grid-viewport').on('scroll', function (evt) {

                maxVerticalScroll = $('#poi-rows div.ui-grid-viewport')[0].scrollHeight - $('#poi-rows div.ui-grid-viewport')[0].clientHeight;
                var currentVerticalScroll = $('#poi-rows div.ui-grid-viewport').scrollTop();

                if (maxVerticalScroll > 0 && currentVerticalScroll >= (maxVerticalScroll - 12) && $scope.hasResults && lastMaxVerticalScroll != maxVerticalScroll) {
                    $scope.pageNumber = $scope.pageNumber + 1;
                    $scope.applyFilter();
                    lastMaxVerticalScroll = maxVerticalScroll;
                }
            });
        });

        /**
         * @method parseToGrid
         * @param {*} poi 
         */
        function parseToGrid(poi) {

            if (poi != null) {
                if (poi.CategoriumId) {
                    poi.CategoriaNome = getCategoriaNome(poi);
                }

                if (poi.extras) {
                    for (var index in poi.extras.informacoes) {

                        if (poi.extras.informacoes[index].tipo != 'HTML') {
                            poi[poi.extras.informacoes[index].label] = poi.extras.informacoes[index].valor;
                        } else {
                            poi[poi.extras.informacoes[index].label] = 'HTML';
                        }
                    }
                }
            }

            return poi;
        }

        /**
         * @method getCategoriaNome
         * @param {*} poi 
         */
        function getCategoriaNome(poi) {

            for (var index in $scope.categorias) {
                if ($scope.categorias[index].categoriaId == poi.CategoriumId) {
                    return $scope.categorias[index].nome;
                }
            }

            return '';
        }

        var lastPoi;
        /**
         * @method voarPoi
         */
        $scope.voarPoi = function (poi) {

            if (poi == lastPoi) {
                return;
            }

            lastPoi = poi;

            var ponto;
            if (!poi.geometry || poi.geometry.type === 'Point' || (poi.geometry.type != 'Point' && poi.latitude && poi.longitude)) {

                if (poi.latitude && poi.longitude) {
                    ponto = {
                        lat: poi.latitude,
                        lng: poi.longitude
                    };
                } else {
                    ponto = {
                        lat: poi.geometry.coordinates[1],
                        lng: poi.geometry.coordinates[0]
                    };
                }
            } else {
                ponto = {
                    lat: turf.centroid(poi.geometry).geometry.coordinates[1],
                    lng: turf.centroid(poi.geometry).geometry.coordinates[0]
                };
            }

            MapaService.piscarAzul(ponto);
            MapaService.setView(ponto, 18);
            CamadasService.ativarMenuPoi(poi);
            DetalhamentoManager.resetarDetalhamento();
        };

        /**
         * @method reloadPois
         */
        function reloadPois() {
            $scope.filterPois(false);
        }

        /**
         * @method exportarExcel
         */
        $scope.exportarExcel = function () {
            var data = {};
            $http.post(API_ENDPOINT + 'pois/categorias/simpleSemPaginacao', {
                nome: $scope.nameToSearch,
                categorias: $scope.selectedCategories,
                ordenacao: $scope.ordenacao.field || $scope.ordenacao,
                moduloId: $scope.moduloPoi.id,
                presetId: $scope.presetId,
                fields: _.filter($scope.fields, function (field) {
                    return field.active == true;
                })

            }).then(function (result) {
                data.pois = result.data.pois;
                if (data.pois.length) {
                    data.headers = [$scope.res('COMUM_NOME')];
                    $http
                        .post(API_ENDPOINT + 'pois/excel/downloadSelectedPoisFromExcel', data, { responseType: 'arraybuffer', })
                        .then(function (res) {

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

                            var file = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
                            var fileURL = URL.createObjectURL(file);

                            a.href = fileURL;
                            a.download = $scope.res('Pois') + ".xlsx";
                            a.click();

                            $mdDialog
                                .show($mdDialog.alert()
                                    .title($scope.res('COMUM_SUCESSO'))
                                    .content('Arquivo gerado com sucesso.')
                                    .ok($scope.res('COMUM_OK')));
                        }, function (err) {
                            console.log(err);
                        });

                } else {
                    $mdDialog
                        .show($mdDialog.alert()
                            .title($scope.res('COMUM_AVISO'))
                            .content($scope.res('SEM_INCIDENTES'))
                            .ok('OK'));
                }
            }, function (err) {

            });
        }

        loadCategoriesTree();

        $scope.$apipoi = { reloadPois: reloadPois };

        angular.extend($scope, {

            toggleMenu: toggleMenu,
            isIndeterminate: isIndeterminate,
            isChecked: isChecked,
            treeOptions: {
                nodeChildren: 'subMenus'
            }
        });

        if (MainState.getDirective('moduloPoi')) {
            MainState.unregisterDirective('moduloPoi');
        }
        MainState.registerDirective('moduloPoi', $scope.$apipoi);

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

    function s4cPoi() {

        return {
            restrict: 'EA',
            templateUrl: 'app/directives/poi/poi.html',
            controller: poiCtrl
        };
    }

    angular.module('s4c.components.poi', ['ui.tree']).directive('s4cPoi', s4cPoi);

})();