var RING = RING || {};
RING.domain = RING.domain || "ring-dot-domain-not-defined";
RING.Util = RING.Util || {};
// configure the fragment checking frequency here
RING.Util.checkFragmentDelay = RING.Util.checkFragmentDelay || 50;

RING.Util.Iframe = RING.Util.Iframe || undefined;
RING.Util.CallQueue = RING.Util.CallQueue || {};
RING.Util.QueueBusy = RING.Util.QueueBusy || false;
RING.Util.checkFragmentTimout = RING.Util.checkFragmentTimout || undefined;
RING.Util.CallQueueCounter = RING.Util.CallQueueCounter || 1;
RING.Util.IFrameCounter = RING.Util.IFrameCounter || 2;

RING.Util._nextCall = function(){
    if(!RING.Util.QueueBusy) {
        var id;
        var moreCallback = false;
        for(id in RING.Util.CallQueue) {
            var callParameters = RING.Util.CallQueue[id];
            moreCallback = true;
            break;
        }
        if(moreCallback) {
            if(RING.Util.Iframe==undefined) {
                RING.Util.Iframe = document.createElement('IFRAME');
                RING.Util.Iframe.style.display='none';
                RING.Util.Iframe.id='ring-iframe';
                RING.Util.Iframe.setAttribute('name', 'ring-iframe');
                document.body.appendChild(RING.Util.Iframe);
            }
            RING.Util.Iframe.src = '//' + RING.domain + '/static/iframe.htm' + "?uri=" + encodeURIComponent(callParameters['uri']) + "&callback=ring-response-"+id+"&href="+encodeURIComponent(location.href);
            RING.Util.QueueBusy = true;
            if(RING.Util.checkFragmentTimout==undefined)
                RING.Util.checkFragmentTimout = setTimeout(RING.Util._checkURLFragment, RING.Util.checkFragmentDelay);
        }
    }
};

RING.Util._newCall = function(uri) {
    var iframeId = RING.Util.IFrameCounter;
    RING.Util.IFrameCounter++;
    var iframe = document.createElement('IFRAME');
    iframe.style.display='none';
    iframe.id='ring-iframe-' + iframeId;
    iframe.setAttribute('name', 'ring-iframe-' + iframeId);
    document.body.appendChild(iframe);
    iframe.src = '//' + RING.domain + '/static/iframe.htm' + "?uri=" + encodeURIComponent(uri);
};

RING.Util.Call = function(uri, callback) {
    if(callback!=undefined) {
        var id=RING.Util.CallQueueCounter;
        RING.Util.CallQueueCounter++;
        var callParameters = {};
        callParameters['uri'] = uri;
        callParameters['success'] = callback['success'];
        callParameters['failure'] = callback['failure'];
        callParameters['argument'] = callback['argument'];
        RING.Util.CallQueue[id]=callParameters;
        RING.Util._nextCall();
    } else {
        RING.Util._newCall(uri);
    }
};

RING.Util._checkURLFragment = function() {
    RING.Util.checkFragmentTimout = undefined;
    var i = location.hash.indexOf("#");
    var hash = (i>=0) ? location.hash.substr(i+1) : '';
    if(hash!='') {
        var splitHash = hash.split('&');
        var paramValueSplit, param, value;
        var leftOverHash='';
        var processed,iframe;
        for(i=0;i<splitHash.length;i++) {
            processed=false;
            paramValueSplit = splitHash[i].split('=');
            if(paramValueSplit.length==2) {
                param = paramValueSplit[0]; value = paramValueSplit[1];
                var successRegex = new RegExp('^ring-response-\\d+-s$');
                var failureRegex = new RegExp('^ring-response-\\d+-f$');
                if(param.match(successRegex) || param.match(failureRegex)) {
                    var id = param.match(new RegExp('\\d+'))[0];
                    if(id in RING.Util.CallQueue) {
                        RING.Util.QueueBusy = false;
                        var callParameters = RING.Util.CallQueue[id];
                        delete RING.Util.CallQueue[id];
                        if(param.match(successRegex) && callParameters['success']) {
                            callParameters['success'].call(undefined, decodeURIComponent(value), callParameters['argument']);
                        }
                        if(param.match(failureRegex) && callParameters['failure']) {
                            callParameters['failure'].call(undefined, decodeURIComponent(value), callParameters['argument']);
                        }
                        RING.Util._nextCall();
                    }
                }
            }
        }
    }
    var moreCallback = false;
    for(id in RING.Util.CallQueue) { moreCallback = true; break; }
    if(moreCallback) RING.Util.checkFragmentTimout = setTimeout(RING.Util._checkURLFragment, RING.Util.checkFragmentDelay);
};

