///////////////////////////////////
//      Element version 0.2      //
//-------------------------------//
//     Created on 2007-01-29     //
//     By N.Z.R. (Marc Drulot)   //
//       www.noizer-bug.net      //
//-------------------------------//
//         last revision         //
//           2007-02-28          //
//-------------------------------//
//    Feel free to use, modify   //
//  Please send me an e-mail for //
//   every correction you do       //
//  -------------------------------   //
//        Special Thanks :            //
//         protoype lib                 //
//     www.prototypejs.org        //
//////////////////////////////////////

// this is from prototype lib
Object.extend = function(destination, source) {
    for (var property in source) {destination[property] = source[property];}
    return destination;
}
var IterateCancel = {};
var IterateContinue = {};
function E (el) {
    if('string' == typeof el) el = document.getElementById(el);
    return Object.extend(el || {}, E.Meths);
}
// Element Methods
E.Meths = {
    find : function (el) {
        if('string' == typeof el) el = document.getElementById(el);
        return (null != el && el.parentNode);
    },
    erase : function () {if(E().find(this)) this.parentNode.removeChild(this);},
    empty : function () {
        while(this.hasChildNodes()) {
            this.removeChild(this.childNodes.item(0));
        }
    },
    create : function(n, pObj) {
        var el = E(document.createElement(n));
        if(pObj) el.setProps(pObj);
        return el;
    },
    setProps : function(pObj) {
        for(var p in pObj) {this[p] = pObj[p];}
    },
    createText : function(t) {return E(document.createTextNode(t));},
    addText : function(t) {
        var n = document.createTextNode(t);
        this.appendChild(n);
    },
    addElement : function(n, pObj) {
        var el = this.create(n, pObj);
        this.appendChild(el);
        return el;
    },
    replaceText : function (t) {
        this.empty();
        this.addText(t);
    },
    prev : function () {return E(this.previousSibling);},
    next : function () {return E(this.nextSibling);},    
    each : function(f) {
        var i=0, child;
        if(this.hasChildNodes) {
            try {
                while(child = this.childNodes[i++]) {
                    try {
                        if(child.nodeType == 1) f(E(child));
                    } catch (e) {
                        if(e != IterateContinue) throw e;
                    }
                }
            } catch (e) {
                if(e != IterateCancel) throw e;
            }
        }
    }
}
////////////////////////////////////////////////////////////////////////
var Event = {
    add : function (o, t, f) {
        // creation de l'objet Events et de ses sous-objet (Eventstype) s'il n'existe pas
        if(!o.Events) o.Events = {};
        if(!o.Events[t]) o.Events[t] = {n:0, fct: {}};            
        var isIn = false;
        // on regarde si il n'existe pas deja la fct dans Eventstypes
        for(var z in o.Events[t].fct) {
            if(f == o.Events[t].fct[z]) {
                isIn = true;
                break;
            }
        }
        // si elle n'existe pas
        if(!isIn) {
        // on l'ajoute à la fin
            var n = o.Events[t].n ++;
            o.Events[t].fct[n] = f;
        }
        // Combien de fct à appeler
        var m = o.Events[t].n;
        o['on'+t] = function(e) {
            var r = [];
            if(this.Events[t]) {
                for(var z in this.Events[t].fct) {
                    // si une fct a été rajouté pendant l'execution on ne l'appele pas
                    if(z <= m && null != this.Events[t].fct[z]) r.push(this.Events[t].fct[z].apply(this, [e||window.event]));
                }
                return !r.isIn(false);
            }
        }
    },
    remove : function (o, t, f) {
        if(o.Events && o.Events[t]) {
            var rem = false;
            var _t = o.Events[t];
            var n = _t.n;
            for(var i=0; i<n; i++) {
                if(f == _t.fct[i]) {
                    o.Events[t].fct[i] = null;
                    delete o.Events[t].fct[i];
                    o.Events[t].n --;
                    rem = true;
                }
            }
            var n = o.Events[t].n
            if(rem) {
                for(var z in o.Events[t].fct) {
                    if(z>=n) {
                        var m = o.Events[t].fct[z];
                        o.Events[t].fct[z] = null;
                        delete o.Events[t].fct[z];
                        o.Events[t].fct[z-n] = m;
                    }
                }
                if(o.Events[t].n == 0) {
                    o.Events[t] = null;
                    delete o.Events[t];
                }
            }    
        }
    } 
}
////////////////////////////////////////////////////////////////////////
E.Event = {
    load : function (fct) {
        if(window.attachEvent)
            window.attachEvent('onload', fct);
        else
            window.addEventListener('load', fct, false);
    },
    DOMload : function(fct) {
        var x;
        if (UA.safari) {
            var safariLoader = setInterval(
            function() {
                if(/complete|loaded/.test(document.readyState)) {
                    clearInterval(safariLoader);
                    fct();
                }
            }, 10);
        }
        else if (UA.msie) {
            /*@cc_on @*/
            /*@if (@_win32)
            document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
            var script = document.getElementById("__ie_onload");
            script.onreadystatechange = function() {
                if (this.readyState == "complete") {
                    fct(); // call the onload handler
                }
            };
            /*@end @*/
        }
        else if (UA.mozilla || UA.opera )
		    document.addEventListener("DOMContentLoaded", fct, false);
        else E.Event.load(fct);
    }
}
Object.extend(E.Meths, E.Event);
////////////////////////////////////////////////////////////////////////////
E.Style = {
    addClass : function (cl) {
        var oCl;
        if('undefined' != this.className) oCl = this.className+' ';
        this.className = oCl+' '+cl;
    },
    removeClass : function (cl) {
        if(cl == this.className || this.className.match('(^|\\s)'+cl+'(\\s|$)')) {
            this.className = this.className.split(' ').without(cl).join(' ');
        }
    },
    getClass : function(cl) {
        if(this.className.split(' ') .isIn(cl)) return true;
        else return false;
    },
    alpha : function (pA) {
        var s = this.style;
        s.opacity = pA;
        s.MozOpacity = pA;
        s.KhtmlOpacity = pA;
        s.filter = 'alpha(opacity='+(pA*100)+')';
    }
}
Object.extend(E.Meths ,E.Style);
//FRom JQuery////////////////////////////////////////////////////
var UA = (
    function() {
        var uA = navigator.userAgent.toLowerCase();
        return {
            safari : /webkit/.test(uA),
            opera : (/opera/.test(uA)),
            msie : (/msie/.test(uA) && !/opera/.test(uA)),
            mozilla : (/mozilla/.test(uA) && !/(compatible|webkit)/.test(uA))
        }
    }
)();
//Extend Array///////////////////////////////////////////////////
var Iterable = {
    iterator : 0,
    next : function () {
	   return this[this.iterator++];
    },
    
    hasNext : function() {
	    return this.iterator <= this.length-1;
    },
    
    rewind : function () {
	    this.iterator = 0;
    },
    
    each : function (fn) {
        var i = 0;
        try {
            while(this[i]) {
                try {
                    fn(i, this[i++]);
                } catch(e) {
                    if(e != IterateContinue) throw e;
                }
            }
        } catch(e) {
            if(e != IterateCancel) throw e;
        }
        
    },
    map : function (fn) {
        var a = [];
        this.each(function(i, e){a.push(fn(e));});
        return a;
    },
    shuffle : function () {
        var l;
        for(var i=0, l=this.length; i<l; ++i) {
            var tmp = this[i];
            var randN = Math.round(Math.random()*(l-1));
            this[i] = this[randN];
            this[randN] = tmp;
        }
        return this;
    },
    filter : function (fn) {
        var a = [];
        this.each(function(i, e) {if(fn(i,e)) a.push(e);});
        return a;
    },
    empty : function () {
        this.length = 0;
        return this;
    },
    without : function (o) {
        return this.filter(function(i,e){return (o != e);});
    },
    isIn : function (v) {
        for(var i=0, l=this.length; i<l; i++) {
            if(v == this[i]) { return true;}
        }
        return false;
    },
    isEmpty : function() {
	    return this.length == 0;
    },
    every : function (fn) {
        var l;
        for(var i=0, l=this.length; i<l; ++i) {
            if(!fn(i,this[i])) return false;
        }
        return true;
    }
}
Object.extend(Array.prototype, Iterable);
function I(e) {
    return Object.extend(!e ? [] : e, Iterable);
}
////////////////////////////////////////////////////////////////////////
function Timer () {};
Timer._timers_ = {};
Object.extend(Timer.prototype, {
    id : 0,
    isPaused: false,
    o: null,
    f : null,
    s : 0,
    args : [],
    play : function(o, fct, s, args) {
        this.o = o;
        this.f = fct;
        this.s = s;
        this.args = args || [];
        this.id = window.setInterval(function () {fct.apply(o, args || []);},s*1000);
        return this;
    },
    stop : function() {
        clearInterval(this.id);
        this.id = 0;
        this.o = null;
        this.f = null;
        this.s = 0;
        this.args = [];
    },
    pause : function() {
        if(!this.isPaused) clearInterval(this.id);
        else this.play(this.o, this.f, this.s, this.args);
        this.isPaused = !this.isPaused;
    }
});
//////////////////////////////////////////////////////////////////////
if (!window.XMLHttpRequest)
    XMLHttpRequest = function () {
        var _xhr_ = false;
        try { _xhr_ = new ActiveXObject("Msxml2.XMLHTTP");}
        catch (e) {
            try {_xhr_ = new ActiveXObject("Microsoft.XMLHTTP");}
            catch(e) {_xhr_ = false;};
        }
        return _xhr_;
    }
