// json2.js by Douglas Crockford
if(!this.JSON){this.JSON={};}(function(){function f(n){return n<10?"0"+n:n;}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key);}if(typeof rep==="function"){value=rep.call(holder,key,value);}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null";}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null";}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v;}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==="string"){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v);}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v;}}if(typeof JSON.stringify!=="function"){JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" ";}}else{if(typeof space==="string"){indent=space;}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify");}return str("",{"":value});};}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}return reviver.call(holder,key,value);}cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4);});}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j;}throw new SyntaxError("JSON.parse");};}}());

// Fonction pour que IE puisse traiter les images encodées
// en base64. Attend en paramètre l'url du script PHP de
// décodage
function fixBase64(el) {
    var b64Pattern = /data:(.*?;base64,[\w\/=+-]+)/i;
    var decoderUrl = '/wp-content/themes/demontiers/base64.php';
    
    // stop the CSS expression from being endlessly evaluated
    el.runtimeStyle.behavior = 'none';
    
    if (el.src && el.src.match(b64Pattern)) {
        el.src = decoderUrl + '?' + RegExp.$1;
    }
    
    var bgImage = el.currentStyle.backgroundImage;
    if (bgImage.match(b64Pattern)) {
        el.style.backgroundImage = 'url(' + decoderUrl + '?' + RegExp.$1 + ')';
    }
};

// Reproduction en JS de la fonction in_array() de PHP
function in_array(needle, stack, strict){
    for (var i=0, l=stack.length; i<l; i++)
        if (!strict && stack[i] == needle || stack[i] === needle)
            return true;
    return false;
}

// imite la propriété length des tableaux, pour les objets
function size(obj) {
    var s = 0;
    for (var k in obj)
        if (obj.hasOwnProperty(k))
            s++;
    return s;
}


/*******************/
/*    CARROUSEL    */
/*******************/
var Carousel = {

    init: function(ul, controls) {
        // Préparation
        this.ul = $(ul);
        this.div = this.ul
            .width(10000)
            .attr('className', '')
            .wrap('<div class="carousel"><div class="mask"></div></div>')
            .parent().parent()
            .prepend('<a class="control prev" href="?">' + controls.prev + '</a>')
            .append('<a class="control next" href="?">' + controls.next + '</a>')
            .find('.control').click(function(){
                Carousel.goToPage(
                    Carousel.currentPage + ($(this).is('.prev') ? -1 : 1)
                );
                return false;
            }).end();
        this.items = this.ul.children();
        this.mask = this.ul.parent();
        this.currentPage = 1;
        this.itemsPerPage = Math.floor((
                this.mask.innerWidth() - parseInt(this.ul.css('paddingLeft'), 10)
                ) / this.getItemSize()
        );
        this.totalPages = Math.ceil(this.items.length / this.itemsPerPage);
    },

    getItemSize: function() {
        return this.items.eq(0).width()
            + parseInt(this.items.eq(0).css('borderLeftWidth'), 10)
            + parseInt(this.items.eq(0).css('borderRightWidth'), 10)
            + parseInt(this.items.eq(0).css('marginRight'), 10);
    },
 
    goToPage: function(x, speed) {
        // on force x a être compris entre 0 et totalPages
        var x = Math.min(Math.max(x, 1), Carousel.totalPages);
        
        this.mask
            .filter(':not(:animated)')
            .animate({
                    scrollLeft: this.getItemSize() * this.itemsPerPage * (x - 1)
                },
                 // on doit accepter speed=0 pour des transitions sans animation
                (speed === undefined ? 500 : speed),
                function(){
                    Carousel.currentPage = x;
                }
            );
    },
    
    getPagination: function() {
        var imgPath = '/wp-content/themes/demontiers/images/';
        var html = '<div class="pagination">'
            +    '<ul>'
            +        '<li class="prevnext prev">'
            +            '<a href="?">'
            +                '<img src="' + imgPath + 'fleche-blanche-gauche.png" alt="Page précédente" />'
            +            '</a>'
            +        '</li>';
        for (var i=1; i<=this.totalPages; i++) {
            html += '<li><a href="?">' + i + '</a></li>';
        }
        return $(html += '<li class="prevnext next">'
            +            '<a href="?">'
            +                '<img src="' + imgPath + 'fleche-blanche-droite.png" alt="Page suivante" />'
            +            '</a>'
            +        '</li>'
            +    '</ul>'
            + '</div>')
                .click(function(e){
                    var x, target = $(e.target);
                    while (target.is(':not(a)') && target[0].ownerDocument) {
                        target = target.parent();
                    }
                    if (target.is('a')) {
                        if (target.is('.next a')) {
                            x = Carousel.currentPage + 1;
                        } else if (target.is('.prev a')) {
                            x = Carousel.currentPage - 1;
                        } else {
                            x = target.text();
                        }
                        Carousel.goToPage(x);
                    }
                    return false;
                });
    }
};

/*******************/
/*    OBJET DMT    */
/*******************/

var DMT = {
    isIE: /*@cc_on+!@*/false,

    // Vignettes en niveaux de gris
    grayWhenIdle: function(image) {
        image = $(image);
        if (DMT.isIE) {
            image
                .css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)')
                .hover(
                    function() {this.filters.item(0).enabled = 0;},
                    function() {this.filters.item(0).enabled = 1;}
                );    
        } else {
            var nWidth = this.getNaturalWidth(image[0]);
            var actualWidth = image.width();
            var canvas = $('<canvas width="' + nWidth + '" height="' + nWidth + '">')
                            .width(actualWidth)
                            .height(actualWidth);
            if (canvas[0].getContext) {
                var context = canvas[0].getContext('2d');
                context.drawImage(image[0], 0, 0);
                var pixels = context.getImageData(0, 0, canvas[0].width, canvas[0].height);
                for (var h=0, hl=pixels.width; h<hl; h++){
                    for (var v=0, vl=pixels.height; v<vl; v++){
                        var idx = h * 4 + v * 4 * pixels.width;
                        pixels.data[idx] = pixels.data[idx+1] = pixels.data[idx+2] = Math.floor(
                              0.299 * pixels.data[idx]
                            + 0.587 * pixels.data[idx+1]
                            + 0.114 * pixels.data[idx+2]
                        );
                        pixels.data[idx+3] = 255;
                    }
                }
                context.putImageData(pixels, 0, 0, 0, 0, pixels.width, pixels.height);
                image
                    .hide()
                    .parent().hover(
                        function(){image.show(); canvas.hide();},
                        function(){image.hide(); canvas.show();}
                    )
                    .append(canvas);            
            }
        }
        image.addClass('grayscaled');
    },
    
    getNaturalWidth: function(image) {
        if (image.naturalWidth) {
            var nWidth = image.naturalWidth;
        } else {
            image = $(image);
            var bkpStyle = image.attr('style');
            var nWidth = image.css({width: '', height: ''}).width();
            image.attr('style', bkpStyle);
        }
        return nWidth;
    },

    // Redimensionnement automatique des vignettes
    resizeThumbs: function() {
        var clients = $('ul.clients');
        var works = $('.works:not(h3)');
        // De clients et works, seule la largeur de celui qui est visible est fiable
        // Note : filter(':visible') a déconné sous IE8...
        var both = clients.add(works).filter(function(index) {
            return $(this).css('display') != 'none';
        });
        // Redimensionnement de la liste (en px car '100%' pourrait se traduire par des demi-pixels)
        var listWidth = both.width('100%').width();
        both.width(listWidth);
        // Redimensionnement des vignettes (largeur totale - bordures - marges droites / 10)
        var tutu = $('img, canvas', clients);
        tutu.width(Math.floor((listWidth - 100 - 90) / 10));
        tutu.height(Math.floor((listWidth - 100 - 90) / 10));
        var toto = $('li img, li canvas, ', works).not('.pagination img');
        toto.width(Math.floor((listWidth - 10 - 50 - 50) / 5)); // 10 = padding-left de la ul
        toto.height(Math.floor((listWidth - 10 - 50 - 50) / 5));
        var titi = $('> a > img', works);
        titi.width(20);
        titi.height(Math.floor((listWidth - 10 - 50) / 5)); // on prend pas les bordures en compte
    },
    
    setupCarousel: function(){
        // Réorganisation HTML/CSS
        var clientList = $('ul.clients'),
            workList = $('ul.works');
        clientList
            .find('li:eq(9), li:eq(19)')
                .css('margin-right', 0).end()
            .next()
                .after(clientList)
                // Gestionnaire de clic sur les h3
                .click(function switchTab(){
                        var tutu = $(this).unbind('click', switchTab);
                        var toto = tutu.siblings('h3').click(switchTab);
                        var tete = toto.siblings('h3, ul, .carousel').andSelf().toggleClass('active');
                        // Lors du premier clic sur le h3 des réalisations, on construit le carrousel
                        if ($(this).is('h3.works') && $('.carousel').length == 0) {
                            DMT.resizeThumbs();
                            Carousel.init(workList, {
                                prev: '<img src="/wp-content/themes/demontiers/images/carousel-prev.png" width="20" height="178" alt="Page précédente" />',
                                next: '<img src="/wp-content/themes/demontiers/images/carousel-next.png" width="20" height="178" alt="Page suivante" />'
                            });
                            Carousel.div
                                .addClass('works')
                                .toggleClass('active', $('#featured h3.active').is('.works'))
                                .append(Carousel.getPagination());
                        }
                        $(window).resize();
                    });
    
        DMT.resizeThumbs();
                
        // Passage en noir et blanc et redimensionnement des vignettes
        var featuredImgs = $('.clients li img, .works li img');
        
        featuredImgs
            .load(function() {
                DMT.grayWhenIdle(this);
            })
            .each(function(){
                // IE n'a pas besoin d'attendre que l'image soit chargée
                // (en serait-il même capable...?)
                if (DMT.isIE) {
                    $(this).load();
                }
            });    
        
        $(window)
            .resize(function(){
                DMT.resizeThumbs();
                if (Carousel && Carousel.mask) {
                    Carousel.goToPage(Carousel.currentPage, 0);
                }
                return false;
            })
            .load(function(){
                // Lorsque les images n'envoient pas l'événement load
                // (Opera, ou utilisation du bouton Back, par exemple),
                // il nous faut invoquer DMT.grayWhenIdle() ici
                featuredImgs.filter(':not(.grayscaled)').each(function() {
                        DMT.grayWhenIdle(this);
                    });
            });
    }
};

