﻿// JScript File

var visualizador = {

    // CONSTANTES
    ROOT_PATH: '../../../../',

    TRYING_ACTIVATE_TEMPLATE_LOOP_TIME: 500, //millisecond
    TRYING_ACTIVATE_TEMPLATE_TIME_LIMIT: 10, //seconds
    TIME_INTERVAL_SESSION_TICK: 60, //seconds
    TICK_NULL_RESPONSE_TOLERANCE_COUNT: 3,


    // PROPRIEDADES
    Transmissao: null,
    Sessao: null,
    Cliente: null,
    Usuario: null,
    Credito: null,
    PPoint: null,
    PPoint_espelho: null,
    ArquivosAuxiliares: null,
    Agendas: null,
    Palestrantes: null,
    TrechosOnDemand: null,
    Scripts: null,
    Indices: null,
    Templates: null,
    PadraoTransmissao: null,
    IframeTemplate: null,

    pathSlidesList: null,
    idxPathSlides: 0,

    flagTemplateInitOk: false,

    TransmissaoConsomeCredito: null,
    ConsomeAcessoTransmissao: null,

    lstTabsState: new Array(),

    tickNullResponseCount: 0,

    main: function () {
        trace('visualizador.main()');

        simpleRemoveEvent(document.body, 'load', visualizador.main);

        document.getElementById("divWebCastersMensagem").style.display = 'none';
        document.getElementById("divWebCastersMensagemContainer").style.display = 'none';


        // busca os dados no servidor e valida a transmissao
        if (!visualizador.validateTransmissao()) { return; }

        //List of slides's path
        visualizador.pathSlidesList = visualizador.Transmissao.PathSlides.split('|');



        //Iframe para carregar o template
        visualizador.IframeTemplate = $('iframeTemplate');

        //carrega o template
        visualizador.loadTemplate(visualizador.Transmissao.AoVivo ?
                                      visualizador.Transmissao.CodTemplateVisualizadorAtual
                                      : visualizador.Transmissao.CodTemplateVisualizadorInicial);

        //Inicia o chat
        chat.iniciarChat(visualizador.Transmissao.Codigo, visualizador.Usuario.Codigo);
        // Inicia a interação multimidia
        multimidia.iniciarMultimidia(visualizador.Transmissao.Codigo, visualizador.Usuario.Codigo);

        //Inicia Anotacao
        anotacao.iniciarAnotacao(visualizador.Transmissao.Codigo, visualizador.Usuario.Codigo);

        // inicia o gerenciador de enquetes
        gerenciadorEnquete.iniciar(visualizador.Transmissao.Codigo, visualizador.Usuario.Codigo);


        //cria o player - callback

        if (visualizador.Transmissao.CelularDisponivel) {
            wcplayer.CelularDisponivel = true;
        }

        wcplayer.init();


        indirectRun(visualizador.mainContinue);


    },

    mainContinue: function () {
        //só é executado quando o load e a inicialização do template terminam
        if (!visualizador.flagTemplateInitOk || !wcplayer.CheckPlayer()) {
            setTimeout(function () { visualizador.mainContinue(); }, visualizador.TRYING_ACTIVATE_TEMPLATE_LOOP);
            return;
        }

        trace('DEBUG: visualizador.mainContinue()');

        streamManager.init();
        config.activate();

        streamManager.GetStream();

        //dispara o tick da sessão da transmissão
        visualizador.sessionTick();

        visualizador.checkOffset();



    },


    checkOffset: function () {

        if (typeof (Request) == "undefined" || Request.queryString("offset") == null) {
            return;
        }

        var pOffset = 0;

        try {
            pOffset = parseInt(Request.queryString("offset"));
        }
        catch (e) {
            pOffset = 0;
        }

        if (pOffset > 0) {
            trace('seeking video by offset parameter');
            wcplayer.currentTotal(pOffset);
        }

    },


    sessionTick: function () {
        try {
            var playingStream = (wcplayer.CurrentState() == wcplayer.WM_STATE_PLAYING);

            trace('Ticking...');

            var res = VisualizadorServer.sessionTick(visualizador.Usuario.Codigo
                                                , visualizador.Sessao.Codigo
                                                , visualizador.Transmissao.AoVivo
                                                , visualizador.Transmissao.CodCategoria
                                                , visualizador.TransmissaoConsomeCredito
                                                , visualizador.Transmissao.Codigo
                                                , playingStream
                                                , Date.now());

            if (!visualizador._processSessionTickResponse(playingStream, res)) {
                // se retornar falso, é pra parar de ticar.
                trace('>>> TICKING STOPPED !!!');

                window.location = 'ListaTransmissao.aspx';

                return;
            }


        } catch (error) {

            trace('>>> TICKING ERROR !!!');
            trace(error.message);
            visualizador.escreveLog("tic routine error : " + error.message);

        }

        setTimeout(function () { visualizador.sessionTick(); }, visualizador.TIME_INTERVAL_SESSION_TICK * 1000);
    },



    _processSessionTickResponse: function (playingStream, res) {

        if (visualizador.ajaxErrorCheck(res) == -1) {
            trace('sessionTick: error received');

            // houve um erro de verdade
            return false; // já era

        }
        else if (visualizador.ajaxErrorCheck(res) == 0) {
            trace('sessionTick: no response');

            // sem resposta
            visualizador.tickNullResponseCount++;

            if (visualizador.tickNullResponseCount >= visualizador.TICK_NULL_RESPONSE_TOLERANCE_COUNT) {
                // passou do limite.
                alert("Erro PTK003 \nVerifique se você está conectado com a internet. \nCaso o erro persista, entre em contato com o suporte.");
                return false; // já era
            }

            // ainda está dentro do limite
            return true; // continua ticando

        }

        // veio resposta, reseta o contador
        visualizador.tickNullResponseCount = 0;
        // e continua 


        trace('sessionTick: return ok');


        if (playingStream && visualizador.Credito != null) {
            if (res.value == null) {
                /* problema, deveria ter debitado um crédito e retornado 
                o saldo atual, porém retornou valor nulo */

                trace('sessionTick: res.value = null ERROR!');
                visualizador.escreveLog("TIC ERROR: Não retornou saldo atual.");
                alert("Erro PTK001 \n Caso o erro persista, entre em contato com o suporte.");

                return false; // pára de ticar
            }

            //atualiza o saldo do usuário
            visualizador.Credito = res.value.rows[0];
            trace('sessionTick: updating user credits... [ok] aovivo(' + visualizador.Credito.MinutosAoVivo + ',' + visualizador.Credito.QtdAcessosAoVivo + ')  ondemand(' +
              visualizador.Credito.MinutosOnDemand + ',' + visualizador.Credito.QtdAcessosOnDemand + ')');
            indirectRun(template.loadUserCredit);
        }
        else {
            if (res.value != null) {
                /* pelo que consta no js, não era para ter ocorrido um débito dos créditos,
                porém o servidor não retornou nulo */

                visualizador.escreveLog("TIC ERROR: Débito Incorreto.");
                alert("Erro PTK002 \n Caso o erro persista, entre em contato com o suporte.");

                return false; // pára de ticar
            }
        }

        return true; // continua ticando
    },




    /*
    VERIFICA A RESPOSTA AJAX
    Retorna 0 caso não haja resposta
    Retorna -1 caso a resposta venha COM mensagem erro
    Retorna 1 caso a resposta venha SEM mensagem de erro
    */
    ajaxErrorCheck: function (res) {

        if (res == null) {
            // sem resposta???
            trace('ajaxErrorCheck :: res = null // sem resposta???');

            return 0;
        }



        //se der algum erro redireciona para o que a mensagem indicar
        if (res.error != null) {
            trace(res.error.message);
            visualizador.escreveLog("ajaxErrorCheck: ERROR message - " + res.error.message);

            var msgErro = res.error.message.split('\n');
            switch (msgErro[0]) {

                case 'redirect':
                    visualizador.escreveLog("ajaxErrorCheck[REDIRECT];" + msgErro[1]);

                    // TODO: tratar isso direito (não voltar para página de lista de transmissões)

                    if (res.error.message.indexOf("ListaTransmissao.aspx") == -1) {
                        window.location = msgErro[1];
                        break;
                    }

                    var addr = msgErro[1].split("msgErro=");
                    window.location = "/mensagem.html?msgErro=" + addr[1];

                    visualizador.AEC001Threshold_Reset();
                    break;

                case 'message':
                    alert(msgErro[1]);
                    visualizador.escreveLog("ajaxErrorCheck[MESSAGE];" + msgErro[1]);

                    visualizador.AEC001Threshold_Reset();
                    break;

                case 'block':
                    visualizador.escreveLog("ajaxErrorCheck[BLOCK];" + msgErro[1]);
                    visualizador.Bloquear(msgErro[1]);

                    visualizador.AEC001Threshold_Reset();
                    break;

                default:
                    // pode cair aqui em caso de queda de conexão...
                    trace('erro não identificado: \n\n' + res.error.message);

                    // esse bagulho é para continuar tentando 
                    // mais um pouco antes de mostrar o erro.
                    if (visualizador.AEC001Threshold > 0) {
                        trace('Tentando mais um pouco ... '
                            + visualizador.AEC001Threshold + ' / 5 <br />');
                        visualizador.AEC001Threshold--;
                        return;
                    }

                    visualizador.AEC001Threshold_Reset();

                    visualizador.escreveLog("ajaxErrorCheck[DEFAULT];" + res.error.message);
                    alert("Erro AEC001 \nVerifique se você está conectado com a internet. \nCaso o erro persista, entre em contato com o suporte.");

                    break;
            }

            return -1;
        }

        visualizador.AEC001Threshold_Reset();

        return 1;
    },

    AEC001Threshold: 5,
    AEC001Threshold_Reset: function () {
        visualizador.AEC001Threshold = 5
    },

    escreveLog: function (mensagem) {
        try {
            VisualizadorServer.EscreveLog("t:" + visualizador.Transmissao.Codigo + " s:" + visualizador.Sessao.Codigo + " m:" + mensagem);
        } catch (error) {
            trace("NÃO ESCREVEU O LOG : " + error.message);
            trace("MENSAGEM : " + mensagem);
        }
    },


    validateTransmissao: function () {
        //Valida a transmissão para o usuário logado
        trace('Validating Transmission code ' + Request.queryString('CodTransmissao') + ' from query string');
        var res = VisualizadorServer.Initializing(Request.queryString('CodTransmissao'));

        if (visualizador.ajaxErrorCheck(res) < 1) { return false; }

        //Popula as variáveis com a resposta do servidor
        visualizador.Transmissao = res.value.tables['Transmissao'].rows[0];

        visualizador.TransmissaoConsomeCredito = res.value.tables['VisualizadorInfo'].rows[0].TransmissaoConsomeCredito;
        visualizador.ConsomeAcessoTransmissao = !res.value.tables['VisualizadorInfo'].rows[0].ConsumiuCreditoAcesso;

        visualizador.Sessao = res.value.tables['Sessao'].rows[0];

        streamManager.ListaServidores = res.value.tables['ListaServidores'];
        visualizador.PPoint = res.value.tables['PublishingPoint'].rows[0];

        visualizador.PPoint_espelho = visualizador.PPoint.Nome + '_espelho_' + streamManager.ListaServidores.rows[0].Nome.replace(' ', '');

        visualizador.Cliente = res.value.tables['Cliente'].rows[0];
        visualizador.Usuario = res.value.tables['Usuario'].rows[0];
        visualizador.PadraoTransmissao = res.value.tables['PadraoTransmissao'].rows[0];
        visualizador.ArquivosAuxiliares = res.value.tables['ArquivosAuxiliares'];
        visualizador.Templates = res.value.tables['Templates'];



        visualizador.Agendas = res.value.tables['Agendas'];
        visualizador.Palestrantes = res.value.tables['Palestrantes'];


        if (res.value.tables['Credito'] != null) {
            visualizador.Credito = res.value.tables['Credito'].rows[0];
            trace('Table "Credito" [ok] aovivo(' + visualizador.Credito.MinutosAoVivo + ',' + visualizador.Credito.QtdAcessosAoVivo + ')  ondemand(' +
                  visualizador.Credito.MinutosOnDemand + ',' + visualizador.Credito.QtdAcessosOnDemand + ')');
        }


        if (res.value.tables['TrechosOnDemand'] != null) {

            visualizador.TrechosOnDemand = res.value.tables['TrechosOnDemand'];

            visualizador.Scripts = visualizador.populateScriptsTrechos(res.value.tables['TrechosOnDemand'],
                                                                       res.value.tables['Scripts']);

            visualizador.Indices = visualizador.populateTableIndice(res.value.tables['TrechosOnDemand'],
                                                                    res.value.tables['Indices']);
        }

        trace('Validation OK')
        return true;
    },



    loadTemplate: function (codTemplate) {

        trace('Loading template code ' + codTemplate);

        var i = visualizador.Templates.indexOf('Codigo', codTemplate);
        if (i == -1) { alert('erro: o template de visualizador não foi encontrado.'); return; }

        var t = visualizador.Templates.rows[i];
        if (t.Diretorio == '') { alert('erro: o template de visualizador não possui arquivos no servidor.'); return; }

        var actualPathSite = window.location.href.substring(0, window.location.href.lastIndexOf('/')) + '/';

        if ((visualizador.Transmissao.AoVivo && visualizador.IframeTemplate.src == actualPathSite + t.Diretorio + '/visualizador_aovivo.html')
          || (!visualizador.Transmissao.AoVivo && visualizador.IframeTemplate.src == actualPathSite + t.Diretorio + '/visualizador_arquivo.html')) {

            trace('Template code ' + codTemplate + ' already loaded');
            return;

        }

        //daqui para frente já pode carregar o template

        //marca o template a ser carregado como o template atual da transmissão
        visualizador.Transmissao.CodTemplateVisualizadorAtual = codTemplate;


        document.body.focus();
        //visualizador.IframeTemplate.style.visibility = 'hidden';

        visualizador.flagTemplateInitOk = false;
        trace('Adding Event load to iframe');
        simpleAddEvent(visualizador.IframeTemplate, 'load', function () { visualizador.activateTemplate(false, Date.now()); });

        template.webPath = t.Diretorio;

        if (visualizador.Transmissao.AoVivo) { visualizador.IframeTemplate.src = actualPathSite + t.Diretorio + '/visualizador_aovivo.html'; }
        else { visualizador.IframeTemplate.src = actualPathSite + t.Diretorio + '/visualizador_arquivo.html'; }



        trace('template page: ' + visualizador.IframeTemplate.src);
    },

    activateTemplate: function (retry, startedAt) {

        if (visualizador.flagTemplateInitOk) { return; }

        if (retry != true) {
            trace('Loaded - Removing Event load from iframe');
            simpleRemoveEvent(visualizador.IframeTemplate, 'load', visualizador.activateTemplate);
        }

        if (Date.diff(startedAt, Date.now(), 'ss') > visualizador.TRYING_ACTIVATE_TEMPLATE_TIME_LIMIT) {
            alert('Erro ao carregar o template do visualizador. Tempo limite foi excedido.');
            return;
        }

        /*Ocorre um problema no IE que quando o usuário está com algum evento na página no momento da ativação
        a função template.init() não consegue retornar para cá e não dá erro nem nada, como se o programa se perdesse,
        esse esquema do setTimeout e para ficar tentando recarregar a página enquanto o usuário não libera o evento*/
        setTimeout(function () { visualizador.activateTemplate(true, startedAt); }, visualizador.TRYING_ACTIVATE_TEMPLATE_LOOP);

        document.body.focus();

        trace('INFO: trying to initialize template...');

        try {
            if (!template.init()) {
                return;
            }
        } catch (e) {
            trace("ERROR: Could not initialize template. " + e.message);
            return;
        }


        visualizador.flagTemplateInitOk = true;

        //visualizador.IframeTemplate.style.visibility = 'visible';
        trace('template\'s initialization ok');
    },

    populateScriptsTrechos: function (tTr, tSc) {

        if (visualizador.Transmissao.AoVivo) { return; }

        if (tTr == null || tSc == null || tTr.rows.length == 0) { return }


        var tScTr = new DataTable();
        tScTr.addColumn('IdxArquivo', 'System.Int32');
        tScTr.addColumn('Offset', 'System.Int32');
        tScTr.addColumn('Codigo', 'System.Int32')
        tScTr.addColumn('Tipo', 'System.Int32');
        tScTr.addColumn('Valor', 'System.String');

        //iteração dos trechos
        for (var itr = 0; itr < tTr.rows.length; itr++) {

            //se for o primeiro arquivo, preenche com os valores iniciais
            if (itr == 0) {

                //Slide Inicial
                var nr = tScTr.newRow();
                nr.IdxArquivo = itr;
                nr.Offset = 0;
                nr.Codigo = 0;
                nr.Tipo = 1;
                nr.Valor = visualizador.Transmissao.ArquivoSlideInicial + '';
                tScTr.addRow(nr);

                //Legenda Inicial
                var nr = tScTr.newRow();
                nr.IdxArquivo = itr;
                nr.Offset = 0;
                nr.Codigo = 0;
                nr.Tipo = 4;
                nr.Valor = '';
                tScTr.addRow(nr);

                //Template Inicial
                var nr = tScTr.newRow();
                nr.IdxArquivo = itr;
                nr.Offset = 0;
                nr.Codigo = 0;
                nr.Tipo = 6;
                nr.Valor = visualizador.Transmissao.CodTemplateVisualizadorInicial + '';
                tScTr.addRow(nr);
            }

            //filtra os scripts para conter somente os do trecho atual
            tSc.unfilter(true);
            tSc.filter('CodTrecho', tTr.rows[itr].Codigo, filterMode.equals);

            //iteração dos scripts dos trechos
            for (var isc = 0; isc < tSc.rows.length; isc++) {

                rSc = tSc.rows[isc];

                var nr = tScTr.newRow();

                nr.IdxArquivo = itr;
                nr.Offset = rSc.Offset;
                nr.Codigo = rSc.Codigo;
                nr.Tipo = rSc.Tipo;
                nr.Valor = rSc.Valor;

                tScTr.addRow(nr);
            }

        } //iteração dos trechos

        var sb = new StringBuilder();
        sb.append('<br><br><b>scripts dos trechos</b><br>');

        for (var i = 0; i < tScTr.rows.length; i++) {
            sb.append(tScTr.rows[i].IdxArquivo + ' | ');
            sb.append(tScTr.rows[i].Offset + ' | ');
            sb.append(tScTr.rows[i].Codigo + ' | ');
            sb.append(tScTr.rows[i].Tipo + ' | ');
            sb.append(tScTr.rows[i].Valor + ' <br> ');
        }

        sb.append('<br><br><br>');

        trace(sb.toString());

        return tScTr;
    },


    populateTableIndice: function (tTr, tIdx) {

        if (visualizador.Transmissao.AoVivo) { return; }

        if (tTr == null || tIdx == null || tTr.rows.length == 0) { return }

        var dtIdxVis = new DataTable();
        dtIdxVis.addColumn('ObjId', 'System.String');
        dtIdxVis.addColumn('IdxArquivo', 'System.Int32');
        dtIdxVis.addColumn('Arquivo', 'System.String');
        dtIdxVis.addColumn('Nome', 'System.String');
        dtIdxVis.addColumn('OffSet', 'System.Int32');
        dtIdxVis.addColumn('OffSetTotal', 'System.Int32');
        dtIdxVis.addColumn('CSS', 'System.String');
        dtIdxVis.addColumn('CSSSEL', 'System.String');
        dtIdxVis.addColumn('SubIndice', 'System.Boolean');

        var timebefore = 0;

        //iteração dos trechos
        for (var itr = 0; itr < tTr.rows.length; itr++) {

            rTr = tTr.rows[itr];

            var nr = dtIdxVis.newRow();

            nr.ObjId = 'WebCasters_CodTrecho' + rTr.Codigo;
            nr.IdxArquivo = itr;
            nr.Arquivo = rTr.NomeArquivo;
            nr.Nome = rTr.Nome;
            nr.CSS = 'WebCastersIndiceArquivo';
            nr.CSSSEL = 'WebCastersIndiceArquivoSelecionado';
            nr.SubIndice = false;
            nr.OffSet = 0;
            nr.OffSetTotal = timebefore;

            dtIdxVis.addRow(nr);

            //filtra os indices para conter somente os do trecho atual
            tIdx.unfilter(true);
            tIdx.filter('CodTrecho', rTr.Codigo, filterMode.equals);

            //iteração dos indices dos trechos
            for (var idx = 0; idx < tIdx.rows.length; idx++) {

                rIdx = tIdx.rows[idx];

                var nr = dtIdxVis.newRow();

                nr.ObjId = 'WebCasters_CodTrecho' + tTr.Codigo + '_CodIndice' + rIdx.Codigo;
                nr.IdxArquivo = itr;
                nr.Arquivo = rTr.NomeArquivo;
                nr.Nome = rIdx.Nome;
                nr.CSS = 'WebCastersSubIndiceArquivo';
                nr.CSSSEL = 'WebCastersSubIndiceArquivoSelecionado';
                nr.SubIndice = true;
                nr.OffSet = rIdx.OffSet;
                nr.OffSetTotal = timebefore + rIdx.OffSet;

                dtIdxVis.addRow(nr);
            }

            timebefore += rTr.Duracao;

        } // end main for

        return dtIdxVis;
    },


    runScriptCommand: function (type, value) {

        switch (type) {
            case 1: //Envio de Slides

                var urlImagem = value;

                //se já tiver http é a imagem padrão
                if (urlImagem != '' && urlImagem.indexOf("http://") == -1) {

                    //Monta a url da imagem do slide
                    var urlImagem = visualizador.pathSlidesList[visualizador.idxPathSlides] + value;

                    if (value.toLowerCase().indexOf('.jpg') == -1
			           && value.toLowerCase().indexOf('.jpeg') == -1
			           && value.toLowerCase().indexOf('.png') == -1
			           && value.toLowerCase().indexOf('.gif') == -1) {

                        //urlImagem = visualizador.Transmissao.PathSlides + value + '.jpg';
                        urlImagem = visualizador.pathSlidesList[visualizador.idxPathSlides] + value + '.jpg';

                    }
                }

                //define a imagem como sendo o slide atual da transmissão
                visualizador.Transmissao.SlideAtual = urlImagem;

                //carrega o slide
                indirectRun(template.loadSlide);
                indirectRun(function () { template.btnClick(template.slides); });

                break;



            case 3: //Envio de Enquete 

                if (value != '') {

                    var codEnqueteTransmissao = parseInt(value);

                    indirectRun(function () { gerenciadorEnquete.abrir(codEnqueteTransmissao); });
                    indirectRun(function () { template.btnClick(template.enquetes); });
                }

                break;



            case 4: //Envio de Legenda

                var legenda = value;

                indirectRun(function () { template.setLegenda(legenda); });

                break;



            case 6: //Envio de Troca de Template de Visualizador

                if (value != '') {

                    var codTemplateVisualizador = parseInt(value);

                    indirectRun(function () { visualizador.loadTemplate(codTemplateVisualizador); });
                }

                break;




            case 7: //WMC terminou a transmissão
                alert('essa transmissão terminou');
                window.location.reload();
                break;




            default:
                trace('Código de script não identificado');
                break;
        }
    },


    Bloquear: function (mensagem) {
        if (visualizador.IframeTemplate != null) {
            visualizador.IframeTemplate.style.display = 'none';
        }

        wcplayer.stop();
        wcplayer.visible(false);

        document.getElementById("divWebCastersMensagem").style.display = 'block';
        document.getElementById("divWebCastersMensagemContainer").style.display = 'block';
        document.getElementById("divWebCastersMensagem").innerHTML = mensagem;
    },


    getHTMLPalestrante: function (cod) {
        var sb = new StringBuilder();

        var idxPal = visualizador.Palestrantes.indexOf('Codigo', cod);
        if (idxPal > -1) {
            var pal = visualizador.Palestrantes.rows[idxPal];

            sb.append('<div class=WebCastersInfoTransmissaoPalestranteNome >' + pal.Nome + '</div>');

            sb.append('<div class=WebCastersInfoTransmissaoPalestranteDescricao >');

            if (pal.ArquivoFoto != '') {
                sb.append('<img class=WebCastersInfoTransmissaoPalestranteFoto src="' + visualizador.ROOT_PATH + 'usuarios/' + pal.ArquivoFoto + '" />');
            }

            sb.append(pal.Descricao + '</div>');

        }

        sb.append('<div class=WebCastersInfoTransmissaoPalestranteVoltar onclick=parent.template.infoTransmissaoClick() >voltar</div>');

        trace('creating html for palestrante ' + cod);
        return sb.toString();
    },

    getHTMLInfoTransmissao: function () {

        if (visualizador.htmlInfoTransmissao != null) { return visualizador.htmlInfoTransmissao; }

        var sb = new StringBuilder();
        var dtTra = visualizador.Transmissao;


        //Coloca os dados da transmissão 
        sb.append('<div class=WebCastersInfoTransmissao>');
        sb.append('<div class=WebCastersInfoTransmissaoNome >' + dtTra.Nome.htmlEncode() + '</div>');
        sb.append('<div class=WebCastersInfoTransmissaoInicio >Início previsto para: ' + dtTra.DataInicio.toString('dd/MM/yyyy') + ' às ' + dtTra.DataInicio.toString('HH:mm') + '</div>');
        sb.append('<div class=WebCastersInfoTransmissaoFim >Fim previsto para: ' + dtTra.DataFim.toString('dd/MM/yyyy') + ' às ' + dtTra.DataFim.toString('HH:mm') + '</div>');
        if (!dtTra.AoVivo) {
            sb.append('<div class=WebCastersInfoTransmissaoDuracao >Duração: ' + template._mstotime(dtTra.Duracao) + '</div>');
        }

        if (dtTra.ExibeDescricaoFicha) {
            sb.append('<div class=WebCastersInfoTransmissaoDescricao >' + dtTra.Descricao.htmlEncode() + '</div>');
        }
        sb.append('</div>');

        var dtAge = visualizador.Agendas;
        var dtPal = visualizador.Palestrantes;

        sb.append('<div class=WebCastersInfoTransmissaoAgendas >');

        if (dtAge.rows.length > 0) { sb.append('<div class=WebCastersInfoTransmissaoAgendasTitulo >Agendas</div>'); }

        for (var i = 0; i < dtAge.rows.length; i++) {

            sb.append('<div class=WebCastersInfoTransmissaoAgenda >');
            sb.append('<div class=WebCastersInfoTransmissaoAgendaNome >' + dtAge.rows[i].Nome.htmlEncode() + '</div>');


            if (!dtAge.rows[i].EscondeData) {
                sb.append('<div class=WebCastersInfoTransmissaoAgendaData >');

                if (dtTra.DataInicio.toString('dd/MM/yyyy') != dtAge.rows[i].DataHoraInicio.toString('dd/MM/yyyy')) {
                    sb.append('de ' + dtAge.rows[i].DataHoraInicio.toString('dd/MM/yyyy') + ' &agrave;s ');
                }

                sb.append(dtAge.rows[i].DataHoraInicio.toString('HH:mm'));

                sb.append(' at&eacute; ');

                if (dtTra.DataInicio.toString('dd/MM/yyyy') != dtAge.rows[i].DataHoraInicio.toString('dd/MM/yyyy')) {
                    sb.append(' ' + dtAge.rows[i].DataHoraFim.toString('dd/MM/yyyy') + ' &agrave;s ');
                }

                sb.append(dtAge.rows[i].DataHoraFim.toString('HH:mm'));

                sb.append('</div>');
            }

            if (dtAge.rows[i].Descricao.trim() != '') {
                sb.append('<div class=WebCastersInfoTransmissaoAgendaDescricao >' + dtAge.rows[i].Descricao.htmlEncode() + '</div>');
            }

            sb.append('<div class=WebCastersInfoTransmissaoPalestrantes >');


            if (dtAge.rows[i].CodPalestrantes != '') {
                var lstPal = dtAge.rows[i].CodPalestrantes.split(';');

                if (lstPal.length > 0) { sb.append('<div class=WebCastersInfoTransmissaoPalestrantesTitulo >Palestrantes:</div>'); }

                for (var ip = 0; ip < lstPal.length; ip++) {
                    if (lstPal[ip] == '') { continue; }

                    var idxPal = dtPal.indexOf('Codigo', lstPal[ip]);
                    if (idxPal == -1) { continue; }
                    var pal = dtPal.rows[idxPal];


                    sb.append('<div class=WebCastersInfoTransmissaoPalestranteNomeLista onclick=parent.template.palestranteClick(' + pal.Codigo + ') >');
                    sb.append(pal.Nome.htmlEncode() + '</div>');

                }
            }

            sb.append('</div>');
            sb.append('</div>');
        }

        sb.append('</div>');

        trace('creating html for infoTransmissao');

        visualizador.htmlInfoTransmissao = sb.toString();
        return visualizador.htmlInfoTransmissao;

    },

    getHTMLArquivosAuxiliares: function () {
        if (visualizador.ArquivosAuxiliares == null) { return ''; }
        if (visualizador.htmlArquivosAuxiliares != null) { return visualizador.htmlArquivosAuxiliares; }

        var sb = new StringBuilder();
        var dt = visualizador.ArquivosAuxiliares;

        sb.append('<table width=100% >');

        for (var i = 0; i < dt.rows.length; i++) {
            sb.append('<tr><td align=center valign=middle width=28px>');
            sb.append('<a href="' + visualizador.ROOT_PATH + 'DownloadArquivoAuxiliar.aspx?nome=' + dt.rows[i].Arquivo + '" target=_blank>');
            sb.append('<img src=' + visualizador.ROOT_PATH + 'images/download.gif width=12px height=12px border=0 />');
            sb.append('</a>');
            sb.append('</td>');
            sb.append('<td>');
            sb.append('<div class=WebCastersArquivosAuxiliaresNome >' + dt.rows[i].ArquivoOriginal.htmlEncode() + '</div>');
            if (dt.rows[i].Descricao != '') {
                sb.append('<div class=WebCastersArquivosAuxiliaresDescricao >' + dt.rows[i].Descricao.htmlEncode() + '</div>');
            }
            sb.append('</td></tr>');
            sb.append('<tr><td>&nbsp;</td><td>&nbsp;</td></tr>');

        }
        if (dt.rows.length < 1) {
            sb.append('<tr><td class=WebCastersArquivosAuxiliaresNome >N&atilde;o h&aacute; material para essa transmiss&atilde;o.</td></tr>');
        }

        sb.append('</table>');

        trace('creating html for ArquivosAuxiliares');

        visualizador.htmlArquivosAuxiliares = sb.toString();
        return visualizador.htmlArquivosAuxiliares;
    },

    getHTMLAjuda: function () {
        if (visualizador.htmlAjuda != null) { return visualizador.htmlAjuda; }

        var sb = new StringBuilder();
        sb.append('<div class=WebCastersAjudaTitulo >Ajuda</div>');

        sb.append('<div class=WebCastersAjudaParagrafo >');
        sb.append('<span class=WebCastersAjudaItem >Janela do Video: </span>');
        sb.append('<span class=WebCastersAjudaTexto >Abaixo do video existem bot&otilde;es que voc&ecirc; pode usar para controlar a aparencia ');
        sb.append('e o funcionamento da apresenta&ccedil;&atilde;o. Neles voc&ecirc; poder&aacute; alterar o tamanho do ');
        sb.append('video, verificar o status da transmiss&atilde;o e mudar o volume do ');
        sb.append('webcast.<br/>Durante o webcast legendas ser&atilde;o apresentadas para informar pontos ');
        sb.append('interessantes sobre o que esta acontecendo durante cada passo da apresenta&ccedil;&atilde;o.</span>');
        sb.append('</div>');

        sb.append('<div class=WebCastersAjudaParagrafo >');
        sb.append('<span class=WebCastersAjudaItem >Slides: </span>');
        sb.append('<span class=WebCastersAjudaTexto >');
        sb.append('Nesta janela voc&ecirc;');
        sb.append('receber&aacute; as imagens da m&aacute;quina do apresentador. Normalmente essa imagem &eacute; um ');
        sb.append('slide do powerpoint do apresentador.');
        sb.append('</span>');
        sb.append('</div>');

        sb.append('<div class=WebCastersAjudaParagrafo >');
        sb.append('<span class=WebCastersAjudaItem >Formularios: </span>');
        sb.append('<span class=WebCastersAjudaTexto >');
        sb.append('Nesta janela ');
        sb.append('voc&ecirc; poder&aacute; responder a perguntas ou pesquisas enviadas pelo palestrante ao ');
        sb.append('p&uacute;blico da internet no decorrer da apresenta&ccedil;&atilde;o.');
        sb.append('</span>');
        sb.append('</div>');

        sb.append('<div class=WebCastersAjudaParagrafo >');
        sb.append('<span class=WebCastersAjudaItem >Ficha T&eacute;cnica: </span>');
        sb.append('<span class=WebCastersAjudaTexto >');
        sb.append('Esta janela ');
        sb.append('cont&eacute;m informa&ccedil;ões sobre todas as palestras do evento e seus respectivos ');
        sb.append('palestrantes. Para saber mais informa&ccedil;&otilde;es sobre um palestrante, clique sobre o ');
        sb.append('seu nome.');
        sb.append('</span>');
        sb.append('</div>');

        sb.append('<div class=WebCastersAjudaParagrafo >');
        sb.append('<span class=WebCastersAjudaItem >Painel Chat: </span>');
        sb.append('<span class=WebCastersAjudaTexto >');
        sb.append('O chat permite ');
        sb.append('que voc&ecirc; converse com as outras pessoas que est&atilde;o assistindo a apresenta&ccedil;&atilde;o e ');
        sb.append('com o palestrante.');
        sb.append('</span>');
        sb.append('</div>');


        trace('creating html for Ajuda');

        visualizador.htmlAjuda = sb.toString();
        return visualizador.htmlAjuda;
    }


};







