/**
 * Valid proxy detector with progress control
 * Cookie name: lwku
 * Test path: "http:// ... /private/domainAvailability2.jsp"
 *
 * I.Spirin
 * 2010
 */

function getEvent(evt)
{
    evt = (evt || event || false);
    if(!evt.preventDefault)
    {
        evt.preventDefault = function(){
            this.returnValue = false; return false;
        }
    }
    if(!evt.stopPropagation)
    {
        evt.stopPropagation = function(){
            this.cancelBubble = true;
        }
    }
    evt.kill = function(){
        this.preventDefault();
        this.stopPropagation();
    }
    return evt;
}

cookies = {
    cookies:null,
    init: function()
    {
        this.cookies = {};
        var ca = document.cookie.split(';');
        var re = /^[\s]*([^\s]+?)$/i;
        for(var i = 0; i < ca.length; i++)
        {
            var c = ca[i].split("=");
            if(c.length == 2)
            {
                this.cookies[c[0].match(re)[1]] = unescape(c[1].match(re) ? c[1].match(re)[1] : '');
            }
        }
    },

    get: function(name)
    {
        if(!this.cookies) this.init();
        return this.cookies[name];
    },

    set: function(name, value, days)
    {
        if(!this.cookies) this.init();
        this.cookies[name] = value;
        var expires = "";
        if(days)
        {
            var date = new Date();
            date.setTime(date.getTime()+(days*24*60*60*1000));
            expires = "; expires="+date.toGMTString();
        }
        var domain = location.host.match(/[^.]+\.[^.]+$/);
        document.cookie = name+"="+escape(value)+expires+"; path=/"+(domain ? '; domain=.'+domain : '');
    }
}

window._checkers = {};
window._getChecker = function(name)
{
    return window._checkers[name];
}

SerialSingleURLChecker = function(url, key, checker){
    this.url = url;
    this.key = key;
    this.finished = false;
    this.script = null;
    this.checker = checker;

    this.run = function()
    {
        var callback = new Function('', "var c=window._getChecker('"+this.checker+"')._checkers["+this.key+"];if(!c||c.finished)return;c.finished=true;var u=window._getChecker('"+this.checker+"').hasConfirm()?c.url:false;window._getChecker('"+this.checker+"').complete(u,c)");
        var head = document.getElementsByTagName("head")[0] || document.documentElement;
        var script = document.createElement("script");
        script.src = window._getChecker(this.checker).complitURL(this.url);
        script.onreadystatechange = function() {
            if(!this.readyState || this.readyState === "loaded" || this.readyState === "complete")
            {
                script.onreadystatechange = null;
                callback();
                try{
                    script.parentNode.removeChild(script, true);
                }catch(e){}
            }
        };
        this.script = script;
        head.insertBefore(script, head.firstChild);
    };
}

SingleURLChecker = function(url, key, checker){
    this.url = url;
    this.key = key;
    this.finished = false;
    this.script = null;
    this.checker = checker;

    this.run = function()
    {
        var callback = new Function('', "var c=window._getChecker('"+this.checker+"')._checkers["+this.key+"];if(!c||c.finished)return;c.finished=true;var u=window._getChecker('"+this.checker+"').hasConfirm()?c.url:false;window._getChecker('"+this.checker+"').complete(u,c)");
        var head = document.getElementsByTagName("head")[0] || document.documentElement;
        var script = document.createElement("script");
        script.src = window._getChecker(this.checker).complitURL(this.url);
        var done = false;
        script.onload = script.onreadystatechange = function() {
            if(!done){
                done = true;
                if(!this.readyState || this.readyState === "loaded" || this.readyState === "complete") {
                    script.onload = script.onreadystatechange = null;
                    try{
                        script.parentNode.removeChild(script, true);
                    }catch(e){}
                }
                callback();
            }
        };
        this.script = script;
        head.insertBefore(script, head.firstChild);
    };
}

function scale(from, to, num)
{
    if(from == 0) return 0;
    var step = to / from;
    return Math.round(num * step);
}

function now()
{
    return (new Date()).getTime();
}

