
// ------------------------------------------------------------------------
// Global Variables
// ------------------------------------------------------------------------
var rondHeight = 340; // Hauteur de l'ovale
var itemHeight = 36; // Hauteur de chaque item de la liste primaire
var space = 18; // Marge entre l'ovale et l'item
var timeout = null; // Variable pour garder en mémoire le timeout
var timeoutDelay = 1000; // Délai de fermeture d'un sous-menu en millisecond
var menuToClose = null; // Variable pour garder en mémoire le menu à fermer
var arrowUrl = "/medias/communs/brioArrow.gif"; // Url de la flèche à afficher sur un hover
var arrowTop = -8; // Position y de la flèche à afficher sur un hover en pixel
var arrowLeft = -50; // Position x de la flèche à afficher sur un hover en pixel
var rondId = "rondRenderer"; // Id de la div rondRenderer
var primaryListClass = "primaryMenu"; // Classe css de la liste principal
var secondaryListClass = "secondaryMenu"; // Classe css des sous-listes
var hoverClass = "hover"; // Classe css à appliquer sur un liste qui affiche une sous-liste

// ------------------------------------------------------------------------
// Coordonnées de l'ovale
// ------------------------------------------------------------------------

var c = 0;
var rondCoords = new Array();
rondCoords[c++] = "100;0";
rondCoords[c++] = "115;12";
rondCoords[c++] = "121;22";
rondCoords[c++] = "132;32";
rondCoords[c++] = "141;42";
rondCoords[c++] = "149;52";
rondCoords[c++] = "155;62";
rondCoords[c++] = "159;72";
rondCoords[c++] = "163;82";
rondCoords[c++] = "167;92";
rondCoords[c++] = "168;102";
rondCoords[c++] = "165;112";
rondCoords[c++] = "165;122";
rondCoords[c++] = "165;132";
rondCoords[c++] = "164;142";
rondCoords[c++] = "163;152";
rondCoords[c++] = "161;162";
rondCoords[c++] = "159;172";
rondCoords[c++] = "150;182"; 
rondCoords[c++] = "152;192";
rondCoords[c++] = "148;202";
rondCoords[c++] = "143;212";
rondCoords[c++] = "127;222"; 
rondCoords[c++] = "131;232";
rondCoords[c++] = "125;242";
rondCoords[c++] = "97;252"; 
rondCoords[c++] = "109;262";
rondCoords[c++] = "99;272";
rondCoords[c++] = "89;282";
rondCoords[c++] = "50;292";
rondCoords[c++] = "64;302";
rondCoords[c++] = "50;312";
rondCoords[c++] = "33;322";
rondCoords[c++] = "0;332";

// ------------------------------------------------------------------------
// Load de la page
// ------------------------------------------------------------------------

$(document).ready(function() {
    // Positionner la hauteur de la liste selon le nombre de ces éléments
    var topMenu = getListTop();
    $("#" + rondId + " ." + primaryListClass).css("padding-top", getListTop());
    debug("Hauteur de la liste défini");

    // Pour chaque élément de la liste, on calcul la position horizontal selon la position
    // vertical de l'élément
    var i = 0;
    $("#" + rondId + " ." + primaryListClass + " > li").each(function() {
        var top = (itemHeight * i++) + topMenu;
        var left = getLeftCoord(getNearestCoordIndex(top)) + space;
        $(this).css("margin-left", left);
    });
    debug("Position horizontal des éléments défini");

    // Attacher un eventhandler lorsque l'usager passe sa souris sur le TEXTE d'un élément
    $("#" + rondId + " ." + primaryListClass + " > li span").hover(function() {
        ElementText_MouseOver($(this));
    });
    debug("EventHandler ElementText_MouseOver défini");

    // Attacher un eventhandler lorsque l'usager passe sa souris sur l'élément
    $("#" + rondId + " ." + primaryListClass + " > li").hover(function() {
        Element_MouseOver($(this));
    }, function() {
        Element_MouseOut($(this));
    });
    debug("EventHandler Element_MouseOver, Element_MouseOut défini");

    // Télécharger la flèche tout de suite 
    // Éviter le clignotement lors de la première apparition de celle-ci.
    preloadImage(arrowUrl);
    debug("Preload flèche terminé");
});

// ------------------------------------------------------------------------
// Event Handler
// ------------------------------------------------------------------------

