Ext.namespace('PSRTV');

PSRTV.LoadBalancer = function() {
    var ajaxRequestTimeout = 10000; //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 highQ = 'HighQ';
    var lowQ = 'LowQ';

    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.getDate()+' '+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(options.noMoreServers)
                addDebug('No more servers in queue');
            options.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 - query: '+webserver.server+' '+webserver.locationGroup);

        Ext.Ajax.request(
        {
            url : serverMonitorUrl,
            method : 'GET',
            message: 'Checking server',
            timeout: ajaxRequestTimeout,
            params: {
                proxy_url: webserver.server,
                highQ: highQ,
                lowQ: lowQ,
                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(a, b){
                serveresQueredFromSelectedTimezone--;
                if(options.finished) return;
                if(a.isTimeout){
                    addDebug('TIMEOUT ('+a.statusText+')- '+webserver.server+' '+webserver.locationGroup);
                } else {
                    debugger
                    addDebug('ERROR - '+webserver.server+' '+webserver.locationGroup);
                    addDebug('ERROR STATUS - '+a.statusText);
                    addDebug('ERROR RESPONSE - '+a.responseText);
                }
                
                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);