/**
 * @author Nicolas Desy
 * Copyright © 2005-2006 Les solutions Net-Logik. All rights reserved.
 */

Delegate = {
    create : function(o,f){
        return function(){ return f.apply(o,arguments); };
    }
};


/**
 * Classe qui g la communication avec le serveur
 *
 * METHODES
 * reset()
 * setAttribute(key, value)
 * setData(data)
 * addListener(listener)
 * sendAndLoad(url)
 */
XML = function(){				
    this._listener = [];	
    this.reset();
}

XML.SPECIAL_CHARS = [
    {code:8211, value:"-"},
    {code:8217, value:"'"},
    {code:339, value:"oe"},
    {code:37, value:"%25"},
    {code:38, value:"&amp;"},
    {code:43, value:"%2B"},
    {code:37, value:"%2F;"} 
];


/* idea :
 
function callback(response){
 
}
 
XML.sendAndLoad("loadText.do", {textId:12, lang:"fr"}, callback, "POST");
 */
 

XML.sendAndLoad = function(){
    
}

XML.prototype.reset = function(){
    this._params = null;
    this._method = "GET";
}

XML.prototype.setAttribute = function(/*String*/ key, /*String*/ value){		
    
    if(this._params == null){
        this._params = {};
    }
    
    
    

    
   // if(typeof value == "string"){   
        var chars = XML.SPECIAL_CHARS;
        var nbchars = chars.length;
        var size = value.length;
        for(var i=0; i<size; i++){
            for(var j=0; j<nbchars; j++){
                if(value.charCodeAt(i) == chars[j].code){   
               //     alert("char replaced : " + chars[j].code + " : " + chars[j].value);
                    value = value.substring(0, i) + chars[j].value + value.substring(i+1);  
                    size = value.length;
                    i += chars[j].value.length-1;
                    j = nbchars;
                }
            }
        }
  //  }
    
   // value = escape(value);
    value = encodeURIComponent(value);
    this._params[key] = value;	
}

XML.prototype.setData = function(/*String*/ data){		
    this._params = data;
    this._method = "POST";
}

XML.prototype.addListener = function(/*Function*/ listener){
    this._listener.push(listener);
}

XML.prototype.sendAndLoad = function(/*String*/ url) {
    var conn = null;
    
    try {
        conn = new XMLHttpRequest();		
    }
    catch (error) {        
        try {
            conn = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch (error) {
            try {
                conn = new ActiveXObject("Msxml2.XMLHTTP");
            }
            catch (error) {}
        }
    }
    
    var ls = this._listener;
    
    conn.onreadystatechange = function() {
        try{        
            if (conn.readyState == 4 && conn.status == 200){             
                var i = ls.length;				
                while(--i > -1) ls[i](conn);			
            }
        }catch (error) {}
    }
    
    var params = "";
    
    if(this._params != null) {                	
        for(var i in this._params) {          
            params += "&"+ i + "=" + this._params[i];
        }		
        
        if(this._method == "GET") {
            url += "?" + params.substring(1);
            this.reset();	
            params = null;
        }	
    }	
    
    conn.open(this._method, url);
    
    if(this._method == "POST") {
        conn.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    }	
    
    conn.send(params);   
}	


/**
 * Search 
 *
 * Usage : 
 *      XML.findChildren(divElement, "p", {class:"dark"});
 *      XML.findChildren(formElement, "input", {type:"text"});
 *      XML.findChildren(formElement, "input", {type:"text", class:"darkField"});
 */ 
XML.findChildren = function(target, name, value, attributes, recurse){
    
    if(!target || !target.childNodes || !name) return [];
    
    var checkAttributes = (attributes != undefined);
    var checkValue = (value != undefined);   
    var result = [];
    var ns = (recurse) ? target.getElementsByTagName(name) : target.childNodes;
    var length=ns.length;
   
    for(var i=0; i<length; i++){
        var node = ns[i];             
        
        if(node.nodeName.toLowerCase() == name) {
            if(checkAttributes){
                var isValid = true;
                
                for(var attributeName in attributes){
                    if(node.getAttribute(attributeName) != attributes[attributeName]){
                        isValid = false;
                        break;
                    }
                }
                
                if(isValid){
                    if(checkValue){
                        if(node.firstChild.nodeValue == value){
                            result.push(node);
                        }
                    }else{
                        result.push(node);
                    }
                }
            }else{
                if(checkValue){                   
                    if(node.firstChild.nodeValue == value){
                        result.push(node);
                    }
                }else{                  
                    result.push(node);
                }
            }
        }
    }
    return result;
}


XML.insertAfter = function(target, newNode){   
    if(target.nextSibling){
        target.parentNode.insertBefore(newNode, target.nextSibling);
    }else{
        target.parentNode.appendChild(newNode);
    }
}

XML.prependChild = function(target, newNode){
    if(target.firstChild){
        target.insertBefore(newNode, target.firstChild);
    }else{
        target.appendChild(newNode);
    }
}

XML.createElement = function(name, text){
    var el = document.createElement(name);
    el.innerHTML = text;  
    return el;
}

XML.nextElement = function(target){
    var result = target.nextSibling;    
    while(result && result.nodeType != 1){
        if(!result.nextSibling) return null;
        result = result.nextSibling
    }
    return result;
}

XML.previousElement = function(target){
    var result = target.previousSibling;       
    while(result && result.nodeType != 1){      
        if(!result.previousSibling) return null;
        result = result.previousSibling
    }
    return result;
}