// Fonction appellé lorsque la souris est sur un élément
function Element_MouseOver(sender) {
    // Si l'élément qui est sous la souris est déjà ouvert, on annule le timeout et menuToClose
    // pour éviter que l'élément se ferme lorsque la souris est sur l'élément
    if (sender.hasClass(hoverClass)) {
        menuToClose = null;
        if (timeout) { clearTimeout(timeout); }
    }
}

// Fonction appellé lorsque la souris sort d'un élément
function Element_MouseOut(sender) {
    // Si l'élément était ouvert (avec sous-élément), on le ferme
    // On utilise un timeout pour éviter que l'élément se ferme trop rapidement
    if (sender.hasClass(hoverClass)) {
        menuToClose = sender;
        timeout = setTimeout("Timeout_Finished();", timeoutDelay);
    }
}

// Fonction appellé lorsque la souris est sur le texte d'un élément
function ElementText_MouseOver(sender) {
    // Vérifier si cet élément contient un sous-élément
    if (sender.parent().find("ul").hasClass(secondaryListClass)) {
        // S'il y a déjà un élément ouvert avec un sous-élément, on commence par le fermer.
        // On n'utilise pas de timeout car on veut que l'élément se ferme immédiatement
        hideSubElement();
        if (timeout) { clearTimeout(timeout); }
        
        // Afficher le sous-élément
        showSubElement(sender.parent());
    }    
}

// Fonction appellé lorsque le timeout arrive à la fin de son décompte
function Timeout_Finished() {
    hideSubElement();
}

// ------------------------------------------------------------------------
// Fonctions
// ------------------------------------------------------------------------

// Fonction qui s'occupe de faire disparaître un sous-élément
function hideSubElement() {
    if (menuToClose) {
        // Faire disparaître le sous-élément
        menuToClose.removeClass(hoverClass);
        
        // Faire disparaître la flèche
        menuToClose.find("img").remove();

        menuToClose = null;
    }
}

// Fonction qui s'occupe d'afficher un sous-élément
function showSubElement(element) {
    // Afficher le sous-élément
    element.addClass(hoverClass);
    
    // Afficher la flèche
    element.prepend("<img src='" + arrowUrl + "' style='position:absolute;top:" + arrowTop + "px;left:" + arrowLeft + "px;' />");
}

// Fonction qui trouve la coordonnée qui concorde le plus à la coordonnée y reçu en paramètre
// Cette fonction utilise un algorithme de recherche binaire afin d'améliorer les performances de la recherche
function getNearestCoordIndex(top) {
	var coordIndex = -1;
	var lowerIndex = 0;
	var higherIndex = rondCoords.length-1;

	while (coordIndex == -1) {
		if (higherIndex - lowerIndex == 1) {
			var diff1 = getTopCoord(higherIndex) - top;
			var diff2 = top - getTopCoord(lowerIndex);
			if (diff1 < diff2) {
				coordIndex = higherIndex;
			} else {
				coordIndex = lowerIndex;
			}
		} else {
			var currentIndex = parseInt(lowerIndex+((higherIndex-lowerIndex)/2));
			var currentTop = getTopCoord(currentIndex);
			
			if (currentTop == top) {
				coordIndex = currentIndex;
			} else if (currentTop > top) {
				higherIndex = currentIndex;
			} else {
				lowerIndex = currentIndex;
			}
		}
	}
	
	return coordIndex;
}

// Fonction qui retourne la hauteur de la liste pour centrer celle-ci selon le nombre d'élément
// qu'elle contient
function getListTop() {
    var nbElement = countElement();
    var top = (rondHeight / 2) - (((nbElement * itemHeight) - 28) / 2);
    return top;
}

// Fonction qui retourne le nombre d'élément contenu dans la liste primaire
function countElement() {
    var nbElement = $("#" + rondId + " ." + primaryListClass + " > li").length;
    return nbElement;
}

// Fonction qui retourne la position y d'une coordonnée
function getTopCoord(index) {
	var topCoord = parseInt(rondCoords[index].split(";")[1]);;
	return topCoord;
}

// Fonction qui retourne la position x d'une coordonée
function getLeftCoord(index) {
	var leftCoord = parseInt(rondCoords[index].split(";")[0]);
	return leftCoord;
}