﻿// JScript File


function onSilverlightError(sender, args) {
    trace("ERROR: onSilverlightError()");
    var appSource = "";
    if (sender != null && sender != 0) {
        appSource = sender.getHost().Source;
    }

    var errorType = args.ErrorType;
    var iErrorCode = args.ErrorCode;

    if (errorType == "ImageError" || errorType == "MediaError") {
        return;
    }

    var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";

    errMsg += "Code: " + iErrorCode + "    \n";
    errMsg += "Category: " + errorType + "       \n";
    errMsg += "Message: " + args.ErrorMessage + "     \n";

    if (errorType == "ParserError") {
        errMsg += "File: " + args.xamlFile + "     \n";
        errMsg += "Line: " + args.lineNumber + "     \n";
        errMsg += "Position: " + args.charPosition + "     \n";
    }
    else if (errorType == "RuntimeError") {
        if (args.lineNumber != 0) {
            errMsg += "Line: " + args.lineNumber + "     \n";
            errMsg += "Position: " + args.charPosition + "     \n";
        }
        errMsg += "MethodName: " + args.methodName + "     \n";
    }

    throw new Error(errMsg);
}



function silverlightPluginOnLoaded(sender, args) {
    trace('silverlightPluginOnLoaded');

    wcWMPlayer.isSilverlight = true;
    wcWMPlayer.Initialize(sender.getHost().Content.MainPageVisualizador);
    wcplayer._player = wcWMPlayer;

    wcplayer._PlayerActivated();

}


