var logger = null;

// funzione per il recupero del logger
// parametri:
// category la categoria del logger
// url l'url per l'eventuale AjaxAppender
function getLoggerSE(category, url)
{
    var myCategory = category;
    if (myCategory != null)
    {
        var categorySplitted = myCategory.split("/");
        if (categorySplitted != null)
        {
            categorySplitted.reverse();
            var i = null;
            for (i in categorySplitted)
            {
                myCategory = categorySplitted[i];
                if ((myCategory != null && myCategory != ""))
                {
                    break;
                }
            }
        }
    }
    logger = log4javascript.getLogger(myCategory);
    var popUpAppender = new log4javascript.PopUpAppender();
    var popUpLayout = new log4javascript.PatternLayout("%d [%c] [%5p] %m%n");
    popUpAppender.setLayout(popUpLayout);
    popUpAppender.setThreshold(log4javascript.Level.DEBUG);
    logger.addAppender(popUpAppender);
    /*var ajaxAppender = new log4javascript.AjaxAppender(url);
    ajaxAppender.setThreshold(log4javascript.Level.DEBUG);
    ajaxAppender.setWaitForResponse(true);
    logger.addAppender(ajaxAppender);*/
    
    logger.debug("getLogger - logger recuperato");
}

// funzione per il recupero dell'oggetto XMLHttpRequest o equivalente
function getXmlHttpObjectSE()
{
    var xmlHttp = null;
    
    try
    {
        // Firefox, Opera 8.0+, Safari (anche Internet Explorer 7)
        xmlHttp = new XMLHttpRequest();
    }
    catch (e)
    {
        // Internet Explorer
        try
        {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e)
        {
            try
            {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e)
            {
                logger.error("getXmlHttpObject - " + e, e);
            
                alert("Il tuo browser non supporta AJAX!");
            }
        }
    }
    
    return xmlHttp;
}

// funzione per l'interazione asincrona
// parametri:
// action l'url da richiamare
// id l'id dell'elemento che include il contenuto da aggiornare
// nextCall la funzione da eseguire al completamento della chiamata
// inline true se occorre eseguire l'eventuale javascript inline nell'url da richiamare, altrimenti se non occorre
function ajaxCallSE(action, id, nextCall, inline)
{  
    logger.debug("ajaxCall - inizio");
    logger.debug("ajaxCall - action: " + action);
    logger.debug("ajaxCall - id: " + id);
    logger.debug("ajaxCall - nextCall: " + nextCall);
    logger.debug("ajaxCall - inline: " + inline);
    
    // semaforo assente: posso eseguire la chiamata
    if (document.getElementById('semaforo_' + id) == null)
    {
        try
        {
            // creo il semaforo
            var semaforo = document.createElement('div');
            semaforo.setAttribute('id', 'semaforo_' + id);
            var ajaxDiv = document.getElementById(id);
            if (ajaxDiv != null)
            {
                ajaxDiv.appendChild(semaforo);
                
                logger.debug("ajaxCall - messo semaforo_" + id);
            }
            
            // recupero l'oggetto XMLHttpRequest o equivalente
            var xmlHttp = getXmlHttpObjectSE();
            if (xmlHttp == null)
            {
                return;
            }
            
            // gestisco l'esito della chiamata ajax
            xmlHttp.onreadystatechange = function()
            {
                if(xmlHttp.readyState == 4)
                {
                    if (xmlHttp.status == 200)
                    {
                        logger.trace("ajaxCall - responseText: " + xmlHttp.responseText);
                        
                        // caso cambio pagina
                        if (xmlHttp.responseText.indexOf("location.href") == 0)
                        {
                            eval(xmlHttp.responseText);
                            nextCall = null;
                        }
                        // caso messaggio
                        else if (xmlHttp.responseText.indexOf("alert") == 0)
                        {
                            eval(xmlHttp.responseText);
                        }
                        // caso pop up
                        else if (xmlHttp.responseText.indexOf("window.open") >= 0)
                        {
                            eval(xmlHttp.responseText);
                        }
                        // caso cambio stato
                        else if (xmlHttp.responseText.indexOf("noop") == 0)
                        {
                        }
                        // caso sostituzione
                        else
                        {
                            if (ajaxDiv != null)
                            {
                                logger.trace("ajaxCall - innerHTML: " + ajaxDiv.innerHTML);
                                
                                ajaxDiv.innerHTML = xmlHttp.responseText;
                                
                                if (inline == true)
                                {
                                    inlineEvalSE(xmlHttp.responseText);
                                }
                            }
                        }
                        
                        logger.debug("ajaxCall - fine callback");
                        
                        // funzione in cascata
                        if (nextCall != null)
                        {
                            eval(nextCall);
                        }
                    }
                    else
                    {
                        logger.error("ajaxCall - status: " + xmlHttp.status);
                    }
                }
            };
            
            // eseguo la chiamata ajax
            xmlHttp.open("POST", action, true);
            xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xmlHttp.send('');
            delete xmlHttp;
        }
        catch(e)
        {
            logger.error("ajaxCall - " + e, e);
            
            try
            {
                // rimuovo il semaforo
                ajaxDiv.removeChild(semaforo);
            }
            catch(e)
            {
                logger.error("ajaxCall - " + e, e);
            }
            
            logger.debug("ajaxCall - tolto semaforo_" + id);
        }
    }
    // semaforo presente: non eseguo la chiamata
    else
    {
        logger.debug("ajaxCall - semaforo_" + id + " presente");
    }
    
    logger.debug("ajaxCall - fine");
}