var streamManager = {

    ListaServidores: null,

    idxServidor: 0,  // indice do servidor atual
    idxProtocols: 0, // indice do protocolo atual

    idxArquivoAtual: 0,

    retryFromBeginning: false,

    protocols: null,

    idxVelocidadeSelecionada: 0,
    velocidadeSelecionada: '',

    servidoresCelular: null,

    playingWmv: true,

    init: function () {

        streamManager.loadDefaultVelocidade();

        // puts the default protocol in first position
        switch (visualizador.Transmissao.Protocolo) {
            case 'mms': streamManager.protocols = new Array('mms', 'http', 'rtsp'); break;
            case 'http': streamManager.protocols = new Array('http', 'mms', 'rtsp'); break;
            case 'rtsp': streamManager.protocols = new Array('rtsp', 'mms', 'http'); break;
            default: streamManager.protocols = new Array('mms', 'http', 'rtsp'); break;
        }

        if (wcplayer.PlaysMp4()) {
            streamManager.carregaServidoresCelular();
            streamManager.playingWmv = false;
            wcplayer.LOW_BUFFER_COUNT_LIMIT = 100;
        }


    },

    carregaServidoresCelular: function () {
        var res = WCAjax.ServidorCelularOnDemand_Busca();

        if (res.error) {
            trace("ERRO: carregaServidoresCelular : " + res.error.message);
            return;
        }

        if (res.value.rows.length < 1) {
            alert("Não há servidor de H264 configurado.");
        }


        streamManager.servidoresCelular = res.value;

        if (visualizador.Transmissao.AoVivo) {

        }

    },

    GetListaServidores: function () {
        if (streamManager.playingWmv) {
            return streamManager.ListaServidores;
        }

        return streamManager.servidoresCelular;

    },

    loadDefaultVelocidade: function () {

        //idx 0 is the first auto option
        var vb = '';
        var ivb = 0;

        var va = '';
        var iva = 0;

        var idx = 0;

        if (visualizador.Transmissao.Velocidade1 > 0) {
            idx++;

            if (vb == '' || visualizador.Transmissao.Velocidade1 < vb) {
                ivb = idx;
                vb = visualizador.Transmissao.Velocidade1;
            }

            if (va == '' || visualizador.Transmissao.Velocidade1 > va) {
                iva = idx;
                va = visualizador.Transmissao.Velocidade1;
            }
        }

        if (visualizador.Transmissao.Velocidade2 > 0) {
            idx++;

            if (vb == '' || visualizador.Transmissao.Velocidade2 < vb) {
                ivb = idx;
                vb = visualizador.Transmissao.Velocidade2;
            }

            if (va == '' || visualizador.Transmissao.Velocidade2 > va) {
                iva = idx;
                va = visualizador.Transmissao.Velocidade2;
            }
        }

        if (visualizador.Transmissao.Velocidade3 > 0) {
            idx++;

            if (vb == '' || visualizador.Transmissao.Velocidade3 < vb) {
                ivb = idx;
                vb = visualizador.Transmissao.Velocidade3;
            }

            if (va == '' || visualizador.Transmissao.Velocidade3 > va) {
                iva = idx;
                va = visualizador.Transmissao.Velocidade3;
            }
        }


        //0:auto, 1:baixa, 2: alta 
        switch (visualizador.Cliente.DefaultVelocidade) {

            case 1:
                streamManager.idxVelocidadeSelecionada = ivb;
                streamManager.velocidadeSelecionada = vb;
                break;

            case 2:
                streamManager.idxVelocidadeSelecionada = iva;
                streamManager.velocidadeSelecionada = va;
                break;

            default:
                streamManager.idxVelocidadeSelecionada = 0;
                streamManager.velocidadeSelecionada = '';
                break;

        }
    },


    GetStream: function () {

        wcplayer._dvp.style.backgroundImage = 'url(images/loadwcplayer.gif)';


        if (wcplayer.PlaysMp4()) {
            streamManager.GetMp4Stream();
            return;
        }

        return streamManager.GetWmaStream();

    },

    GetWmaStream: function () {
        // todos os protocolos já foram testados no servidor atual
        if (streamManager.idxProtocols == streamManager.protocols.length) {
            streamManager.idxServidor++;
            streamManager.idxProtocols = 0;
        }

        if (streamManager._GetWmaStream()) {
            // se deu certo vai embora
            return;
        }

        // se não deu certo, tenta o próximo servidor/protocolo
        indirectRun(streamManager.NextSource);

    },

    _GetWmaStream: function () {

        var servidor = streamManager.ListaServidores.rows[streamManager.idxServidor];
        var pbPoint = visualizador.PPoint.Nome;
        var nomeArqAtual = '';

        if (!visualizador.Transmissao.AoVivo) {
            nomeArqAtual = visualizador.TrechosOnDemand.rows[streamManager.idxArquivoAtual].NomeArquivo;
        }


        // se for espelho, muda o nome do publishing point
        if (servidor.Espelho == true) {
            // teoricamente, o índice 0 sempre é o publishing point 'princial'
            pbPoint = visualizador.PPoint_espelho;

        }

        trace('DEBUG: streamManager._GetWmaStream :: '
            + (servidor.Nome == null ? servidor.Ip : servidor.Nome)
            + ', ' + pbPoint
            + ', ' + streamManager.protocols[streamManager.idxProtocols]
            + ', vel:' + streamManager.velocidadeSelecionada
            + ', arq:' + nomeArqAtual);

        // TODO: DESGAMBIARRAR ISSO
        // SE A TRANSMISSÃO FOR ON DEMAND, E O SERVIDOR FOR SEM CDN, 
        // CORRIGE O NOME DO PUBLISHING POINT.
        // AVERIGUAR SE ESSA É A MELHOR SOLUÇÃO (TALVEZ SEJA MELHOR FAZER SERVERSIDE)
        try {
            if (visualizador.Transmissao.AoVivo == false && servidor.CDN == false) {
                pbPoint = visualizador.Cliente.Nome + "_" + pbPoint;
            }

        } catch (e) {
            trace("DEBUG: streamManager._GetWmaStream ppnamemake error : " + e.Message);
        }


        var res = VisualizadorServer.StreamRequire(visualizador.Usuario.Codigo
           , visualizador.Sessao.Codigo
           , pbPoint
           , visualizador.TransmissaoConsomeCredito
           , visualizador.ConsomeAcessoTransmissao
           , visualizador.Transmissao.AoVivo
           , visualizador.Transmissao.CodCategoria
           , visualizador.Transmissao.Codigo
           , nomeArqAtual
           , streamManager.velocidadeSelecionada
           , streamManager.protocols[streamManager.idxProtocols]
           , servidor.CDN
           , servidor.Ip
           , servidor.URLPublicarStream);


        if (visualizador.ajaxErrorCheck(res) != 1) {
            return false;
        }

        wcplayer.setUrl(res.value);
        //se voltou valor uma url para o vídeo, não deu erro e já consumiu o acesso que precisava
        if (visualizador.ConsomeAcessoTransmissao) {
            trace('visualizador.ConsomeAcessoTransmissao = false');
            visualizador.ConsomeAcessoTransmissao = false;
        }

        return true;

    },


    GetMp4Stream: function () {
        trace("INFO : Buscando url do vídeo h264 ... ");

        var suporta = true;

        if (visualizador.Transmissao.CelularHabilitado == false) {
            suporta = false;
        }

        if (visualizador.Transmissao.CelularDisponivel == false &&
            visualizador.Transmissao.CelularAoVivoDisponivel == false) {
            suporta = false;
        }

        if (!suporta) {
            trace('WARNING: H246 indisponível : ');
            trace('WARNING: Habilitado: ' + visualizador.Transmissao.CelularHabilitado);
            trace('WARNING: OD-Disponível: ' + visualizador.Transmissao.CelularDisponivel);
            trace('WARNING: Live-Disponível: ' + visualizador.Transmissao.CelularAoVivoDisponivel);

            alert('Atenção: sua plataforma não suporta o conteúdo disponível.\nEntre em contato com o suporte.');

            return;
        }

        var tipoPlayer = wcplayer._player.type == wcplayer.types.VIDEO_TAG
            ? "videoTag" // atenção, esses string estão pareados com strings no serverside
            : "flash";

        var res = VisualizadorServer.GetMp4Stream(
            visualizador.Transmissao.Codigo,
            visualizador.Sessao.Codigo,
            streamManager.servidoresCelular.rows[0].CodServidorCelular,
            tipoPlayer);

        if (res.error) {
            trace("ERROR : Erro ao buscar url do vídeo " + res.error.message);
            // tentar no próximo servidor
            indirectRun(streamManager.NextSource);
        }

        wcplayer.setUrl(res.value);

        return;

    },


    NextSource: function () {
        // se o pedido anterior falhou, e está marcado
        // para tentar do começo, zera tudo, e vai.
        if (streamManager.retryFromBeginning == true) {
            trace('Tentando servidores do começo');
            streamManager.idxServidor = 0;
            streamManager.idxProtocols = 0;

            streamManager.retryFromBeginning = false;

            indirectRun(streamManager.GetStream);
            return;
        }


        var servidores = streamManager.GetListaServidores();

        streamManager.idxProtocols++; //try next protocol

        if (streamManager.playingWmv &&
            streamManager.idxProtocols < streamManager.protocols.length) {

            template.setInformacao('Tentando "' + streamManager.protocols[streamManager.idxProtocols] + '"', 3000);

            indirectRun(streamManager.GetStream);
            return;
        }

        streamManager.idxProtocols = 0;

        streamManager.idxServidor++;

        //protocol's list is finished; try next server
        if (streamManager.idxServidor < servidores.rows.length) {

            template.setInformacao('Próximo servidor', 3000);
            indirectRun(streamManager.GetStream);

            return;
        }

        streamManager.idxServidor = 0;

        wcplayer._dvp.style.backgroundImage = 'url(images/error.gif)';

        template.setInformacao('Falha na conexão.', 10000);

        trace('Todos servidores foram testados sem sucesso');
        alert('Atenção: Sua conexão falhou.\nPressione F5 para reconectar.');

    },



    SetServerById: function (id) {
        if (!id) {
            id = 0;
        }

        streamManager.idxServidor = id;
        streamManager.retryFromBeginning = true;

        streamManager.GetStream();

    },


    // Tenta tocar o próximo arquivo.
    // se for tocar o próximo, retorna true
    // caso contrário, false
    NextFile: function () {

        if (visualizador.Transmissao.AoVivo) {
            return;
        }

        // em mp4, é tudo num arquivo só
        if (!streamManager.playingWmv) {
            return;
        }

        // se ainda tem arquivos para tocar,
        if (streamManager.idxArquivoAtual < visualizador.TrechosOnDemand.rows.length - 1) {

            streamManager._ChangeFile(streamManager.idxArquivoAtual + 1, 0);

            return;
        }

        trace('INFO: streamManager: all files played');

    },



    SetFileByIndex: function (idxIndice) {
        var indice = visualizador.Indices.rows[idxIndice];

        streamManager._ChangeFile(indice.IdxArquivo, indice.OffSet);

    },

    SetAbsoluteTime: function (time) {
        var idx = streamManager.getFileIndexByAbsoluteTime(time);

        // current file's offset
        var offsetTime = time - streamManager.timeBeforeArquivo(idx);

        streamManager._ChangeFile(idx, offsetTime);

    },


    // condição empacotada
    // se estiver tocando MP4 não há outro arquivo a ser tocado
    _ChangeFile: function (idx, offsetTime) {

        if (streamManager.playingWmv) {
            streamManager._ChangeFile_WMV(idx, offsetTime);
        } else {
            streamManager._ChangeFile_H264(idx, offsetTime);
        }

        template.indicesSetSelection();
    },

    _ChangeFile_WMV: function (idx, offsetTime) {
        if (streamManager.idxArquivoAtual != idx) {

            streamManager.idxArquivoAtual = idx;
            wcplayer.offset = offsetTime; //will seek after load the file

            streamManager.GetWmaStream();

        }
        else {
            wcplayer.current(offsetTime);

        }
    },

    _ChangeFile_H264: function (idx, offsetTime) {

        wcplayer.current(offsetTime + streamManager.timeBeforeArquivo(idx));

    },


    timeBeforeArquivoAtual: function () {
        return streamManager.timeBeforeArquivo(streamManager.idxArquivoAtual);
    },

    timeBeforeArquivo: function (idxarq) {

        var dr = visualizador.TrechosOnDemand.rows;

        var timeBefore = 0;

        for (var i = idxarq - 1; i > -1; i--) {
            timeBefore += dr[i].Duracao;
        }

        return timeBefore;
    },

    getFileIndexByAbsoluteTime: function (time) {

        var d = visualizador.Transmissao.Duracao;

        var dr = visualizador.TrechosOnDemand.rows;

        //gets the index of the file that contains the desire seek time 
        var idx = 0;

        while (idx < dr.length && streamManager.timeBeforeArquivo(idx) <= time) {
            idx++;
        }
        idx--;

        return idx;

    }



};