var wcplayer = {
    _dvp: null,

    _player: null,
    _currentState: -1,

    // determina se está disponível para 
    // tocar com flash ou html5
    CelularDisponivel: false,

    _playerReady: false,

    _playsMp4: false,
    _playsWm: false,

    types: {
        WINDOWS_MEDIA_PLAYER: 'wmp',
        SILVERLIGHT: 'silver',
        VIDEO_TAG: 'videotag',
        FLASH: 'flash'
    },


    init: function () {
        wcplayer._dvp = $('divWebCastersPlayer');

        var plataforma = navigator.platform.toLowerCase();
        var bName = navigator.appName.toLowerCase();

        trace('PlayerManager | plataforma: ' + plataforma);
        trace('PlayerManager | browser: ' + bName);
        trace('PlayerManager | userAgent: ' + navigator.userAgent);

        // força o tipo de player
        if (Request.queryString("html5") == "true") {
            indirectRun(wcplayer._initPlayerHtml5);
            return;
        }
        if (Request.queryString("flash") == "true") {
            indirectRun(wcplayer._initPlayerFlash);
            return;
        }
        if (Request.queryString("silver") == "true") {
            indirectRun(wcplayer._initPlayerSilver);
            return;
        }


        var userAgent = navigator.userAgent.toLowerCase();

        // testa se a configuração força o uso de flash / tagvideo
        if (visualizador.Transmissao.H264Desktop == true) {
            if (userAgent.indexOf('ipod') != -1
                || userAgent.indexOf('ipad') != -1
                || userAgent.indexOf('iphone') != -1) {
                wcplayer._initPlayerHtml5();
            } else {
                wcplayer._initPlayerFlash();
            }
            return;

        }

        if (userAgent.indexOf('msie') != -1) {
            // se for windows
            wcplayer._initPlayerWindows(navigator);
        }
        else if (userAgent.indexOf('android') != -1
            || plataforma.indexOf('linux arm') != -1) {
            // se for android
            wcplayer._initPlayerFlash();
        }
        else if (userAgent.indexOf('ipod') != -1
            || userAgent.indexOf('ipad') != -1
            || userAgent.indexOf('iphone') != -1) {
            wcplayer._initPlayerHtml5();
        } else {
            // em todos os outros casos
            wcplayer._initPlayerSilver();
        }

    },

    // se for windows
    _initPlayerWindows: function (navegador) {
        // se for internet explorer
        if (navigator.appName.indexOf('Exp') != -1) {
            indirectRun(wcplayer._initPlayerWM);
            return;
        }

        indirectRun(wcplayer._initPlayerSilver);

    },

    _initPlayerWM: function () {

        trace('PlayerManager | initializing : WindowsMediaPlayer');

        var sb = new StringBuilder();

        //WindowsMedia Object
        sb.append('<object');
        sb.append(' viewastext');
        sb.append(' id="objWindowsMediaPlayer" ');
        sb.append(' classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95" ');
        sb.append(' standby="Loading Microsoft® Windows® Media Player components..." ');
        sb.append(' type="application/x-oleobject" ');
        sb.append(' style="position:absolute; ');
        sb.append('        visibility:visible; ');
        sb.append('        left:0px; top:0px; ');
        sb.append('        width:100%; height:100%;"> ');
        sb.append('         <param name="AnimationatStart" value="true" /> ');
        sb.append('         <param name="ShowControls" value="false" /> ');
        sb.append('         <param name="TransparentatStart" value="false" /> ');
        sb.append('         <param name="AutoStart" value="True" /> ');
        sb.append('         <param name="UIMode" value="none" /> ');
        sb.append('</object> ');

        wcplayer._dvp.innerHTML = sb.toString();

        indirectRun(wcplayer._testeWMP);

    },

    // testa se criou o WMP
    _testeWMP: function () {

        if (!$('objWindowsMediaPlayer')) {
            indirectRun(wcplayer._testeWMP);
            return;
        }

        wcWMPlayer.Initialize($('objWindowsMediaPlayer'));
        wcplayer._player = wcWMPlayer;

        wcplayer._player.ShowTracker = false;
        wcplayer._player.ShowPositionControls = false;
        wcplayer._player.ShowStatusBar = false;
        wcplayer._player.ShowAudioControls = false;
        wcplayer._player.ShowControls = false;

        wcplayer._PlayerActivated();
    },



    _initPlayerSilver: function () {

        trace('PlayerManager | initializing : Silverlight');

        var sb = new StringBuilder();

        //Silverlight Object
        sb.append('<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" '); // width="100%" height="100%">
        sb.append(' id="objSilverlightPlayer" ');
        sb.append(' style="position:absolute; ');
        sb.append('        visibility:visible; ');
        sb.append('        left:0px; top:0px; ');
        sb.append('        width:100%; height:100%;"> ');
        sb.append(' <param name="source" value="VideoPlayer.xap"/> ');
        sb.append(' <param name="onLoad" value="silverlightPluginOnLoaded" /> ');
        sb.append(' <param name="onError" value="onSilverlightError" /> ');
        sb.append(' <param name="background" value="white" /> ');
        sb.append(' <param name="minRuntimeVersion" value="3.0.40624.0" /> ');
        sb.append(' <param name="autoUpgrade" value="true" /> ');
        sb.append(' <param name="AutoPlay" value="true" /> ');
        sb.append(' <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration:none;"> ');
        sb.append('   <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none;position:absolute;left:0px;top:0px;height:100%;width:100%;"/> ');
        sb.append(' </a> ');
        sb.append(' </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px;"></iframe> ');

        trace('PlayerManager | SilverLight | creating object.');
        wcplayer._dvp.innerHTML = sb.toString();


    },




    _initPlayerHtml5: function () {
        trace('initializing WcPlayer: Html5 Video Tag');

        wcHtmlPlayer.Initialize();
        wcplayer._player = wcHtmlPlayer;


    },

    _initPlayerFlash: function () {
        trace('initializing WcPlayer: Flash Player');

        wcFlashPlayer.Initialize();

        wcplayer._player = wcFlashPlayer;

    },


    // testa se instanciou o player
    _PlayerActivated: function () {

        trace('PlayerManager | _PlayerActivated');

        wcplayer._playerReady = true;

        // memoriza qual o tipo de player
        wcplayer._playsMp4 =
            wcplayer._player.type == wcplayer.types.FLASH
            || wcplayer._player.type == wcplayer.types.VIDEO_TAG;

        wcplayer._playsWm =
            wcplayer._player.type == wcplayer.types.WINDOWS_MEDIA_PLAYER 
            || wcplayer._player.type == wcplayer.types.SILVERLIGHT;

        if (!wcplayer._playsMp4 && !wcplayer._playsWm) {
            trace("PlayerManager | _PlayerActivated | ERROR: loaded player type is unknown.");
            wcplayer._playerReady = false;
        }

        // futuramente, se for h264, esconde os controles
        if (wcplayer._player.type == wcplayer.types.VIDEO_TAG) {
            template.controlsVisibility = false;
            template.checkControlsVisibility();
        }

        //inicia sempre com o volume no máximo
        indirectRun(function () { wcplayer.volume(100); });

    },


    // vê se o objeto já foi criado
    CheckPlayer: function () {

        return wcplayer._playerReady;

    },


    PlaysWm: function () {
        return wcplayer._playsWm;
    },

    PlaysMp4: function () {
        return wcplayer._playsMp4;
    },


    handlerDisconnect: function (lResult) {
        trace('PlayerManager | SilverLight | handlerEndOfStream (' + lResult + ')');
        // lResult - Long value specifying the cause of the disconnection
    },

    handlerEndOfStream: function (lResult) {
        /* lResult - Long value specifying the status of the clip after it has finished playing.
        A value of zero indicates the clip completed successfully. */
        trace('PlayerManager | SilverLight | handlerEndOfStream(' + lResult + ')');

        streamManager.NextFile();

    },

    handlerNewStream: function () {
        trace('PlayerManager | SilverLight | handlerNewStream()');
    },



    /*
    WMP - Eventos listados em visualizador.aspx
    SilverLight - O player chama as funções "de dentro".
    */

    offset: null,

    BUFFERING_PROGRESS_TIME: 1500,

    handlerBuffering: function (bStart) {

        // trace('wcplayer.handlerBuffering(' + (bStart ? 'true' : 'false') + ')');

        if (bStart) {

            template.setInformacao('carregando... ', wcplayer.BUFFERING_PROGRESS_TIME);

            setTimeout(wcplayer._onStreamBuffering, wcplayer.BUFFERING_PROGRESS_TIME);

            wcplayer.current(wcplayer.offset);
            wcplayer.offset = null;

        } else {

            template.setInformacao('carregando: OK! ', wcplayer.BUFFERING_PROGRESS_TIME);

        }
    },


    _onStreamBuffering: function () {

        // se não está bufferizando, sai fora.
        if (wcplayer.CurrentState() != wcplayer.WM_STATE_WAITING) {
            trace('_onStreamBuffering: not in WM_STATE_WAITING');
            wcplayer.lowBufferCount = 0;
            return;
        }

        var buffPercent = wcplayer._player.GetBufferPercent();

        trace('_onStreamBuffering: ' + buffPercent + '%');

        if (!buffPercent) {
            template.setInformacao('carregando vídeo... ', wcplayer.BUFFERING_PROGRESS_TIME);
        }
        else {
            template.setInformacao('carregando: ' + buffPercent + '%', wcplayer.BUFFERING_PROGRESS_TIME);
        }

        if (wcplayer._lowBufferControl(buffPercent) == false) {
            return;
        }

        setTimeout(wcplayer._onStreamBuffering, wcplayer.BUFFERING_PROGRESS_TIME);

    },


    // XGH : LOW BUFFER CONTROL
    lowBufferCount: 0, // conta quantas vezes deu low buffer
    LOW_BUFFER_PERCENT: 5, // constante, abaixo de que porcentagem é low buffer
    LOW_BUFFER_COUNT_LIMIT: 10, // constante, máximo de low buffer antes de tentar o próximo servidor

    _lowBufferControl: function (bufferPercentage) {

        if (bufferPercentage < wcplayer.LOW_BUFFER_PERCENT) {
            trace('_lowBufferControl: low buffer.');
            wcplayer.lowBufferCount++;
        }
        else {
            wcplayer.lowBufferCount = 0;

        }

        if (wcplayer.lowBufferCount > wcplayer.LOW_BUFFER_COUNT_LIMIT) {
            trace('_lowBufferControl: low buffer count limit reached - trying another server.');
            wcplayer.lowBufferCount = 0;

            indirectRun(streamManager.NextSource);
            return false;
            // retorna false para indicar que não é mais pra tentar carregar o vídeo.

        }

        return true;
        // retorna true, para prosseguir com o carregamento do vídeo
    },




    SHOWING_STATE_TIME: 2000,
    _externalVisibility: true,
    _internalVisibility: true,

    handlerPlayStateChange: function (OldPlayState, PlayState) {

        trace('DEBUG: wcplayer: StateChange: ' + OldPlayState + ' - ' + PlayState);
        wcplayer._currentState = PlayState;

        // WARNING: for some reason, the Silverlight event listening
        //          behaves "monoprogrammed", sometimes the current thread
        //          is killed to start another function.
        //          So, the ondemand loop call block was brought up to avoid
        //          some Siverlight's nightmares
        if (visualizador.Transmissao.AoVivo == false
            && PlayState == wcplayer.WM_STATE_PLAYING) {

            // se for onDemand, 
            if (wcplayer.ONDEMAND_PLAYING_LOOP_WORKING == false) {
                wcplayer._onDemandPlayingLoop();
            }
            
            //if it is ondemand and has started to play, load last state of events from scripts
            indirectRun(function () { wcplayer.scriptHandlerArquivo(true); });
        }


        wcplayer._internalVisibility = true;
        wcplayer._toggleVisibility();

        indirectRun(template.btnPlayVisualState);


        if (PlayState == wcplayer.WM_STATE_PLAYING) {
            wcplayer._onPlaying(OldPlayState);
        }
        else if (OldPlayState == wcplayer.WM_STATE_PLAYING) {
            wcplayer._wasPlaying(PlayState);
        }
        else if (PlayState == wcplayer.WM_STATE_WAITING) {
            template.setInformacao('aguarde, carregando', wcplayer.SHOWING_STATE_TIME);
        }
        else {
            template.setInformacao('aguarde...', wcplayer.SHOWING_STATE_TIME);

        }

        wcplayer._waitingTooMuchControl(PlayState);

    },


    _onPlaying: function (OldPlayState) {

        if (OldPlayState == wcplayer.WM_STATE_PAUSED ||
            OldPlayState == wcplayer.WM_STATE_STOPPED) {
            // se estava parado
            template.setInformacao('tocando', wcplayer.SHOWING_STATE_TIME);
            return;
        }

        if (OldPlayState != wcplayer.WM_STATE_WAITING) {
            return;
        }

        // se estava bufferizando
        var kbps = '';
        var bw = wcplayer._player.GetBandwidth();

        if (!bw) {
            template.setInformacao('tocando.', wcplayer.SHOWING_STATE_TIME);
            return;
        }

        kbps = Math.floor(bw / 1000) + 'Kbps';

        // wait a little while before show playing message
        setTimeout(function () {
            template.setInformacao('tocando ' + kbps, wcplayer.SHOWING_STATE_TIME);
        }, wcplayer.BUFFERING_PROGRESS_TIME);



    },

    _wasPlaying: function (PlayState) {
        if (PlayState == wcplayer.WM_STATE_STOPPED) {
            template.setInformacao('parado', wcplayer.SHOWING_STATE_TIME);
        }
        else if (PlayState == wcplayer.WM_STATE_PAUSED) {
            template.setInformacao('pausado', wcplayer.SHOWING_STATE_TIME);
        }
        else {
            template.setInformacao('aguarde...', wcplayer.SHOWING_STATE_TIME);
        }
    },


    // XGH : WAITING TOO MUCH CONTROL
    _waitingCounter: 0,
    _WAITING_STATE_COUNT_LIMIT: 30,

    _waitingTooMuchControl: function (PlayState) {
        if (PlayState == wcplayer.WM_STATE_WAITING) {
            wcplayer._waitingCounter++;
            trace("XGH: _waitingTooMuchControl: waiting...");
        }
        else {
            wcplayer._waitingCounter = 0;
        }

        if (wcplayer._waitingCounter > wcplayer._WAITING_STATE_COUNT_LIMIT) {
            trace("XGH: _waitingTooMuchControl: waiting state count limit reached - trying next server");
            wcplayer._waitingCounter = 0;


            indirectRun(streamManager.NextSource);

        }

    },



    ONDEMAND_PLAYING_LOOP_TIME: 250,
    ONDEMAND_PLAYING_LOOP_WORKING: false,

    _onDemandPlayingLoop: function () {

        // isto é para parar o ciclo quando o status atual mudar
        if (wcplayer.CurrentState() != wcplayer.WM_STATE_PLAYING) 
        {
            wcplayer.ONDEMAND_PLAYING_LOOP_WORKING = false;
            trace("STATUS MUDOU " + wcplayer.CurrentState());
            return;

        }

        wcplayer.ONDEMAND_PLAYING_LOOP_WORKING = true;

        var current = wcplayer.currentTotal();

        indirectRun(function () {
            template.setRelogioVideo(current
                , visualizador.Transmissao.Duracao);
        });
        indirectRun(function () {
            template.setSliderVideoPosition(current
                , visualizador.Transmissao.Duracao);
        });


        setTimeout(function () { wcplayer._onDemandPlayingLoop(); }, wcplayer.ONDEMAND_PLAYING_LOOP_TIME);

        setTimeout(function () { template.indicesSetSelection(); }, 1000);

        indirectRun(function () { wcplayer.scriptHandlerArquivo(); });
    },


    currentTotal: function (seek) {

        if (seek == null) {
            // get
            return streamManager.timeBeforeArquivoAtual() + wcplayer.current();

        }

        streamManager.SetAbsoluteTime(seek);


    },

    currentTotalPercent: function (seekPercent) {

        var d = visualizador.Transmissao.Duracao;

        if (seekPercent == null) {
            // get
            var c = wcplayer.currentTotal();

            if (d == 0) { return 0; }

            if (c > d) { c = d; }

            return Math.floor(100 * c / d);

        } else {
            // set
            //gets the time that percent refers
            var seekTotal = Math.floor(seekPercent * d / 100);

            wcplayer.currentTotal(seekTotal);
        }
    },

    current: function (seek) {

        if (!wcplayer._playerReady) { return 0; }

        if (seek == null) {
            // get
            var r = 0;

            // time comes in seconds
            r = wcplayer._player.GetCurrentTime();

            return (r == null || r < 0 ? 0 : Math.floor(r * 1000)); // convert to milliseconds

        } else {
            // set
            var d = wcplayer.duration();

            seek = Math.round(seek / 1000);

            if (seek > d) { seek = d }

            // set value in seconds
            wcplayer._player.SetCurrentTime(seek);

            //if it's a seek action, resume last state 
            indirectRun(function () { wcplayer.scriptHandlerArquivo(true); });
        }

    },

    currentPercent: function (seekPercent) {

        var d = wcplayer.duration();

        if (seekPercent == null) {

            var c = wcplayer.current();

            if (d == 0) { return 0; }

            if (c > d) { c = d; }

            return Math.floor(100 * c / d);

        } else {

            //calculo a posição de acordo com a porcentagem
            var seek = Math.floor(seekPercent * d / 100);

            wcplayer.current(seek);
        }

    },

    duration: function () {
        return wcplayer._player.GetDuration();

    },


    handlerError: function () {

        trace('wcplayer.handlerError() : stream ' + wcplayer._player.GetUrl());

        streamManager.NextSource();

    },



    scriptHandlerArquivo: function (resumeLastState) {

        var tSc = visualizador.Scripts;
        tSc.unfilter(true);

        var curTime = wcplayer.current();
        var curArq = streamManager.idxArquivoAtual;

        if (resumeLastState == true) {

            // executa os ultimos scripts

            var lastSlide = '';
            var lastLegenda = '';
            var lastTemplate = '';

            for (var i = tSc.rows.length - 1; i >= 0; i--) {

                if (tSc.rows[i].IdxArquivo > curArq ||
                  (tSc.rows[i].IdxArquivo == curArq && tSc.rows[i].Offset > curTime)) {
                    continue;
                }

                switch (tSc.rows[i].Tipo) {
                    case 1:
                        if (lastSlide == '') {
                            lastSlide = tSc.rows[i].Valor;
                        }
                        break;

                    case 4:
                        if (lastLegenda == '') {
                            lastLegenda = tSc.rows[i].Valor;
                        }
                        break;

                    case 6:
                        if (lastTemplate == '') {
                            lastTemplate = tSc.rows[i].Valor;
                        }
                        break;

                }

                if (lastSlide != '' && lastLegenda != '' && lastTemplate != '') { break; }
            }

            visualizador.runScriptCommand(1, lastSlide);
            visualizador.runScriptCommand(4, lastLegenda);
            visualizador.runScriptCommand(6, lastTemplate);


            var sb = new StringBuilder();
            sb.append('scriptArquivo lastState: ');
            sb.append('<br> 1, ' + lastSlide);
            sb.append('<br> 4, ' + lastLegenda);
            sb.append('<br> 6, ' + lastTemplate);

            trace(sb.toString());

            tSc.unfilter(true);
            return;

        }

        // executa todos os scripts (???)

        var preTime = curTime - wcplayer.ONDEMAND_PLAYING_LOOP_TIME;
        if (preTime < 0) { preTime = 0; }

        tSc.filter('IdxArquivo', streamManager.idxArquivoAtual, filterMode.equals);
        tSc.filter('Offset', curTime, filterMode.lessOrEquals);
        tSc.filter('Offset', preTime, filterMode.greaterThan);

        for (var i = 0; i < tSc.rows.length; i++) {

            visualizador.runScriptCommand(tSc.rows[i].Tipo, tSc.rows[i].Valor);

            var sb = new StringBuilder();
            sb.append('scriptArquivo: ');
            sb.append(tSc.rows[i].IdxArquivo + ' | ');
            sb.append(tSc.rows[i].Offset + ' | ');
            sb.append(tSc.rows[i].Codigo + ' | ');
            sb.append(tSc.rows[i].Tipo + ' | ');
            sb.append(tSc.rows[i].Valor);

            trace(sb.toString());
        }

        tSc.unfilter(true);

    },

    handlerScriptCommand: function (scType, Param) {

        //se a transmissão for arquivo os scripts do vídeo são ignorados e o _onDemandPlayingLoop entra em ação
        if (!visualizador.Transmissao.AoVivo) { return; }

        trace('wcplayer.handlerScriptCommand(' + scType + ', ' + Param + ')');

        var type = parseInt(Param.substring(0, 2));
        var value = Param.substring(2);

        visualizador.runScriptCommand(type, value);
    },




    WM_READYSTATE_UNINITIALIZED: 0, //The FileName property has not been initialized.
    WM_READYSTATE_LOADING: 1, //The Windows Media Player control is asynchronously loading a file.
    WM_READYSTATE_INTERACTIVE: 3, //The Windows Media Player control loaded a file, and downloaded enough data to play the file, but has not yet received all data.
    WM_READYSTATE_COMPLETE: 4, //All data has been downloaded. 

    handlerReadyStateChange: function (lReadyState) {
        trace('wcplayer.handlerReadyStateChange(' + lReadyState + ')');
        // PASS?
    },


    // No código do wcplayer são utilizados somente
    // stopped, paused, playing e waiting(buffering)

    WM_STATE_STOPPED: 0,
    WM_STATE_PAUSED: 1,
    WM_STATE_PLAYING: 2,
    WM_STATE_WAITING: 3,

    // estes de baixo não são utilizados aparentemente
    WM_STATE_SCAN_FORWARD: 4,
    WM_STATE_SCAN_REVERSE: 5,
    WM_STATE_SKIP_FORWARD: 6,
    WM_STATE_SKIP_REVERSE: 7,
    WM_STATE_CLOSED: 8,

    CurrentState: function () {

        if (!wcplayer._playerReady) { return 0; }

        return wcplayer._currentState;

    },


    _currentVisibility: "visible",
    _toggleVisibility: function () {

        trace('toggle video visibility internal:'
            + (wcplayer._internalVisibility ? "true" : "false")
            + ' external:'
            + (wcplayer._externalVisibility ? "true" : "false")
            );

        if (!wcplayer._playerReady) { return; }

        var show = wcplayer._internalVisibility && wcplayer._externalVisibility;

        if (show && wcplayer._currentVisibility != "visible") {
            trace('htmlObjPlayer visible ' +
                wcplayer._toggleVisibilitySizeMemo.w + "x" + wcplayer._toggleVisibilitySizeMemo.h);

            wcplayer._resize(
                wcplayer._toggleVisibilitySizeMemo.w,
                wcplayer._toggleVisibilitySizeMemo.h);

            wcplayer._currentVisibility = "visible";



        }
        else if (!show && wcplayer._currentVisibility != "hidden") {
            trace('htmlObjPlayer hidden');

            wcplayer._toggleVisibilitySizeMemo.w = wcplayer.width();
            wcplayer._toggleVisibilitySizeMemo.h = wcplayer.height();

            wcplayer._resize(1, 1);

            wcplayer._currentVisibility = "hidden";

        }

    },



    _toggleVisibilitySizeMemo: {
        w: 0, h: 0
    },



    width: function () { return parseInt(wcplayer._dvp.style.width); },

    height: function () { return parseInt(wcplayer._dvp.style.height); },

    x: function () { return parseInt(wcplayer._dvp.style.left); },

    y: function () { return parseInt(wcplayer._dvp.style.top); },

    move: function (x, y) {
        if (!x) {
            x = 0;
        }

        if (!y) {
            y = 0;
        }

        if (!wcplayer._dvp || !wcplayer._dvp.style) {
            indirectRun(function () {
                // espera o _dvp existir
                wcplayer.move(x, y);
            });
            return;
        }

        wcplayer._dvp.style.left = x + 'px';
        wcplayer._dvp.style.top = y + 'px';

    },


    resize: function (w, h) {
        if (!h) {
            h = 0;
        }

        if (!w) {
            w = 0;
        }

        if (!wcplayer._dvp || !wcplayer._dvp.style) {
            indirectRun(function () {
                // espera o _dvp existir
                wcplayer.resize(w, h);
            });
            return;
        }

        if (wcplayer._internalVisibility && wcplayer._externalVisibility) {
            wcplayer._resize(w, h);
        }
        else {
            wcplayer._toggleVisibilitySizeMemo.w = w;
            wcplayer._toggleVisibilitySizeMemo.h = h;
        }

    },

    _resize: function (w, h) {
        wcplayer._dvp.style.height = h + 'px';
        wcplayer._dvp.style.width = w + 'px';
    },


    visible: function (visibility) {
        wcplayer._externalVisibility = visibility;
        wcplayer._toggleVisibility();

    },

    fullscreen: function () {

        if (wcplayer.CurrentState() == wcplayer.WM_STATE_PLAYING) {
            wcplayer._player.FullScreen();
        }

    },











    stop: function () {
        try {
            wcplayer._player.Stop();
        }
        catch (e) {
            trace("ERROR: Could not stop. " + e.message);
        }
    },

    pause: function () { try { wcplayer._player.Pause(); } catch (e) { } },

    play: function () { try { wcplayer._player.Play(); } catch (e) { } },


    setUrl: function (url) {

        trace("INFO: URL Video: " + url);

        if (url == null || url.length < 1) {
            return;
        }

        wcplayer._player.SetUrl(url);

        indirectRun(function () {
            wcplayer.play();
        });

    },







    MAX_WM_VOLUME: 0,

    MIN_WM_VOLUME: -3000,

    volume: function (porcento) {

        if (!wcplayer._playerReady) { return 0; }

        if (porcento == null) {
            // retorna um valor de 0 a 100
            return wcplayer._player.GetVolume();
        }

        // insere um valor de 0 a 100
        wcplayer._player.SetVolume(porcento);

        indirectRun(function () {
            template.setAudioSliderPosition();
        });

        return;

    },


    mute: function (b) {

        if (!wcplayer._playerReady) { return false; }

        if (b == null) {
            return wcplayer._player.GetMute();
        }
        else {
            wcplayer._player.SetMute(b);
        }

    }

}





