/* GLOBAL*/
function hasClass(elm, className)
{
    if (!elm || !elm.className)
    {
        return false;
    }
    var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
    return elm.className.match(re)
}

function addClass(elm, className)
{
    if (!elm)
    {
        return false;
    }
    if (!hasClass(elm, className))
    {
        elm.className += (elm.className ? " " : "") + className;
    }
}

function removeClass(elm, className)
{
    if (!elm || !elm.className)
    {
        return false;
    }
    var regexp = new RegExp("(^|\\s)" + className + "(\\s|$)", "g");
    elm.className = elm.className.replace(regexp, "$2");
}

function getElementsByClassName(className, parentElement, nodeName)
{
    // prototype réécri la méthode "[].filter", ce qui génére un bug dans le test suivant
    // utilisation d'un test spécifique corriger
    if (typeof $ != "undefined")
    {
        if (!parentElement)
        {
            parentElement = document.body;
        }
        if (!nodeName)
        {
            nodeName = '';
        }
        if (typeof $(parentElement).select != "undefined")
        {
            return $(parentElement).select(nodeName.toLowerCase() + "." + className);
        }
    }
    
    // native
    if (document.getElementsByClassName)
    {    
        if (!parentElement)
        {
            parentElement = document.body;
        }
        // HACK pour corriger ce bug : https://bugs.webkit.org/show_bug.cgi?id=19974
        parentElement.setAttribute('data-refresh', '1');
        parentElement.removeAttribute('data-refresh');
        
        var s = parentElement.getElementsByClassName(className);
        if (nodeName && nodeName != '*')
        {
            return [].filter.call(s, function(el) { return el.nodeName == nodeName.toUpperCase(); });
        }
        else
        {
            return [].slice.call(s, 0);
        }
    }
    
    var results = [], s, i = 0, element;
    if (!nodeName)
    {
        nodeName = '*';
    }
    if (!parentElement)
    {
        parentElement = document;
    }
    
    // xpath
    if (document.evaluate)
    {
        s = document.evaluate(
            ".//" + nodeName + "[contains(concat(' ', @class, ' '), ' " + className + " ')]",
            parentElement,
            null,
            XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
            null
        );

        while ((element = s.snapshotItem(i++)))
        {
            results.push(element);
        }

        return results;
    }

    // generic
    var re = new RegExp('(^|\\s)' + className + '(\\s|$)'), elementClassName;
    s = parentElement.getElementsByTagName(nodeName);

    while ((element = s[i++]))
    {
        if ((elementClassName = element.className) &&
            (elementClassName == className || re.test(elementClassName)))
        {
            results.push(element);
        }
    }

    return results;
}



/*
    Base, version 1.0.2
    Copyright 2006, Dean Edwards
    License: http://creativecommons.org/licenses/LGPL/2.1/
*/

var Base = function() {
    if (arguments.length) {
        if (this == window) { // cast an object to this class
            Base.prototype.extend.call(arguments[0], arguments.callee.prototype);
        } else {
            this.extend(arguments[0]);
        }
    }
};

Base.version = "1.0.2";

Base.prototype = {
    extend: function(source, value) {
        var extend = Base.prototype.extend;
        if (arguments.length == 2) {
            var ancestor = this[source];
            // overriding?
            if ((ancestor instanceof Function) && (value instanceof Function) &&
                ancestor.valueOf() != value.valueOf() && /\bbase\b/.test(value)) {
                var method = value;
            //    var _prototype = this.constructor.prototype;
            //    var fromPrototype = !Base._prototyping && _prototype[source] == ancestor;
                value = function() {
                    var previous = this.base;
                //    this.base = fromPrototype ? _prototype[source] : ancestor;
                    this.base = ancestor;
                    var returnValue = method.apply(this, arguments);
                    this.base = previous;
                    return returnValue;
                };
                // point to the underlying method
                value.valueOf = function() {
                    return method;
                };
                value.toString = function() {
                    return String(method);
                };
            }
            return this[source] = value;
        } else if (source) {
            var _prototype = {toSource: null};
            // do the "toString" and other methods manually
            var _protected = ["toString", "valueOf"];
            // if we are prototyping then include the constructor
            if (Base._prototyping) _protected[2] = "constructor";
            for (var i = 0; (name = _protected[i]); i++) {
                if (source[name] != _prototype[name]) {
                    extend.call(this, name, source[name]);
                }
            }
            // copy each of the source object's properties to this object
            for (var name in source) {
                if (!_prototype[name]) {
                    extend.call(this, name, source[name]);
                }
            }
        }
        return this;
    },

    base: function() {
        // call this method from any other method to invoke that method's ancestor
    }
};

Base.extend = function(_instance, _static) {
    var extend = Base.prototype.extend;
    if (!_instance) _instance = {};
    // build the prototype
    Base._prototyping = true;
    var _prototype = new this;
    extend.call(_prototype, _instance);
    var constructor = _prototype.constructor;
    _prototype.constructor = this;
    delete Base._prototyping;
    // create the wrapper for the constructor function
    var klass = function() {
        if (!Base._prototyping) constructor.apply(this, arguments);
        this.constructor = klass;
    };
    klass.prototype = _prototype;
    // build the class interface
    klass.extend = this.extend;
    klass.implement = this.implement;
    klass.toString = function() {
        return String(constructor);
    };
    extend.call(klass, _static);
    // single instance
    var object = constructor ? klass : _prototype;
    // class initialisation
    if (object.init instanceof Function) object.init();
    return object;
};