/*****************
* PLUGINS JQUERY *
*****************/
// jQuery Color animations
jQuery.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(i,attr){jQuery.fx.step[attr]=function(fx){if(fx.state==0){fx.start=getColor(fx.elem,attr);fx.end=getRGB(fx.end);}fx.elem.style[attr]="rgb("+[Math.max(Math.min(parseInt((fx.pos*(fx.end[0]-fx.start[0]))+fx.start[0]),255),0),Math.max(Math.min(parseInt((fx.pos*(fx.end[1]-fx.start[1]))+fx.start[1]),255),0),Math.max(Math.min(parseInt((fx.pos*(fx.end[2]-fx.start[2]))+fx.start[2]),255),0)].join(",")+")";};});function getRGB(color){var result;if(color&&color.constructor==Array&&color.length==3){return color;}if(result=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)){return[parseInt(result[1]),parseInt(result[2]),parseInt(result[3])];}if(result=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)){return[parseFloat(result[1])*2.55,parseFloat(result[2])*2.55,parseFloat(result[3])*2.55];}if(result=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)){return[parseInt(result[1],16),parseInt(result[2],16),parseInt(result[3],16)];}if(result=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)){return[parseInt(result[1]+result[1],16),parseInt(result[2]+result[2],16),parseInt(result[3]+result[3],16)];}return colors[jQuery.trim(color).toLowerCase()];}function getColor(elem,attr){var color;do{color=jQuery.curCSS(elem,attr);if(color!=""&&color!="transparent"||jQuery.nodeName(elem,"body")){break;}attr="backgroundColor";}while(elem=elem.parentNode);return getRGB(color);}var colors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]};
// Utilitaires
$.fn.descendantOf = function(parent) {
    return $.inArray(
        this[0],
        parent.getElementsByTagName(this[0].tagName)
    ) !== -1;
};
// Tooltips
$.fn.dootip = function(prefs) {
    var tooltip = $(
            $('.dootip')[0]
            ||
            $('<div class="dootip"><div class="text"></div><img class="dootip_tip"/></div>')
                .hide()
                .appendTo(document.body)
                .find('img').andSelf()
                .css({
                    position: 'absolute',
                    zIndex: 1000
                }).end().end());            
            
    return this.each(function(){
        $(this)
            .mouseover(function(e) {
                var from = e.relatedTarget;
                    if (
                        // On affiche la tooltip lorsqu'il n'y en a pas déjà une d'affichée
                        // et que la souris ne vient pas déjà d'un enfant de l'élément
                        ! tooltip.is(':visible:not(:animated)')
                        && from
                        && from !== this && !$(from).descendantOf(this)
                        // Ou bien lorsque la souris est passée d'un élément à la tooltip, et est
                        // ressortie de la tooltip directement sur un autre élément
                        || !$(e.target).descendantOf(tooltip.data('hoveredElement'))
                    ) {
                        var li = $(this),
                            thumb = $.extend( li.position(), { width: li.width(), height: li.height() }),
                            tooltipOnLeft = !!prefs.forceLeft || (thumb.left - li.parent().position().left > li.parent().width() / 2);
                        tooltip
                            .stop(true, true)
                            .find('> .text')
                                .text(typeof prefs.text === 'string' ? prefs.text
                                        : typeof prefs.text === 'function' ? prefs.text.apply(this)
                                            : $(this).attr('title')
                                ).end()
                            .css('width', 'auto')
                            .fadeIn()
                            .data('hoveredElement', this)
                            .css(
                                'width', tooltip.width() > prefs.maxWidth ? prefs.maxWidth : 'auto'
                            )
                            .css({    // Positionnement (nécessite que la largeur soit fixée pour qu'on ait la hauteur)
                                left: (tooltipOnLeft ?
                                    thumb.left - tooltip.width()
                                    : thumb.left + thumb.width * 0.85),
                                top: thumb.top
                                    + thumb.height * 0.5
                                    - tooltip.outerHeight()
                                    + 15 // bordures
                            })
                            .find('img')
                                .attr('src', prefs.imagePath + '/' + (tooltipOnLeft ? prefs.tipRight : prefs.tipLeft))
                                .css({
                                    left: (tooltipOnLeft ? '100%' : -17),
                                    bottom: -1
                                });
                    }
                })
            .mouseout(function(e) {
                    var to = e.relatedTarget;
                    if (
                        to
                        && to !== this && !$(to).descendantOf(this)
                        && to !== tooltip[0] && !$(to).descendantOf(tooltip[0])
                    ) {
                        tooltip
                            .fadeOut('slow')
                            .data('hoveredElement', undefined);
                    }
                });
    });
};
// Affichage du flux Twitter
$.fn.displayTweets = function(username, limit) {
    var months = {'Jan':1, 'Feb':2, 'Mar':3, 'Apr':4, 'May':5, 'Jun':6, 'Jul':7, 'Aug':8, 'Sep':9, 'Oct':10, 'Nov':11, 'Dec':12};
    return this.each(function(){
        var div = $(this), lis ='';
        $.getJSON("http://twitter.com/statuses/user_timeline/" + username + ".json?count=" + limit + "&callback=?", function(data) {
            $.each(data, function(i, item) {
                var d = item.created_at.match(/\S+\s(\S+)\s(\d+)\s0?(\d+):(\d+):\d+\s\S+\s(\d+)/);
                lis += '<li' + (i ? '' : ' class="firstchild"') + '>'
                    +        '<p>'
                    +             item.text
                                    .replace(/\b((http|ftp):\/\/\S+)/, '<a href="$1">$1</a>')
                                    .replace(/(^|\b)@(\w+)/, '<a href="http://twitter.com/$2" title="Voir la page Twitter de $2">@$2</a>')
                    +         '</p>'
                    +        '<p class="pubDate">Publié le ' + d[2] + '/' + months[d[1]] + '/' + d[5] + ' à ' + d[3] + 'h' + d[4] + '</p>'
                    +    '</li>';
            });                
            div.append('<ul>' + lis + '</ul>');
        });
    });
};
// Menu LavaLamp
$.fn.lavaLamp = function(o) {
    o = $.extend({
            fx: "linear",
            speed: 500,
            click: function(){}
        },
        o || {}
    );

    return this.each(function() {
        var me = $(this),
            $back = $('<li class="back"><div class="left"></div></li>').appendTo(me),
            $li = $("li", this),
            curr = $("li.current_page_item", this)[0] || $($li[0]).addClass("current_page_item")[0];

        $li.not(".back").hover(
            function() {move(this);},
            function() {}
        );

        $(this).hover(
            function() {},
            function() {move(curr);}
        );

        $li.click(function(e) {
            setCurr(this);
            return o.click.apply(this, [e, this]);
        });

        setCurr(curr);

        function setCurr(el) {
            $back.css({ left: el.offsetLeft, width: el.offsetWidth });
            curr = el;
        };

        function move(el) {
            $back.each(function() {
                    $(this).dequeue();
                })
                .animate({
                    width: el.offsetWidth,
                    left: el.offsetLeft
                }, o.speed, o.fx);
        };

    });
};


