var Gis=function()
{
    /**Ils sont les modules telecharge par le method Gis.require()**/
    this.modules=[];
    //var chargee=[];
    /**Le path vers le librairie Gis  **/
    this.LIB_PATH="js/lib";
    /** Le path vers le store des images **/
    this.IMAGES_PATH="images";
    /** automatics ids**/
    this._ids=1;
    /**si on outiliser de assertions sur le code on peut mettre la valeur true **/
    this.debug=false,

    this.isIE=window.ActiveXObject?true:false
	

}



/**
 *Propiete static utilise pour connetre si tous les modules sont chargees.
 *@access public
 *@static
 **/
Gis.chargee=[];
/**
 *Methode utilize pour comencer les scritp
 *@access public
 *@static
 *@param f Function
 */
Gis.init=function(f){
  Gis.onReady(f); 
}
/**
 *Methode utilize pour registre un module.
 *@access public
 *@static
 *@param mod string route ver le ficher js. ex.:gis.utils.string
 *@return void
 */
Gis.prototype.charger=function(mod){
   if(!this.modules.containsValue(mod)) G.require(mod);//this.modules.push(mod);
    var t=this.modules.arrayKeys(mod);
    if(t.length>0) Gis.chargee[t[0]]=true;
    
}
/*methode private*/
Gis.onReady=function(f){
   
    var t=Gis.chargee.length;
    var cc=0; 
    for(var i=0; i<t; i++) if(Gis.chargee[i]) cc++;

    if(cc!=t)
        window.setTimeout("Gis.onReady("+f+")",100);
    else f();
      
}
/**
 *Import les modules Gis.
 *@param r string la route du script.
 *@access public
 *@return boolean
 *ex. G.require("gis.connection.Ajax");
 *
 **/
Gis.prototype.require=function (r){

   if(this.modules.containsValue(r)) return true;
    
this.modules.push(r);
    var _1=this.LIB_PATH+"/"+(r.replace(/\./g, '/'))+".js";
    Gis.chargee.push(false);
    if(this.loadScript(_1,null)){
        

        return true;
    }
    return false;
}

Gis.prototype.Anim={
    toggleClass:function(ele,obj){
        for(var i in obj)  m(i,obj[i])
        function m(i,t){
            G.Event.addListener(ele,i,function (){
                G.setClass(ele,t)
            });
        }
    }
}


var G=new Gis();
/**
 *Il cree un element html 'script' avec le contenu du ficher qui est sur url.Il est place 
 *dans le header du document.
 *Il telecharge le script qui est fixe sur url.
 *Le code qui contiene le script peut etre utilize par la function callback
 *@param url String le path du script
 *@param callback la function que va courrir au moment que le script est "onready"
 *@access public
 *@return boolean mais il n'est pas garanti que le script est deja telecharge, on doit utilice callback
 *
 **/
Gis.prototype.loadScript=function (url, callback){

    var script = document.createElement("script");
    script.type = "text/javascript";

    if (script.readyState){  //IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded" ||
                script.readyState == "complete"){
                script.onreadystatechange = null;
                if(callback) callback();
            }
        };
    } else {  //Others
        script.onload = function(){
            if(callback) callback();
        };
    }

    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
    return true;
}

/**
 *Retours l'element html.
 *
 *@param ele String[]  avec le id d'element html
 *@access public
 *@return mixed String au String[] qui contien le element html
 *
 **/
Gis.prototype.ele=function(ele) {
    if ( typeof ele == 'string') return document.getElementById(arguments[0]);

    var ret=[];
    for (var i = 0; i < ele.length; i++)    ret.push(document.getElementById(ele[i]));
    return ret;
}//ok


/**
 *Retourne les id des html element  qui sont sur ele.
 *Si l'element n'a pas Id, il crée un.
 *@param ele HtmlElement|HtmlCollection|HtmlElement[] le peut etre un HtmlElement ou un HtmlCollection de HtmlElements
 *@return string|string[]
 *Ex. G.getId(document.getElementsByTagName("div"))
 *
 **/
