﻿dojo.require("dojo.fx");
dojo.require("cyim.ajax");
var timer = new Array();
(function() {
    if (typeof (this.ModuleNewsPublic) == "undefined") {
        this.ModuleNewsPublic = {};
    }

    if (typeof (this.ModuleNewsPublic.Slider) == "undefined") {
        this.ModuleNewsPublic.Slider = {};
    }

    // Classe pour un slider
    dojo.declare("ModuleNewsPublic.Slider.SliderBox", null, {
        constructor: function(id, height, newsHeight, newsNumber, displayedCount) {
            this.id = id;
            this.height = height;
            this.newsHeight = newsHeight;
            this.newsNumber = newsNumber;
            this.isRunning = false;
            this.canMoveUp = false;
            this.canMoveDown = false;
            this.displayedCount = displayedCount;
        }
    });

    // Tableau des sliders
    ModuleNewsPublic.SliderBoxArray = new Array();

    //  Permet d'activer le debug pour l'écriture dans la console
    ModuleNewsPublic.SliderDebug = true;
    if (ModuleNewsPublic.SliderDebug) console.clear;

    /*
    Fonction d'initialisation du slider. 
    On regarde la hauetur du conteneur d'actualité afin de calculer la hauteur
    unitaire de chaque actualité.
    Il faut que la hauteur totale du nombre d'actualité à afficher rentre dans la hauteur dispo.
    - SliderId : identifiant du slider .
    - displayedCount : Nombre de news affichee.
    */
    ModuleNewsPublic.Slider.InitSlider = function(sliderId, displayedCount) {
        if (ModuleNewsPublic.SliderDebug) {
            console.log("****** Initialisation du slider : " + sliderId + " *******");
        }

        // Nb d'actu dans le slider donne la hauteur de chaque actu par rapport à la hauteur du slider.
        var slider = dojo.byId(sliderId);

        // Hauteur disponible :  doit vraiment correspondre à celle où les actus vont s'afficher.
        // On utilise le contentBox qui permet de pallier au problèmes de bordures, et padding...
        var sliderHeight = dojo.contentBox(slider).h;

        if (ModuleNewsPublic.SliderDebug) {
            console.log("dojo.coords(slider).h : " + dojo.coords(slider).h);
            console.log("dojo.contentBox(slider).h : " + dojo.contentBox(slider).h);
            console.log("dojo.marginBox(slider).h : " + dojo.marginBox(slider).h);
        }

        // Par défaut, on prend le HTML généré comme source.
        // La plus haute hauteur d'une news va alors correspondre à la hauteur appliquées à toutes les news.
        // Cette fois-ci, on prend la méthode marginBox afin de prendre en compte les dimensions réelles des actualités
        var newsItemHeight = 0;
        dojo.query('#' + sliderId + ' .mNewsSliderItem').forEach(
            function(tag) {
                if (dojo.marginBox(tag).h > newsItemHeight) {
                    newsItemHeight = Math.round(dojo.marginBox(tag).h);
                    if (ModuleNewsPublic.SliderDebug) {
                        console.log("hauteur d'une actu recalculée : " + newsItemHeight);
                    }
                }
            }
        );


        if (ModuleNewsPublic.SliderDebug) {
            console.log("Hauteur d'une actu : " + newsItemHeight);
            console.log("Nombre d'actus à afficher spécifié : " + displayedCount);
            console.log("Hauteur nécessaire pour afficher les " + displayedCount + " souhaitées : " + newsItemHeight * displayedCount);
            console.log("Hauteur diponible : " + sliderHeight);
        }

        if (newsItemHeight * displayedCount < sliderHeight) {
            if (ModuleNewsPublic.SliderDebug) console.log("La hauteur dispo. " + sliderHeight + " est suffisante.");

            // Si on ne remplit pas toute la hauteur du slide, on augmente la hauteur des news
            if (newsItemHeight > 0 && displayedCount > 0){
                while (newsItemHeight * displayedCount <= sliderHeight) {
                    newsItemHeight += 1;
                }
            }
            // Diminution pour ne pas dépasser la hauteur dispo
            if (newsItemHeight * displayedCount > sliderHeight) {
                while (newsItemHeight * displayedCount > sliderHeight) {
                    newsItemHeight -= 1;
                }
            }

            displayedCount = Math.min(dojo.query('#' + sliderId + ' .mNewsSliderItem').length, displayedCount);

        } else {
            if (ModuleNewsPublic.SliderDebug) console.log("La hauteur dispo. " + sliderHeight + " n'est pas suffisante.");

            // Si hauteur des news affichées ne rentre pas dans le slide, on doit diminuer le nombre de news
            while (newsItemHeight * displayedCount > sliderHeight) {
                displayedCount -= 1;
                if (ModuleNewsPublic.SliderDebug) {
                    console.log("Hauteur nécessaire pour afficher les " + displayedCount + " souhaitées : " + newsItemHeight * displayedCount);
                }
            }
            // Si on ne remplit pas toute la hauteur du slide, on augmente la hauteur des news
            if (displayedCount > 0 && newsItemHeight > 0){
                while (newsItemHeight * displayedCount < sliderHeight) newsItemHeight += 1;
            }
        }

        if (ModuleNewsPublic.SliderDebug) {
            console.log("Hauteur recalculée pour remplir l'espace : " + newsItemHeight + " soit au total : " + newsItemHeight * displayedCount);
        }


        dojo.query('#' + sliderId + ' .mNewsSliderItem').forEach(
                function(tag) {
                    // Atribution de la hauteur calculée à toutes les news du slide.
                    dojo.marginBox(tag, { h: newsItemHeight });

                    // Par défaut les actu sont masquée pour ne pas voir l'effet de redimensionnement
                    // On les affiche, et on peut par exemple placer en css un arrière plan de chargement
                    dojo.style(tag, 'visibility', "visible");
                }
            );


        // Instanciation d'un nouveau slider dans le tableau des sliders
        ModuleNewsPublic.SliderBoxArray[sliderId] = new ModuleNewsPublic.Slider.SliderBox(sliderId, sliderHeight, newsItemHeight, null, displayedCount);
        ModuleNewsPublic.Slider.SetSliderLinksAvailability(sliderId);
    };
    /*
    Description :
    - Récupération de la Hauteur séparant le dernier élément du premier.
    Paramètres :
    - SliderId : identifiant du slider .
    - mode : page-> glisser un bloc de news entier.
    item-> glisser d'une news.
    - displayedCount : Nombre de news affichee.
    */
    ModuleNewsPublic.Slider.GetSliderMoveValueFirstElement = function(sliderId, mode, displayedCount) {
        // Récupération de la hauteur d'une actu pour le slider
        var newsItemHeight = ModuleNewsPublic.SliderBoxArray[sliderId].newsHeight;

        // Récupération de la hauteur du slider
        var sliderHeight = ModuleNewsPublic.SliderBoxArray[sliderId].height;

        switch (mode) {
            // La dernière news affichée est affichée en 1ère ou la 1ère en dernière selon le sens.                                                                                                                                                            
            case 'lastInFirst':
                slideMoveValue = sliderHeight - newsItemHeight;
                break;
            // Les news affichées sont toutes slidées pour laisser la place au suivante/précédentes.                                                                                                                                                            
            case 'page':
                slideMoveValue = sliderHeight;
                break;
            // On slide news par news.                                                                                                                                                             
            default:
                slideMoveValue = newsItemHeight
        }
        if (ModuleNewsPublic.SliderDebug) {
            console.log("Slide de " + slideMoveValue);
        }
        var nbElement = dojo.query('#' + sliderId + ' h3.mNewsTitle a').length;

        //On vient du dernier élément, il faut donc enlever le nombre d'actualité affiché au nombre d'élément total
        var retour = slideMoveValue * (nbElement - displayedCount);
        return retour;
    };
    /*
    Description :
    - Récupération de la hauteur du glissement.
    Paramètres :
    - SliderId : identifiant du slider .
    - mode : page-> glisser un bloc de news entier.
    item-> glisser d'une news.
    */
    ModuleNewsPublic.Slider.GetSliderMoveValue = function(sliderId, mode) {
        // Récupération de la hauteur d'une actu pour le slider
        var newsItemHeight = ModuleNewsPublic.SliderBoxArray[sliderId].newsHeight;

        // Récupération de la hauteur du slider
        var sliderHeight = ModuleNewsPublic.SliderBoxArray[sliderId].height;

        switch (mode) {
            // La dernière news affichée est affichée en 1ère ou la 1ère en dernière selon le sens.                                                                                                                                                           
            case 'lastInFirst':
                slideMoveValue = sliderHeight - newsItemHeight;
                break;
            // Les news affichées sont toutes slidées pour laisser la place au suivante/précédentes.                                                                                                                                                           
            case 'page':
                slideMoveValue = sliderHeight;
                break;
            // On slide news par news.                                                                                                                                                            
            default:
                slideMoveValue = newsItemHeight
        }
        if (ModuleNewsPublic.SliderDebug) {
            console.log("Slide de " + slideMoveValue);
        }
        return slideMoveValue;
    };

    /*
    Effet de slide vers le haut.
    - SliderId : identifiant du slider .
    - mode : page-> glisser un bloc de news entier (la 1ère se retrouve en dernière position).
    item-> glisser d'une news (la dernière disparaît).
    - duration : durée de la transition.
    - autoSlide : Defini si le changement de slide est automatique
    - autoSlideTimeOut : Defini le temps de défilement des slides en mode automatique
    - displayedCount : Nombre de news affichee.
    - newsType : Type de news a afficher
    */
    ModuleNewsPublic.Slider.MoveUp = function(sliderId, mode, duration, autoSlide, autoSlideTimeOut, displayedCount, newsType) {
        if (ModuleNewsPublic.SliderBoxArray[sliderId].canMoveUp) {
            ModuleNewsPublic.Slider.Move(sliderId, ModuleNewsPublic.Slider.GetSliderMoveValue(sliderId, mode), duration, autoSlide, autoSlideTimeOut, displayedCount, newsType)
        }
    };

    /*
    Effet de slide vers le bas.
    - SliderId : identifiant du slider .
    - mode : page-> glisser un bloc de news entier (la 1ère se retrouve en dernière position).
    item-> glisser d'une news (la dernière disparaît).
    - duration : durée de la transition.
    - autoSlide : Defini si le changement de slide est automatique
    - autoSlideTimeOut : Defini le temps de défilement des slides en mode automatique
    - displayedCount : Nombre de news affichee.
    - newsType : Type de news a afficher
    */
    ModuleNewsPublic.Slider.MoveDown = function(sliderId, mode, duration, autoSlide, autoSlideTimeOut, displayedCount, newsType, click) {
        var booContent = false;
        if (newsType == "CONTENT") {
            booContent = true;
        }
        if (ModuleNewsPublic.SliderBoxArray[sliderId].canMoveDown) {
            if (autoSlide && booContent) {
                //On change l'element affiché
                if (!click) {
                    ModuleNewsPublic.Slider.ChangeSelectedSlide(sliderId)
                }
            }
            //On Descend le Slider
            ModuleNewsPublic.Slider.Move(sliderId, -ModuleNewsPublic.Slider.GetSliderMoveValue(sliderId, mode), duration, autoSlide, autoSlideTimeOut, displayedCount, newsType);
        }
        else {
            if (autoSlide) {
                if (booContent) {
                    if (!(ModuleNewsPublic.Slider.ChangeSelectedSlide(sliderId))) {
                        //Si on est pas sur le dernier élément 
                        //On change l'element affiché Sans descendre le slider
                        //On boucle pour arriver au dernier element
                        ModuleNewsPublic.Slider.LoadAutoSlideMove(sliderId, mode, duration, autoSlide, autoSlideTimeOut, displayedCount, newsType);
                    } else {
                        //Si on est sur le dernier élément
                        //On change l'element affiché pour remonter au premier élément
                        ModuleNewsPublic.Slider.SetSelectedSlide(sliderId, 1);
                        //On Remonte le slider pour afficher les premiers éléments
                        ModuleNewsPublic.Slider.Move(sliderId, ModuleNewsPublic.Slider.GetSliderMoveValueFirstElement(sliderId, mode, displayedCount), duration, autoSlide, autoSlideTimeOut, displayedCount, newsType);
                    }
                }
                else {
                    ModuleNewsPublic.Slider.Move(sliderId, ModuleNewsPublic.Slider.GetSliderMoveValueFirstElement(sliderId, mode, displayedCount), duration, autoSlide, autoSlideTimeOut, displayedCount, newsType);
                }
            }
        }
    };
    /*
    Description : 
    - Selectionne un élément par son id 
    
    Paramètres :  
    - sliderId : Id du slider
    - id : Element à selectionner
    */
    ModuleNewsPublic.Slider.SetSelectedSlide = function(sliderId, id) {
        var i = 0;

        dojo.query('#' + sliderId + ' h3.mNewsTitle a').forEach(

                            function(tag) {
                                i = i + 1;

                                if (i == id) {
                                    dojo.addClass(tag, "mActiveNewsLink");
                                    ModuleNewsPublic.Slider.DisplayNewsSummaryByTag(tag, sliderId);
                                }
                            });
        i = 0;
        dojo.query('#' + sliderId + ' li.mNewsSliderItem').forEach(
                            function(tag) {
                                i = i + 1;
                                if (i == id) {
                                    dojo.addClass(tag, "mNewsSliderActiveItem");
                                }
                            });
        i = 0;
        dojo.query('#' + sliderId + ' div.mNewsItem').forEach(
                            function(tag) {
                                i = i + 1;
                                if (i == id) {
                                    dojo.addClass(tag, "mNewsActiveItem");
                                }
                            });
    };
    /*
    Description : 
    - Déplace l'element selectionné d'une case vers le bas
    Retourne : 
    - True lorsque l'élément sélectionné est le dernier de la liste
    - False dans les autres cas
    Paramètres :  
    - sliderId : Id du slider
    */
    ModuleNewsPublic.Slider.ChangeSelectedSlide = function(sliderId) {
        var booLastA = false;
        var booLastLi = false;
        var booLastDiv = false;
        var lastElement = true;
        var i = 0;
        dojo.query('#' + sliderId + ' h3.mNewsTitle a').forEach(

                            function(tag) {

                                i = i + 1;

                                if (dojo.hasClass(tag, "mActiveNewsLink")) {
                                    dojo.removeClass(tag, "mActiveNewsLink"); booLastA = true;
                                    if (dojo.query('#' + sliderId + ' h3.mNewsTitle a').length == i) { lastElement = true; }
                                    else { lastElement = false; }
                                }
                                else {
                                    if (booLastA) {
                                        dojo.addClass(tag, "mActiveNewsLink");
                                        ModuleNewsPublic.Slider.DisplayNewsSummaryByTag(tag, sliderId);
                                        booLastA = false;
                                    }
                                }
                            }
                        );

        dojo.query('#' + sliderId + ' li.mNewsSliderItem').forEach(
                            function(tag) {
                                if (dojo.hasClass(tag, "mNewsSliderActiveItem")) { dojo.removeClass(tag, "mNewsSliderActiveItem"); booLastLi = true; }
                                else { if (booLastLi) { dojo.addClass(tag, "mNewsSliderActiveItem"); booLastLi = false; } }
                            }
                        );
        dojo.query('#' + sliderId + ' div.mNewsItem').forEach(
                            function(tag) {
                                if (dojo.hasClass(tag, "mNewsActiveItem")) { dojo.removeClass(tag, "mNewsActiveItem"); booLastDiv = true; }
                                else { if (booLastDiv) { dojo.addClass(tag, "mNewsActiveItem"); booLastDiv = false; } }
                            }
                        );
        return lastElement;
    }
    /*
    Description : 
    - Affiche le contenu d'une actualité 
    Paramètres : 
    - tag : Element du DOM contenant les informations (a) 
    - sliderId : Id du slider
    */
    ModuleNewsPublic.Slider.DisplayNewsSummaryByTag = function(tag, sliderId) {
        var chaine = tag.href;
        chaine = chaine.replace("javascript:ModuleNewsPublic.Slider.DisplayNewsSummary('" + sliderId + "',", "");
        chaine = chaine.replace("')", "");

        while (chaine.indexOf("'") > -1) {
            chaine = chaine.replace("'", "");
        }

        var pos = chaine.indexOf(",");
        var sectionPath = chaine.substring(0, pos);
        var newsUri = chaine.substring(pos + 1, (chaine.length));

        while (sectionPath.indexOf("%2f") > -1) {
            sectionPath = sectionPath.replace("%2f", "/");
        }

        while (newsUri.indexOf("%2f") > -1) {
            newsUri = newsUri.replace("%2f", "/");
        }

        ModuleNewsPublic.Slider.DisplayNewsSummary(sliderId, sectionPath, newsUri);
    }
    /*
    Exécution d'un slide
    - SliderId : identifiant du slider .
    - value : valeur en pixel de la distance de déplacement.
    - duration : durée de la transition.
    - autoSlide : Defini si le changement de slide est automatique
    - autoSlideTimeOut : Defini le temps de défilement des slides en mode automatique
    - displayedCount : Nombre de news affichee.
    - newsType : Type de news a afficher
    */
    ModuleNewsPublic.Slider.Move = function(sliderId, value, duration, autoSlide, autoSlideTimeOut, displayedCount, newsType) {
        // Si slide déjà en cours, on sort
        if (ModuleNewsPublic.SliderBoxArray[sliderId].isRunning) { return }

        var sliderContentId = sliderId + '_NewsList';
        console.log(dojo.contentBox(sliderId).t);
        console.log(dojo.marginBox(sliderId).t);
        console.log("top : " + (dojo.marginBox(sliderContentId).t + value).toString());
        var slideArgs = {
            node: sliderContentId,
            duration: duration,
            top: (dojo.marginBox(sliderContentId).t + value).toString(),
            left: (dojo.marginBox(sliderContentId).l).toString(),
            unit: "px",
            beforeBegin: function() {
                ModuleNewsPublic.SliderBoxArray[sliderId].isRunning = true;
            },
            onEnd: function() {
                ModuleNewsPublic.SliderBoxArray[sliderId].isRunning = false;
                ModuleNewsPublic.Slider.SetSliderLinksAvailability(sliderId);
                // Si autoSlide, on slide vers le bas tant qu'on peut.
                if (autoSlide) {
                    ModuleNewsPublic.Slider.LoadAutoSlideMove(sliderId, value, duration, autoSlide, autoSlideTimeOut, displayedCount, newsType);
                }
            }
        };
        dojo.fx.slideTo(slideArgs).play();
    };


    /*
    Mise à jour des disponibilités des liens de slide haut/bas
    - SliderId : identifiant du slider .
    */
    ModuleNewsPublic.Slider.SetSliderLinksAvailability = function(sliderId) {
        var sliderContentId = sliderId + '_NewsList';

        // Activation / désactivation du lien de slide vers le haut
        ModuleNewsPublic.SliderBoxArray[sliderId].canMoveUp = true;
        if (dojo.coords(sliderContentId).t == 0) {
            ModuleNewsPublic.SliderBoxArray[sliderId].canMoveUp = false;
        };
        dojo.query('#' + sliderId + '_upLink a').forEach(
            function(tag) {
                if (ModuleNewsPublic.SliderBoxArray[sliderId].canMoveUp) {
                    dojo.addClass(tag, "mActiveSlideLnk");
                    dojo.removeClass(tag, "mUnActiveSlideLnk");
                } else {
                    dojo.addClass(tag, "mUnActiveSlideLnk");
                    dojo.removeClass(tag, "mActiveSlideLnk");
                }
            }
        );

        // Activation / désactivation du lien de slide vers le bas
        var virtualBot = dojo.coords(sliderId).h - dojo.coords(sliderContentId).t;
        ModuleNewsPublic.SliderBoxArray[sliderId].canMoveDown = true;
        if (virtualBot >= dojo.coords(sliderContentId).h) {
            ModuleNewsPublic.SliderBoxArray[sliderId].canMoveDown = false;
        }
        dojo.query('#' + sliderId + '_downLink a').forEach(
            function(tag) {
                if (ModuleNewsPublic.SliderBoxArray[sliderId].canMoveDown) {
                    dojo.addClass(tag, "mActiveSlideLnk");
                    dojo.removeClass(tag, "mUnActiveSlideLnk");
                } else {
                    dojo.addClass(tag, "mUnActiveSlideLnk");
                    dojo.removeClass(tag, "mActiveSlideLnk");
                }
            }
        );
    };
    /*
    Description : 
    - Démarre le Slider en mode automatique
    Paramètres :
    - SliderId : identifiant du slider .
    - mode : page-> glisser un bloc de news entier (la 1ère se retrouve en dernière position).
    item-> glisser d'une news (la dernière disparaît).
    - duration : durée de la transition.
    - autoSlide : Defini si le changement de slide est automatique
    - autoSlideTimeOut : Defini le temps de défilement des slides en mode automatique
    - displayedCount : Nombre de news affichee.
    - newsType : Type de news a afficher
    */
    ModuleNewsPublic.Slider.LoadAutoSlideMove = function(sliderId, mode, duration, autoSlide, autoSlideTimeOut, displayedCount, newsType) {
        //Gestion du timer : Suppression du timer actuel s'il existe et lancement du nouveau timer
        ModuleNewsPublic.Slider.StopAutoSlideMove()
        d = new Date();
        timer[d.toLocaleDateString() + d.toLocaleTimeString()] = setTimeout(function() { ModuleNewsPublic.Slider.MoveDown(sliderId, mode, duration, autoSlide, autoSlideTimeOut, ModuleNewsPublic.SliderBoxArray[sliderId].displayedCount, newsType) }, autoSlideTimeOut);
    }
    /*
    Description : 
    - Stoppe le Slider en mode automatique
    */
    ModuleNewsPublic.Slider.StopAutoSlideMove = function() {
        for (key in timer) {
            clearTimeout(timer[key]);
        }
    }
    /*
    Récupération de l'accroche d'une news pour l'afficher dans le slider.
    
    - newsType : Type de news a afficher
    */
    ModuleNewsPublic.Slider.DisplayNewsSummary = function(sliderId, sectionPath, newsUri) {
        var form = document.createElement('form');
        form.method = 'POST';
        form.action = sectionPath + "GetNewsSummary.phtml?newsUri=" + newsUri;
        form.id = 'newsSummaryForm';
        document.getElementsByTagName('head')[0].appendChild(form);

        //lance la requête asynchrone
        var d = cyim.ajax.xhrPost({ form: form, url: form.action, handleAs: "text" });
        d.addCallback(dojo.hitch(cyim.ajax, "getDataBack", dojo.byId(sliderId + "_content"),
             function() {
                 // Désactivation du lien précedemment sélectionné
                 dojo.query('#' + sliderId + ' a.mActiveNewsLink, #' + sliderId + ' li.mNewsSliderActiveItem, #' + sliderId + ' div.mNewsActiveItem').forEach(
                    function(tag) {
                        dojo.removeClass(tag, "mActiveNewsLink");
                        dojo.removeClass(tag, "mNewsSliderActiveItem");
                        dojo.removeClass(tag, "mNewsActiveItem");
                    }
                );

                 // Activation du lien vers la news.
                 newsLinkId = sliderId + '-' + newsUri.replace(/\//gi, "-");
                 dojo.byId(newsLinkId).className = "mActiveNewsLink";
                 var parentDiv = dojo.byId(newsLinkId).parentNode.parentNode;
                 dojo.addClass(parentDiv, "mNewsActiveItem");
                 var parentLi = parentDiv.parentNode;
                 dojo.addClass(parentLi, "mNewsSliderActiveItem");

             }
        ));
        d.addErrback(function() { "Erreur de chargement..." });
    }
})();
