/**************************************
 * AJAX : 
 * asynchronous multiple whois queries LIGTH :) 
 **************************************/

//COMPTATIBILITY (tested on...)
// Firefox 1.5.03
// Mozilla 1.7.12
// IE 6.0
// Opera 8.52
// Konqueror 3.4.3
// Netscape 7.1

// ============================================================= Vars

// the array that store the XMLHttpRequest objects
var wiz__xhrs;

//timer to abort op in a too long time
var wiz__timer;

//show logs or not
var wiz__VERBOSE = 0;

// ============================================================= Objects

/**
 * Object domainsCheckRequest (alias 'dcr')
 *
 * @param   xhr         the XmlGttpRequest Object used
 * @param   tld         list of tlds requested
 * @param   domains     list of domain requested
 */
function wiz__domainsCheckRequest( xhr, domains, activationFunction)
{

    this.state          = 0;        // 0 WAIT
                                    // 1 IN WORK
                                    // 2 DONE (COMPLETE)
                                    // 3 ERROR
                                    
    this.xhr            = xhr;      // the XMLHttpRequest

    this.domains        = domains;  // keeping a copy of domains requested / faster than parsing XML (IMO)
                                    // BTW, needed to deal with the case where responseXML is NULL

    this.activationFunction = activationFunction; // this function will be called when we need to alter display (params: domain, status)
}


// ============================================================ Methods

/**
 * main :: whois query
 */
function wiz__ajaxDomainChecker( url_init, param_domains, param_tlds, param_excepts, activationFunction )
{

    //lauch timer
    if(wiz__timer==undefined)
    {
        wiz__timer = 0;
        wiz__timerUpdate();
    }

    if (wiz__xhrs==null)
        wiz__xhrs = new Array();

    //----------------------------------------------------<get_params>
    
    //get tlds
    if ( param_tlds== "")
    {
        alert("You should at least give one top level domain .");
        return;
    }

    var tlds_all = param_tlds.replace(/:/g, " ").replace(/\s+/g, " ").split(" ");
    var tlds = noDuplicate( tlds_all);

    //sort randomly tlds :)
    tlds.sort( wiz__randOrd );

    //get domain+tld exceptions
    var except_all = param_excepts.replace(/:/g, " ").replace(/\s+/g, " ").split(" ");
    var except     = noDuplicate( except_all);
    
    //----------------------------------------------------</get_params>

      
    //----------------------------------------------------<valid_params>
   
    // verify there is a least one domain request
    if ( param_domains== "")
    {
        alert("You should at least enter one domain name.");
        return;
    }

    var the_domains_all = param_domains.replace(/:/g, " ").replace(/\s+/g, " ").split(" ");
    var the_domains     = noDuplicate(the_domains_all);

    
    //limit request to 5 domain name
    /*
    if ( the_domains.length > 5)
    {
        alert("Maximum domains request is limit to 5.");
        return;
        
    }
    */
    //----------------------------------------------------</valid_params>
    
    // gonna make a xml http request per domain
    // these are store in the global xhrs array
    for (var i=0; i < tlds.length; i++)
    {
            // made list of domain for this tlds

            //normalize tld
            tlds[i].replace( /^\./, '');
            
            var toRequest_all = new Array();
            for(var k=0; k<the_domains.length; k++) 
            {
                toRequest_all.push( the_domains[k]+'.'+tlds[i]);
            }

            // remove exception
            var remove;
            var toRequest = new Array();
            for(var m=0; m<toRequest_all.length; m++)
            {
                remove = 0;
                for( var n=0; n<except.length; n++)
                {
                    if( toRequest_all[m]==except[n])
                        remove = 1;
                }
                if( !remove)
                    toRequest.push( toRequest_all[m]);
            }
            
            //check request is not empty
            if( toRequest.length==0) {
                continue; // next loop
            }
            
            // made request string
            var request = url_init+"?domains="+toRequest[0];

            for(var p=1; p<toRequest.length; p++)
            {
                request += ":"+toRequest[p];
            }
           
            // create XmlHttpRequest
            var xhr  = newXMLHttpRequest();
            
            if(!xhr)
            {
                // go to alternative without AJAX
                alert("Your browser don't support XMLHttpRequest Object ...");
                window.location.href="error.html";
            }
 
            try
            {
                xhr.open("GET", request, true);
                xhr.setRequestHeader("Content-Type","text/xml"); //force response content-type 
            }
            catch (exception)
            {
                alert(exception);
            }

            //asynchrone call
            xhr.onreadystatechange = wiz__processRequest;

            var dcr = new wiz__domainsCheckRequest( xhr, toRequest, activationFunction);
            wiz__xhrs.push( dcr);

            xhr.send("");
    }
}

/**
 * This function is called when a readyState has change by the onreadystatechange event
 * ...
 */
