/**
    SCL SOFTWARE.
    Santiago Corredoira Lascaray
    Copyright (C) SCL SOFTWARE 1999/2009.  All rights reserved.
    
    Libreria base.
    version: 3.0
*/

if (typeof Scl == "undefined") 
{
    var Scl =
    {
        isDefined: function(o) {
            return typeof o !== 'undefined';
        },

        isString: function(o) {
            return typeof o === 'string';
        },

        isNumber: function(o) {
            return typeof o === 'number' && isFinite(o);
        },

        isNull: function(o) {
            return o === null;
        },

        isEmpty: function(value) {
            return value == null || value == '';
        },

        isFunction: function(o) {
            return typeof o === 'function';
        },

        isArray: function(o) {
            if (o) {
                return Scl.isNumber(o.length) && Scl.isFunction(o.splice);
            }
            return false;
        },








        /**************************************************
        *
        *  Strings
        *
        **************************************************/
        strEqual: function(a, b) {
            if (a == null && b == null) return true;
            if (a == null || b == null) return false;
            return a.toLowerCase() == b.toLowerCase();
        },

        toLower: function(value) {
            return value != null ? value.toLowerCase() : null;
        },

        toUpper: function(value) {
            return value != null ? value.toUpperCase() : null;
        },

        startsWith: function(text, value) {
            return text.indexIf(value) === 0;
        },


        /**************************************************
        *
        *  URL
        *
        **************************************************/


        getUrlValue: function(variable) {
            var query = window.location.search.substring(1);
            var vars = query.split("&");
            for (var i = 0; i < vars.length; i++) {
                var pair = vars[i].split("=");
                if (pair[0] == variable) {
                    return pair[1];
                }
            }
        },




        /**************************************************
        *
        *  ARRAYS
        *
        **************************************************/

        /**
        * Returns true if the array contains the element.
        */
        indexOf: function(array, element) {
            for (var i = 0; i < array.length; i++) {
                if (array[i] == element) {
                    return i;
                }
            }
            return -1;
        },

        /**
        * Añade el elemento solo una vez. Si el elemento ya existe no hace nada.
        */
        addSingle: function(array, element) {
            var index = Scl.indexOf(array, element);

            if (index == -1) {
                array[array.length] = element;

                // indica que se ha añadido el elemento
                return true;
            }

            // indica que no ha añadido nada por que ya estaba dentro del array
            return false;
        },

        /**
        * Returns true if the array contains the element.
        */
        remove: function(array, element) {
            var index = Scl.indexOf(array, element);

            if (index > -1) {
                array.splice(index, 1);

                // indica que se ha eliminado el elemento
                return true;
            }

            // indica que no ha eliminado nada por que no estaba dentro del array
            return false;
        },

        /**
        * Enumera cada uno de los elementos
        */
        each: function(collection, functionName) {
            for (var i = 0; i < collection.length; i++) {
                functionName(collection[i]);
            }
        },






        /**************************************************
        *
        *  DOM
        *
        **************************************************/

        get: function(id) {
            if (typeof (id) == 'string') {
                return document.getElementById(id);
            }
            else {
                return id; // Not an id name, just return it.
            }
        },

        getByClass: function(searchClass, node, tag) {
            var classElements = new Array();

            if (node == null) {
                node = document;
            }

            if (tag == null) {
                tag = '*';
            }

            var els = node.getElementsByTagName(tag);
            var elsLen = els.length;
            var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
            for (i = 0, j = 0; i < elsLen; i++) {
                if (pattern.test(els[i].className)) {
                    classElements[j] = els[i];
                    j++;
                }
            }
            return classElements;
        },

        /**
        * Obtiene los nodos -hijos- buscando por class o por etiqueta.
        * Para buscar por class especificar "." al principio.
        */
        getChildNodes: function(element, searchPattern) {
            element = Scl.get(element);

            var result = new Array();

            var searchByClass = searchPattern.indexOf(".") === 0;

            if (searchByClass) {
                // Quitar el . para hacer la busqueda
                searchPattern = searchPattern.substring(1);
            }

            Scl.each(element.childNodes, function(item) {
                if (searchByClass) {
                    if (Scl.strEqual(item.className, searchPattern)) {
                        result.push(item);
                    }
                }
                else {
                    if (Scl.strEqual(item.tagName, searchPattern)) {
                        result.push(item);
                    }
                }
            });

            return result;
        },

        /**
        * Remove all child nodes from an element
        */
        clearChildNodes: function(element) {
            element = Scl.get(element);

            while (element.hasChildNodes()) {
                element.removeChild(element.firstChild);
            }
        },

        /**
        * gets the inner text of an Html element
        */
        getText: function(element) {
            element = Scl.get(element);

            if (Scl.isDefined(element.innerText)) {
                return element.innerText;
            }
            else {
                return element.textContent;
            }
        },

        ///
        /// Sets the inner text of an Html element
        ///
        setText: function(element, text) {
            if (text == null) {
                text = "";
            }

            element = Scl.get(element);

            if (Scl.isDefined(element.innerText)) {
                element.innerText = text;
            }
            else {
                element.textContent = text;
            }
        },

        ///
        /// Adds text to an Html element
        ///
        appendText: function(item, text) {
            if (text == null) {
                return;
            }

            var txtNode = document.createTextNode(text);
            Scl.get(item).appendChild(txtNode);
        },

        ///
        /// Adds a text line to an Html element
        ///
        appendLine: function(item, text) {
            if (text == null) {
                return;
            }

            item = Scl.get(item);

            var txtNode = document.createTextNode(text);
            item.appendChild(txtNode);

            item.appendChild(document.createElement("br"));
        },

        ///
        /// Returns the size of the object as an array [width, height]
        ///
        getSize: function(item) {
            return { width: item.offsetWidth, height: item.offsetHeight };
        },


        getMousePostion: function(event) {
            var posx = 0;
            var posy = 0;

            if (!event) {
                var event = window.event;
            }

            if (event.pageX || event.pageY) {
                posx = event.pageX;
                posy = event.pageY;
            }
            else if (event.clientX || event.clientY) {
                posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
            }

            return { x: posx, y: posy };
        },


        /**
        * Returns the position of the object as an array [left, top]
        */
        getPosition: function(item) {
            return { x: item.offsetLeft, y: item.offsetTop };
        },


        getPosition8: function(element) {
            var posx = 0;
            var posy = 0;

            if (element.offsetParent) {
                do {
                    if (element.style.position == 'absolute') {
                        break;
                    }

                    posx += element.offsetLeft;
                    posy += element.offsetTop;
                }
                while (element = element.offsetParent)
            }
            else if (element.x) {
                posx += element.x;
                posy += element.y;
            }

            return { x: posx, y: posy };
        },

        ///
        /// Returns the size of the window as an array [width, height]
        ///
        getWindowSize: function() {
            var width = 0;
            var height = 0;

            if (typeof (window.innerWidth) == 'number') {
                //Non-IE
                width = window.innerWidth;
                height = window.innerHeight;
            }
            else if (document.documentElement && (document.documentElement.clientWidth ||
                 document.documentElement.clientHeight)) {
                //IE 6+ in 'standards compliant mode'
                width = document.documentElement.clientWidth;
                height = document.documentElement.clientHeight;
            }
            else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
                //IE 4 compatible
                width = document.body.clientWidth;
                height = document.body.clientHeight;
            }

            return [width, height];
        },

        ///
        /// Returns the size of the object as an array [width, height]
        ///
        getStyle: function(element, property) {
            element = Scl.get(element);

            if (element.currentStyle) {
                return element.currentStyle[property];
            }
            else {
                return element.style[property];
            }
        },

        getComputedStyle: function(element, property) {
            element = Scl.get(element);

            if (element.currentStyle) {
                alert(2);
                return element.currentStyle[property];
            }
            else if (window.getComputedStyle) {
                return document.defaultView.getComputedStyle(element, null).getPropertyValue(property);
            }
        },

        ///
        /// Sets the CSS Style for the Html element
        ///
        setStyle: function(element, property, value) {
            element = Scl.get(element);

            if (property.toLowerCase() == 'opacity') {
                if (typeof element.style.filter === 'string') {
                    element.style.filter = 'alpha(opacity=' + value * 100 + ')';

                    if (!element.currentStyle || !element.currentStyle.hasLayout) {
                        element.style.zoom = 1; // when no layout or cant tell
                    }
                }
            }

            element.style[property] = value;
        },

        addClass: function(element, className) {
            element = Scl.get(element);

            if (element.className == null) {
                element.className = className;
            }
            else {
                element.className = element.className + " " + className;
            }
        },

        /**
        * Ensures that the element if visible if the page has scroll bars.
        */
        scrollTo: function(element) {
            if (typeof (element) == 'string') {
                element = document.getElementById(element);
            }

            var x = 0;
            var y = 0;

            while (element != null) {
                x += element.offsetLeft;
                y += element.offsetTop;
                element = element.offsetParent;
            }

            window.scrollTo(x, y);
        },

        /**
        * Ensures that the element if visible if the page has scroll bars.
        */
        getWindowScroll: function() {
            if (Scl.isDefined(window.scrollX)) {
                return [window.scrollX, window.scrollY];
            }
            else {
                return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
            }
        },






        /**************************************************
        *
        *  AJAX
        *
        **************************************************/

        Ajax: function() {
            var instance = this;
            this.http = null;
            this.url;
            this.method;
            this.evalResult = false; // Si hay que hacer eval del resultado por ejemplo por llamar a Json
            this.parameters;
            this.serializedParameters;
            this.successCallback = null;
            this.errorCallback = null;
            this.errorMessage = "";
            this.async = true;
            this.contentType = "application/x-www-form-urlencoded";
            this.headers = {};

            this.appendHeader = function(header, value) {
                instance.headers[header] = value;
            }

            /**
            * Realiza una petición ajax
            *
            *  Ejemplo: 
             
            Scl.getAjax({ 
            url:"/gallery/share",
            parameters: { imageId:imageId },
            success: function(result){ alert("OK!: " + result); },
            error: function(result) { alert("Ha ocurrido un error al procesar la petición: " + result); }
            });  
                        
            *
            */
            this.getAjax = function(ajaxParameters) {
                instance.url = ajaxParameters.url;
                instance.parameters = ajaxParameters.parameters;
                instance.successCallback = ajaxParameters.success;
                instance.errorCallback = ajaxParameters.error;
                instance.sendRequest();
            }

            this.postAjax = function(ajaxParameters) {
                instance.url = ajaxParameters.url;
                instance.parameters = ajaxParameters.parameters;
                instance.successCallback = ajaxParameters.success;
                instance.errorCallback = ajaxParameters.error;
                instance.method = "POST";
                instance.sendRequest();
            }

            this.getJson = function(ajaxParameters) {
                instance.url = ajaxParameters.url;
                instance.parameters = ajaxParameters.parameters;
                instance.successCallback = ajaxParameters.success;
                instance.errorCallback = ajaxParameters.error;
                instance.method = "POST";
                instance.evalResult = true;
                instance.sendRequest();
            }

            this.sendRequest = function() {
                try {
                    instance.http = instance.getXmlHttp();

                    if (instance.http == null) {
                        instance.errorMessage = "Couldn't create XmlHttp Object";
                        return false;
                    }

                    if (instance.successCallback || instance.errorCallback) {
                        instance.http.onreadystatechange = instance.onReadyStateChange;
                    }

                    if (instance.parameters) {
                        instance.serializedParameters = instance.serializeParameter(instance.parameters); //.toString();  		
                    }

                    instance.method = !instance.method ? "GET" : instance.method.toUpperCase();

                    if (instance.method == "GET" && instance.serializedParameters) {
                        instance.url += "?" + instance.serializedParameters;
                    }

                    instance.http.open(instance.method, instance.url, instance.async);

                    if (instance.method == "POST") {
                        instance.appendHeader("Content-type", instance.contentType);

                        if (instance.serializedParameters) {
                            instance.appendHeader("Content-length", instance.serializedParameters.length.toString());
                        }
                    }

                    instance.appendHeader("Pragma", "no-cache");

                    for (var header in instance.headers) {
                        instance.http.setRequestHeader(header, instance.headers[header]);
                    }

                    instance.http.send(instance.serializedParameters);
                }
                catch (e) {
                    if (typeof (e) == "string") {
                        instance.errorMessage = "XmlHttp Error: " + e;
                    }
                    else {
                        instance.errorMessage = "XmlHttp Error: " + e.message;
                    }

                    instance.returnError(instance.errorMessage);

                    return false;
                }
                return true;
            }

            this.onReadyStateChange = function() {
                if (instance.http == null || instance.http.readyState != 4) {
                    return;
                }

                var errorException = null;
                var result = instance.http.responseText;

                if (instance.http.status != 200) {
                    errorException = new CallbackException(instance.http.statusText);
                }

                instance.http = null;

                if (errorException) {
                    if (instance.errorCallback) {
                        instance.errorCallback(errorException, instance);
                    }
                    return;
                }
                else if (instance.successCallback) {
                    instance.successCallback(instance.evalResult ?
			            eval('(' + result + ')') :
			            result, instance);
                }
            }

            this.getXmlHttp = function() {
                var http = null;

                if (typeof (XMLHttpRequest) != "undefined") {
                    http = new XMLHttpRequest();
                }
                else {
                    try {
                        http = new ActiveXObject("Msxml2.XMLHTTP");
                    }
                    catch (e) {
                        try {
                            http = new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        catch (e) { }
                    }
                }
                return http;
            }

            this.returnError = function(Message) {
                var errorException = new CallbackException(Message);

                if (instance.errorCallback) {
                    instance.errorCallback(errorException, instance);
                }
            }

            /*
            * Serializa un parámetro de una función
            */
            this.serializeParameter = function(value) {
                var result = [];

                function add(key, value) {
                    if (value != null) // no añadir valores null ya que se reciben en el servidor como el texto "null"
                    {
                        result[result.length] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
                    }
                };

                // If an array was passed in, assume that it is an array of form elements		        
                if (Scl.isArray(value)) {
                    // Serialize the form elements
                    Scl.each(value, function(item) {
                        add(item.name, item.value);
                    });
                }
                // Otherwise, assume that it's an object of key/value pairs
                else {
                    // Serialize the key/values
                    for (var j in value) {
                        // If the value is an array then the key names need to be repeated
                        if (Scl.isArray(value[j])) {
                            Scl.each(value[j], function(item) {
                                add(j, item);
                            });
                        }
                        else {
                            add(j, Scl.isFunction(value[j]) ? value[j]() : value[j]);
                        }
                    }
                }

                // Return the resulting serialization
                return result.join("&").replace(/%20/g, "+");
            }

            var CallbackException = function(Message) {
                this.isCallbackError = true;

                if (typeof (Message) == "object" && Message.message) {
                    this.message = Message.message;
                }
                else {
                    this.message = Message;
                }
            }
        },


        /**
        * Realiza una petición ajax con el método GET
        *
        *  Ejemplo: 
         
        Scl.getAjax({ 
        url:"/gallery/share",
        parameters: { imageId:imageId },
        success: function(result){ alert("OK!: " + result); },
        error: function(result) { alert("Ha ocurrido un error al procesar la petición: " + result); }
        });  
                    
        *
        */
        getAjax: function(ajaxParameters) {
            new Scl.Ajax().getAjax(ajaxParameters);
        },

        postAjax: function(ajaxParameters) {
            new Scl.Ajax().postAjax(ajaxParameters);
        },

        getJson: function(ajaxParameters) {
            new Scl.Ajax().getJson(ajaxParameters);
        },



















        /**************************************************
        *
        *  EVENTS
        *
        **************************************************/

        /**
        * Attaches an event to an Html element
        * @userCapture: ver https://developer.mozilla.org/en/AddEventListener
        */
        bind: function(element, evType, functionName, useCapture) {
            if (typeof (element) == 'string') {
                element = document.getElementById(element);
            }

            if (Scl.isDefined(element.addEventListener)) {
                element.addEventListener(evType, functionName, useCapture);
            }
            else if (Scl.isDefined(element.attachEvent)) {
                element.attachEvent('on' + evType, functionName);
            }
            else {
                element['on' + evType] = functionName;
            }
        },

        /**
        * Attaches a function to the window onload event
        */
        onLoad: function(functionName) {
            Scl.bind(window, 'load', functionName);
        },

        /**
        * Attaches a function to the window onload event
        */
        onUnLoad: function(functionName) {
            Scl.bind(window, 'unload', functionName);
        },

        /**
        * Prevents further propagation of the current event.
        */
        cancelBubble: function(event) {
            if (!event) var e = window.event;

            event.cancelBubble = true;

            if (event.stopPropagation) {
                event.stopPropagation();
            }
        },










        /**************************************************
        *
        *  ANIMATIONS
        *
        **************************************************/

        animate: function(parameters) {
            if (!parameters.currentStep) {
                parameters.currentStep = parameters.from;
            }

            if (!parameters.intervalSpeed) {
                parameters.intervalSpeed = 13;
            }

            var stepSize = (parameters.to - parameters.from) / parameters.steps;
            var forward = parameters.to > parameters.from;

            parameters.threadId = window.setInterval(
	            function() {
	                // llamar a la funcion que se ejecuta a cada paso
	                parameters.animationFunction(parameters);

	                // avanzar la anumacion	        
	                parameters.currentStep += stepSize;

	                // Comprobar si hay que finalizar
	                if ((forward && parameters.currentStep > parameters.to) ||
			            (!forward && parameters.currentStep < parameters.to)) {
	                    window.clearInterval(parameters.threadId);

	                    if (parameters.callback) {
	                        parameters.callback(parameters);
	                    }
	                }
	            },
		        parameters.intervalSpeed)
        },

        fadeIn: function(element, speed, callback) {
            if (!speed) {
                speed = 20;
            }

            element = Scl.get(element);

            // hacer visible para iniciar la animacion.
            Scl.setStyle(element, 'opacity', 0);
            element.style.display = 'block';

            Scl.animate({
                element: element,
                animationFunction: function(parameters) { Scl.setStyle(element, 'opacity', parameters.currentStep); },
                from: 0,
                to: 1,
                steps: speed,
                callback: callback
            });
        },

        fadeOut: function(element, speed, callback) {
            if (!speed) {
                speed = 20;
            }

            element = Scl.get(element);

            Scl.animate({
                element: element,
                animationFunction: function(parameters) { Scl.setStyle(element, 'opacity', parameters.currentStep); },
                from: 1,
                to: 0,
                steps: speed,
                callback: function(parameters) {
                    element.style.display = 'none';

                    if (callback) {
                        callback();
                    }
                }
            });
        },


        /**************************************************
        *
        *  TRATAMIENTO DE IMAGENES
        *
        **************************************************/
        
        /*
        *cambia el ancho de la imagen por el que se le pasa, si el ancho 
        *de la imagen es mayor que este
        */
        resizeImage: function(imageSelector, pxWidth) {

            if ((imageSelector != null) && (pxWidth != null)) {

                var image = $(imageSelector);

                if (image.attr("width") > pxWidth) {
                    image.attr("width", pxWidth);
                }

            }
        }



    };
}
   