var XHR = {
    // default values
    _method_  : 'POST',
    _async_   : true,
    _xhr_     : null,
    _params_  : null,
    _headers_         : null,
    onStart      : null,
    onData       : null,
    onComplete   : null,
    
    setParams : function(opt) {
        this._method_ = opt.method || this._method_;
        this._async_  = opt.async  || this._async_;
        this._params_ = opt.params || this._params_;
        if('headers' in opt) this._headers_ = opt.headers;
    },
    
    request : function (remote, opt) {        
        this.setParams(opt || {});
        var datas = null;	   
        this._xhr_ = new XMLHttpRequest();
        var ref = this;
	   
        if( 'GET' == this._method_ && null != this._params_ ) 
		   remote += '?'+this._params_;
        //else 
	  
	   
        this._xhr_.onreadystatechange = function() { ref.__onDialog__(); }
        this._xhr_.open(this._method_, remote, this._async_);
	   
        if(null != this._headers_) {
            this._headers_.each(function(i, e) {ref._xhr_.setRequestHeader(e.type, e.value); });
        }
	   
		if ('POST' == this._method_) {
		   datas = this._params_;
		   this._xhr_.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		}
        this._xhr_.send(datas);
    },
    
    __onDialog__ : function() {
        if(this._xhr_.readyState == 1 && null != this.onStart)
            this.onStart(this._xhr_.readyState);
        if(this._xhr_.readyState == 3 && null != this.onData)
            this.onData(this._xhr_);
        if (this._xhr_.readyState == 4) {
            if (this._xhr_.status == 200) {
                if(this._xhr_.readyState == 4 && null != this.onComplete) {
					var __rep__ = this.__getFormat__();
                    this.onComplete(this._xhr_, __rep__);				
				}
            }
        }
    },
    __getFormat__ : function() {
        var rep;
        try {
            if(this._xhr_.getResponseHeader('Content-Type') && 
				(this._xhr_.getResponseHeader('Content-Type') == 'text/xml') ||
				(this._xhr_.getResponseHeader('Content-Type') == 'application/xml') )
                rep = this._xhr_.responseXML;
            if(this._xhr_.getResponseHeader('Json-Active') =='true') 
			  rep = eval('('+this._xhr_.responseText+')');
        } catch(eXML) {
            throw eXML;
        }
        return rep;
    },
    playStep : function(r, o, s) {
        this.request(r, o);
        return new Timer().play(this, this.request, s, [r, o]);
    },
    stopStep : function(t) {t.stop();},
    pauseStep : function(t) {t.pause();}
}
function Ajax (r, o) {
    Object.extend(this, XHR);
    if( 2 == arguments.length) this.request(r, o);
}

//~ //////////////////////////////////////////////////////////////////////
//~ Below functions are for an ease use
//~ just 'cause i'm always invert flash trace func ans JS alert func and some time php echo, print_r
///////////////////////////////////////////////////////////////////
function trace(s) {
	alert(s);
}
function echo(s) {
	alert(s);
}