window.URLChecker = function(domains, service)
{
    this.urls = domains;
    this.valid = false;
    this.onComplete = null;
    this.onFail = null;
    this.timeout = 6000;
    this.count = 0;
    this.index = 0;
    this.current = 0;
    this.startTime = 0;
    this.endTime = 0;
    this.lastTimeout = 0;
    this.nextTimeout = 0;
    this.cookieName = service + '_lwku';
    this.service = service;

    this._checkers = [];
    this._current = null;
    this._tid = null;
    this._isSerial = false;
    this._urlKeys = [];
    
    window._checkers[service] = this;

    this.run = function(completeCallback, failCallback, timeout)
    {
        if(completeCallback){
            this.onComplete = completeCallback;
        }
        if(failCallback){
            this.onFail = failCallback;
        }
        if(timeout){
            this.timeout = timeout;
        }
        this.detectSerialChecking();

        var lastWorkedUrl = cookies.get(this.cookieName);
        cookies.set(this.cookieName, "", 30);
        if(lastWorkedUrl && (""+lastWorkedUrl) != 'undefined')
        {
            this._unshift(lastWorkedUrl);
        }
        for(var key in this.urls)
        {
            this._urlKeys.push(key);
        }
        this._urlKeys.reverse();
        this.count = this._urlKeys.length;
        this.startTime = now();
        this.endTime = 0;
        this._next();
    };

    this.progress = function()
    {
        if(this.endTime > 0){
            return 100;
        }
        var step = (100 / this.count);
        var result = step * this.index;
        result += scale(this.timeout, step, now() - this.lastTimeout);
        return Math.round(result);
    };

    this.complete = function(url) // (url, sender)
    {
        if(!url){
            this._next();
        }else{
            this.valid = url;
            this._finalizations();
            cookies.set(this.cookieName, url, 30);
            if(this.onComplete){
                this.onComplete(url);
            }
        }
    };

    this.fail = function()
    {
        if(this.onFail){
            this.onFail();
        }
    };

    this.detectSerialChecking = function()
    {
        this._isSerial = !!document.createElement('script')['readyState'];
    };

    this._next = function()
    {
        clearTimeout(this._tid);
        if(this._current){
            this._current.finished = true;
        }
        if(this._urlKeys.length){
            var url = this.urls[this._urlKeys.pop()];
            var key = this._checkers.length;
            this._current = new SingleURLChecker(url, this._checkers.length, this.service);
            if(this._isSerial){
                this._current = new SerialSingleURLChecker(url, this._checkers.length, this.service);
            }
            this.index = key;
            this.current = url;
            this._checkers.push(this._current);
            this.lastTimeout = now(),
            this.nextTimeout = this.lastTimeout + this.timeout;
            this._tid = setTimeout('window._getChecker("'+this.service+'")._timeout()', this.timeout);
            this._current.run();
        }else{
            this._finalizations();
        }
    };
        
    this._unshift = function(url)
    {
        for(var cu in this.urls)
        {
            if(this.urls[cu] == url)
            {
                var us = url ? [url] : [];
                for(var u in this.urls)
                {
                    if(u != cu)
                    {
                        us.push(this.urls[u]);
                    }
                }
                this.urls = us;
                break;
            }
        }
    };

    this._timeout = function()
    {
        this._next();
    };

    this.setUrls = function(urls)
    {
        this.urls = [];
        for(var idx in urls)
        {
            this.urls[idx] = urls[idx];
        }
    };

    this._remove = function()
    {
        for(var i in this._checkers)
        {
            try{
                this._checkers[i].script.parentNode.removeChild(this._checkers[i].script, true);
            }catch(e){}
            this._checkers[i] = null;
        }
        this._current = null;
    };

    this._finalizations = function()
    {
        this.endTime = now();
        this._remove();
        this._urlKeys = [];
        if(this.valid == false)
        {
            this.fail();
        }
    };

    this.complitURL = function(srcUrl)
    {
        return "http://"+srcUrl+"/home287/domainAvailability.js?ajax=" + (new Date()).getTime();
    };

    this.hasConfirm = function()
    {
        return window['urlConfirm'] && window.urlConfirm === true && this.valid === false;
    }
};