Base.implement = function(_interface) {
    if (_interface instanceof Function) _interface = _interface.prototype;
    this.prototype.extend(_interface);
};

// written by Dean Edwards, 2005
// with input from Tino Zijdel, Matthias Miller, Diego Perini
// http://dean.edwards.name/weblog/2005/10/add-event/

function addEvent(element, type, handler)
{
    // Pour mieux maitriser l'ensemble, on gère qu'avec des handler
    if (element.addEventListener)
    {
        element.addEventListener(type, handler, false);
    } 
    else
    {
        // assign each event handler a unique ID
        if (!handler.$$guid) handler.$$guid = addEvent.guid++;
        
        // create a hash table of event types for the element
        if (!element.events) element.events = {};
        
        // create a hash table of event handlers for each element/event pair
        var handlers = element.events[type];
        if (!handlers) 
        {
            handlers = element.events[type] = {};
            
            // store the existing event handler (if there is one)
            if (element["on" + type])
            {
                handlers[0] = element["on" + type];
            }
        }
        
        // store the event handler in the hash table
        handlers[handler.$$guid] = handler;
        
        // assign a global event handler to do all the work
        element["on" + type] = handleEvent;
    }
};

// a counter used to create unique IDs
addEvent.guid = 1;

function removeEvent(element, type, handler) {
    if (element.removeEventListener)
    {
        element.removeEventListener(type, handler, false);
    } else
    {
        // delete the event handler from the hash table
        if (element.events && element.events[type])
        {
            delete element.events[type][handler.$$guid];
        }
    }
};

function handleEvent(event) {
    var returnValue = true;
    
    // grab the event object (IE uses a global event object)
    event = event || fixEvent(window.event);
    
    // get a reference to the hash table of event handlers
    var handlers = this.events[event.type];
    
    // execute each event handler
    for (var i in handlers) 
    {
        this.$$handleEvent = handlers[i];
        if (this.$$handleEvent(event) === false)
        {
            returnValue = false;
        }
    }
    return returnValue;
};

function fixEvent(event)
{
    // add W3C standard event methods
    event.preventDefault = fixEvent.preventDefault;
    event.stopPropagation = fixEvent.stopPropagation;
    return event;
};

fixEvent.preventDefault = function()
{
    this.returnValue = false;
};

fixEvent.stopPropagation = function() {
    this.cancelBubble = true;
};


/********************************/
/********************************/
/*** Comportements génériques ***/
/********************************/
handleOnload = [];

/*
 * Affichage des liens dans une nouvelle fenêtre
 */
function setTargetLink(elm)
{
	if (!elm)
	{
		return false;	
	}
	
	var links = elm.getElementsByTagName("a");
	for (var i=0, len=links.length; i<len; i++)
	{
		var link = links[i];
		
		if (!hasClass(link, "blank"))
		{
			continue;	
		}
		
		link.clickEvent = link.onclick || false;
		link.onclick = function(e)
		{
			var href = this.href || false;
			if (href)
			{
				window.open(href);
			}
			return false;
		}
	}
	
	return links.length;
}


/*
 * handler: submitCommentsHandler
 * gestion Ajax des formulaires de commentaires
 */
var submitCommentsHandler = function()
{
    var form = (this && this.tagName.toLowerCase() == "form") ? this : false;
    var elmMessage = document.getElementById("comment-error-message");
    
    if (!form || !elmMessage)
    {
        return false;
    }
    
    //
    // Récupération du message
    //
    var getMessage = function(bodyElm)
    {
        if (typeof bodyElm == "undefined")
        {
            return false;
        }
        return bodyElm.textContent || "";
    };
    
    //
    // Affichage du message
    //
    var setMessage = function(textData)
    {
        elmMessage.innerHTML = textData || "";
        return true;
    };
    
    //
    // Récupération param dans la page
    //
    var serializeParams = function(elements)
    {
        if (!elements)
        {
            return false;
        }
        
        var result = "";
        for (var i=0, len=elements.length; i<len; i++)
        {
            var elm = elements[i];
        
            if (result && result.length)
            {
                result += "&";
            }
            result += elm.name + "=" + escape(elm.value);
        }
        
        return result;
    };
    
    //
    // Gestion des erreurs du formulaire
    //
    var errorHandler = function(oError)
    {
        var docRef = oError.documentElement || false;
        if (!docRef || !docRef.getElementsByTagName("body").length)
        {
            return false;
        }
        
        var message = getMessage(docRef.getElementsByTagName("body")[0]);
        if (!message || !message.length)
        {
            return false;
        }
        setMessage(message);
    };
    
    //
    // Handler Success
    //
    var successHandler = function(oMessage)
    {
        window.location.href = window.location.href;
        return true;
    };
    
    var params = serializeParams(this.elements) || false;
    var request = new ajaxRequest({
        url: this.action,
        method: "post",
        data: params,
        returnxml: true,
        error: errorHandler,
        success: successHandler
    });
    
    return false;
}