// funzione per l'interazione asincrona (versione semplificata)
// parametri:
// action l'url da richiamare
// id l'id dell'elemento che include il contenuto da aggiornare
// async false per richieste sincrone, altrimenti asincrone
// inline true se occorre eseguire l'eventuale javascript inline nell'url da richiamare, altrimenti se non occorre
// method GET o POST (il default)
function simpleAjaxCallSE(action, id, async, inline, method)
{  
    logger.debug("simpleAjaxCall - inizio");
    logger.debug("simpleAjaxCall - action: " + action);
    logger.debug("simpleAjaxCall - id: " + id);
    logger.debug("simpleAjaxCall - async: " + async);
    logger.debug("simpleAjaxCall - inline: " + inline);
    logger.debug("simpleAjaxCall - method: " + method);
    
    try
    {
        // recupero l'oggetto XMLHttpRequest o equivalente
        var xmlHttp = getXmlHttpObjectSE();
        if (xmlHttp == null)
        {
            return;
        }
        
        // gestisco l'esito della chiamata ajax asincrona
        xmlHttp.onreadystatechange = function()
        {
            if(xmlHttp.readyState == 4)
            {
                if (xmlHttp.status == 200)
                {
                    logger.trace("simpleAjaxCall - responseText: " + xmlHttp.responseText);
                    
                    var ajaxDiv = document.getElementById(id);
                    
                    if (ajaxDiv != null)
                    {
                        logger.trace("simpleAjaxCall - innerHTML: " + ajaxDiv.innerHTML);
                        
                        ajaxDiv.innerHTML = xmlHttp.responseText;
                                
                        if (inline == true)
                        {
                            inlineEvalSE(xmlHttp.responseText);
                        }
                    }
                    
                    logger.debug("simpleAjaxCall - fine callback");
                }
                else
                {
                    logger.error("simpleAjaxCall - status: " + xmlHttp.status);
                }
            }
        };
        
        // eseguo la chiamata ajax
        xmlHttp.open(((method == 'GET') ? 'GET' : "POST"), action, ((async == false) ? false : true));
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttp.send('');
        
        // gestisco l'esito della chiamata ajax sincrona
        if (async == false)
        {
            if(xmlHttp.readyState == 4)
            {
                if (xmlHttp.status == 200)
                {
                    logger.trace("simpleAjaxCall - responseText: " + xmlHttp.responseText);
                    
                    var ajaxDiv = document.getElementById(id);
                    
                    if (ajaxDiv != null)
                    {
                        logger.trace("simpleAjaxCall - innerHTML: " + ajaxDiv.innerHTML);
                        
                        ajaxDiv.innerHTML = xmlHttp.responseText;
                                
                        if (inline == true)
                        {
                            inlineEvalSE(xmlHttp.responseText);
                        }
                    }
                }
                else
                {
                    logger.error("simpleAjaxCall - status: " + xmlHttp.status);
                }
            }
        }
        delete xmlHttp;
    }
    catch(e)
    {
        logger.error("simpleAjaxCall - " + e, e);
    }
    
    logger.debug("simpleAjaxCall - fine");
}

// funzione per l'esecuzione di codice javascript inline
// parametri:
// html il codice hmtl (generalmente un xmlHttp.responseText) in cui cercare codice javascript inline
function inlineEvalSE(html)
{  
    logger.debug("inlineEval - inizio");
    logger.trace("inlineEval - html: " + html);
    
    try
    {
        // cerco gli elementi <script> di tipo "text/javascript"
        if (html != null)
        {
            var startScriptTagRegExp = /<(script|SCRIPT)\s+(type|TYPE)\s*=\s*"(text\/javascript|TEXT\/JAVASCRIPT)"\s*>/;
            var endScriptTagRegExp = /<\/(script|SCRIPT)>/;
            var script;
            var myHtml = html;
            var startScriptTagIndex = myHtml.search(startScriptTagRegExp);
            var endScriptTagIndex = startScriptTagIndex + myHtml.substring(startScriptTagIndex).search(endScriptTagRegExp);
            while (startScriptTagIndex != -1 && endScriptTagIndex != -1)
            {
                script = myHtml.substring(startScriptTagIndex, endScriptTagIndex).replace(startScriptTagRegExp, "");
                
                logger.debug("ajaxEval - inline javascript: " + script);
                
                eval(script);
                
                myHtml = myHtml.substring(endScriptTagIndex).replace(endScriptTagRegExp, "");
                startScriptTagIndex = myHtml.search(startScriptTagRegExp);
                endScriptTagIndex = startScriptTagIndex + myHtml.substring(startScriptTagIndex).search(endScriptTagRegExp);
            }
        }
    }
    catch(e)
    {
        logger.error("inlineEval - " + e, e);
    }
    
    logger.debug("inlineEval - fine");
}
