Source: directives/rotas-unificadas/rotas-unificadas.js

/**
 * @ngdoc directives
 * @name RotasUnificadas
 * @module s4c.directives.rotasUnificadas.RotasUnificadas
 *
 * @description
 * `RotasUnificadas` Controller da funcionalidade de Rotas Unificadas 
 * 
 * @example
 *   <s4c-rotas-unificadas>
 *   </s4c-rotas-unificadas> 
 * 
 */
(function () {
    'use strict';

    rotasUnificadasCtrl.$inject = [
        '$scope',
        'RotasUnificadasService',
        'PermissoesService',
        'MainState',
        'RotasUnificadasManager',
        'CommService',
        'RotasUnificadasFilter',
        'localize',
        '$interval',
        'MapaService'
    ];

    function rotasUnificadasCtrl($scope, RotasUnificadasService, PermissoesService, MainState,
        RotasUnificadasManager, CommService, RotasUnificadasFilter, localize, $interval, MapaService) {

        var instance = RotasUnificadasFilter.getInstance('rotas-unificadas-filter');

        var rotasAtivas = {};

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

        $scope.search = '';

        $scope.filterAgencias = [];

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

        $scope.textoBusca;
        /**
         * @method executeSearch
         */
        $scope.executeSearch = function (textoBusca) {

            $scope.textoBusca = textoBusca;
            if (!$scope.textoBusca || $scope.textoBusca.length == 0) {
                $scope.rotasSelecionadas = $scope.rotas;
                return;
            }

            $scope.rotasSelecionadas = [];
            var texto = $scope.textoBusca.toLowerCase();
            angular.forEach($scope.rotas, function (rota) {

                var nome = rota.nome.toLowerCase();

                if (nome.indexOf(texto) !== -1) {
                    $scope.rotasSelecionadas.push(rota);
                }
            });
        }

        /**
         * @method rotasUnificadasFilter
         */
        $scope.rotasUnificadasFilter = function (rota) {
            // Filter not set at this point.
            if ($scope.filterAgencias.length === 0) return true;
            if (!instance) return true;
            if (!instance.agencias) return true;

            return $scope.filterAgencias.indexOf(rota.DepartamentoId) > -1;
        };

        instance.on('rotas', function () {
            atualizarRotas();
        });

        /**
         * @method filterChanged
         */
        instance.on('filterChanged', function () {
            var agencias = _.chain(instance.agencias)
                .filter(function (agencia) {
                    return agencia.ativo;
                })
                .map('id')
                .value();

            $scope.filterAgencias = agencias;

            var rotasFiltered = [];

            _.each($scope.rotas_bd, function (rota) {

                var rota_dep = _.find(agencias,
                    function (agencia) {
                        return agencia === rota.DepartamentoId;
                    });

                if (rota_dep != null) {
                    rotasFiltered.push(rota);
                }
            });

            $scope.rotas = rotasFiltered;

        });



        /**
         * @method rotaUnificadasRemoved
         */
        instance.on('rotaUnificadasRemoved', function () {
            _.each(rotasAtivas, function (rotasAtiva_) {
                MapaService.removerCamada(rotasAtiva_);
            });
        });

        /**
         * @method tempoRotaAtualiazado
         */
        instance.on('tempoRotaAtualiazado', function (rotaUnificada) {
            _.each($scope.rotas, function (rota) {
                if (rota.id == rotaUnificada.id) {
                    rota.RotaLeituras[0].currentTime = rotaUnificada.tempo_atual;
                    rota.cor = rotaUnificada.cor;
                } else {
                    _.each(rota.rotasAlternativas, function (rotaAlternativa) {
                        if (rotaAlternativa.id == rotaUnificada.id) {
                            rotaAlternativa.RotaLeituras[0].currentTime = rotaUnificada.tempo_atual;
                            rotaAlternativa.cor = rotaUnificada.cor;
                        }
                        return rotaAlternativa;
                    });
                }
                return rota;
            });
        });

        /**
         * @method marcarRota
         * @param {*} rota 
         */
        function marcarRota(rota) {
            RotasUnificadasManager.desenharPoligono(rota);
        }

        /**
         * @method detalhesDaRota
         * @param {*} rota 
         */
        function detalhesDaRota(rota) {
            if (rota.active) {
                rota.active = false;
                var camada_ativa = rotasAtivas[rota.id];
                MapaService.removerCamada(camada_ativa);
                rotasAtivas[rota.id] = null;
            }
            RotasUnificadasManager.fechar();
            setTimeout(function () {
                RotasUnificadasManager.editar(rota);
            }, 500);

        }

        /**
         * @method atualizarRotas
         */
        function atualizarRotas() {
            RotasUnificadasService.pegarRotas()
                .then(function (rotas) {

                    MapaService.removerRotasUnificadasDoMapa();

                    $scope.rotas = _.chain(rotas.data)
                        .map(function (rota) {
                            definirAtraso(rota);
                            rota.cor = $scope.pegarCor(rota);
                            if (rota.myColor == null || rota.myColor == '') {
                                rota.myColor = 'hsl(259, 91%, 49%)';
                            }
                            _.each(rota.rotasAlternativas, function (rotaAlternativa) {
                                definirAtraso(rotaAlternativa);
                                rotaAlternativa.cor = $scope.pegarCor(rotaAlternativa);

                                if (rotaAlternativa.myColor == null || rotaAlternativa.myColor == '') {
                                    rotaAlternativa.myColor = 'hsl(259, 91%, 49%)';
                                }

                                return rotaAlternativa;

                            });

                            return rota;
                        })
                        .value();
                    $scope.rotas_bd = $scope.rotas;
                    $scope.rotasSelecionadas = $scope.rotas;
                });

        }

        /**
         * @method definirAtraso
         * @param {*} rota 
         */
        function definirAtraso(rota) {
            if (rota.RotaLeituras &&
                rota.RotaLeituras[0] &&
                rota.RotaLeituras[0].currentTime) {

                rota.atraso = ((100 * (rota.RotaLeituras[0].currentTime / rota.RotaLeituras[0].regularTime)) - 100);
            }

            return rota;
        }


        /**
         * @method pegarCor
         * @param {*} rota 
         */
        function pegarCor(rota) {
            if (rota.atraso) {

                if (rota.atraso <= 10) {
                    return '#8AC249';
                } else if (rota.atraso >= 10 && rota.atraso <= 50) {
                    return '#FFFF00';
                } else {
                    return '#F34235';
                }
            } else {
                return '#DDD';
            }
        }

        $scope.formatOptions = [{ label: 'HSL', value: 'hsl' }, { label: 'HSV', value: 'hsv' }, { label: 'RGB', value: 'rgb' }, { label: 'HEX', value: 'hex' }, { label: 'HEX8', value: 'hex8' }, { label: 'Raw', value: 'raw' }];
        $scope.boolOptions = [{ label: 'Yes', value: true }, { label: 'No', value: false }];
        $scope.swatchPosOptions = [{ label: 'Left', value: 'left' }, { label: 'Right', value: 'right' }];
        $scope.posOptions = [{ label: 'Bottom Left', value: 'bottom left' }, { label: 'Top Left', value: 'top left' }, { label: 'Bottom Right', value: 'bottom right' }, { label: 'Top Right', value: 'top right' }];
        $scope.caseOptions = [{ label: 'Upper Case', value: 'upper' }, { label: 'Lower Case', value: 'lower' }];


        /**
         * @method novaRotaAlternativa
         */
        $scope.novaRotaAlternativa = function (rota) {
            if (rota.active) {
                rota.active = false;
                MapaService.removerCamada(rotasAtivas[rota.id]);
            }
            RotasUnificadasManager.abrir(rota);
        }

        $scope.color = 'hsl(259, 91%, 49%)';
        $scope.options = {
            close: { show: true },
            clear: { show: true },
            reset: { show: true },
            placeholder: $scope.color
        };

        $scope.options.hue = true;
        $scope.options.saturation = false;
        $scope.options.lightness = false;
        $scope.options.alpha = false;
        $scope.options.format = 'hsl';
        $scope.options.pos = 'bottom right';
        $scope.options.swatchPos = 'left';
        $scope.options.round = false;
        $scope.options.horizontal = false;

        $scope.api = {};

        $scope.eventApi = {
            onChange: function () {
                console.log("Rota Ativa: " + $scope.rotaAtiva);
                _.each($scope.rotas, function (rota) {
                    if (rota.id == $scope.rotaAtiva.id) {
                        rota.active = true;
                        _exibirRota(rota);
                    }
                    _.each(rota.rotasAlternativas, function (rotaAlternativa) {
                        if (rotaAlternativa.id == $scope.rotaAtiva.id) {
                            rotaAlternativa.active = true;
                            _exibirRota(rotaAlternativa);
                        }
                        return;
                    });

                    return;
                })

                console.log('change', arguments);
            },
            onBlur: function () {
                console.log('blur', arguments);
            },
            onOpen: function () {
                console.info('open', arguments);
            },
            onClose: function () {
                console.info('close', arguments);
            },
            onClear: function () {
                console.info('clear', arguments);
            },
            onReset: function () {
                console.info('reset', arguments);
            },
            onDestroy: function () {
                console.info('destroy', arguments);
            }
        };

        $scope.open = function () {
            $scope.api.open();
        };

        $scope.close = function () {
            $scope.api.close();
        };

        /**
         * @method printGeoM
         */
        $scope.printGeoM = function (geom, color, rotaUnificadaId) {
            geom.setStyle({ color: color });
            geom.options.rota = true;
            geom.options.rotaUnificadaId = rotaUnificadaId;

            MapaService.addLayer(geom);
            MapaService.fitBounds(geom);
        };

        /**
         * @method _exibirRota
         * @param {*} rota 
         */
        function _exibirRota(rota) {
            var layer = L.geoJson(JSON.parse(rota.geom));

            if (rotasAtivas[rota.id] != null) {
                MapaService.removerCamada(rotasAtivas[rota.id]);
            }

            var jsonObject = {};
            jsonObject.myColor = rota.myColor;

            RotasUnificadasService.updateColorRoute(rota.id, jsonObject);

            rotasAtivas[rota.id] = layer;

            rotasAtivas[rota.id].on('click', function (e) {
                MapaService.removerCamada(rotasAtivas[rota.id]);
                RotasUnificadasManager.editar(rota);
                rota.active = false;
            });
        };

        function _exibirRota(rota) {
            var layer = L.geoJson(JSON.parse(rota.geom));

            if (rotasAtivas[rota.id] != null) {
                MapaService.removerCamada(rotasAtivas[rota.id]);
            }

            var jsonObject = {};
            jsonObject.myColor = rota.myColor;

            RotasUnificadasService.updateColorRoute(rota.id, jsonObject);

            rotasAtivas[rota.id] = layer;

            rotasAtivas[rota.id].on('click', function (e) {
                MapaService.removerCamada(rotasAtivas[rota.id]);
                RotasUnificadasManager.editar(rota);
                rota.active = false;
            });

            $scope.printGeoM(rotasAtivas[rota.id], rota.myColor, rota.id);
        }

        /**
         * @method mapearRota
         */
        $scope.mapearRota = function (rota) {

            if (rota.active) {
                var layer = L.geoJson(JSON.parse(rota.geom));

                rotasAtivas[rota.id] = layer;

                rotasAtivas[rota.id].on('click', function (e) {
                    MapaService.removerCamada(rotasAtivas[rota.id]);
                    RotasUnificadasManager.editar(rota);
                    rota.active = false;
                });

                $scope.printGeoM(rotasAtivas[rota.id], rota.myColor, rota.id);
            } else {
                MapaService.removerCamada(rotasAtivas[rota.id]);
                rotasAtivas[rota.id] = null;
            }
        }

        CommService.on('rotas', function (data) {
            atualizarRotas();
        });

        CommService.on('rotaComAtraso', function (rota) {
            toasty({
                msg: 'A rota ' + rota.nome + ' está com engarrafamentos.'
            });
        });

        angular.extend($scope, {
            $apiRotas: {
                atualizarRotas: atualizarRotas
            },
            pegarCor: pegarCor,
            marcarRota: marcarRota,
            detalhesDaRota: detalhesDaRota,
            res: $scope.$root.res
        });

        MainState.registerDirective('rotas', $scope.$apiRotas);
        $scope.$on('$destroy', function () {
            MainState.unregisterDirective('rotas');
        });
        atualizarRotas();

        $scope.hide_input = function () {
            $('.md-tile-content :input').hide();
        }

        $scope.definirRotaAtiva = function (rota) {
            $scope.rotaAtiva = rota;
        }


    }

    function s4cRotasUnificadas() {

        return {
            restrict: 'E',
            templateUrl: 'app/directives/rotas-unificadas/rotas-unificadas.html',
            controller: rotasUnificadasCtrl
        };
    }

    function SalvarRotaUnificadaCtrl($scope, $mdDialog, MapaService, MainState, RotasUnificadasManager, waypoints, toasty, Departamento, localize, res) {
        $scope.res = res;
        var user = MainState.getManager('UserInfo');

        $scope.agencias = [];

        Departamento.getAgencias()
            .then(function (agencias) {
                $scope.agencias = agencias;
            });

        $scope.formRota = {};

        $scope.rota = {
            DepartamentoId: user.Departamento.id
        };

        $scope.$watch('rota.nome', function (newVal, oldVal) {
            if (newVal && newVal.length > 0) {
                if ($scope.formRota.nome) {
                    $scope.formRota.nome.error.required = false;
                    $scope.formRota.nome.touch = false;
                }
            }
        });

        $scope.enableButton = true;
        /**
         * @method saveRota
         */
        $scope.saveRota = function (rotaOpts) {

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

            $scope.enableButton = false;

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

            $scope.enableButton = false;

            if (!rotaOpts.hasOwnProperty('nome') || rotaOpts.nome.length === 0) {
                $scope.formRota = {
                    nome: {
                        touched: true,
                        error: {
                            required: true
                        }
                    }
                };

                return false;
            }

            RotasUnificadasService.salvarRota({
                nome: rotaOpts.nome,
                descricao: rotaOpts.descricao,
                origem: rotaOpts.origem,
                destino: rotaOpts.destino,
                publico: rotaOpts.publico,
                trechos: waypoints,
                DepartamentoId: rotaOpts.DepartamentoId || user.Departamento.id,
                editavel: !RotasUnificadasManager.rotaAtiva.kml,
                trajeto: RotasUnificadasManager.rotaAtiva.trajeto
            }).then(function (obj) {
                RotasUnificadasManager.fechar();
                $scope.enableButton = true;
                $mdDialog
                    .show($mdDialog.alert()
                        .title('Sucesso.')
                        .content('Rota criada com sucesso.')
                        .ok('OK'));
                var rotas = MainState.getDirective('rotas');
                if (rotas) {
                    rotas.atualizarRotas();
                }
            }, function (err) {
                toasty({
                    msg: 'Ocorreu um erro ao salvar a rota'
                });
            });
        };

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

    angular.module('s4c.components.rotas-unificadas')
        .directive('s4cRotasUnificadas', s4cRotasUnificadas)
        .controller('SalvarRotaUnificadaCtrl',
            ['$scope', '$mdDialog', 'MapaService', 'MainState', 'RotasUnificadasManager', 'waypoints', 'toasty',
                'Departamento', 'localize', 'res', SalvarRotaUnificadaCtrl]);
}());