Gis.prototype.getId=function(ele){
    var ret=[];

    if(ele instanceof Array){
        for(var y=0; y < ele.length; y++)
        {
            if(!ele[y].getAttribute("id")) ele[y].id=G.getNewId();
            ret.push(ele[y].getAttribute("id"));
        }
        return ret;
    }
    else    if(ele.length>=0)//si es una HtmlCollection
    {
        for(var i=0; i < ele.length; i++)
        {
            if(!ele.item(i).getAttribute("id")) ele.item(i).id=G.getNewId();
            ret.push(ele.item(i).getAttribute("id"));
        }
        return ret;
    }
    else{//esto debe ser un HtmlElement
        if(!ele.getAttribute("id")) ele.id=G.getNewId();
        return  ele.getAttribute("id");
    }
}


/**
 *Il retours les elements html qui sont de la class que indique sc.
 *
 *@param sc string  qui a les noms des class.
 *@param node String node de parti pour la recherche.
 *@param tag string limite la recherche suelement aux element qui s'appel come tag
 *@access public
 *@return mixed HtmlElement[] qui contien le element html
 *
 **/
Gis.prototype.eleByClass=function(sc,node,tag) {
    var arrEle = new Array();
    if ( node == null )  node = document;
    if ( tag == null )   tag = '*';
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)"+sc+"(\\s|$)");
    for (i = 0, j = 0; i < elsLen; i++) {
        if ( pattern.test(els[i].className) ) {
            arrEle[j] = els[i];
            j++;
        }
    }
    return arrEle;
}
/**
 *Mette au change la class d'HtmlElement
 *@param ele HtmlElement|HtmlCollection|HtmlElement[] le peut etre un HtmlElement ou un HtmlCollection de HtmlElements
 *@param className String nom de la class
 *@return this
 **/
Gis.prototype.setClass=function(ele,className){
    var _u=G.isIE?"className":"class";//Tres importante c'est line!!'
    
    if(ele instanceof Array)  for(var y=0; y < ele.length; y++) ele[y].setAttribute(_u,className);
    else if(ele.length>=0)  for(var i=0; i < ele.length; i++)  ele.item(i).setAttribute(_u,className);
    else ele.setAttribute(_u,className);
    return this;
}

/**
 *Mette aux elements le style inline
 *@param ele HtmlElement|HtmlCollection|HtmlElement[] le peut etre un HtmlElement ou un HtmlCollection de HtmlElements
 *@param style String le style
 *@return this
 */
Gis.prototype.setStyle=function(ele,style){

    if(ele instanceof Array)  for(var y=0; y < ele.length; y++) G.isIE?ele[y].style.setAttribute("cssText",style):ele[y].setAttribute("style",style);
    else if(ele.length>=0)  for(var i=0; i < ele.length; i++)  G.isIE?ele.item(i).style.setAttribute("cssText",style):ele.item(i).setAttribute("style",style);
    else G.isIE?ele.style.setAttribute("cssText",style):ele.setAttribute("style",style);
    return this;

}

Gis.prototype.addStyle=function(ele,obj){
    if(!(ele instanceof Array)) ele=[ele];
    for(var j=0; j<ele.length; j++){
        for(var i in obj){
            ele[j].style[i]=obj[i];
        }
    }
}


Gis.prototype.getStyle=function (ele, style) {

    var value = ele.style[style];

    if(!value)
        if(document.defaultView)
            value = document.defaultView.getComputedStyle(ele, "").getPropertyValue(style);

        else if(ele.currentStyle)
            value = ele.currentStyle[style];

    return value;
}



/**
 *
 *G.createElement("span",{className:"gui-header-text",style:null,textNode:"hola",innerHTML:"<br>"});
 */
Gis.prototype.createElement=function(type,obj){
    var r=document.createElement(type);
    r.setAttribute("id",G.getNewId());
    for(var i in obj){
        
        if(i=="className") G.setClass(r,obj[i]);
        else if(i=="style") G.setStyle(r,obj[i]);
        else if(i=="textNode") r.appendChild(document.createTextNode(obj[i]));
        else if(i=="innerHTML") r.innerHTML=obj[i];
        else if(i=="HtmlElement")  r.appendChild(obj[i]);
        else if(i=="attributes")  for(var j in obj[i]){ 
            r.setAttribute(j,obj[i][j]);
        }
        else if(i=="HtmlElements")  {
            for(var t=0; t<obj[i].length;t++){
                r.appendChild(obj[i][t]);
            }
            }
          
    }
    return r;
}
//#################### EVENT/LISTENER ####################
//#################### EVENT/LISTENER ####################
//#################### EVENT/LISTENER ####################
//#################### EVENT/LISTENER ####################