/////////////////////////////////////////////////////////////////////
/// WMPLAYER - WMP e SilverLight ////////////////////////////////////
/////////////////////////////////////////////////////////////////////
var wcWMPlayer = {

    type: wcplayer.types.WINDOWS_MEDIA_PLAYER,

    _player: null,

    isSilverlight: false,

    Initialize: function (player) {
        wcWMPlayer._player = player;

    },

    CheckPlayer: function () {
        if (wcWMPlayer._player == null || wcWMPlayer._player.PlayState == null) {
            return false;
        }

        return true;
    },

    SetUrl: function (url) {
        wcWMPlayer._player.FileName = url;
    },
    GetUrl: function () {
        return wcWMPlayer._player.FileName;
    },

    Play: function () {
        wcWMPlayer._player.Play();
    },
    Stop: function () {
        wcWMPlayer._player.Stop();
        wcWMPlayer._player.CurrentPosition = 0;
    },
    Pause: function () {
        wcWMPlayer._player.Pause();
    },

    GetVolume: function () {
        if (wcWMPlayer._player.Volume == null) {
            return 0;
        }

        // converte para porcentagem;
        var r = wcWMPlayer._player.Volume;
        r = 100 * (r - wcplayer.MIN_WM_VOLUME) / (wcplayer.MAX_WM_VOLUME - wcplayer.MIN_WM_VOLUME);

        return Math.floor(r);
    },
    SetVolume: function (percent) {
        if (wcWMPlayer._player.Volume == null) {
            return;
        }

        if (percent > 100) { percent = 100; }
        else if (percent < 0) { percent = 0; }

        var r = (percent * (wcplayer.MAX_WM_VOLUME - wcplayer.MIN_WM_VOLUME) / 100) + wcplayer.MIN_WM_VOLUME;

        wcWMPlayer._player.Volume = Math.floor(r);
    },

    GetMute: function () {
        return wcWMPlayer._player.Mute;
    },
    SetMute: function (m) {
        wcWMPlayer._player.Mute = m;
    },

    GetCurrentTime: function () {
        return wcWMPlayer._player.CurrentPosition;
    },

    SetCurrentTime: function (seek) {
        // seek time comes in seconds
        wcWMPlayer._player.CurrentPosition = seek;
    },

    GetDuration: function () {
        var r = wcWMPlayer._player.Duration;
        // return time in seconds
        return (r == null ? 0 : r);
    },

    GetBufferPercent: function () {
        if (wcWMPlayer._player.bufferingProgress == null) {
            return 0;
        }

        if (wcWMPlayer._player.bufferingProgress > 0) {
            return wcWMPlayer._player.bufferingProgress;
        }

        return 0;
    },

    GetBandwidth: function () {
        if (wcWMPlayer.isSilverlight) {
            return null;
        }

        return wcWMPlayer._player.Bandwidth;
    },

    GetState: function () {
        return wcWMPlayer._player.PlayState;
    },

    FullScreen: function () {
        wcWMPlayer._player.DisplaySize = 3;
    }

}





