Ext.namespace('PSRTV');

PSRTV.LoadBalancer = function() {
    var ajaxRequestTimeout = 8000; //In microseconds. We dont want it too high and not to low. 2000ms is ok.
    var concurrentRequests = 2; // how many stream servers do we ask at once. Too high number might actually slow things down.

    var debug = false;

    var webserversUrl = "webservers.php";
    var serverMonitorUrl = "serverMonitor.php";
    

    var addDebug = function(toAdd){
        if(! debug) return;
        var debugDiv = Ext.get('debug');
        if(debug != undefined){
            debugDiv.dom.innerHTML = toAdd + '<br>' + debugDiv.dom.innerHTML;
        }
    }

    var run = function (protocol, point, timezone, embeded, embededLocation){

        var finished = false;
        var noMoreServers = false;
        var differentTimezone = false;
        var firstTimezone = '';
        var serverQueue;
        var firstWebserver = true;

        var automaticTimezone = true;
        if(timezone != undefined && timezone != null && timezone != ''){
            automaticTimezone = false;
        }
        var options = {
            protocol: protocol ,
            point: point,
            embeded: embeded,
            embededLocation: embededLocation,
            timezone: timezone,
            automaticTimezone: automaticTimezone,
            finished: finished,
            noMoreServers: noMoreServers,
            differentTimezone: differentTimezone,
            firstTimezone: firstTimezone,
            serverQueue: serverQueue,
            firstWebserver: firstWebserver
        }
        var date = new Date();
        var dateString = date.getFullYear()+'-'+(date.getMonth()+1)+'-'+date.getDay()+' '+date.getHours()+':'+date.getMinutes()+':'+date.getSeconds();
        addDebug('Client date '+dateString);
        Ext.Ajax.request(
        {
            url : webserversUrl,
            method : 'GET',
            message: 'Reading server data from database',
            params: {
                time: dateString,
                selectedTimezone: timezone,
                automaticTimezone: automaticTimezone
            },
            success: function(response){
                var json = Ext.util.JSON.decode(response.responseText);
                options.serverQueue = json.data;
                addDebug('Timezone used '+json.timezone);
                for (var i = 0; i < concurrentRequests; i++) {
                    firstQueryServer(options);
                }
            },
            failure: function(a,b,c,d){
                alert("Error getting webservers."+a.statusText);
            }
        });
    }
    var queriesNumber = 0;
    

    //
    var serveresQueredFromSelectedTimezone = 0;

    var firstQueryServer = function(options){
        if(options.finished) return;
        var webserver = options.serverQueue.shift();
        if(webserver == undefined){
            if(noMoreServers)
                addDebug('No more servers in queue');
            noMoreServers = true;
            return;
        }

        if(options.firstWebserver){
            options.firstTimezone = webserver.locationGroup;
            options.firstWebserver = false;
        }
        
        if(!options.differentTimezone)
            if(true){
                if(options.firstTimezone == webserver.locationGroup){
                    serveresQueredFromSelectedTimezone++;
                } else {
                    if(serveresQueredFromSelectedTimezone>0){
                        addDebug('Waiting for finishing selected timezone query');
                        options.serverQueue.unshift(webserver);
                        return;
                    } else {
                        options.differentTimezone = true;
                        for (var i = 1; i < concurrentRequests; i++) {
                            firstQueryServer(options);
                        }
                    }
                }
            }


        queriesNumber++;
        addDebug('Query - first query: '+webserver.server+' '+webserver.locationGroup);

        Ext.Ajax.request(
        {
            url : serverMonitorUrl,
            method : 'GET',
            message: 'Checking server',
            timeout: ajaxRequestTimeout,
            params: {
                proxy_url: webserver.server
            },
            success: function(response){
                if(options.finished) return;
                var json = Ext.util.JSON.decode(response.responseText);
                if(options.finished) return;
                if(json.accepting != undefined){
                    var serverReady = isReadyServer(options, webserver, json.accepting);
                    if(!serverReady){
                        //try more servers
                        serveresQueredFromSelectedTimezone--;
                        firstQueryServer(options);
                    }
                } else {
                    var eventValidation = json.eventValidation;
                    var viewState = json.viewState;
                    finalQueryServer(options, webserver, eventValidation, viewState);
                }
            
            },
            failure: function(){
                serveresQueredFromSelectedTimezone--;
                if(options.finished) return;
                addDebug('TIMEOUT - '+webserver.server+' '+webserver.locationGroup);
                firstQueryServer(options);
            }
        });

    }

    var finalQueryServer = function(options, webserver, eventValidation, viewState){
        if(options.finished) return;
        addDebug('Query - second query: '+webserver.server);
        Ext.Ajax.request(
        {
            url : serverMonitorUrl,
            method : 'GET',
            message: 'Checking server',
            timeout: ajaxRequestTimeout,
            params: {
                proxy_url: webserver.server,
                DropDownList1: 'Cache/Proxy On-Demand',
                __EVENTTARGET: 'DropDownList1',
                __EVENTVALIDATION: eventValidation,
                __VIEWSTATE: viewState,
                parseClients: true
            },
            success: function(response){
                if(options.finished) return;
                var json = Ext.util.JSON.decode(response.responseText);
                if(options.finished) return;
                var accepting = json.accepting;
                addDebug('Answer - server: '+webserver.server+' accepting: '+accepting);

                var serverReady = isReadyServer(options, webserver, accepting);
                if(!serverReady){
                    //try more servers
                    serveresQueredFromSelectedTimezone--;
                    firstQueryServer(options);
                }
            },
            failure: function(){
                serveresQueredFromSelectedTimezone--;
                if(options.finished) return;
                addDebug('TIMEOUT - Server: '+webserver.server+' '+webserver.locationGroup);
                firstQueryServer(options);
            }
        });
    };

    var isReadyServer = function(options, webserver, accepting){
        if(accepting || accepting == "true"){
            foundServer(options, webserver);
            return true;
        }
        return false;
    };

    var foundServer = function(options, webserver){
        if(options.finished) return;
        addDebug("FOUND NOT FULL SERVER"+' - '+webserver.server+' '+webserver.locationGroup);
        options.finished = true;
        if(options.embeded){
            insertPlayer(options, webserver.server);
        } else {
            var media = options.protocol+webserver.server+options.point;
            window.location.href = media;
        }
    }

    var insertPlayer = function(options, server){
        var media = options.protocol+server+options.point;
        var div = document.getElementById('silverlightControlHost');

        Ext.Ajax.request(
        {
            url : options.embededLocation,
            method : 'GET',
            message: 'Checking server',
            timeout: ajaxRequestTimeout,
            params: {
            },
            success: function(response){
                var text = response.responseText;
                div.innerHTML = text.replace('<MediaSource></MediaSource>','<MediaSource>'+media+'</MediaSource>');
            },
            failure: function(){
                serveresQueredFromSelectedTimezone--;
                if(options.finished) return;
                firstQueryServer(options);
            }
        });

    }
	
    return {
        run: run
    }
}();

//Ext.onReady(PSRTV.LoadBalancer.init, PSRTV.LoadBalancer);