/**
 *Il mettre un listener a un objet qui est listerable ex.Panel
 *@param listerable Listerable c'est un objet qui extends de Listerable.
 *@param eventType string qui est le nom del type de event. ex.: 'loaded'
 *@param callback Function qui es la function paur executer.
 *@access public
 *@return this
 ***/
Gis.prototype.addListener=function addListener(listerable,eventType,callback){
    listerable.addListener(eventType,callback);
    return this;
}//ok

/**
 *Il est la super class par tous les objet qui ont d'events.
 *@access public
 **/
Gis.prototype.Listerable = function() {
    var  listeners={},_sp=false;
    /**
 *Il ajoute un listener a un event sur le objet qui extends de cette clase.
 *@param eventType string qui est le nom del type de event. ex.: 'loaded'
 *@param callback Function qui es la function paur executer.
 *@access public
 *@return this
 **/
    this.addListener=function(eventType,callback){
        if(! listeners[eventType]) listeners[eventType]=[];

        listeners[eventType].push(callback);
        return this;
    }//ok
    /**
 *Il remove un listener a l'objet qui extends de cette clase.
 *@param eventType string qui est le nom del type de event. ex.: 'loaded'
 *@param callback Function qui es la function paur executer.
 *@access public
 *@return this
 **/
    this.removeListener=function(eventType,callback){
        if(! listeners[eventType])return this;        
        var br= listeners[eventType].arrayKeys(callback);
        if(br.isEmpty()) return this;
        listeners[eventType]= listeners[eventType].removeKeys(br);
        return this;
    }//ok
    /**
 *Il arrete la propagation de events sur l'objet qui extends cette class.
 *@return this
 **/
    this. stopPropagation=function(){
        _sp=true;return this;
    }//ok

    /**
 *Delete tous les listeners
 *@return this
 **/
    this.removeListeners=function(){
        listeners={},_sp=false;return this;
    }
    /**
 *Il cloche un event a l'objet qui extends cette class
 *@param eventType string qui est le nom del type de event. ex.: 'loaded'
 *@param eventData Objet avec la configuration du event.
 *@access public
 *@return this
 **/
    this.fireEvent=function (eventType,eventData){
		
        eventData['event']=eventType;
        if(! listeners[eventType])return this;
        for(var i=0; i< listeners[eventType].length; i++){
            if(listeners[eventType][i]==null) continue;
            listeners[eventType][i](eventData);
            if(_sp) {
                _sp=false;break;
            }
        }
        return this;
    }//ok
}


/**
 * Class qui est un cross-browser pour les events
 * @access public
 *
 */