/////////////////////////////////////////////////////////////////////
/// HTML5PLAYER - Tag Video //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
var wcHtmlPlayer = {

    type: wcplayer.types.VIDEO_TAG,

    _player: null,
    _currentState: wcplayer.WM_STATE_STOPPED,

    Initialize: function () {

        // constructor
        
        var sb = new StringBuilder();
        //Silverlight Object
        sb.append('<video id="objHtml5Player" width="100%" height="100%" controls style="background-color:#000">');
        sb.append('</video>');

        wcplayer._dvp.innerHTML = sb.toString();

        trace("DEBUG | PlayerManager | Html5Player | loading player... ");

        indirectRun(wcHtmlPlayer._testPlayer);

    },

    _testPlayer: function () {

        if ($('objHtml5Player') == null) {
            // se não achou, tenta de novo daqui a pouco
            trace("DEBUG | PlayerManager | Html5Player | player NOT ready... ");
            indirectRun(wcHtmlPlayer._testPlayer);
            return;
        }

        trace("DEBUG | PlayerManager | Html5Player | player READY... ");

        // se achou, firmeza.
        wcHtmlPlayer._player = $('objHtml5Player');

        /* bind events */

        // * o evento stalled informa que o buffering foi interrompido por
        // algum motivo. Isto não significa que parou de tocar, mas que
        // vai continuar bufferizando assim que os pacotes chegarem.

        simpleAddEvent(wcHtmlPlayer._player, 'pause', function () {
            trace("DEBUG | PlayerManager | Html5Player | Event: pause ");
            wcHtmlPlayer._ChangeState(wcplayer.WM_STATE_PAUSED);
        });

        simpleAddEvent(wcHtmlPlayer._player, 'play', function () {
            trace("DEBUG | PlayerManager | Html5Player | Event: play ");
            wcHtmlPlayer._ChangeState(wcplayer.WM_STATE_PLAYING);
        });

        simpleAddEvent(wcHtmlPlayer._player, 'playing', function () {
            trace("DEBUG | PlayerManager | Html5Player | Event: playing ");
            wcHtmlPlayer._ChangeState(wcplayer.WM_STATE_PLAYING);
        });

        simpleAddEvent(wcHtmlPlayer._player, 'waiting', function () {
            trace("DEBUG | PlayerManager | Html5Player | Event: waiting ");
            wcHtmlPlayer._ChangeState(wcplayer.WM_STATE_WAITING);
        });

        simpleAddEvent(wcHtmlPlayer._player, 'ended', function () {
            trace("DEBUG | PlayerManager | Html5Player | Event: ended ");
            wcHtmlPlayer._ChangeState(wcplayer.WM_STATE_CLOSED);
        });

        // avisa o wcplayer que inicializou
        wcplayer._PlayerActivated();

    },



    CheckPlayer: function () {
        return wcHtmlPlayer._player != null;
    },

    SetUrl: function (url) {
        // url = 'http://200.177.228.81:8080/WEBCASTERS_WebCastersMobile/bunny.mp4';
        wcHtmlPlayer._player.src = url;
    },
    GetUrl: function () {
        return wcHtmlPlayer._player.src;
    },

    Play: function () {
        wcHtmlPlayer._player.play();
    },
    Stop: function () {
        wcHtmlPlayer._player.stop();
        wcHtmlPlayer.SetCurrentTime(0);
    },
    Pause: function () {
        wcHtmlPlayer._player.pause();
    },

    GetVolume: function () {
        return wcHtmlPlayer._player.volume * 100;
    },
    SetVolume: function (percent) {

        return wcHtmlPlayer._player.volume = percent / 100;
    },

    GetMute: function () {
        return wcHtmlPlayer._player.muted;
    },
    SetMute: function (m) {
        wcHtmlPlayer._player.muted = m;
    },

    GetCurrentTime: function () {
        // return time in seconds
        return wcHtmlPlayer._player.currentTime;
    },

    SetCurrentTime: function (seek) {
        // seek comes in seconds
        return wcHtmlPlayer._player.currentTime = seek;
    },

    GetDuration: function () {
        return wcHtmlPlayer._player.duration;
    },

    GetBufferPercent: function () {
        return wcHtmlPlayer._player.buffered.end() / wcHtmlPlayer._player.duration;
    },
    
    GetBandwidth: function () {
        return null;
    },

    GetState: function () {
        return wcHtmlPlayer._currentState;
    },

    FullScreen: function () {
        // _player.DisplaySize = 3;
        trace("ERROR | PlayerManager | Html5Player | FullScreen | there's no full screen API for HTML5 Video Element");
    },

    _ChangeState: function (CurrentState) {
        var OldState = wcHtmlPlayer._currentState;
        wcHtmlPlayer._currentState = CurrentState;

        indirectRun(function () {
            wcplayer.handlerPlayStateChange(OldState, CurrentState);
        });
    }


}





