var pathSeparatore = "/";

/**
 * Reagisce agli eventi di onclick sugli elementi del menu
 */
function _menu_onclick(e)
{
    // Codice cross browser - recupera evento
    if (!e) e = window.event;

    // Codice cross browser - recupera elemento
    var tg = (e.target) ? e.target : e.srcElement;

    var oMenuRoot = CallBack_Menu_OnClick();
    var oMenu = oMenuRoot.getMenuDaPath( tg.id, 0 );

    var bfr = "";
    for ( var prp in oMenu )
        bfr += prp +"\n"

    oMenu.onclick();
}


/**
    * Reagisce agli eventi di mouseover sugli elementi del menu
    */
function _menu_mouseover(e)
{
    // Codice cross browser - recupera evento
    if (!e) var e = window.event;
    // Codice cross browser - recupera elemento
    var tg = (e.target) ? e.target : e.srcElement;

    var oMenuRoot = CallBack_Menu_OnClick();
    var oMenu = oMenuRoot.getMenuDaPath( tg.id, 0 );

    // Rollover immagine
    if ( (oMenu.haImmagine()) && (oMenu.immagine.isRollover()) )
    {
        // Se c'č un'immagine di rollover, la mostra
        if ( oMenu.immagine.immagineAlternativa != "" )
            oMenu.htmlImg.src = oMenu.immagine.immagineAlternativa;

        // Se č presente solo l'immagine di rollover, deve scoprirla
        if ( oMenu.immagine == "" )
            oMenu.htmlImg.style.visibility = "visible";
    }

    // abilita rollover del colore del testo
    // oMenu.htmlTag.style.color = eval("oMenu.configurazione.testoRolloverLivello" + oMenu.livello)
}

/**
    * Reagisce agli eventi di mouseout sugli elementi del menu
    */
function _menu_mouseout(e)
{
    // Codice cross browser - recupera evento
    if (!e) var e = window.event;
    // Codice cross browser - recupera elemento
    var tg = (e.target) ? e.target : e.srcElement;

    var oMenuRoot = CallBack_Menu_OnClick();
    var oMenu = oMenuRoot.getMenuDaPath( tg.id, 0 );

    // Se č presente un'immagine di rollover, deve tornare all'immagine normale
    if ( (oMenu.haImmagine()) && (oMenu.immagine.isRollover()) )
    {
        oMenu.htmlImg.src = oMenu.immagine.immagine;
        // Se č presente solo l'immagine di rollover, deve nascondere l'immagine normale
        if ( oMenu.immagine.immagine == "" )
            oMenu.htmlImg.style.visibility = "hidden";
    }
    // disabilita rollover del colore del testo
    // oMenu.htmlTag.style.color = eval("oMenu.configurazione.testoLivello" + oMenu.livello)
}

/**
    * Costruttore della classe Menu
    *
    * @param pNome   (String) - il nome che verrā visualizzato del menų
    * @param pLink   (String) - lo URL da caricare
    * @param pTarget (String) - la finestra dove visualizzare il contenuto
    * @param pImmagine (Immagine) - URL di un'immagine da inserire nel DIV
    * @param pConfig (Configurazione) - l'oggetto di configurazione da utilizzare
    * @param pDimensione (String) - l'eventuale dimensione da utilizzare per la dimensione libera
    * @param pIdDaVisualizzare (String) - eventuale id di un oggetto da visualizzare
    */
function Menu( pNome, pLink, pTarget, pPath, pImmagine, pConfig, pDimensione, pIdDaVisualizzare )
{
    // salva i parametri
    this.nome = pNome;
    this.link = pLink;
    this.target = pTarget;
    this.immagine = pImmagine;
    this.configurazione = pConfig;
    this.dimensione = pDimensione;
    this.IdDaVisualizzare = pIdDaVisualizzare;

    // Rappresenta il path dal menu radice
    this.path = pPath + pNome + pathSeparatore;

    // Contiene l'oggetto HTML che sarā visualizzato
    // e l'immagine associata
    this.htmlTag = undefined;
    this.htmlImg = undefined;

    // Punta al padre dell'oggetto menu (nel primo menų č indefinito)
    this.menuPadre = undefined;

    // il livello del menu (base = 0)
    this.livello = 1;
    // i sottomenu
    this.sottomenu = new Array(0);

    // associa i metodi
    this.mostra = _mostra;
    this.aggiungiSottomenu = _aggiungiSottomenu;
    this.getMenuDaPath = _getMenuDaPath;
    this.onclick = _onClick;
    this.seleziona = _seleziona;
    this.getMenuPadre = _getMenuPadre;
    this.haImmagine = _haImmagine;
    this.linkInterno = _linkInterno;
    this.getMenuDaNomeLink = _getMenuDaNomeLink;
}

