/*
    capping.js : Gère le capping des publicités.

    Lors du chargement d'une pub, le navigateur mémorise des infos de capping,
    de manière à pouvoir les transmettre au serveur lors des sélections de pubs
    suivantes :
    * l'autohandler charge ce capping.js, qui contient une grosse fonction enregistre_capping()
    * chaque pub devant être cappée doit appeler cette fonction, avec des paramètres (à voir dans une pub normale cappée, et reproduire dans les pub.js ou walpaper.js hacked)
    * cet appel JS dans la navigateur mémorise le nombre d'affichage de chaque pub cappée
    * à chaque demande de pub ultérieure, le navigateur envoie les infos de capping à e-pubs/pub.phtml
    * ce dernier utilise les infos de capping pour exclure les pubs arrivées au maxi

    Attention : IE interprête le script avec le même encodage que la page, soit UTF8,
    mais comme le fichier est écrit en Latin1, tous les accents sont cassés, et
    certains bouffent les \n, rendant la syntaxe du script erronée. Quand la page n'a
    pas d'encodage, elle est considérée comme Latin1, et le même script passe bien...
*/

// enregistre_capping : enregistre un nouvel affichage d'une pub, et ajuste les compteurs de capping (cookie)
//  cle_pub : clé de la pb affichée (pas d'accent en fin de ligne, IE est trop c.n)
//  nombre_max : nombre d'affichages autorisés (capping_partiel)
//  periode_max : période sur laquelle le nombre s'applique (en jours) (capping_total)
// (les noms entre parenthèse correspondent à ce qui est stocké dans la base de données, qui ne contient que ces données, et pas de période)
// Le processus est le suivant :
//  - enregistre le nouvel affichage de la cle_pub, avec sa date, dans un cookie
//  - supprime les anciens affichages (plus vieux que la période et plus nombreux que le nombre d'affichages)
//  - le cookie sera envoyé au serveur à la prochaine demande de pub
//  - le serveur tiendra compte des cle_pub à exclure, en fonction du nombre d'affichage, de la période et des dates
// C'est le serveur qui doit mesurer les exclusions, au moment du prochain affichage, car il peut se trouver loin dans le futur.
// On peut se retrouver, lors de l'exécution de enregistre_capping(), à arriver au nombre maxi, mais le prochain affichage ne se fera
// peut-être qu'après expiration de la période, et donc la pub pourra tout de même être affichée.

function enregistre_capping(cle_pub, nombre_max, periode_max) {
    //alert('enregistre_capping('+cle_pub+','+nombre_max+','+periode_max+')');
    
    // Détermine la date actuelle de l'affichage, à mémoriser
    var date_courante = Math.round((new Date()).getTime() / 1000); // getTime() renvoie des millièmes de seconde, mais on veut des secondes écoulées depuis le 1/1/1970...

    // Récupère la valeur de l'ancien cookie...
    // Les cookies ont la forme suivante, encodé en JSON (http://json.org) :
    //  {cle:[nombre_max,periode_max,[time,time...],cle:[...]}
    var cookie = document.cookie.match(/(?:^|; )CAP=([^;]*)/);
    var capping;
    try {
        // Dans le cas où le cookie n'est pas évaluable, il faut continuer comme si de rien n'était...
        //document.write('Evaluation de '+decodeURIComponent(cookie[1])+'<br>');
        capping = cookie ? eval("(" + decodeURIComponent(cookie[1]) + ")") : undefined;
    } finally {
        // Après évaluation, si on n'a pas un Objet (hash contenant une clé par publicité cappée), on en initialise un vide
        // IE ne laisse pas un objet après le eval, comme Moz, donc il faut le recréer pour que le test un peu après passe correctement
        if (typeof(capping) != 'object') {
            capping = [];
        }
    }

    // On ajoute l'affichage en cours de la cle_pub demandée (pas d'accent en fin de ligne, IE est trop c.n)
    if (!(cle_pub in capping)) {
        capping[cle_pub] = []; // ...dans le cas où elle n'existe pas encore, on créé le tableau la décrivant
    }
    capping[cle_pub][0] = nombre_max; // ...puis on ajoute les variables de la pub
    capping[cle_pub][1] = periode_max;
    if (2 in capping[cle_pub]) {
        capping[cle_pub][2].push(date_courante); // S'il existe déjà une date, on l'ajoute à la fin...
    } else {
        capping[cle_pub][2] = [date_courante]; // ...mais s'il n'y en a pas encore, on crée le tableau du les contiendra toutes.
    }

    // On parcoure toutes les clés stockées, et on ajuste leurs valeurs :
    //  - ne conserver que nombre_max dates 
    //  - supprimer les dates antérieures à periode_max
    //  - s'il ne reste aucune date, supprimer toute la clé (ne pas laisser d'accent en fin de ligne, IE n'aime pas ça, quel c.n)
    for (var cle in capping) {
        //document.write('Capping de cle='+cle+'<br>');
        if (capping[cle][2].length > capping[cle][0]) {
            capping[cle][2].splice(0, capping[cle][2].length - capping[cle][0]); // supprime les premier éléments, pour n'en garder que nombre_max
        }
        while (capping[cle][2][0] < date_courante - periode_max*86400) {
            capping[cle][2].shift(); // supprime le premier élément, trop ancien
        }
        if (capping[cle][2].length == 0) {
            delete capping[cle]; // supprime toute la clé, s'il ne reste plus aucune date...
        }
    }

    // On reconstitue le cookie à partir de l'objet capping
    var cles = [];
    for (var cle in capping) {
        // Le format est adapté à ce que le package Perl JSON (libjson-perl) est capable de décoder : notamment, les identifiants sont placés entre " et non entre '
        // cf. http://json.org/
        cles.push('"' + cle + '":[' + capping[cle][0] + ',' + capping[cle][1] + ',[' + capping[cle][2] + ']]');
    }
    cookie = '{' + cles.join(',') + '}';
    
    // Stocke le cookie, qui sera envoyé la prochaine fois au serveur.
    // Il expirera dans très longtemps, de manière à ne pas perdre les infos de capping...
    document.cookie = 'CAP=' + encodeURIComponent(cookie) + '; expires=Tue, 19 Jan 2038 04:14:07 GMT; path=/';

    cookie += '';
    return cookie;
}
