Source: directives/zonas-de-observacao/zonas-de-observacao.js

/**
 * @ngdoc directives
 * @name ZonasDeObservacao
 * @module s4c.directives.zonasDeObservacao.ZonasDeObservacao
 *
 * @description
 * `ZonasDeObservacao` Controller do módulo de Zonas De Observacao
 * 
 * 
 */
(function () {
    'use strict';

    angular.module('s4c.components.zonas-de-observacao')
        .directive('zonasDeObservacao', ZonasDeObservacao);

    ZonasDeObservacaoCtrl.$inject = [
        '$scope',
        '$filter',
        '$anchorScroll',
        'ngTableParams',
        'ZonasDeObservacaoService',
        'ZonasDeObservacaoFilter',
        'MainState',
        'CommService',
        'CamadasService',
        'DetalhamentoManager',
        'ZonaDeObservacaoManager',
        'AuthService',
        'localize',
        'PermissoesService',
        'MapaService'
    ];

    function ZonasDeObservacao() {
        return {
            restrict: 'EA',
            templateUrl: 'app/directives/zonas-de-observacao/zonas-de-observacao.html',
            scope: {},
            replace: true,
            controller: ZonasDeObservacaoCtrl,
            link: function ($scope, $elem, $attrs) {
                $scope.zonas = [];
            }
        };
    }

    function ZonasDeObservacaoCtrl(
        $scope,
        $filter,
        $anchorScroll,
        ngTableParams,
        ZonasDeObservacaoService,
        ZonasDeObservacaoFilter,
        MainState,
        CommService,
        CamadasService,
        DetalhamentoManager,
        ZonaDeObservacaoManager,
        AuthService,
        localize,
        PermissoesService,
        MapaService
    ) {

        CommService.on('newDocuments', function (document) {
            if (document.tipo === "zona_observacao") {
                if (!!MainState.getDirective('zonasDeObservacao')) {
                    loadZonas();
                }
            }
        });

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

        $scope.filterDefault = { timeWindow: _timeSet() };
        $scope.filterDataRange = _getFilterDataRange();

        $scope.res = $scope.$root.res;
        $scope.me = AuthService.user.info;

        $scope.zonas = [];
        $scope.allSelected = false;
        ZonasDeObservacaoFilter.getInstance('zonas-de-observacao-filter').on('filterChanged', loadZonas);
        ZonasDeObservacaoFilter.getInstance('zonas-de-observacao-filter').on('filterChangedZona', loadSavedZona);
        ZonasDeObservacaoFilter.getInstance('zonas-de-observacao-filter').on('removedZonaObs', removedZonaObs);
        ZonasDeObservacaoFilter.getInstance('zonas-de-observacao-filter').on('reloadZonaObs', reloadZonaObs);

        $scope.hasPermission = function () {
            return $scope.permissoesVisualizacao.zonaObservacaoPublica;
        }

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

            if (!$scope.hasPermission()) {
                return;
            }

            ZonasDeObservacaoService.obterZonas()
                .then(function (zonas) {
                    $scope.zonas = zonas;
                    loadZonas();
                });
        }

        /**
         * @method $watch
         * @param {*} zonas
         */
        $scope.$watch('zonas', function (zonas) {
            var activeZonas = _getActiveZonas(zonas);

            _filtrarZonas(activeZonas);
        }, true);


        /**
         * @method toggleCheckboxes
         * @param {*} data
         */
        $scope.toggleCheckboxes = function (data) {
            $scope.allSelected = !$scope.allSelected;

            if ($scope.allSelected) {
                _checkAll(data);
            } else {
                _uncheckAll(data);
            }
        }

        /**
         * @method _filtrarZonas
         * @param {*} zonas 
         */
        function _filtrarZonas(zonas) {
            ZonasDeObservacaoService.filtrarZonas(zonas);
        }

        /**
         * @method _uncheckAll
         * @param {*} data 
         */
        function _uncheckAll(data) {
            var data = data || $scope.zonas;

            data.map(function (zona) {
                zona.active = false;
            });
        }

        /**
         * @method _checkAll
         * @param {*} data 
         */
        function _checkAll(data) {
            var data = data || $scope.zonas;

            data.map(function (zona) {
                zona.active = true;
            });
        }

        /**
         * @method reloadZonaObs
         */
        function reloadZonaObs() {
            loadZonas();
        }

        /**
         * @method removedZonaObs
         * @param {*} data 
         */
        function removedZonaObs(data) {
            var zonasArray = [];
            _.each($scope.zonas, function (zona) {
                if (zona.id != data.id) {
                    zonasArray.push(zona);
                }
            });
            $scope.zonas = zonasArray;
            loadZonas();
        }

        /**
         * @method loadSavedZona
         * @param {*} data 
         */
        function loadSavedZona(data) {
            var userIsParticipante = isParticipante(data);
            if (userIsParticipante) {
                var zonasArray = [];

                var zonaNova = _.find($scope.zonas, function (zona) { return zona.id === data.id; });

                _.each($scope.zonas, function (zona) {
                    if (zona.id == data.id) {
                        zonasArray.push(data);
                    } else {
                        zonasArray.push(zona);
                    }
                });
                $scope.zonas = zonasArray;
                if (zonaNova == null) {
                    $scope.zonas.push(data);
                }

                loadZonas();
            } else {
                removedZonaObs(data);
            }
        }

        /**
         * @method isParticipante
         * @param {*} zona
         */
        function isParticipante(zona) {
            var zonaPublica = isPublic(zona);
            var retorno = false; //Foi feito assim para evitar o bug do javascript de não sair do método quando tem um return dentro de um foreach que está danetro de um if 
            if (zonaPublica) {
                retorno = true;
            }

            if (!zona.criador) {
                return true;
            }

            if (zona.criador.id == $scope.me.id) {
                retorno = true;
            }
            if (zona.Usuarios != null) {
                _.each(zona.Usuarios, function (usuario) {
                    if (usuario.id == $scope.me.id) {
                        retorno = true;
                    }
                });
            }
            if (zona.GruposUsuarios != null) {
                _.each(zona.GruposUsuarios, function (grupo) {
                    _.each(grupo.Usuarios, function (usuario) {
                        if (usuario.id == $scope.me.id) {
                            retorno = true;
                        }
                    });
                });
            }
            return retorno;
        }

        /**
         * @method isPublic
         * @param {*} zona 
         */
        function isPublic(zona) {
            if ((zona.Usuarios == null || zona.Usuarios.length == 0) && (zona.GruposUsuarios == null || zona.GruposUsuarios.length == 0)) {
                return true;
            } else {
                return false;
            }
        }


        /**
         * @method verificaMenuCarregado
         */
        function verificaMenuCarregado() {
            setTimeout(function () {
                loadZonas();
            }, 1000);
        }

        /**
         * @method loadZonas
         */
        function loadZonas() {
            if ($scope.hasPermission()) {
                CamadasService.exibirZonasDeObservacao();
            }
        }

        /**
         * @method _getFilterDataRange
         */
        function _getFilterDataRange() {
            return {
                timeWindow: ZonasDeObservacaoFilter.getInstance('zonas-de-observacao-filter').dataRange
            };
        }

        /**
         * @method initFilter
         */
        function initFilter() {
            ZonasDeObservacaoFilter.getInstance('zonas-de-observacao-filter').dataRange = _timeSet();
        }

        /**
         * @method _timeSet
         */
        function _timeSet() {
            return {
                start: moment().subtract(1, 'day').startOf('day').format(),
                end: moment().endOf('day').format()
            }
        };

        /**
         * @method _setQueryTimeWindow
         * @param {*} filterData 
         */
        function _setQueryTimeWindow(filterData) {
            return {
                $between: [
                    filterData.timeWindow.start,
                    filterData.timeWindow.end
                ]
            };
        }

        /**
         * @method _setQueryDepartamentoIds
         */
        function _setQueryDepartamentoIds() {
            var departamentosIds = CamadasService.departamentosAtivosZO();
            return (departamentosIds.length) ? { $in: departamentosIds } : null;
        }

        /**
         * @method setQuery
         */
        function setQuery() {
            var data = {};
            var filterData = _getFilterDataRange();
            data.inicio = _setQueryTimeWindow(filterData);
            data.DepartamentoIds = _setQueryDepartamentoIds();
            return {
                where: data
            };
        }

        /**
         * @method _filterZonas
         * @param {*} zonas 
         * @param {*} filterData 
         */
        function _filterZonas(zonas, filterData) {
            var timeWindow = filterData.timeWindow;

            var filteredZonas = zonas.filter(function (zona) {
                var zonaInicio = moment(parseInt(zona.inicio, 10)),
                    zonaFim = moment(parseInt(zona.fim, 10));

                if (timeWindow.start) {
                    if ((zonaInicio.isSame(moment(timeWindow.start)) || zonaInicio.isAfter(moment(timeWindow.start))) &&
                        zonaInicio.isBefore(moment(timeWindow.end))) {
                        return zona;
                    }
                }

                if (timeWindow.end) {
                    if ((zonaFim.isSame(moment(timeWindow.end)) || zonaFim.isBefore(moment(timeWindow.end))) &&
                        zonaFim.isAfter(moment(timeWindow.start))) {
                        return zona;
                    }
                }
                return false;
            });

            return filteredZonas;
        }

        /**
         * @method applyTable
         * @param {*} zonas 
         */
        function applyTable(zonas) {
            $scope.tableParams = new ngTableParams({}, {
                total: zonas.length,
                getData: function ($defer, params) {
                    zonas = params.sorting() ? $filter('orderBy')(zonas, params.orderBy()) : zonas;
                    $defer.resolve(zonas);
                }
            });
        }

        /**
         * @method _getActiveZonas
         * @param {*} zonas
         */
        function _getActiveZonas(zonas) {
            return zonas.filter(function (zona) {
                if (zona.active) return zona;
            });
        }

        /**
         * @method refreshZonas
         * @param {*} zonas 
         */
        function refreshZonas(zonas) {
            $scope.zonas = zonas;

            var filterDataRange = _getFilterDataRange();
            var filteredZonas = _filterZonas($scope.zonas, filterDataRange);

            $scope.filterDataRange = filterDataRange;
            applyTable(filteredZonas);

            if (filteredZonas.length) {
                $scope.selectAll = true;
            } else {
                $scope.selectAll = false;
            }

            _uncheckAll();

        }

        MainState.registerDirective('zonasDeObservacao', {
            refreshZonas: refreshZonas,
            setQuery: setQuery,
            initFilter: initFilter
        });

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

        $scope.flyTo = function (zona) {
            var coords = JSON.parse(zona.geojson);
            MapaService.flyTo(coords);
            CamadasService.exibirZonasDeObservacao();
        }
    }

}());