/**
    * Restituisce vero se ha un'immagine impostata
    */
function _haImmagine()
{
    return this.immagine != undefined;
}

/**
    * Visualizza il menu
    */
function _mostra()
{
    // Esegue la funzione del livello corrispondente
    eval( "_mostraLivello" + this.livello + "(this)" );

    // Esegue il mostra anche per tutti i sottomenų
    for ( var iPos=0; iPos < this.sottomenu.length; iPos++ )
    {
        this.sottomenu[iPos].mostra();
    }
}


/**
    * Realizza la logica di visualizzazione di 1° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    *
    */
function _mostraLivello1( pCurObj )
{
    // imposta la posizione dell'oggetto
    var iX = pCurObj.configurazione.origineX
    var iY = pCurObj.configurazione.dinamicaY;

    // parte fissa
    var oMenu = _mostraLivelloFisso( pCurObj, iX, iY );

    // imposta l'altezza, se impostata la dimensione facoltativa
    if ( pCurObj.dimensione != undefined )
        oMenu.style.height = pCurObj.dimensione;

    // imposta il valore per il menų successivo
    pCurObj.configurazione.dinamicaY += parseInt( oMenu.style.height );
}

/**
    * Realizza la logica di visualizzazione di 2° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _mostraLivello2( pCurObj )
{

    // imposta la posizione dell'oggetto
    var iX = pCurObj.configurazione.origineX
    var iY = pCurObj.configurazione.dinamicaY;
    // resetta l'impostazione per i menų verticali
    pCurObj.configurazione.dinamicaX = pCurObj.configurazione.partenzaX;

    // parte fissa
    var oMenu = _mostraLivelloFisso( pCurObj, iX, iY );

    // imposta l'altezza, se impostata la dimensione facoltativa
    if ( pCurObj.dimensione != undefined )
        oMenu.style.height = pCurObj.dimensione

    // imposta il valore per il menų successivo
    pCurObj.configurazione.dinamicaY += parseInt( oMenu.style.height );


}

/**
    * Realizza la logica di visualizzazione di 3° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _mostraLivello3( pCurObj )
{
    // imposta la posizione dell'oggetto
    var iX = pCurObj.configurazione.dinamicaX;
    var iY = pCurObj.configurazione.origineY;

    // parte fissa
    var oMenu = _mostraLivelloFisso( pCurObj, iX, iY );
        oMenu.style.visibility = "hidden";

    // imposta la larghezza, se impostata la dimensione facoltativa
    //alert( "pCurObj.dimensione: " + pCurObj.dimensione );
    //alert( "oMenu.style.height: "  + oMenu.style.height );
    if ( pCurObj.dimensione != undefined )
        oMenu.style.width = pCurObj.dimensione

    // imposta il valore per il menų successivo
    pCurObj.configurazione.dinamicaX += parseInt( oMenu.style.width );
}


/**
    * Realizza la logica di visualizzazione fissa per tutti i livelli
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    * @param iX, iY (Integer) - la posizione X e Y di inizio visualizzazione
    *
    * @return restituisce l'elemento aggiunto
    */
function _mostraLivelloFisso( pCurObj, iX, iY )
{
    // aggiunge un nuovo div
    var oMenu = document.createElement("DIV");
        oMenu.id = pCurObj.path;
        comp_impostaTestDiv( pCurObj.configurazione.detectBrowser,
                                oMenu, pCurObj.nome );


    // imposta le varie proprietā
    oMenu.style.top = iY;
    oMenu.style.left = iX;
    oMenu.style.cssText += "; " + eval( "pCurObj.configurazione.stileLivello" + pCurObj.livello );
    //oMenu.style.cssText += "; border:solid";
    document.body.appendChild(oMenu);

    // se ha un'immagine impostata, la aggiunge
    if ( pCurObj.haImmagine() )
    {
        var oImg = document.createElement("IMG");
            oImg.src = pCurObj.immagine.immagine;
            oImg.width = pCurObj.immagine.larghezza;
            oImg.height = pCurObj.immagine.altezza;
            oImg.align= "absmiddle";

        // Se č presente solo l'immagine di rollover, la nasconde
        if ( pCurObj.immagine.immagine == "" )
            oImg.style.visibility = "hidden";

        // Aggiunge l'immagine e la collega al menų
        if ( (pCurObj.immagine.isPrima()) && (oMenu.hasChildNodes()) )
        {
            // Se č da inserire prima, e c'č giā almeno un elemento
            var oPrimo = oMenu.childNodes[0];
            oMenu.insertBefore( oImg, oPrimo );
        }
        else
        {
            oMenu.appendChild(oImg);
        }
        pCurObj.htmlImg = oImg;

    }

    // Abilita il rollover
    oMenu.onmouseover = _menu_mouseover;
    oMenu.onmouseout  = _menu_mouseout;

    // imposta la funzione per reagire al click
    oMenu.onclick = _menu_onclick;
    //alert( oMenu.onclick );

    // salva l'oggetto html nell'oggetto menų
    pCurObj.htmlTag = oMenu;

    return oMenu;
}


