/**
 * Usa Prototype asi que se debe incluir previamente a incluir este script
 */
net = new Object();

net.READY_STATE_UNINITIALIZED = 0;
net.READY_STATE_LOADING       = 1;
net.READY_STATE_LOADED        = 2;
net.READY_STATE_INTERACTIVE   = 3;
net.READY_STATE_COMPLETE      = 4;

net.ContentLoader = new Class();

net.ContentLoader.prototype = {

    /**
     * Funcion que inicializa los valores del objecto
     *
     * @param    object   component         Objecto que lo invoca
     * @param    string   url               URL del servidor a invocar
     * @param    string   method            POST o GET
     * @param    array    requestParams     Vector con los parametros
     * @param    array    options           Vector con opciones(errorHandler, successHandler, etc.)
     *
     * @access    public
     */
    initialize: function(component, url, method, requestParams, options) {
        this.component     = component;
        this.url           = url;
        this.method        = method;

        // Añadimos una variable ajaxenabled para que el servidor pueda
        // diferenciar cuando nos llegan los datos desde AJAX y cuando no

        if (!requestParams) {
            requestParams = [];
        }
        requestParams.push('ajaxenabled=1');

        this.requestParams = requestParams;
        this.options       = options;
    },

    /**
     * Crea el objecto con el que nos vamos a comunicar con el servidor
     *
     * @access    public
     * @return    object        Devuelve el objeto creado
     */
    getTransport: function() {
        var xmlhttp;
        if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            try {
                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch(e) {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
        } else if (window.createRequest) {
            xmlhttp = window.createRequest();
        }
        return xmlhttp;
    },

    /**
     * Se encarga de usar el objecto creado por getTransport para enviar los
     * parametros pasados como argumento. Se puede pasar cualquier numero de
     * de parametros.
     *
     * @access    public
     */
    sendRequest: function() {

        var requestParams = [];
        for (var i = 0; i < arguments.length; i++) {
            requestParams.push(arguments[i]);
        }
        var request = this.getTransport();

        if ($('log')) {
            if (document.all) {
                $('log').setAttribute('className', 'bbox');
            } else {
                $('log').setAttribute('class', 'bbox');
            }
            $('log').innerHTML = '<img src="../images/loading.gif" /> Cargando ...';
        }

        request.open(this.method, this.url, true);
        request.setRequestHeader('Content-type','application/x-www-form-urlencoded; charset=utf-8');

        var oThis = this;
        request.onreadystatechange = function() {
            oThis.handleAjaxResponse(request);
        }
        request.send(this.queryString(requestParams));
    },

    /**
     * Convierte el vector de parametros a cadena en formato GET/POST que
     * se pasara al servidor mediante la conexion creada anteriormente.
     * Se le puede pasar cualquier numero de parametros
     *
     * @param    array    args  Vector con los parametros
     *
     * @access    private
     * @return    string        Cadena en formato POST/GET
     */
    queryString: function(args) {

        var requestParams = [];
        for (var i = 0; i < this.requestParams.length; i++) {
            requestParams.push(this.requestParams[i]);
        }
        for (var i = 0; i < args.length; i++) {
            requestParams.push(args[i]);
        }

        var queryString = "";
        if (requestParams && requestParams.length > 0) {
            queryString = requestParams[0];
            for (var i = 1; i < requestParams.length; i++) {
                queryString += '&'+requestParams[i];
            }
        }
        return queryString;
    },

    /**
     * Metodo al que se llama cuando se recibe la respuesta del servidor.
     * Si se ha definido los manejadores pasandoles dicha informacion al
     * constructor en el vector options, se llamaran a estos, sino se
     * llamara a los metodos definidos por defecto en esta clase.
     *
     * @param    object    request      Objecto respuesta
     *
     * @access    private
     */
    handleAjaxResponse: function(request) {
        if (request.readyState == net.READY_STATE_COMPLETE) {
            if ($('log')) {
                if (document.all) {
                    $('log').setAttribute('className', '');
                } else {
                    $('log').setAttribute('class', '');
                }
                $('log').innerHTML = '';
            }
            if (this.isSuccess(request)) {
                if (this.component && this.component.successHandler) {
                    this.component.successHandler(request);
                } else {
                    this.successHandler(request);
                }
            } else {
                if (this.component && this.component.errorHandler) {
                    this.component.errorHandler(request);
                } else {
                    this.errorHandler(request);
                }
            }
        }
    },

    /**
     * Devuelve si el estado HTTP es correcto o no
     *
     * @param    object    request      Objecto respuesta
     *
     * @access    private
     */
    isSuccess: function(request) {
        return request.status == 0 || (request.status >=200 && request.status < 300);
    },

    /**
     * Metodo al que se llama cuando todo ha ido bien
     *
     * @param    object    request      Objeto HTTP
     *
     * @access private
     */
    successHandler: function(request) {
        if (request.responseXML && request.responseXML.documentElement) {
            var xml = request.responseXML.documentElement;

			var infos = xml.getElementsByTagName('infos');
            if (infos.length) {
                var idinfo = infos[0].getAttribute('to');
                if (idinfo && $(idinfo)) {
                    $(idinfo).innerHTML = '';
                }
            }

			var msgs = xml.getElementsByTagName('messages');
            if (msgs.length) {
                var idmsg = msgs[0].getAttribute('to');
                if (idmsg && $(idmsg)) {
                    $(idmsg).innerHTML = '';
                }
            }

			var errors = xml.getElementsByTagName('errors');
            if (errors.length) {
                var iderror = errors[0].getAttribute('to');
                if (iderror && $(iderror) && (!idmsg || idmsg != iderror)) {
                    $(iderror).innerHTML = '';
                }
            }

			var html_info = '';
            var info = xml.getElementsByTagName('info');
            if (info.length) {
                if (info.length > 1) {
                    var html_info = '<ul>';
                    for (var i = 0; i< info.length; i++) {
                        html_info += '<li>'+info[i].firstChild.data+'</li>';
                    }
                    html_info += '</ul>';
                } else {
                    var html_info = info[0].firstChild.data;
                }
            }

            var html_msg = '';
            var msg = xml.getElementsByTagName('message');
            if (msg.length) {
                if (msg.length > 1) {
                    var html_msg = '<ul>';
                    for (var i = 0; i< msg.length; i++) {
                        html_msg += '<li>'+msg[i].firstChild.data+'</li>';
                    }
                    html_msg += '</ul>';
                } else {
                    var html_msg = msg[0].firstChild.data;
                }
            }

            var html_error = '';
            var error = xml.getElementsByTagName('error');
            if (error.length) {
                if (error.length > 1) {
                    var html_error = '<ul>';
                    for (var i = 0; i< error.length; i++) {
                        html_error += '<li>'+error[i].firstChild.data+'</li>';
                    }
                    html_error += '</ul>';
                } else {
                    var html_error = error[0].firstChild.data;
                }
            }

            if (html_error != '') {
				if ($(iderror)) {
                    $(iderror).innerHTML = html_error;
					$(iderror).className = 'rbox';
                }
			} else if (html_msg != '') {
            	if ($(idmsg)) {
				    $(idmsg).innerHTML = html_msg;
					$(idmsg).className = 'gbox';
                }
            }

			if (html_info != '') {
				if ($(idinfo)) {
				    $(idinfo).innerHTML = $(idinfo).innerHTML + html_info;
					$(idinfo).className = 'bbox';
                }
			}
        } else {
            if ($('log')) {
                $('log').innerHTML = request.responseText;
				$('log').className = 'bbox';
            } else {
                alert(request.responseText);
            }
        }
    },

    /**
     * Metodo al que se llama cuando ha habido algun error
     *
     * @param    object    request      Objeto HTTP
     *
     * @access private
     */
    errorHandler: function(request) {
        if ($('log')) {
            $('log').innerHTML = request.responseText;
            $('log').className = 'rbox';
        } else {
            alert(request.responseText);
        }
    }
}