function PConVeiculos(options) {
    this._dataUltimaAtualizacao = new Date().getTime();
    //this._viewModelFromKnockout = options.viewModel;
    this._handlers = ko.observableArray([]);
    this._mapeamento = options.mapeamento;
    this._limiteMaximoSemAtualizacao = 3 * 60 * 1000; // 3 minutos
    this._tempoCicloVerificacao = 60 * 1000; // 1 minuto
    this._poolingDivLog = "poolingDivLog";
    this._limiteEsperandoAtualizacao = 5;
    this._options = options;
    this._lastGuid = "";
    this._conectado = false;
    this.init();
    try {
        //this.pingTimeout = new PingTimeOut(this, 2000);
    } catch (Exc) { }
};

PConVeiculos.prototype.timeoutCallBack = function (self) {
    //CloseMessage();
    self.init();
};

PConVeiculos.prototype.init = function () {
    $('body').append("<div id='" + this._poolingDivLog + "' class='hide'></div>");
    this._conn = $.connection(this._mapeamento);
    var self = this;
    this._conn.received(function (data) { self.onDataReceived(data); });
    this._conn.start().done(function () { self.onConnected(); });
    this._conn.reconnected(function () { self.onReconnected(); });
    $(this._conn).bind("onDisconnect", function (e, data) {
        self.onDisconnect(self._conn);
        if (self.pingTimeout) {
            self.pingTimeout.Init();
        }
    });
};

PConVeiculos.prototype.onDisconnect = function () {
    this.log("SignalR Desconectado!");
    //ShowMessage("A aplicação perdeu conexão com o servidor, aguarde enquanto tentamos reestabelecer os eventos!", ERROR_LEVEL, 5000, true);
    this._conectado = false;
    function reset() {
        var self = vmEventos.TempoReal;
        if (self._conectado == false) {
            self._conn.start();
            self.log("SignalR Conectado novamente!");
        }
    }
    setTimeout(reset, 3000);
};

PConVeiculos.prototype.getMapeamento = function () {
    return this._mapeamento;
};

PConVeiculos.prototype.log = function (mensagem) {
    console.log(mensagem);
    //$("#" + this._poolingDivLog).prepend("[" + new Date().toString() + "] => " + mensagem + "<br />");
};

//PConVeiculos.prototype.onDataReceived = function (evento) {
//    if (evento != null && typeof (evento) !== "undefined") {
//        this._dataUltimaAtualizacao = new Date().getTime();

//        //this.log("Mensagem Recebida! Tipo Evento[" + evento + "]!");
//        try {
//            var json = $.parseJSON(evento);
//            if (json.Tipo == 1) { // Posicao
//                this._viewModelFromKnockout.atualizarPosicao(json.Codigo, $.parseJSON(json.Objeto));
//            } else if (json.Tipo == 2) { // Status
//                this._viewModelFromKnockout.atualizarStatus(json.Codigo, $.parseJSON(json.Objeto));
//            } else if (json.Tipo == 3) { // Alarme
//                this._viewModelFromKnockout.atualizarAlarme(json.Codigo, json.CodigoAlarme, $.parseJSON(json.Objeto));
//            } else if (json.Tipo == 5) { // Alarme
//                this._viewModelFromKnockout.novoAlarme(json.Codigo, json.CodigoAlarme, $.parseJSON(json.Objeto));
//            } else if (json.Tipo == 6) { // Remover vínculo de linha com veículo
//                this._viewModelFromKnockout.RemoverVeiculoLinha(json.Objeto);
//            } else if (json.Tipo == 7) { // Atualizar vínculo de linha de veículo
//                this._viewModelFromKnockout.AtualizarVeiculoLinha($.parseJSON(json.Objeto));
//            }
//        } catch (Exception) {
//            this.log("Erro OnDataReceived: [" + Exception + "] JSON [" + evento.Conteudo + "]");
//        }
//    }
//};


PConVeiculos.prototype.onDataReceived = function (evento) {

    if (evento) {
        this._dataUltimaAtualizacao = new Date().getTime();

        //this.log("Mensagem Recebida! Tipo Evento[" + evento + "]!");

        try {

            if (evento.TipoEvento == 999)
            {
                try {
                    vm.ShowMensagemAlerta(evento.Conteudo.Mensagem);
                } catch (ex) { }
                return;
            }
            if (this._handlers().length > 0) {
                var json = $.parseJSON(evento);

                ko.utils.arrayForEach(this._handlers(), function (handler) {
                    if (json.Tipo == 6) //Caso especial para o evento de remoção do vínculo de linha com veículo
                        handler.TratarEvento(json.Codigo, json.Tipo, json.Objeto);
                    else
                        handler.TratarEvento(json.Codigo, json.Tipo, $.parseJSON(json.Objeto));
                });
            }

        } catch (Exception) {
            this.error(Exception);
            this.log("Erro OnDataReceived: [" + Exception + "] JSON [" + evento.Conteudo + "] TIPO [" + evento.TipoEvento + "]");
        }
    }
};

PConVeiculos.prototype.error = function (Exception) {
    console.error(Exception);
};

PConVeiculos.prototype.GetId = function () {
    return this._conn.id;
};

PConVeiculos.prototype.enviarFiltro = function (filtro) {
    this.Send(JSON.stringify({ Objeto: filtro, Tipo: 4 }));
    this.log("Filtro enviado!");
};

PConVeiculos.prototype.Send = function (obj) {
    if (poolingTempoReal._conn.state == 1) {
        this._conn.send(obj);
    }
    else {
        var self = this;
        setTimeout(function () { self.Send(obj); }, 1000);
    }
};

PConVeiculos.prototype.trocaDeGuid = function (lasGuid) {
    this._conn.send(JSON.stringify({ Tipo: 5, Objeto: lasGuid }));
    this.log("solicitar troca de guid enviada!");
};


PConVeiculos.prototype.onReconnected = function () {
    if (this._lastGuid != "" && this._lastGuid != this._conn.id) {
        var self = this;
        var funcaoReconectar = function () { self._conn.send(JSON.stringify({ Tipo: 5, Objeto: self._lastGuid })); };
        setTimeout(funcaoReconectar, 2000);
        this._lastGuid = this._conn.id;
    }
    this.log('SignalR Reconectado');
    this._conectado = true;
};

PConVeiculos.prototype.onConnected = function () {
    if (this._options && this._options.onConnected) {
        this._options.onConnected();
    }

    if (this._lastGuid != "" && this._lastGuid != this._conn.id) {
        var self = this;
        var guid = self._lastGuid;
        var func = function () { self.trocaDeGuid(guid) };
        setTimeout(func, 2000);
    }
    
    this._lastGuid = this._conn.id;
    this.log("SignalR Conectado!");
    this._conectado = true;
};

PConVeiculos.prototype.SetHandlers = function (handler) {

    this._handlers.push(handler);
};