/////////////////////////////////////////////////////////////////////
/// FLASHPLAYER - JwPlayer //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
var wcFlashPlayer = {

    type: wcplayer.types.FLASH,

    _player: null,

    _currentVideoUrl: "",

    _bufferPercent: 0,
    _currentState: wcplayer.WM_STATE_STOPPED,

    _reconnecting: false,
    _urlReceived: false,

    Initialize: function () {
        loadExternalJs("/flashplayer/swfobject.js");

        trace('DEBUG | PlayerManager | FlashPlayer | Loading Scripts...');

        wcplayer._dvp.innerHTML = "<div id='divWebCastersFlashPlayer'>Carregando Flash Player...</div>";

        indirectRun(wcFlashPlayer._initializePlayer);
    },


    _initializePlayer: function () {

        trace('typeof swfobject ' + typeof swfobject);

        if (typeof swfobject == 'undefined') {

            trace('DEBUG | PlayerManager | FlashPlayer | Scripts NOT loaded.');

            indirectRun(wcFlashPlayer._initializePlayer);
            return;
        }

        trace('DEBUG | PlayerManager | FlashPlayer | Scripts loaded.');


        // monta o player
        var flashvars = {
            'autostart': 'true'
        };

        var params = {
            'allowfullscreen': 'true',
            'allowscriptaccess': 'always',
            'bgcolor': '#000000'
        };

        var attributes = {
            'id': 'WcFlashPlayer',
            'name': 'WcFlashPlayer'
        };

        swfobject.embedSWF('/flashplayer/VideoPlayer.swf'
            , 'divWebCastersFlashPlayer'
            , "100%", "100%", '10.2.000'
            , '/flashplayer/expressInstall.swf'
            , flashvars, params, attributes
            , wcFlashPlayer._flashLoaded);

        trace('DEBUG | PlayerManager | FlashPlayer | swfobject done...');

    },


    _flashLoaded: function (e) {

        trace('DEBUG | PlayerManager | FlashPlayer | flash player loaded (' + e.success + ') : ' + e.ref);

        // wcFlashPlayer._player = e.ref;
        wcFlashPlayer._player = getFlashMovieObject('WcFlashPlayer');

        wcFlashPlayer._playerLoaded();

        /* bind events *

        wcFlashPlayer._player.onBufferChange(function (event) {
        wcFlashPlayer._bufferPercent = event.bufferPercent;
        });
        */

    },

    _playerLoaded: function () {

        // verifica se o callback já pode ser chamado
        if (typeof wcFlashPlayer._player.IsReady != 'function') {

            trace('WARNING | PlayerManager | FlashPlayer | callback indisponível');
            setTimeout(wcFlashPlayer._playerLoaded, 1000);
            return;
        }

        if (wcFlashPlayer._player.IsReady() == false) {
            trace('DEBUG | PlayerManager | FlashPlayer | waiting player set up...');
            indirectRun(wcFlashPlayer._playerLoaded);
            return;
        }



        wcplayer._PlayerActivated();
        trace('DEBUG | PlayerManager | FlashPlayer | flash player READY');

    },


    CheckPlayer: function () {
        return wcFlashPlayer._player != null && wcFlashPlayer._player != null;
    },

    SetUrl: function (url) {

        if (wcFlashPlayer._reconnecting == false) {
            // dummy call to make the player assume that 
            // the player is buffering.
            trace('DEBUG | PlayerManager | FlashPlayer | Dummy Buffer Empty.');
            wcFlashPlayer._OnNetStatus("NetStream.Buffer.Empty");
        } else {
            trace('DEBUG | PlayerManager | FlashPlayer | New Url received.');
        }

        wcFlashPlayer._urlReceived = true;

        wcFlashPlayer._currentVideoUrl = url;
        wcFlashPlayer._player.SetUrl(url);

    },

    GetUrl: function () {
        return wcFlashPlayer._player.GetUrl();
    },

    Play: function () {
        // if Flash Player is reconnecting
        if (wcFlashPlayer._reconnecting) {
            trace('DEBUG | PlayerManager | FlashPlayer | Wait, its reconnecting.');
            return;
        }

        wcFlashPlayer._player.PlayVideo();

        // wcFlashPlayer._BufferChecker(); // para ver se o buffer está enchendo
    },

    Stop: function () {
        wcFlashPlayer._player.StopVideo();
    },
    Pause: function () {
        wcFlashPlayer._player.PauseVideo();
        wcFlashPlayer._OnNetStatus("NetStream.Pause.Notify");
    },


    GetCurrentTime: function () {
        // return time in seconds
        return wcFlashPlayer._player.GetCurrentTime();

    },

    SetCurrentTime: function (seek) {
        // seek comes in seconds
        wcFlashPlayer._player.SeekVideo(seek);
    },

    GetDuration: function () {
        return wcFlashPlayer._player.GetVideoDuration();
    },

    // para ver se o buffer está enchendo
    /*
    _BufferChecker: function () {
    trace("flash buffer percent check : " + wcFlashPlayer.GetBufferPercent());
    setTimeout(wcFlashPlayer._BufferChecker, 2500);
    },
    */

    GetBufferPercent: function () {
        return wcFlashPlayer._player.GetBufferPercent();
    },

    GetBandwidth: function () {
        return null;
    },


    GetVolume: function () {
        return wcFlashPlayer._player.GetVolume() * 100;

    },
    SetVolume: function (percent) {
        wcFlashPlayer._player.SetVolume(percent / 100);
    },


    GetMute: function () {
        return wcFlashPlayer._player.GetMute();
    },
    SetMute: function (m) {
        wcFlashPlayer._player.SetMute(m);
    },



    FullScreen: function () {
        wcFlashPlayer._player.FullScreen();
    },

    _OnNetStatus: function (eventCode) {
        if (wcFlashPlayer._currentState == eventCode) {
            //trace("DEBUG wcFlashPlayer.NetStatus : the same.");
            return;
        }

        trace("DEBUG | PlayerManager | FlashPlayer | NetStatus : " + eventCode);

        switch (eventCode) {
            // o NetStream.Play.Stop não significa que o vídeo parou de tocar         
            // mas que o buffer chegou ao fim do vídeo.        
            case "NetStream.Play.Stop":
                // wcFlashPlayer._ChangeState(wcplayer.WM_STATE_STOPPED);
                break;

            case "NetStream.Pause.Notify":
                wcFlashPlayer._ChangeState(wcplayer.WM_STATE_PAUSED);
                break;

            case "NetStream.Play.Start":
                wcFlashPlayer._reconnecting = false;
                wcFlashPlayer._ChangeState(wcplayer.WM_STATE_PLAYING);
                wcplayer.handlerBuffering(false);
                break;

            case "NetStream.Buffer.Empty":
                wcFlashPlayer._CheckFinish();
                break;

            case "NetStream.Play.Failed":
            case "NetStream.Play.StreamNotFound":
                indirectRun(wcplayer.handlerError);
                break;

            case "NetStream.Seek.Notify":
                wcFlashPlayer._ChangeState(wcplayer.WM_STATE_PLAYING);
                wcplayer.handlerBuffering(false);
                break;

            default:
                // trace("WARNING: wcFlashPlayer.NetStatus : " + eventCode);
                break;

        }

    },

    _CheckFinish: function () {
        var current = wcplayer.current();
        var total = visualizador.Transmissao.Duracao;
        var diff = current - total;

        if (diff < 1000 && diff > -1000) {
            trace("Terminou de tocar todos.");
            template.setInformacao('Terminou', 2000);
            return;
        }

        trace("Não terminou: " + current + " / " + total);

        wcFlashPlayer._ChangeState(wcplayer.WM_STATE_WAITING);
        wcplayer.handlerBuffering(true);
    },

    _RequestReconnection: function () {
        wcFlashPlayer._reconnecting = true;
        wcFlashPlayer._urlReceived = false;

        wcFlashPlayer.__RequestReconnection();
    },

    _RequestReconnectionRetry: function () {
        if (wcFlashPlayer._reconnecting == false ||
            wcFlashPlayer._urlReceived == true) {
            return;
        }

        wcFlashPlayer.__RequestReconnection();
    },

    __RequestReconnection: function () {
        trace("DEBUG | PlayerManager | FlashPlayer | requesting new Url...");
        indirectRun(streamManager.GetStream);

        setTimeout(wcFlashPlayer._RequestReconnectionRetry, 5000);
    },

    GetState: function () {
        return wcFlashPlayer._currentState;
    },

    _ChangeState: function (CurrentState) {
        if (CurrentState == wcFlashPlayer._currentState) {
            return;
        }

        // trace("DEBUG | PlayerManager | FlashPlayer | Changing State to " + CurrentState);
        var OldState = wcFlashPlayer._currentState;
        wcFlashPlayer._currentState = CurrentState;

        indirectRun(function () {
            wcplayer.handlerPlayStateChange(OldState, CurrentState);
        });
    }

}