/**
    * Aggiunge un sotto menu, dal nome passato, di un livello pių in basso
    *
    * @param pNome (String) - il nome del nuovo menu
    * @param pLink   (String) - lo URL da caricare
    * @param pTarget (String) - la finestra dove visualizzare il contenuto
    * @param pImmagine (Immagine) - immagine da inserire nel DIV
    * @param pDimensione (String) - l'eventuale dimensione da utilizzare per la dimensione libera
    * @param pIdDaVisualizzare (String) - eventuale id di un oggetto da visualizzare
    */
function _aggiungiSottomenu( pNome, pLink, pTarget, pImmagine, pDimensione, pIdDaVisualizzare )
{
    var lMenu = new Menu( pNome, pLink, pTarget, this.path,
                            pImmagine, this.configurazione, pDimensione, pIdDaVisualizzare );
            lMenu.livello = this.livello + 1;
    this.sottomenu[this.sottomenu.length] = lMenu;
    lMenu.menuPadre = this;
    return lMenu;
}


/**
    * Aggiunge un sotto menu, dal nome passato, di un livello pių in basso
    *
    * @param pNome (String) - il nome del nuovo menu
    * @param pLink   (String) - lo URL da caricare
    * @param pTarget (String) - la finestra dove visualizzare il contenuto
    */
function _getMenuDaPath( pPath, pLivello )
{
    // Il path deve essere lungo almeno 2 caratteri
    if ( pPath.length < 2 )
    {
        return this;
    }

    // Se il path finisce con il separatore, lo toglie
    if ( pPath.substr( pPath.length-1, 1) == pathSeparatore )
        pPath = pPath.substring( 0, pPath.length-1)

    // Nome del sotto menu da cercare
    var primoMenu;
    // Path rimanente da cercare
    var pathRimanente;

    // Singoli pezzi del path
    var pezziPath = pPath.split(pathSeparatore);

    // Dovrebbe esserci almeno un livello
    if ( pezziPath.length < 1 )
        return this;

    // Se si č al primo livello, bisogna scartare il primo nome del path
    if ( pLivello == 0 )
    {
        // Controlla che il primo livello corrisponda con quello attuale
        if ( pezziPath[0] != this.nome )
            return undefined;

        // Se c'č un solo livello nel path, č il livello corrente
        if ( pezziPath.length == 1 )
            return this;

        // Altrimenti si cerca il sotto livello
        primoMenu = pezziPath[1];
        pathRimanente = pPath.substring( pezziPath[0].length + pezziPath[1].length + 2,
                                            pPath.length );
    }
    else
    {
        primoMenu = pezziPath[0];
        pathRimanente = pPath.substring( pezziPath[0].length + 1, pPath.length );
    }

    // Scorre tutti i sotto menu alla ricerca di quello da restituire
    for ( var iPos=0; iPos < this.sottomenu.length; iPos++ )
    {
        // Se lo trova, continua con i sotto menu
        if (this.sottomenu[iPos].nome == primoMenu)
        {
            return this.sottomenu[iPos].getMenuDaPath( pathRimanente, pLivello + 1);
        }
    }

    return undefined;
}


/**
    * Restituisce il menu padre
    */
function _getMenuPadre()
{
    var oMenu = this;
    while ( oMenu.livello > 1 )
    {
        oMenu = oMenu.menuPadre;
    }

    return oMenu;
}



/**
    * Reagisce al click sull'elemento del menu.
    * Ridirige sul metodo adatto per il livello del menų
    */
function _onClick()
{
    // Rigira sulla funzione (non metodo dell'oggetto) del livello corrispondente
    eval( "_onClickLivello" + this.livello + "( this )" );
}


/**
    * Imposta la selezione sull'oggetto
    * Ridirige sul metodo adatto per il livello del menų
    */
function _seleziona()
{
    // Rigira sulla funzione (non metodo dell'oggetto) del livello corrispondente
    eval( "_selezionaLivello" + this.livello + "( this )" );
}