$(function() {

    // HCARD
    $('.vcard')
         .find('.tel > .type')
            .removeClass('type')
            .text('mobile')
            .append('<span class="type" style="display:none">cell</span>')
            .end()
        .find('.email')
            .text('')
            .append('<a href="mailto:laurent@demontiers.com" title="Écrivez-moi">laurent@demontiers.com</a>');

    // Formulaire de recherche
    var searchForm = $('#searchform');
    var searchLabel = $('#searchform').find('label').hide();
    searchForm
        .find('#s')
            .val(searchLabel.text())
        .focus(function(){
            if ($(this).val() == searchLabel.text())
                $(this).val('');})
        .blur(function(){
            if ($(this).val() == '')
                $(this).val(searchLabel.text());});

    // Module abonnements
    var followDiv = $('#follow');
    var nlLabel = $('label[for=newsletter]', followDiv[0])
                    .hide();
    followDiv
        .find('#newsletter')
            .val(nlLabel.text())
    .focus(function(){
            if ($(this).val() == nlLabel.text())
                $(this).val('');})
    .blur(function(){
            if ($(this).val() == '')
                $(this).val(nlLabel.text());})
            .end()
        .find('.rssByCategory')
            .hide()
            .after(
                $('<div class="footer"><a class="more" href="?" title="">Plus d\'options</a></div>')
                    .find('a')
                    .click(function(){
                        $(this).parent().prev()
                                .slideToggle('normal', function(){
                                    var link = $(this).next().find('a');
                                    if (link.text() == "Plus d'options") {
                                        link.text("Masquer les options").addClass('active');
                                    } else {
                                        link.text("Plus d'options").removeClass('active');
                                    }
                                });
                        return false;
                    })
                    .end()
            );

    // Module combo Top-Articles/Commentaires
    // (à améliorer...)
    var topPosts = $('#favoritePosts'),
        both = topPosts.add($('#get-recent-comments')),
        module = $('<div id="favPostsAndRecentComs" class="module" />').insertBefore(topPosts),
        body = $('<div class="body"/>').appendTo(module);

    both.each(function(i){
        /* Déplacement et split des lis */
        var module = $(this),
            subdiv = $('<div class="' + module.attr('id') + '"/>').toggle(!i),
            uls = $([]),
            lis = module.find('li');

        lis.each(function(j){
            if (j % 7 == 0) {
                uls = uls.add($('<ul' + (!i && !j ? ' class="active"' : '') + '/>')
                                .appendTo(subdiv)
                                /*.toggle(!i && !j)*/);
            }
            uls.slice(-1).append(this);
        });
        subdiv.appendTo(body);

        /* Déplacement du header */
        module.find('.header')
                .addClass(module.attr('id'))
                .css('backgroundImage', (!i ? '' : 'none'))
                .click(function(uls) {
                    return function() {
                        var clickedHeader = $(this);
                        body.find('div:visible')
                            // Essayé fadeOut(), sans succès...
                            .fadeTo('fast', 0, function(){
                                $(this).hide().css('opacity', 1);
                                body.siblings('.header').css('backgroundImage', 'none');
                                uls.eq(0).addClass('active').parent().fadeIn(function(){
                                    $(this).css('marginLeft', 0);
                                    clickedHeader.css('backgroundImage', '');
                                });
                            })
							.find('ul:first')
								.removeClass('active');
                    };
                }(uls))
                .insertBefore(body);
    })
    .remove();
    
    function showUl(ul) {
        var uls = body.find('div:visible ul');
        var marginPercent = 106.2 * uls.index(ul);
        uls
            .removeClass('active');
        ul.parent()
            .animate({ marginLeft: -(ul.width())*(marginPercent/100) }, function(){
                $(this).css('marginLeft', '-' + marginPercent + '%');
            });
        ul.addClass('active');
    }

    var imgPath = '/wp-content/themes/demontiers/images/';
    var html = '<div class="pagination">'
        +    '<ul>'
        +        '<li class="prevnext prev">'
        +            '<a href="?">'
        +                '<img src="' + imgPath + 'fleche-blanche-gauche.png" alt="Page précédente" />'
        +            '</a>'
        +        '</li>';
    for (var i=1; i<=3; i++) {
        html += '<li><a href="?">' + i + '</a></li>';
    }
    $(html += '<li class="prevnext next">'
        +            '<a href="?">'
        +                '<img src="' + imgPath + 'fleche-blanche-droite.png" alt="Page suivante" />'
        +            '</a>'
        +        '</li>'
        +    '</ul>'
        + '</div>')
            .click(function(e){
                var target = $(e.target);
                while (target.is(':not(a)') && target[0].ownerDocument) {
                    target = target.parent();
                }
                if (target.is('a')) {
                    var displayedUl = $('ul.active', module).removeClass('active');
                    var x = [];
					if (target.is('.next a')) {
                        x = displayedUl.next();
                    } else if (target.is('.prev a')) {
                        x = displayedUl.prev();
                    } else {
                        x = displayedUl.parent().find('ul').eq(target.text() - 1);
                    }
                    if (x[0]) {
                        showUl(x);
                    } else {
                        displayedUl.addClass('active');
                    }
                }
                return false;
            })
        .wrap('<div class="footer"></div>')
        .parent()
        .appendTo(module);

    /*insérer module à la fin*/


    // Parallax du header
    var Parallax = function(container, params) {
        this.container = $(container);
        this.containerContent = this.container.children();
        var _this = this;
    
        // Insert layers
        $(params).each(function(i){    
            _this.containerContent
                .wrapAll('<div class="parallax" style="height:100%; background:url(' + this.bgImage + ') ' + this.bgStartPos + ' ' + (this.bgRepeat || 'no-repeat') + ';"></div>')
                .parent()
                    .data('scrollRatio', this.scrollRatio)
                    .data('bgStartPos', this.bgStartPos.match(/^\d+/)[0]);
        });
    
        // Handle mousemove
        this.container.mousemove(function(e) {
            var mousePos = e.pageX - _this.container.offset().left;
            // Move images    
            $('.parallax', _this.container).each(function(){
                var layer = $(this),
                    ratio = layer.data('scrollRatio'),
                    start = layer.data('bgStartPos');
                if (ratio != 0) {
                    layer.css('background-position',
                        Math.floor(start - ((start - mousePos) / ratio)) + 'px '
                            + this.style.backgroundPosition.split(' ')[1]);
                }
            });
        });
    };

    var parallaxImg = '/wp-content/themes/demontiers/images/parallax.png';
    new Parallax(
        $('#blogTitle'), [
            {bgImage:parallaxImg, bgStartPos:'600px 0', bgRepeat:null, scrollRatio:20},
            {bgImage:parallaxImg, bgStartPos:'0 -175px', bgRepeat:'repeat-x', scrollRatio:7},
            {bgImage:parallaxImg, bgStartPos:'80px -350px', bgRepeat:null, scrollRatio:0},
            {bgImage:parallaxImg, bgStartPos:'95% -525px', bgRepeat:null, scrollRatio:0}
        ]);


    /***********/
    /* GALERIE */
    /***********/
    var MissionGallery = {
        imgPath: '/wp-content/themes/demontiers/images',
        ul:  $('<ul>'),
        gallery:  $('.gallery'),
        imgs : $('.gallery .body li img'),
        currentImg: undefined,
        goToImg: function(x){
            if (MissionGallery.gallery.is(':not(.animating)') && x >= 0 && x < this.imgs.length) {
                this.imgs.eq(this.currentImg).removeClass('current');
                this.imgs.eq(x).addClass('current');
                MissionGallery.oldCurrentImg = MissionGallery.currentImg;
                MissionGallery.currentImg = x;
                MissionGallery.updateNavigation();
                if (this.imgs.eq(x).is('.loading')) {
                    $('.gallery .loader').show();
                } else {
                    $('.gallery .loader').hide();
                    MissionGallery.gallery
                        .addClass('animating')
                        .find('.body').height(this.imgs.eq(this.oldCurrentImg).height());
                    this.imgs.eq(this.oldCurrentImg)
                        .css('position', 'absolute')
                        .fadeOut('slow', function(){
                            $(this).css('position', '');
                        });
                    this.imgs.eq(x)
                        .css('position', 'absolute')
                        .fadeIn('slow', function(){
                            $(this).css('position', '');
                            MissionGallery.gallery
                                .removeClass('animating')
                                .find('.body').css('height', 'auto');                            
                        });
                }
            }
        },
        updateNavigation: function(){
            this.gallery
                .find('.prev').css('visibility', MissionGallery.currentImg <= 0 ? 'hidden' : 'visible').end()
                .find('.next').css('visibility', MissionGallery.currentImg >= this.imgs.length - 1 ? 'hidden' : 'visible').end()
                .find('.pagination li:not(.prevnext)').removeClass('current')
                .eq(this.currentImg).addClass('current');
        },
        init: function() {
            this.gallery
                .find('img').each(function(i){
                    $(new Image())
                        // Préchargement
                        .addClass('loading' + (i ? '' : ' current'))
                        .load(function(){
                            $(this).removeClass('loading');
                            if ($(this).is('.current')) {
                    $('.gallery .loader').hide();
                                MissionGallery.gallery.find('.body')
                                    .animate(
                                        { height: $(this).height() },
                                        function(){
                                            MissionGallery.currentImg = i;
                                            MissionGallery.updateNavigation();
                                            $(this).find('img.current').fadeIn('slow', function(){
                                                MissionGallery.gallery.find('.body').css('height', 'auto');
                                            });
                                        }
                                    )
                                    .find('.loader')
                                        .hide();
                            }
                        })
                        .attr('src', $(this).parent().attr('href'))
                        // Injection dans la ul
                        .wrap('<li/>')
                        .parent().appendTo(MissionGallery.ul);
                })
                .end()
                // Remplacement de la galerie Wordpress par la nôtre
                .children().remove().end()
                .append('<div class="header"><h2>Galerie</h2></div><div class="body"><span class="loader" style="position:absolute; left:50%; top:50%;"><img src="' + this.imgPath + '/loader.gif" alt="Chargement..." /></span><a class="prev" href="?" title="Image précédente"><img src="' + this.imgPath + '/galerie-prec.png" /></a><a class="next" href="?" title="Image suivante"><img src="/wp-content/themes/demontiers/images/galerie-suiv.png"></a></div>')
                .find('.prev, .next').click(function(){
                    if ($(this).is('.next'))
                        MissionGallery.goToImg(MissionGallery.currentImg + 1);
                    else
                        MissionGallery.goToImg(MissionGallery.currentImg - 1);
                    return false;
                })
                .filter('.prev').after(this.ul)
                .end().end()
                .each(this.getPagination);
                this.imgs = this.gallery.find('.body li img');
        },
        getPagination: function(){
            var html = '<div class="pagination"><ul><li class="prevnext prev"><a href="?"><img src="' + imgPath + '/fleche-noire-gauche.png" alt="Page précédente" /></a></li>';
            $.each($('li > img', MissionGallery.gallery[0]), function(i){
                html += '<li' + ( i ? '' : ' class="current"') + '><a href="?">' + (i+1) + '</a></li>';
            });
            $(html += '<li class="prevnext next"><a href="?"><img src="' + imgPath + '/fleche-noire-droite.png" alt="Page suivante" /></a></li></ul></div>')
                    .click(function(e){
                        var x, target = $(e.target);
                        while (target.is(':not(a)') && target[0].ownerDocument) {
                            target = target.parent();
                        }
                        if (target.is('a')) {
                            if (target.is('.next a')) {
                                x = MissionGallery.currentImg + 1;
                            } else if (target.is('.prev a')) {
                                x = MissionGallery.currentImg - 1;
                            } else {
                                x = target.text() - 1;
                            }
                            MissionGallery.goToImg(x);
                        }
                        return false;
                    })
                .wrap('<div class="footer"></div>')
                .parent()
                .appendTo(MissionGallery.gallery);
        }
    };
    
    MissionGallery.init();




    /********/
    /* HOME */
    /********/
    if ($(document.body).hasClass('home')) {
        
        DMT.setupCarousel();
    
        // Récupération et affichage des tweets
        var twitterPage = $('#tweets .footer a').attr('href');
        $('#tweets .body').displayTweets(
            twitterPage.slice(twitterPage.lastIndexOf('/') + 1),
            6
        );    
    }

    // Infobulles
    var tip = {
        imagePath: '/wp-content/themes/demontiers/images',
        tipLeft: 'tip-left.png', 
        tipRight: 'tip-right.png'
    };
    $('#featured li').dootip($.extend({
        text: function(){ return $(this).find('a').attr('title'); },
        maxWidth: 200
    }, tip));
    $('#pageFooter .QRCode img').dootip($.extend({
        text: 'Ma carte de visite au format QR Code',
        maxWidth: 120,
        forceLeft: true
    }, tip));

    /* Menu Lavalamp */
    $("#menu ul").lavaLamp({speed:'fast'});
    
    $('cite a').click(function(){
        window.open($(this).attr('href'));
        return false;
    });

    /* MODULE CATEGORIES DE LA SIDEBAR */
    $('#categories li').hover(
        function(){
            $(this).find('a')
                .animate({marginLeft:20})
                .parent()
                    .animate({backgroundColor: '#8E0030'}, 'fast');
        },
        function(){
            $(this).find('a')
                .queue('fx', [])
                .animate({marginLeft:0})
                .parent()
                    .queue('fx', [])
                    .animate({backgroundColor: '#000'}, 'fast');
        }
    );
    
    
    /* PAGES BLOG ET REALISATIONS */
    if (/^\/(blog|category|realisations)\//.test(window.location.pathname)) {
        
        var filterPane = $('#filterMissions, #filterPosts');

        // Slide du panneau de filtrage
        var close = $('<a class="close button" href="?" style="opacity:0; visibility:hidden;">Fermer le panneau</a>');    
        close
            .add(filterPane.find('h2'))
            .click(function(){
                $(this)
                    .siblings('.slideMask:not(:animated)')
                    // Pour le slideDown, jQuery doit déterminer la hauteur de l'élement (caché).
                    // Pour cela, elle affiche ce dernier en {position:absolute; visibility:hidden}
                    // Le problème est qu'en position absolue, l'élement a une largeur
                    // minimale et que donc certaines lignes "wrappent", rendant la hauteur
                    // incorrecte. Solution trouvée : définir explicitement la largeur.
                    .width($(this).parent().width())
                    .each(function(){
                        if ($(this).is(':hidden')) {
                            $(this).slideDown(function(){
                                $(this)
                                    .width('auto')
                                    .siblings('a.close').css('visibility', 'visible').animate({opacity:1});
                            });
                        } else {
                            $(this).siblings('a.close').animate({opacity:0}, function(){$(this).css('visibility', 'hidden');});
                            $(this).slideUp();
                        }
                    })
                    .filter('h2').toggleClass('active');
                return false;
            })
                       .siblings('form')
                .each(function(){
                    $(this)
                        .wrap('<div class="slideMask' + ($(this).is('.active') ? ' active' : '') + '" />')
                        .parent()
                            .before(close)
                            .after(close.clone(true));
                });
        
        // Insertion du bouton "Tout décocher"
        filterPane
            .find('div.submit')
            .prepend('<a title="Réinitialiser le formulaire" class="button reset" href="' + window.location.pathname + '">Tout décocher</a>');
        
        function displayPostCount(posts, checked) {
            selectionCount
                .text('')
                .addClass('loading')
                .text(size(getMatchingPosts(posts, checked)))
                .removeClass('loading');
        }
        
        function getMatchingPosts(posts, checked) {
            var r = {};
            
            $.each(posts, function(postId, v){
                var inCats = false, inTags = false, inDates = false;

                // Si le post est dans une des catégories cochées
                if (checked.cats.length === 0) {
                    inCats = true;
                } else if (this.category) {
                    for (var i=0, l=this.category.length; i<l; i++) {
                        if (in_array(this.category[i], checked.cats)) {
                            inCats = true;
                            break;
                        }
                    }
                }
                // Si le post a un des tags cochés
                if (checked.tags.length === 0) {
                    inTags = true;
                } else if (this.post_tag) {
                    for (var i=0, l=this.post_tag.length; i<l; i++) {
                        if (in_array(this.post_tag[i], checked.tags)) {
                            inTags = true;
                            break;
                        }
                    };
                }
                // Si le post est d'une date sélectionnnée
                if (checked.dates.length === 0 || in_array(this.date, checked.dates)) {
                    inDates = true;
                }
                
                if (inCats && inTags && inDates) {
                    r[postId] = this;
                }
                
            });
            return r;
        }
        
        function getSelectedValues() {
            var checked = {cats:[], tags:[], dates:[]};
            $('#byCat input:checked').each(function(){checked.cats.push($(this).val());});
            $('#byTag input:checked').each(function(){checked.tags.push($(this).val());});
            $('#byDate input:checked').each(function(){checked.dates.push(this.id.slice(0, 13));});
            return checked;
        }
        
        function disableEmptyTerms() {
            var checked = getSelectedValues();
            var currentMatches = getMatchingPosts(posts, checked);
            filterPane
                .find(':checkbox:not(:checked, .noSubmit)').each(function(){
                    fsetId = $(this).closest('fieldset').attr('id');
                    switch (fsetId) {
                        case 'byCat': checked.cats.push($(this).val()); break;
                        case 'byTag': checked.tags.push($(this).val()); break;
                        case 'byDate': checked.dates.push(this.id.slice(0, 13)); break;
                    }
                    var gpc = getMatchingPosts(posts, checked);
                    var gpc_length = size(gpc);
                    switch (fsetId) {
                        case 'byCat': checked.cats.splice(checked.cats.length - 1); break;
                        case 'byTag': checked.tags.splice(checked.tags.length - 1); break;
                        case 'byDate': checked.dates.splice(checked.dates.length - 1); break;
                    };
                    
                    if (gpc_length == 0) {
                        var enabled = false;
                    } else if (gpc_length != size(currentMatches)) {
                        var enabled = true;
                    } else {
                        // Y a-t-il dans currentMatches des posts qui matchent cette checkbox ?
                        for (var i=0, l=size(currentMatches); i<l; i++) {
                            switch (fsetId) {
                                case 'byCat': var gpc2 = getMatchingPosts(currentMatches, {cats:[$(this).val()], tags:[], dates:[]}); break;
                                case 'byTag': var gpc2 = getMatchingPosts(currentMatches, {cats:[], tags:[$(this).val()], dates:[]}); break;
                                case 'byDate': var gpc2 = getMatchingPosts(currentMatches, {cats:[], tags:[], dates:[this.id.slice(0, 13)]}); break;
                            }
                        }
                        var enabled = size(gpc2) > 0;
                    }
                    
                    // Application ou non de la désactivation 
                    $(this)
                        .attr('disabled', enabled ? '' : 'disabled')
                        .parent().toggleClass('disabled', !enabled);
                });
        }
        
                
        // Injection des checkboxes d'années
        filterPane.filter('#filterPosts').find('.slideMask li.year').each(function(){
            var year = $(this).children('label').text().slice(-4);
            $('<input type="checkbox" id="year' + year + '" class="noSubmit" />')
                .click(function(){
                    var enabledCheckboxes = $(this)
                                                .parent()
                                                .find(':checkbox:enabled:not(.noSubmit)')
                                                .attr('checked', $(this).is(':checked') ? 'checked' : '');
                    if (enabledCheckboxes.length) {
                        displayPostCount(posts, getSelectedValues());
                        disableEmptyTerms();
                    } else {
                        return false;
                    }                    
                }).prependTo(this);
        });
            
        var posts;
        

        
        filterPane.filter('#filterPosts')
            .each(function(){
                $.getJSON(
                    "/wp-content/themes/demontiers/jsonPostList.php?callback=?",
                    function(data){
                        posts = data;
                        displayPostCount(posts, getSelectedValues());
                        disableEmptyTerms();
                    }
                ); 
            })
            .find('div.submit')
                .prepend('<p id="selectionCount">Votre sélection va afficher <span class="loading">.</span> articles</p>')
                .end()
            .find(':checkbox:enabled:not(.noSubmit)')
                .click(function(){
                    displayPostCount(posts, getSelectedValues());
                    disableEmptyTerms();
                });
        
        var selectionCount = $('#selectionCount span');
    }
    
    
    
    
    
    
});