function wiz__processRequest()
{
    var dcr;
    
    // look which one of xhr is readyState 4 in the xhrs array
    for (var i=0; i < wiz__xhrs.length; i++) {
        
        dcr = wiz__xhrs[i];
        
        if (dcr.xhr.readyState==4 && dcr.state==0)
        {
            // 200 OK
            if (dcr.xhr.status==200) {
                dcr.state = 1;
                wiz__proceed( dcr);
                //remove the element
                wiz__xhrs.splice(i, 1); i--;

            } else {
                // Error
                dcr.state = 3;
                wiz__proceed(dcr);
                wiz__xhrs.splice(i, 1); i--;
            }
         
         } else if (dcr.state==3) {
            wiz__proceed(dcr);
            wiz__xhrs.splice(i, 1); i--;
         
         } else {
         //...
         
        }
    }
}


/**
 * XML Response Parser
 * parse and recup info of the XMLresponse of the xmlHttpRequest
 */
function wiz__proceed( dcr)
{

    wiz__log("proceed :" + dcr.domains );

    if (dcr.state != 3) {

        try {
            var xmldoc = dcr.xhr.responseXML;
       

        //alert(dcr.xhr.responseText);
            // look at un.info for example
            if (xmldoc == null)
                dcr.state = 3; //ERROR
       
            } catch (e) {
                dcr.state = 3;
            }
    }
    
     //var domains = xmldoc.getElementsByTagName("domain");
    //-- idem as --
    var domains = dcr.domains;
    
    for (var i=0; i < domains.length; i++)
    {
        //-- idem as --
        var one_domain = domains[i];

        wiz__log( "->" + one_domain)
 
        switch( dcr.state)
        {
            //ERROR
            case 3:
                
                dcr.activationFunction( one_domain, 'error');
                break;

            //OK
            default:
            
                // W3C DOM node spec
                var value_node  = 1;
                var reason_node = 3;
                if (xmldoc.getElementsByTagName("is_available")[i].childNodes[reason_node]==null) // IE... 
                {
                    value_node  = 0;
                    reason_node = 1;
                }

                // XML doc value
                var is_available_value      = xmldoc.getElementsByTagName("is_available")[i].childNodes[value_node].firstChild.nodeValue;
                //var is_available_reason     = xmldoc.getElementsByTagName("is_available")[i].childNodes[reason_node].firstChild.nodeValue;
                //var is_transferable_value   = xmldoc.getElementsByTagName("is_transferable")[i].childNodes[value_node].firstChild.nodeValue;
                //var is_transferable_reason  = xmldoc.getElementsByTagName("is_transferable")[i].childNodes[reason_node].firstChild.nodeValue;
                //var is_valid_value          = xmldoc.getElementsByTagName("is_valid")[i].childNodes[value_node].firstChild.nodeValue;
                //var is_valid_reason         = xmldoc.getElementsByTagName("is_valid")[i].childNodes[reason_node].firstChild.nodeValue;
                
                switch(is_available_value) 
                {
                    //TRUE : IS AVAILABLE
                    case "TRUE":

                        dcr.activationFunction( one_domain, 'available');
                        break;

                    //FALSE : NOT AVAILABLE
                    case "FALSE":
                        dcr.activationFunction( one_domain, 'nonavailable');
                        break;

                    default:
                        dcr.activationFunction( one_domain, 'error');
                        
                    break;
                                                    
                } // END SWITCH( available_value)
                break;

        }// END SWITCH( dcr.state) 
        
    }// END FOR
}    


//============================== utils Methods 

/*
 * aborting all xmlHttpRequest
 */

function wiz__abortAll()
{
    
    wiz__log("abortAll called");
    
    var dcr;
    
    for (var i=0; i < wiz__xhrs.length; i++)
    {
        dcr = wiz__xhrs[i];
        if( dcr.state!=2)
        {
            dcr.state = 3;
            wiz__proceed( dcr);
            wiz__xhrs.splice(i, 1); i--;            
        }
    }
}


/**
 * timerUpdate
 */
function wiz__timerUpdate()
{
    wiz__timer+=1;

    //waiting 30 seconds abortingAll 
    if(wiz__timer>60)
    {
        wiz__timer = null;
        wiz__abortAll();
    }
    else
    {
        //if there is a div with id="thetimer" then display value into
        var debug = document.getElementById("thetimer");
        if(debug!=undefined)
            debug.firstChild.nodeValue=timer;

        setTimeout("wiz__timerUpdate()", 1000);
    }
    
}

/**
 * random
 */
function wiz__randOrd(a, b)
{
    return (Math.round(Math.random())-0.5);
}

//========================================================================================== ...

/**
 * DEBUG
 * system logger
 */
function wiz__log(msg)
{
    if (wiz__VERBOSE && (document.getElementById("log")!=undefined))
    {
        var logger = document.getElementById("log");
        logger.innerHTML += "<br />" +msg;
    }
}