Gis.prototype.Event={
    /**
    *Cross-browser qui retorne le objet event du browser.
    *@param e mixed Objet Event du browser.
    *@access public
    *@return Objet Event du browser.
    **/
    getEvent:function(e){
        return e || window.event;
    },//ok
    /**
    * Cross-browser qui Retourne l'element qui a cree le evenement.
    * @param e Event du browser
    * @access public
    * @return HtmlElement
    */
    getTarget:function(e) {
        return e.target || e.srcElement;
    },//ok
    /**
    * Cross-browser qui Stopped la propagation des events.
    * @param e Event du browser
    * @access public
    * @return void
    */
    stopPropagation:function(e) {
        if (e.stopPropagation) e.stopPropagation();else e.cancelBubble = true;
    },//ok
    /**
    * Cross-browser qui preventing the Default Browser Action from Occurring.
    * @param e Event du browser
    * @access public
    * @return void
    */
    preventDefault:function(e) {
        if (e.preventDefault)e.preventDefault();else e.returnValue = false;
    },//ok
    /**
    * Cross-browser qui appele a stopPropagation et preventDefault()
    * @param e Event du browser
    * @access public
    * @return void
    */
    stopEvent:function(e) {
        this.stopPropagation(e); this.preventDefault(e);
    },//ok
    /**
    * Cross-browser qui joint un function listener qui reponds a un evenement.
    * Les evenements sont apilables.
    * ex.: G.Event.addListener([window,G.ele("mvy"),G.ele("dvp")],'click',mn);
    * 
    * Le evenement plus comunes sont:
    * Mouse events:
    * ------------
    * mouseup, mousedown, click (the sequence is mousedown-up-click), dblclick
    * mouseover (mouse is over an element), mouseout (mouse was over an element but left it), mousemove
    * Keyboard events:
    * ---------------
    * keydown, keypress, keyup (occur in this sequence)
    * Loading/window events:
    * ---------------------
    * load (an image or a page and all of its components are done loading), unload (user leaves the page), beforeunload (the script can provide the user with an option to stop the unload)
    * abort (user stops loading the page in Firefox or an image in IE), error (a JavaScript error in Firefox and IE, also when an image cannot be loaded in IE)
    * resize (browser window is resized), scroll (the page is scrolled), contextmenu (the right-click menu appears)
    * Form events:
    * ------------
    * focus (enter a form field), blur (leave form field)
    * change (leave a field after the value has changed), select (select text in a text field) reset, submit
    *
    *
    * @param el mixed HtmlElement au HtmlElement[]
    * @param type String qui est le type de event. ex.
    * @param callback Function
    * @access public
    * @return void
    */
    addListener:function(el, type, callback) {
		
        if(!(typeof(el) == "object" && el.constructor == Array))el=[el];
        for(var i=0; i<el.length; i++){
            var tmp=el[i];
            if (window.addEventListener) {
                tmp.addEventListener(type, callback, false);
            }
            else if (window.attachEvent) {
                tmp.attachEvent('on' + type,callback);
            }
            else {
                tmp['on' + type] = callback;
            }
        } return this;
        
    },//ok
    /**
     *
     *Ex. du usage:
     *G.Event.addListener([G.ele("mvy")],'click',mn);
     *  //G.Event.removeListener([G.ele("mvy")],'click',mn);//Ca ne marche pas!!!!
     *
     *function mn(evt){
     *  G.Event.getTarget(evt).style.backgroundColor=c?"green":"red";c=!c;
     *  G.Event.removeListener(G.Event.getTarget(evt),'click',mn);//OK
     *}
    * @param el mixed HtmlElement au HtmlElement[]
    * @param type String qui est le type de event. ex.
    * @access public
    * @return void
     */
    removeListener:function (el, type, fn) {
        if (el.removeEventListener) { //for DOM-compliant browsers
            el.removeEventListener(type, fn, false);
        } else if (el.detachEvent) { //for IE
            el.detachEvent("on" + type, fn);
        } else { //for all others
            el["on" + type] = null;
        }return this;
    }//ok
}






//#################### POO ####################
//#################### POO ####################
//#################### POO ####################
//#################### POO ####################

/**
 * create a new object from a given class structure.
 * @param subClass String le nom de la subclass a grandir
 * @param superClass String le nom de la super class.
 * @access public
 * @return void
 */
Gis.prototype.extend=function (subClass, superClass) {
    var F = function() {};
    F.prototype = superClass.prototype;
    subClass.prototype = new F();
    subClass.prototype.constructor = subClass;
    subClass.superclass = superClass.prototype;
    if(superClass.prototype.constructor == Object.prototype.constructor) {
        superClass.prototype.constructor = superClass;
    }
}//ok





//############### outils ###############
//############### outils ###############
//############### outils ###############

/**
 *Retourne un unique id.
 *Il peut etre utilise  au moment de cree des class,
 *on peut indique a nìmporte pas quel element HTML  quìl va etre son id
 *@access public
 *@return string
 **/
Gis.prototype.getNewId=function(){
    return "gisId_"+(this._ids++);
}//ok


Gis.prototype.Style={
    setOpacity:function( ele, opacity ) {
        var s = ele.style;
        if(G.isIE)s.filter = "alpha(opacity=" + opacity + ")";
        else{
            s.opacity = ( opacity / 100 );
            s.MozOpacity = ( opacity / 100 );
            s.KhtmlOpacity = ( opacity / 100 );
        }

    },
    getOpacity:function(ele) {
        var ret=(ele.style.KHTMLOpacity) ? (ele.style.KHTMLOpacity * 100) : (ele.style.MozOpacity) ? (ele.style.MozOpacity * 100) : (ele.style.opacity) ? (ele.style.opacity * 100) : null;
        return ret===null?100:ret;
    }
}















