function PersistentConnectionSR(options) {
    this._dataUltimaAtualizacao = new Date().getTime();
    //this._viewModelFromKnockout = options.viewModel;
    this._handlers = [];
    this._mapeamento = options.mapeamento;
    this._qs = options.qs;
    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) { }
};

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

PersistentConnectionSR.prototype.init = function () {
    $('body').append("<div id='" + this._poolingDivLog + "' class='hide'></div>");
    this._conn = $.connection(this._mapeamento, this._qs);
    var self = this;
    this._conn.received(self);
    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();
        }
    });
};

PersistentConnectionSR.prototype.onDisconnect = function () {
    this.log("SignalR Desconectado!");
    var self = this;
    this._conectado = false;
    //if (window.location.pathname.indexOf("PainelFinal") > -1) ExibirErro("Painel desconectado!");
    function reset() {
        if (self._conectado == false) {
            //if (window.location.pathname.indexOf("PainelFinal") > -1) PermanceExibirErro("Painel tentanado se conectar!");
            self.init();
        }
    }
    setTimeout(reset, 5000);
    //ShowMessage("A aplicação perdeu conexão com o servidor, aguarde enquanto tentamos reestabelecer os eventos!", ERROR_LEVEL, 5000, true);
};

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

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

//PersistentConnectionSR.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 + "]");
//        }
//    }
//};


PersistentConnectionSR.prototype.call = function (connection, evento) {

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

        //this.log("Mensagem Recebida! Tipo Evento[" + evento + "]!");
        try {
            if (this._handlers.length > 0) {
                for (var i = 0; i < this._handlers.length; i++) {
                    this._handlers[i].TratarEvento(evento);
                }
            }
        } catch (Exception) {
            this.error(Exception);

            this.log("Erro OnDataReceived: [" + Exception + "] JSON [" + evento.Mensagem + "] TIPO [" + evento.Evento + "]");
        }
    }
};

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

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

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

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

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


PersistentConnectionSR.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, Old: this._conn.id })); };
    //    setTimeout(funcaoReconectar, 2000);
    //    this._lastGuid = this._conn.id;
    //}
    this._conn.send(JSON.stringify({ Tipo: 5, Objeto: this._lastGuid, Old: this._conn.id }));
    window.location.reload();
    this.log('SignalR Reconectado');
    this._conectado = true;

    //this._conectado = false;
    //function reset() {
    //    if (self._conectado == false) {
    //        self.init();
    //    }
    //}
    //setTimeout(reset, 5000);
};

PersistentConnectionSR.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._conectado = true;
    this._lastGuid = this._conn.id;


    //if (window.location.pathname.indexOf("PainelFinal") > -1) ExibirSucesso("Painel conectado!");
    this.log("SignalR Conectado!");
};

PersistentConnectionSR.prototype.SetHandlers = function (handler) {

    this._handlers.push(handler);
};