/**
    * Reagisce al click sull'elemento del menu, per il 1° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _onClickLivello1( pCurObj )
{
    _selezionaLivello1( pCurObj );

    if ( pCurObj.link != "" )
    {
        window.open( pCurObj.link, pCurObj.target );
    }
    else
    {
        //alert("_onClickLivello1: condizione inattesa");
    }
}


/**
    * Imposta la selezione sull'elemento del menu, per il 1° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _selezionaLivello1( pCurObj )
{
    _spegneMenuLivello3( pCurObj.getMenuPadre() );
    _disattivaSelezione(pCurObj.getMenuPadre());

    // Se č attiva l'immagine alternativa in fase di selezione
    if ( ( pCurObj.haImmagine() ) && ( pCurObj.immagine.isSelezione() ) )
    {
        pCurObj.htmlImg.src = pCurObj.immagine.immagineAlternativa;
    }

    // Se deve visualizzare un id
    if ( ( pCurObj.IdDaVisualizzare != undefined ) )
    {
        var oID = document.getElementById( pCurObj.IdDaVisualizzare );
            oID.style.visibility = "visible";
        // Scorre tutti i nodi alla ricerca di un testo
        /*for ( var iNodo = 0; iNodo < oID.childNodes.length; iNodo++ )
        {
            // E' un nodo di testo
            if ( oID.childNodes[iNodo].nodeType == 3 )
            {
                oID.childNodes[iNodo].data = pCurObj.nome;
            }
        }*/
    }

}

/**
    * Reagisce al click sull'elemento del menu, per il 2° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _onClickLivello2( pCurObj )
{
    _selezionaLivello2( pCurObj );
    if ( pCurObj.link != "" )
    {
        window.open( pCurObj.link, pCurObj.target );
    }
}


/**
    * Imposta la selezione sull'elemento del menu, per il 2° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _selezionaLivello2( pCurObj )
{
    _spegneMenuLivello3( pCurObj.getMenuPadre() );
    _disattivaSelezione(pCurObj.getMenuPadre());
    _disattivaMenuLivello3( pCurObj.menuPadre );

    // Se č attiva l'immagine alternativa in fase di selezione
    if ( ( pCurObj.haImmagine() ) && ( pCurObj.immagine.isSelezione() ) )
    {
        pCurObj.htmlImg.src = pCurObj.immagine.immagineAlternativa;
    }

    // Se deve visualizzare un id
    if ( ( pCurObj.IdDaVisualizzare != undefined ) )
    {
        var oID = document.getElementById( pCurObj.IdDaVisualizzare );
            oID.style.visibility = "visible";
        
        // Scorre tutti i nodi alla ricerca di un testo
        /* RG - 2005.09.20 - Non č necessario e 
            crea doppia visualizzazione in NS del titolo del menų
        for ( var iNodo = 0; iNodo < oID.childNodes.length; iNodo++ )
        {
            // E' un nodo di testo
            if ( oID.childNodes[iNodo].nodeType == 3 )
            {
                oID.childNodes[iNodo].data = pCurObj.nome;
            }
        }
        */
    }

    for ( var iPos=0; iPos < pCurObj.sottomenu.length; iPos++ )
    {
        pCurObj.sottomenu[iPos].htmlTag.style.visibility = "visible";
    }
}

/**
    * Reagisce al click sull'elemento del menu, per il 1° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _onClickLivello3( pCurObj )
{
    if ( pCurObj.link != "" )
    {
        window.open( pCurObj.link, pCurObj.target );
        pCurObj.seleziona();
    }
    else
    {
        //alert("_onClickLivello3: condizione inattesa");
    }
}

/**
    * Imposta la selezione sull'elemento del menu, per il 3° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _selezionaLivello3( pCurObj )
{
    _disattivaMenuLivello3( pCurObj.menuPadre.menuPadre );

    // abilita colorazione di selezione del tag
    pCurObj.htmlTag.style.color =
        pCurObj.configurazione.testoRolloverLivello3;
}

/**
    * Deseleziona  tutti i menu di 3° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _disattivaMenuLivello3( pCurObj )
{
    // se livello 3, lo spegne
    if ( pCurObj.livello == 3 )
    {
        pCurObj.htmlTag.style.color =
            pCurObj.configurazione.testoLivello3;
    }

    // se inferiore al livello 3, propaga la richiesta ai livelli sottostanti
    if ( pCurObj.livello < 3 )
    {
        for ( var iPos=0; iPos < pCurObj.sottomenu.length; iPos++ )
        {
            _disattivaMenuLivello3( pCurObj.sottomenu[iPos] );
        }
    }
}

/**
    * Nasconde tutti i menu di 3° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _spegneMenuLivello3( pCurObj )
{
    // se livello 3, lo spegne
    if ( pCurObj.livello == 3 )
        pCurObj.htmlTag.style.visibility = "hidden";

    // se inferiore al livello 3, propaga la richiesta ai livelli sottostanti
    if ( pCurObj.livello < 3 )
    {
        for ( var iPos=0; iPos < pCurObj.sottomenu.length; iPos++ )
        {
            _spegneMenuLivello3( pCurObj.sottomenu[iPos] );
        }
    }
}

/**
    * Disattiva le immagini seleziona al 2° livello
    *
    * @param pCurObj (Menu) - il menu su cui si esegue la funzione
    */
