/* driver utilisant Protoype + lib Effect de scriptaculous */

function Driver()
{
	this.prototypeContext = null;
	
	/* Driver.extend(destination:Object, source:Object) */
	/* Merge 2 objets */	
	Driver.prototype.extend = function(elm0, elm1) 
	{
		Object.extend(elm0, elm1);
		return elm0;
	};
	
	/* Driver.selector(elem:String) */
	/* selecteur avancé avec chainage du driver possible */
	/* return: objet Driver */
	/* ex driver.selector('ul').selector('.active').addEvent(remote.ajax.click, function(){}); */
	Driver.prototype.selector = function(elem)
	{
		this.prototypeContext = $(elem);		
		return this;
	};
	Driver.prototype.previousElement = function(elem)
	{
		if (!elem) return false;
		return $(elem).previous();
	};
	Driver.prototype.nextElement = function(elem)
	{
		if (!elem) return false;
		return $(elem).next();
	};
	
	/* Driver.getElement(elm:String) */
	/* selecteur simple */
	/* return: objet prototype*/
	Driver.prototype.getElements = function(path)
	{
		return $$(path) || null;
	};

	/* getParentNode(elm:(String||node), path:string) */
	/* return: objet prototype*/
	Driver.prototype.getParentNode = function(elem, path)
	{
		return $(elem).up(path);
	};
	
	/* Driver.hasClass(className:String [, elem:String ]) */
	/* vérifie la presence dans l'element dom visé */
	/* return: true/false */
	Driver.prototype.hasClass = function(elem, className){
		className = className || elem;
		elem = className ? elem : this.prototypeContext;
		if(!elem){ return false; }
		
		return $(elem).hasClassName(className);
	};
	
	/* Driver.addClass(className:String [, elem:String ]) */
	/* Ajoute la class à l'element dom visé */
	/* return: objet prototype */
	Driver.prototype.addClass = function(elem, className)
	{
        var i, len;
        className = className || elem;
        elem = className ? elem : this.prototypeContext;		
        if(!elem){ return false; }

        if(elem == window || elem.documentElement || (typeof elem.nodeType != "undefined" && elem.nodeType*1 == 1))
        {
            $(elem).addClassName(className);
        }
        else
        {
            for(i = 0, len = elem.length; i < len; i++)
            {
                $(elem[i]).addClassName(className);
            }
        }
	};
	
	/* Driver.removeClass(className:String [, elem:String ]) */
	/* Supprime la class à l'element dom visé */
	/* return: objet prototype */
	Driver.prototype.removeClass = function(elem, className)
	{
            var i, len;
            className = className || elem;
            elem = className ? elem : this.prototypeContext;		
            if(!elem){ return false; }

            if(elem == window || elem.documentElement || (typeof elem.nodeType != "undefined" && elem.nodeType*1 == 1))
            {
                $(elem).removeClassName(className);
            }
            else
            {
                for(i = 0, len = elem.length; i < len; i++)
                {
                    $(elem[i]).removeClassName(className);
                }
            }
	};
	
	/* Driver.getElementByClassName(className:String [, elem:String ]) */
	/* Cherche les élément comportant la class voulut dans l'objet dom cible */
	/* return: objet prototype */
	Driver.prototype.getElement = function(elem, path)
	{
		path = path || elem;
		elem = path ? elem : this.prototypeContext;
		if(!elem){ return false; }
		return $(elem).down(path) || false;
	};
	
	/**
         * addEvent
         * Ajoute un evenement à un DomElement
         * 
         * @param   elem        array/string    éléments à binder
         * @param   eventType   string          type d'évènement voulut
         * @param   callback    function  
         *       
         * @return  void
	 */
	Driver.prototype.addEvent = function(elem, eventType, callback)
	{
		var i, len;
		callback = callback || eventType;		
		eventType = eventType || elem;
	
		elem = callback ? $(elem) : this.prototypeContext;
		if(!elem)
		{ 
			return false; 
		}
        
        if(elem == window || elem.documentElement || (typeof elem.nodeType != "undefined" && elem.nodeType*1 == 1))
        {
            Event.observe(elem, eventType, callback);
            return true;
        }
        for(i = 0, len = elem.length; i < len; i++)
        {
            Event.observe(elem[i], eventType, callback);
        }
        return true;
	};
	
	/**
         * stopEvent
         * Ajoute un evenement à un DomElement
         * 
         * @param   elem        array/string    éléments à binder
         * @param   eventType   string          type d'évènement voulut
         * @param   callback    function  
         *       
         * @return  void
	 */
	Driver.prototype.stopEvent = function(elem, eventType, callback)
	{
        var i, len;
		callback = callback || eventType;		
		eventType = eventType || elem;	
		elem = callback ? $(elem) : this.prototypeContext;
		if(!elem){ return false; }

        if(elem == window || elem.documentElement || (typeof elem.nodeType != "undefined" && elem.nodeType*1 == 1))
        {
            Event.stopObserving(elem, eventType, callback);
            return true;
        }
        for(i = 0, len = elem.length; i < len; i++)
        {
            Event.stopObserving(elem[i], eventType, callback);
        }
        return true;
	};
	
	Driver.prototype.triggerEvent = function(elem, eventName)
	{
	    // safari, webkit, gecko
	    if (document.createEvent)
	    {
		    var evt = document.createEvent('HTMLEvents');
		    evt.initEvent(eventName, true, true);
	        return elem.dispatchEvent(evt);
	    }
	 
	    // Internet Explorer
	    if (elem.fireEvent) 
	    {
	        return elem.fireEvent('on' + eventName);
	    }
	};
        
	/* Driver.changeCSS(style:String [, elem:String ]) */
	/* Change le style de l'élément cible */
	Driver.prototype.changeCSS = function(elem, style){
		style = style || elem;
		elem = style ? elem : this.prototypeContext;
		if(!elem){ return false; }
	
		$(elem).setStyle(style);
                
                return true;
	};

	/* deleteAnimate(elem) */
	/* Remove all effects which are playing on the element 'elem' */
	Driver.prototype.deleteAnimate = function(elem, effect)
	{
		if (typeof effect.cancel !== "undefined")
		{
			effect.cancel();
			return true;
		}
		return false;
	};
	
	/* Driver.animateCSS(style:String, delay:Number, callback:Function [, elem:String ]) */
	/* Anime l'élement cible */
	Driver.prototype.animateCSS = function(elem, style, delay, callback)
	{
		/*
		callback = callback || delay;
		delay = callback ? delay : style;
		style = callback ? style : elem;
		elem = callback ? elem : this.prototypeContext;
		if(!elem) return false;
		*/
		
		return new Effect.Morph(elem, {
			"style" : style,
			"duration" : delay/1000, 
			"afterFinish" : callback
		});
	};
	
	/* Driver.serialize(object:Object) */
	/* concatain le valeur des champs de formulaire */
	/* return: string */
	Driver.prototype.serialize = function(elm)
	{
		if (typeof $(elm).serialize !== "undefined")
		{
			return $(elm).serialize();
		}
		return Object.toQueryString(elm);
	};
	
	/* Driver.ajaxRequest(object:Object) */
	/* requette Ajax */
	/* return: objet Ajax.Request */
	Driver.prototype.ajaxRequest = function(params)
	{
		return new Ajax.Request(params.url, 
		{
			evalJS          : (typeof params.evalJS !== "undefined") ? params.evalJS : false,
			onLoading       : params.loading || function(){},
			onFailure       : params.error || function(){},
			onComplete      : params.complete || function(){},
			onSuccess       : params.success || function(){},
			parameters      : (typeof params.data !== "string") ? "" : params.data,
			method          : params.type || 'get'
		});
	};
	
	/* Driver.find(search:String [, elem:String [, returnJquery:Boolean]]) */
	/* Cherche les élément voulut dans le dom cible */
	/* return: objet  ou objet Driver */
	Driver.prototype.find = function(elem, search){
		search = search || elem;
		elem = search ? elem : this.prototypeContext;
		if(!elem){ return false; }
		
		/*
		_trace(search)
		_trace($(elem))
		_trace($(elem).select(search))
		*/
		
		return $(elem).select(search);
	};
	
	/* Driver.getAttr(attr:String [, elem:String]) */
	/* Retourne l'attribut voulut */
	/* return: objet $ */	
	Driver.prototype.getAttr = function(elem, attr)
	{		
		attr = attr || elem;
		elem = attr ? elem : this.prototypeContext;
		
		return $(elem).readAttribute(attr);
	};
	
	/* Driver.putHTML(attr:String [, elem:String]) */
	/* Remplace le contenu html de l'élément voulut */
	/* return: objet $ */
	Driver.prototype.putHTML = function(elem, html)
	{
		$(elem).update(html);
		
		/*
		//
		// chargement des fichiers externes
		//
		var 
			_scriptsSearch = new RegExp(Prototype.ScriptFragment, 'img'),
			_scripts = html.match(_scriptsSearch) || [],
			_currentScripts = driver.find(document.body, "script"),
			_currentSources = []
		;
		// Scripts déjà chargés
		for (var i=0, len=_currentScripts.length; i<len; i++)
		{
			var _src = _currentScripts[i].src || "";
			if (_src.length)
			{
				_currentSources.push(_src);
			}
		}
		
		// Scripts a ajouter
		for (var i=0, len=_scripts.length; i<len; i++)
		{
			var 
				_script = _scripts[i],
				_getSourceValue = _script.match(/src=[\"\']([\w\_\-\/\.\:]+)[\"\']/) || ["", ""],
				_sourceValue = _getSourceValue[1]
			;
			if (_sourceValue.length && _currentSources.toString().search(_sourceValue) < 0)
			{
				var DSLScript  = document.createElement("script");
				DSLScript.type = "text/javascript";
				DSLScript.src  = _sourceValue;
				//alert(_sourceValue)
				document.body.appendChild(DSLScript);
				//document.body.removeChild(DSLScript);
			}
		}
		*/
		
		return elem;
	};
	
	/* Driver.appendHTML(attr:String [, elem:String]) */
	/* Ajoute le contenu html à la fin de l'élément boulut */
	/* return: objet $ */	
	Driver.prototype.appendHTML = function(elem, html){
		html = html || elem;
		elem = html ? elem : this.prototypeContext;
		if(!elem){ return false; }
		
		return $(this.prototypeContext).insert({bottom : html});
	};
	
	Driver.prototype.slideUp = function(elem)
	{		
		return Effect.SlideUp(elem);
	};
	
	Driver.prototype.slideDown = function(elem)
	{
		return Effect.SlideDown(elem);
	};
	
	/* Driver.getCSS(style:String [, elem:String ]) */
	/* Recupère le style de l'élément cible */
	Driver.prototype.getCSS = function(elem, style){
		style = style || elem;
		elem = style ? elem : this.prototypeContext;
		if(!elem){ return false; }
		return $(elem).getStyle(style);;
	};
	
}

var driver = new Driver();
