/**
 * Clase para gestionar llamadas ajax.
 */

function AjaxHandler(){
    var thisHandler=this; //Referencia para usar en las funciones privadas
    this.$targetContainer=$('<div class="js-targetContainer"/>').appendTo($('body')).hide().uniqueId();
    this.extraParams={
        'ajaxRequest': 'true'
    }

    // *****************************************************
    // Metodos privados
    // *****************************************************

    function newCancelButtonClickHandler($dialogContainer){
        return function(e){
            e.preventDefault();
            $dialogContainer.dialog('close');
            return false;
        };
    }
	
    // Llamado en el evento close del dialogo asociado a un formulario
    function newDialogCloseListener($dialogContainer){
        return function(e,ui){
            $dialogContainer.remove();
        }
    }

    // Llamado tras pulsar un submit en un formulario pero antes de enviar los datos
    function newBeforeSubmitListener($responseContainer){
        return function(formData, $form, ops){
            // Si el boton pulsado tiene title se usa para el dialogo
            var $button=$($form.get(0).clk);
            if ($button && $button.attr('title')){
                $responseContainer.attr('title',$button.attr('title'));
            }
            $form.closest('.js-dialogContainer').dialog('close');
            return true;
        }
    }

    // Llamado al recibir la respuesta de acceder a un enlace o someter un formulario
    function newResponseReadyListener($responseContainer){
        return function(response,status,xhr){
            thisHandler.responseReady(response,status,xhr,$responseContainer);
        }
    }

    // *****************************************************
    // Metodos privilegidados
    // *****************************************************

    // Handler llamado por $.load() tras completar la llamada ajax
    this.responseReady=function responseReady(response,status,xhr,$responseContainer){
        var ajaxFlag=xhr.getResponseHeader('ajax-flag');
        if (ajaxFlag == 'redirect'){
            var ajaxLocation=xhr.getResponseHeader('ajax-location');
            window.location.replace(ajaxLocation);
        } else {
            $responseContainer.moveChildrenToTarget();

            if ($responseContainer.children().length>0){
                var $dialogContainer=$('<div class="js-dialogContainer"/>').appendTo(this.$targetContainer).uniqueId();

                // Si en la respuesta hay algo etiquetado con esta clase, se usa para el titulo
                var $title=$('.js-dialogTitle',$responseContainer);
                if ($title.length==0){
                    $title=$('.ui-widget-header',$responseContainer);
                }
                if ($title.length>0){
                    $dialogContainer.attr('title',$title.eq(0).text())
                }
                // Si en la respuesta hay algo etiquetado con esta clase, se usa para el contenido
                var $content=$('.js-dialogContent',$responseContainer);
                if ($content.length > 0 && $content !== $responseContainer){
                    $dialogContainer.append($content);
                } else {
                    var $content2=$('.ui-widget-content',$responseContainer);
                    if ($content2.length>0){
                        $dialogContainer.append($content2);
                    } else {
                        $dialogContainer.append($responseContainer.children());
                    }
                }

                // Agregar boton cancelar a cada formulario
                var $form=$('form',$dialogContainer);
                var buttons;
                if ($form.length){
                    $form.each(function(){
                        var $form=$(this);
                        var $buttonsHolder=$('.js-buttonsHolder',$form);
                        if (!$buttonsHolder.length){
                            $buttonsHolder=$('.boton:last',$form).parent();
                        }
                        var $menu=$('<li class="menu"></li>');
                        var $button=$('<button class="boton cancel">Cancelar</button>').button({
                            icons:{
                                primary:'ui-icon-close'
                            }
                        });
                        $button.appendTo($menu);
                        $menu.click(newCancelButtonClickHandler($dialogContainer))
                        .appendTo($buttonsHolder);

                        // Preparar para gestionar via ajax.
                        thisHandler.prepareForm($form);
                    });
                    buttons={};
                } else {
                    // Si no hay ningun formulario, agregar un boton Ok.
                    buttons={
                        'Ok': function(){
                            $(this).dialog('close');
                        } 
                    };
                }

                $('title',$dialogContainer).remove();
                $('style',$dialogContainer).remove();
                if ($dialogContainer.children().length>0){
                    $dialogContainer.dialog({
                        modal: true,
                        closeOnEscape: true,
                        draggable: true,
                        resizable: true,
                        position: ['center','middle'],
                        height: 'auto',
                        width: 'auto',
                        close: newDialogCloseListener($dialogContainer),
                        buttons: buttons
                    })
                } else {
                    $dialogContainer.remove();
                }
            }
            $responseContainer.remove();
        }
    }

    this.handleClick=function handleClick(e,$anchor){
        // Click event handler ligado a un anchor 'a' que carga,
        // via ajax, el recurso al que apunta 'a.href'
        // dentro de un dialogo modal.
        e.preventDefault();
        this.loadAnchor($anchor);
        return false;
    }

    this.loadAnchor = function loadAnchor($anchor){
        this.loadUrl($anchor.attr('href'),$anchor.attr('title'));
    }
	
    this.loadUrl =  function loadUrl(href, title){
        var uri=new jsUri(href);
        $.each(this.extraParams,function(key,value){
            uri.replaceQueryParam(key,value);
        });
        href=uri.toString();
        var $responseContainer=$('<div class="js-responseContainer"/>').appendTo(this.$targetContainer).uniqueId();
        if (title){
            $responseContainer.attr('title',title);
        }
        $responseContainer.load(href,newResponseReadyListener($responseContainer,null));
    }
        
    this.prepareForm = function prepareForm($form){
        // Almacenara la respuesta al envio del formulario
        var $responseContainer=$('<div class="js-responseContainer"/>').appendTo(this.$targetContainer).uniqueId();
        var opts={};
        opts.target='#' + $responseContainer.attr('id');
        opts.beforeSubmit= newBeforeSubmitListener($responseContainer);
        opts.success = newResponseReadyListener($responseContainer);
        opts.data = this.extraParams;
        $form.ajaxForm(opts);
    }
}