function _disattivaSelezione( pCurObj )
{
    // se livello 2, lo spegne
    if ( (pCurObj.livello <= 2) && (pCurObj.haImmagine()) )
    {
        pCurObj.htmlImg.src = pCurObj.immagine.immagine;
        // Se deve visualizzare un id
        if ( ( pCurObj.IdDaVisualizzare != undefined ) )
        {
            document.getElementById( pCurObj.IdDaVisualizzare ).style.visibility = "hidden";
        }
    }

    // se inferiore al livello 2, propaga la richiesta ai livelli sottostanti
    if ( pCurObj.livello < 2 )
    {
        for ( var iPos=0; iPos < pCurObj.sottomenu.length; iPos++ )
        {
            _disattivaSelezione( pCurObj.sottomenu[iPos] );
        }
    }
}

/**
    * Gestisce una proprietā diversa tra IE e Mozilla
    * Imposta il contenuto testuale del layer
    *
    * @param oDiv (DIV) - il menu su cui si esegue la funzione
    * @param sTesto (Stringa) - il testo da salvare
    */
    function comp_impostaTestDiv( oDetectBrowser, oDiv, sTesto )
    {
    if ( oDetectBrowser.isNS6() )
    {
        oDiv.textContent = sTesto;
    }
    else
    {
        oDiv.innerText = sTesto;
    }
    }

function dumpObj( oObj )
{
    var bfr = "";
    var cont = 0;
    for ( var iPrp in oObj )
    {

        try
        {
            var prp = eval("oObj." + iPrp);
            if (prp != "")
                bfr += iPrp + ": " + prp + "<br>";
        }
        catch (e)
        {
        }
        // + ": " + eval("oObj." + iPrp);
        cont++;
    }
    document.write( bfr );
    //alert( bfr );
}


/**
    * Reagisce ai link interni al sito
    */
function _linkInterno( nomeLink )
{
    var oMenuRoot = CallBack_Menu_OnClick();
    var oMenu = oMenuRoot.getMenuDaNomeLink( nomeLink );

    // Se il menų non č stato trovato, esce
    if ( oMenu == undefined )
        return;

    // Per il livello 3, attiva anche il livello padre
    if ( oMenu.livello == 3 )
    {
        _spegneMenuLivello3( oMenu.getMenuPadre().getMenuPadre() );
        _disattivaSelezione(oMenu.getMenuPadre().getMenuPadre()  );
        _disattivaMenuLivello3( oMenu.getMenuPadre().getMenuPadre() );
        oMenu.menuPadre.seleziona();
    }

    // Per il livello 2, attiva anche il livello padre
    if ( oMenu.livello == 2 )
    {
        _spegneMenuLivello3( oMenu.getMenuPadre() );
        _disattivaSelezione(oMenu.getMenuPadre() );
        _disattivaMenuLivello3( oMenu.getMenuPadre() );
        oMenu.menuPadre.seleziona();
    }

    // Attiva il menų selezionato
    oMenu.seleziona();
}

/**
    * Cerca il menu cui corrisponde il link passato
    *
    * @param pNomeLink (String) - il link da cercare
    */
function _getMenuDaNomeLink( pNomeLink )
{
    // Se il link di questo menų č quello del link, lo restituisce
    if ( pNomeLink.toLowerCase() == this.link.toLowerCase() )
        return this;

    //  altrimenti lo cerca in tutti i sotto menu
    for ( var iPos=0; iPos < this.sottomenu.length; iPos++ )
    {
        var oMenu = this.sottomenu[iPos].getMenuDaNomeLink( pNomeLink );
        if ( oMenu != undefined )
            return oMenu;
    }

    // se non ha trovato nulla, restituisce undefined
    return undefined;
}