///#################### Augmenting Built-in Objects ####################
///#################### Augmenting Built-in Objects ####################
///#################### Augmenting Built-in Objects ####################
///#################### Augmenting Built-in Objects ####################





///Array///Array///Array///Array///Array///Array///Array///Array///Array///Array
/**
 * Il ajoute une méthode pour objet natif Array.
 * Indique si une valeur appartient à un tableau. Si on travaille avec objets, il fait la comparation de references
 * @param needle mixed qui peut etre object.
 * @access public
 * @return boolean
 */
Array.prototype.containsValue = function(needle) {
    for (var i = 0, len = this.length; i < len; i++) {
        if (this[i] === needle) {
            return true;
        }
    }
    return false;
}//ok


/**
 *Retourne toutes les clés d'un tableau ou la valeur soit equal a needle
 *@param needle mixed qui peut etre object.
 * @access public
 *@return int[]
 */
Array.prototype.arrayKeys=function(needle){
    var ret=[];
    for (var i = 0, len = this.length; i < len; i++) {
        if (this[i] === needle) {
            ret.push(i);
        }
    }
    return ret;
}//ok

/**
 *Retourne true si le tableau es vide.
 * @access public
 *@return boolean
 */
Array.prototype.isEmpty=function(){
    return this.length==0?true:false;
}//ok

/**
 * retoune un autre tableau san considerer les cles qui sont sur array.
 * @param array mixed[] les keys qu'on veut effacer.
 * @access public
 * @return mixed[]
 */
/* exemple de code */
Array.prototype.removeKeys=function(array){
    var ret=[];
    for (var i = 0, len = this.length; i < len; i++) {
        if (!array.containsValue(i)) {
            ret.push(this[i]);
        }
    }
    return ret;
}//ok
///String///String///String///String///String///String///String///String///String


////generales////generales////generales////generales////generales////generales
/**
 *Retourne true si obj est un tableau
 *@param obj mixed
 * @access public
 *@return boolean
 **/
var isArray=function (mx) {
    return mx instanceof Array;
}//ok

var isHtmlElement=function(obj){
    return (typeof obj['nodeName']=='undefined')? false:true;
}
/**
 *On peut utilise isDefined('monVar') pour le variables globals, ou isDefined('monVar',obejt)
 */
var isDefined=function (prop,obj) { 
    if(obj===undefined) obj=window; return prop in obj && obj[prop]!==undefined
}




Gis.prototype.Window={
    getSize: function () {
        var myWidth = 0, myHeight = 0;
        if( typeof( window.innerWidth ) == 'number' ) {
            //Non-IE
            myWidth = window.innerWidth;
            myHeight = window.innerHeight;
        } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
            //IE 6+ in 'standards compliant mode'
            myWidth = document.documentElement.clientWidth;
            myHeight = document.documentElement.clientHeight;
        } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
            //IE 4 compatible
            myWidth = document.body.clientWidth;
            myHeight = document.body.clientHeight;
        }
        return [myWidth, myHeight];
    },

    getScrollSize:   function() {
        var scrOfX = 0, scrOfY = 0;
        if( typeof( window.pageYOffset ) == 'number' ) {
            //Netscape compliant
            scrOfY = window.pageYOffset;
            scrOfX = window.pageXOffset;
        } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
            //DOM compliant
            scrOfY = document.body.scrollTop;
            scrOfX = document.body.scrollLeft;
        } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
            //IE6 standards compliant mode
            scrOfY = document.documentElement.scrollTop;
            scrOfX = document.documentElement.scrollLeft;
        }

        return[ scrOfX,scrOfY ];
    },


    getCenter: function(){
        var scroll=this. getScrollSize();
        var s=this.getSize();
        if(!scroll)return [Math.ceil(s[0]/2)+scroll[0],Math.ceil(s[1]/2)+scroll[1]];
        else return [Math.ceil(s[0]/2),Math.ceil(s[1]/2)];
    }




};

Gis.prototype.print=function(cad,id){
    G.ele(id).innerHTML=cad;
}
$=G.ele;
