var CSSStyles = {};
var QueryViewerCollection = [];
var QueryViewerCollection_index = {};

function QueryViewer()
{
    this.Parameters;
    this.ParametersStr;
    this.UseCache;
    this.FontFamily;
    this.FontSize;
    this.FontColor;
    this.AutoResize;
    this.AutoResizeType;
    this.Width;
    this.Height;
    this.ServiceUrl;
    this.Type;
    this.ChartType;
    this.Paging;
    this.PageSize;
    this.XAxisLabels;
    this.ShowValues;
    this.GenType;
    this.Object;
    this.ObjectId;
    this.ObjectName;
    this.Axes;
    this.AxesStr;
    this.DesignRenderOutputType;
    this.RealType;
    this.RealChartType;
    this.Format;
    this.FormatStr;
    this.AllowChangeAxesOrder;
    this.QueryInfo;
    this.ObjectInfo;
    this.RememberLayout;
    this.DragAndDropData;
    this.FilterChangedData;
    this.AggregationChangedData;
    this.ItemClickData;
    this.AutoRefreshGroup;
    this.ItemDoubleClickData;
    this.debugServices = false;
    this.chartSeriesCount = 0;
    this.chartXmlData = "";
    this.isfirstshow = true;
    this.HideMeasuresPropertiesBox;
    this.ExportHeader;
    this.ExportHeaderHeight;
    this.DisableExpandCollapse;
    
    this.ConvertXmlAxisTypeToSdtAxisType = function(hidden, isdimiennsion, type) 
    {
        if (hidden == true)    
            return "NotShow";
        if (!isdimiennsion)
            return "Data";
        if (type == "rows")
            return "Row";
        if (type == "columns")
            return "Column";
        return "Page";
    }

    this.getSingleElementByTagName = function(parent, name) {
        var nodes;
        var node;
        nodes = this.getMultipleElementsByTagName(parent, name);
        node = (nodes.length > 0 ? nodes[0] : null);
        return node;
    }

    this.getMultipleElementsByTagName = function(parent, name) {
        var nodes;
        var node;
        if (window.DOMParser)  // Firefox, Chrome, Opera and Safari
            nodes = parent.getElementsByTagName(name);
        else // Internet Explorer
            nodes = parent.selectNodes(name);
        return nodes;
    }

    this.getValueNode = function(node) {
        if ((node == null) || (node == undefined))
            return null;
        if ((node.firstChild != null) && (node.firstChild != undefined))
            return node.firstChild.nodeValue;
        else
            return null;
    }

    this.GetXAxisFromChart = function(XmlDoc) {
        var axes_RESULT = [];
        var atts = this.GetMetadataFromChart(XmlDoc);
        var Xaxes = atts["xAxisName"];
        var Xaxes_Array = Xaxes.split(",");
        var h = 0;
        var Xaxis = "";
        for (h = 0; h < Xaxes_Array.length; h++) {
            Xaxis = this.trim(Xaxes_Array[h]);
            var axis_SDT = {};
            axis_SDT = {Name: "", Title: "", Type: "", AxisOrder: null, Format: null};
            //axis_SDT.Name = Xaxis;    // Imposible determinar a partir del xml de la gráfica
            axis_SDT.Title = Xaxis;
            axis_SDT.Type = "Row";
            axes_RESULT.push(axis_SDT);
        }
        return axes_RESULT;
    }

    this.GetMetadataChartOneSerie = function(XmlDoc) {
        var axes_RESULT = [];
        var X_Axes = this.GetXAxisFromChart(XmlDoc);
        var j = 0;
        var num = 1;
        var sdtAxis = {};
        for (j = 0; j < X_Axes.length; j++) {
            sdtAxis = X_Axes[j];
            sdtAxis.DataField = "F" + num;
            axes_RESULT.push(X_Axes[j]);
            num++;
        }
        var atts = this.GetMetadataFromChart(XmlDoc);
        var Yaxis = atts["yAxisName"];
        var axis_SDT = {};
        axis_SDT = {Name: "", Title: "", Type: "", AxisOrder: null, Format: null};
        //axis_SDT.Name = Yaxis;    // Imposible determinar a partir del xml de la gráfica
        axis_SDT.Title = Yaxis;
        axis_SDT.Type = "Data";
        axis_SDT.DataField = "F" + num;
        axes_RESULT.push(axis_SDT);
        return axes_RESULT;
    }

    this.GetDataChartOneSerie = function(XmlDoc) {
        var XML_Result = "<OLAPData format=" + '"' + "adonet" + '"' + ">" + "<Table>";
        var i = 0;
        var setnodes = this.getMultipleElementsByTagName(xmlDoc.documentElement, "set");

        for (i = 0; i < setnodes.length; i++) {
            var XAxesValues = setnodes[i].getAttribute("name");
            var value = setnodes[i].getAttribute("value");

            var XAxesValues_Array = XAxesValues.split(",");
            var g = 0;
            var f = 1;

            XML_Result = XML_Result + "<Record>";
            for (g = 0; g < XAxesValues_Array.length; g++) {
                XML_Result = XML_Result + "<F" + f + ">" + XAxesValues_Array[g] + "</F" + f + ">";
                f++;
            }
            XML_Result = XML_Result + "<F" + f + ">" + value + "</F" + f + ">";
            XML_Result = XML_Result + "</Record>";
        }
        XML_Result = XML_Result + " </Table></OLAPData>";
        return XML_Result;
    }

    this.GetDataChartMultiSerie = function(XmlDoc) {
        var i = 0;
        var j = 0;
        var value = "";
        var n = 0;
        var setsnodes;
        var xmlresult = "<OLAPData format=" + '"' + "adonet" + '"' + ">" + "<Table>";
        var categoriesNode = this.getSingleElementByTagName(XmlDoc.documentElement, "categories");
        var categories = this.getMultipleElementsByTagName(categoriesNode, "category");
        var datasets = this.getMultipleElementsByTagName(XmlDoc.documentElement, "dataset");
        var table = new Array(datasets.length + 1);
        table[i] = new Array(categories.length);

        for (j = 0; j < categories.length; j++) {
            value = categories[j].attributes[0].value;
            table[i][j] = value;
        }
        for (n = 0; n < datasets.length; n++) {
            setsnodes = this.getMultipleElementsByTagName(datasets[n], "set");
            i++;
            j = 0;
            table[i] = new Array(categories.length);
            for (j = 0; j < setsnodes.length; j++) {
                value = setsnodes[j].attributes[0].value;
                table[i][j] = value;
            }
        }

        var f = 1;
        n = datasets.length + 1;
        for (j = 0; j < categories.length; j++) {
            xmlresult = xmlresult + "<Record>";
            f = 1;
            for (i = 0; i < n; i++) {
                xmlresult = xmlresult + "<F" + f + ">" + table[i][j] + "</F" + f + ">";
                f++;
            }
            xmlresult = xmlresult + "</Record>";
        }
        xmlresult = xmlresult + "</Table></OLAPData>";
        return xmlresult;
    }

    this.GetMetadataChartMultiSerie = function(XmlDoc) {
        var axes_RESULT = [];
        var X_Axes = this.GetXAxisFromChart(XmlDoc);
        var j = 0;
        var Y_Axis = "";
        var num = 1;
        var sdtAxis = {};
        
        for (j = 0; j < X_Axes.length; j++) {
            sdtAxis = X_Axes[j];
            sdtAxis.DataField = "F" + num;
            num++;
            axes_RESULT.push(sdtAxis);
        }

        var datasets = this.getMultipleElementsByTagName(XmlDoc.documentElement, "dataset");

        for (j = 0; j < datasets.length; j++) {
            Y_Axis = datasets[j].attributes[0].value;
            var axis_SDT = {};
            axis_SDT = {Name: "", Title: "", Type: "", AxisOrder: null, Format: null};
            //axis_SDT.Name = Y_Axis;     // Imposible determinar a partir del xml de la gráfica
            axis_SDT.Title = Y_Axis;
            axis_SDT.Type = "Data";
            axis_SDT.DataField = "F" + num;
            num++;
            axes_RESULT.push(axis_SDT);
        }
        return axes_RESULT;
    }

    this.createCookie = function (name, value, days) {
        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            var expires = "; expires=" + date.toGMTString();
        }
        else var expires = "";
            document.cookie = name + "=" + value + expires + "; path=/";
    }

    this.readCookie = function (name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }
        return null;
    }

    this.eraseCookie = function(name) {
        createCookie(name, "", -1);
    }

    this.GetMetadataChart = function() {
        
        xmlDoc = this.xmlDocument(this.chartXmlData);
        if (this.chartSeriesCount == 1)
            return this.GetMetadataChartOneSerie(xmlDoc);
         else
           return this.GetMetadataChartMultiSerie(xmlDoc);
   }

   this.GetMetadataPivotStringXML = function() {
       var UCId = this.userControlId();
       var ctl = document.getElementById(UCId);
       var result = ctl.getMetadata();
       return result;
   }

   this.GetDataPivotStringXML = function() {
       var UCId = this.userControlId();
       var ctl = document.getElementById(UCId);
       var result = ctl.getData();
       return result;
   }

   this.SetMetadataPivotStringXML = function(xmlmetadata) {
       var UCId = this.userControlId();
       var ctl = document.getElementById(UCId);
       ctl.setMetadata(xmlmetadata);
   }

   this.SetMetadataPivotStringXMLState = function(xmlmetadata) {
       var UCId = this.userControlId();
       var ctl = document.getElementById(UCId);
       ctl.setMetadata(xmlmetadata, false, true);
   }

   this.SetDataPivotStringXML = function(xmldata) {
       var UCId = this.userControlId();
       var ctl = document.getElementById(UCId);
       ctl.setData(xmldata);
   }

   this.GetMetadataPivot = function() {
       var UCId = this.userControlId();
       var ctl = document.getElementById(UCId);
       var result = ctl.getMetadata();

       xmlDoc = this.xmlDocument(result); 

       var axes = [];
       var axistype = "";

       for (i = 0; i < xmlDoc.documentElement.childNodes.length; i++) {

           var xmlqueryelement = xmlDoc.documentElement.childNodes[i];
           if ((xmlqueryelement.nodeName == "OLAPDimension") || (xmlqueryelement.nodeName == "OLAPMeasure")) {

               var name = this.getValueNode(this.getSingleElementByTagName(xmlqueryelement, "name"));
               var displayName = this.getValueNode(this.getSingleElementByTagName(xmlqueryelement, "displayName"));
               var dataField = this.getValueNode(this.getSingleElementByTagName(xmlqueryelement, "dataField"));
               var hidden = this.getValueNode(this.getSingleElementByTagName(xmlqueryelement, "hidden"));
               var picture = this.getValueNode(this.getSingleElementByTagName(xmlqueryelement, "picture"));

               var includevalues = [];

               if (xmlqueryelement.nodeName == "OLAPDimension") {

                   var defaultPosition = this.getValueNode(this.getSingleElementByTagName(xmlqueryelement, "defaultPosition"));
                   axistype = this.ConvertXmlAxisTypeToSdtAxisType(hidden, true, defaultPosition);

                   var include = this.getSingleElementByTagName(xmlqueryelement, "include");

                   for (j = 0; j < include.childNodes.length; j++) {
                       if (include.childNodes[j].firstChild != null) {
                       if (include.childNodes[j].firstChild.nodeValue.toUpperCase() != "TOTAL")
                           includevalues.push(include.childNodes[j].firstChild.nodeValue);
                       }
                   }
               }
               else {
                   axistype = this.ConvertXmlAxisTypeToSdtAxisType(hidden, false, "");
               }

               var Filter = { Values: null };
               Filter.Values = includevalues;

               var Format = { Picture: "", Color: -1 };
               Format.Picture = picture;

               var axis = {};
               axis = { Name: "", Title: "", Type: "", AxisOrder: null, Format: null };
               axis.Name = name;
               axis.Title = displayName;
               axis.DataField = dataField;
               axis.Type = axistype;
               axis.Filter = Filter;
               axis.Format = Format;
               axes.push(axis);
           }
       }

       return axes;
   }

	this.GetMetadata = function() {
	    var ischart = (this.RealType == "Chart");
	    if (!ischart)
	        return this.GetMetadataPivot();
	    else
	        return this.GetMetadataChart();
	}

    this.GetMetadataFromChart = function(xmlDoc) {
        var result = new Array();
        for (i = 0; i < xmlDoc.documentElement.attributes.length; i++) 
            result[xmlDoc.documentElement.attributes[i].nodeName] = xmlDoc.documentElement.attributes[i].nodeValue;
        return result;
    }

    this.SetMetadataExecutingQuery = function(axes) {
        this.Axes = axes;
        this.realShow();
    }

    this.GetParameterinCollection = function(parameteroraxis, parametercollection) {

        var found = false;
        var i = 0;

        while ((!found) && (i < parametercollection.length)) {
            if (parametercollection[i].Name == parameteroraxis.Name)
                found = true;
            else
                i++;
        }

        if (found)
            return parametercollection[i];
        else
            return null;

    }

    this.GetIncludedValuesForAxis = function(Axis) {
        var result = "[";
        var i = 0;
        for (i = 0; i < Axis.Filter.Values.length - 1; i++) {
            result = result + '"' + Axis.Filter.Values[i] + '"' + ",";
        }

        if (Axis.Filter.Values.length - 1 >= 0)
            result = result + '"' + Axis.Filter.Values[Axis.Filter.Values.length - 1] + '"';

        result = result + "]";
        return result;

    }

    this.GetParameterValues = function(parameters, metadata) {
        // Mergea los valores de los paramtros deacuerdo a 3 variables
        // parameters ==> Con los valores por defecto de los parametros (ultimo nivel de prioridad)
        // this.Parameters ==> Con los valores que le pasa el usuario para ciertos parametros (nivel medio de prioridad)
        //metadata ==> Metadata de la Query asociada al autorefresgroup

        var parameterresult = [];
        var i = 0;
        var item = null;
        for (i = 0; i < parameters.length; i++) {
            // Busco el parametro en la collection de Axis de la Query asociada
            item = this.GetParameterinCollection(parameters[i], metadata);
            if (item != null) {
                // Existe un Eje con este nombre tiene la prioridad
                var value = this.GetIncludedValuesForAxis(item);
                var param = parameters[i];
                param.Value = value;
                parameterresult.push(param);
            }
            else {
                // NO existe un Eje con este nombre busco a ver si hay un parametro que le pasa el usuario
                item = this.GetParameterinCollection(parameters[i], this.Parameters);
                if (item != null) {
                    var param = parameters[i];
                    param.Value = item.Value;
                    parameterresult.push(param);

                }
                else {
                    // NO existe un parametro pasado por el usuario , se ejecuta con el valor por defecto
                    parameterresult.push(parameters[i]);
                }
            }

        } // for
        return parameterresult;
    }

    this.SetMetadataExecutingDifferentQuery = function(metadata) {
        var parametersXML = this.getQueryParameters();
        var parameters = this.GetParametersFromXML(parametersXML);
        var realparameters = this.GetParameterValues(parameters, metadata);
        this.Refresh(realparameters);
    }

    this.GetParametersFromXML = function(XMLparameters) {

        xmlDoc = this.xmlDocument(XMLparameters);

        var parameters = [];
        var i = 0;
        var parameter = {};
        parameter = { Name: "", Description: "", Type: "", IsCollection: true, Value: "" };

        var paramsnodes;

	if (this.GenType == "Ruby")
		paramsnodes = this.getMultipleElementsByTagName(xmlDoc.documentElement, "Item");
	else
		paramsnodes = this.getMultipleElementsByTagName(xmlDoc.documentElement, "gxpl_Parameter");

        for (i = 0; i < paramsnodes.length; i++) {

            parameter = {};
            parameter.Name = this.getValueNode(this.getSingleElementByTagName(paramsnodes[i], "Name"));
            parameter.Description = this.getValueNode(this.getSingleElementByTagName(paramsnodes[i], "Description"));
            parameter.Type = this.getValueNode(this.getSingleElementByTagName(paramsnodes[i], "Type"));
            parameter.IsCollection = this.getValueNode(this.getSingleElementByTagName(paramsnodes[i], "IsCollection"));
            parameter.Value = this.getValueNode(this.getSingleElementByTagName(paramsnodes[i], "Value"));
            parameters.push(parameter);
        }
        return parameters;
    }

    this.SetMetadataForPivotTable = function(UC) {
        var newmetadataXML = UC.GetMetadataPivotStringXML();
        var dataXML = UC.GetDataPivotStringXML();
        this.SetMetadataPivotStringXMLState(newmetadataXML);
        this.SetDataPivotStringXML(dataXML);
        this.RefreshPivot();
    }

	this.GetData = function() {
	    var ischart = (this.RealType == "Chart");
	    if (!ischart)
	        return this.GetDataPivot();
	    else
	        return this.GetDataChart();
	}

	this.GetDataPivot = function() {
	    var UCId = this.userControlId();
	    var ctl = document.getElementById(UCId);
	    var result = ctl.getData();
	    return result;
	}

	this.GetDataChart = function() {
	    xmlDoc = this.xmlDocument(this.chartXmlData);
	    if (this.chartSeriesCount == 1)
	        return this.GetDataChartOneSerie(xmlDoc);
	    else
	        return this.GetDataChartMultiSerie(xmlDoc);
	}

	this.GetFilteredDataPivot = function() {
	    var UCId = this.userControlId();
	    var ctl = document.getElementById(UCId);
	    var result = ctl.getFilteredData();
	    return result;
	}

	this.GetFilteredData = function() {
	    var ischart = (this.RealType == "Chart");
	    if (!ischart)
	        return this.GetFilteredDataPivot();
	    else
	         return this.GetDataChart();  // en las Charts coincide el GetData con el GetFilteredData
	}
	
	this.SetDragAndDropData = function(data) 
	{
	    this.DragAndDropData = data;
	}

	this.GetDragAndDropData = function() 
	{
	    return this.DragAndDropData;
	}
	
	this.SetFilterChangedData = function(data) 
	{
	    this.FilterChangedData = data;
	}

	this.GetFilterChangedData = function() 
	{
	    return this.FilterChangedData;
	}

	this.SetAggregationChangedData = function(data) 
	{
	    this.AggregationChangedData = data;
	}

	this.GetAggregationChangedData = function() 
	{
	    return this.AggregationChangedData;
	}

	this.SetItemClickData = function(data) 
	{
	    this.ItemClickData = data;
	}

	this.GetItemClickData = function() 
	{
	    return this.ItemClickData;
	}

	this.SetItemDoubleClickData = function(data) 
	{
	    this.ItemDoubleClickData = data;
	}

	this.GetItemDoubleClickData = function() 
	{
	    return this.ItemDoubleClickData;
	}

	this.SetParameters = function(data) 
	{
	    this.Parameters = data;
	}

	this.GetParameters = function() 
	{
	    return this.Parameters;
	}

    this.SetFormat = function(data) {
        this.Format = data;
    }

    this.GetFormat = function() {
        return this.Format;
    }    

    this.SetAxes = function(data) {
        this.Axes = data;
    }

    this.GetAxes = function() {
        return this.Axes;
    }

    this.Refresh = function(parameters) {
        this.Parameters = parameters;
        this.realShow();
        var ischart = (this.RealType == "Chart");
        if (!ischart)
            this.RefreshPivot();
    }

    this.RefreshPivot = function() {
        var UCId = this.userControlId();
        var ctl = document.getElementById(UCId);
        ctl.refresh();
    }

    this.show = function() {

        if (QueryViewerCollection_index[this.userControlId()] == undefined) {
            QueryViewerCollection.push(this);
            QueryViewerCollection_index[this.userControlId()] = this;
        }

        this.isfirstshow = true;
        this.realShow();
        this.isfirstshow = false;

    }
        
        
    this.realShow = function() {    
        if (gx.lang.gxBoolean(this.Visible)) {

            this.getContainerControl().style.display = "";

            // Load messages for language
            loadMessages();

            // Verify Parameters and Axes properties
            this.VerifyCustomProperties();

            FlashInstalled = this.DetectFlashPlayer();
            if (FlashInstalled) {
                // Calculate this.GenType
                this.GenType = this.getGenerator();

                if ((this.Type != undefined) && (this.Type != ""))
                    this.RealType = this.Type;
                else
                    this.RealType = "Table";

                if ((this.ChartType != undefined) && (this.ChartType != ""))
                    this.RealChartType = this.ChartType;
                else
                    this.RealChartType = "";

                if (this.GenType == "C#" || this.GenType == "Java" || this.GenType == "Ruby") {
                    if (this.Type == "Table")
                        this.tryToRenderTable();
                    else {
                        if (this.Type == "PivotTable")
                            this.tryToRenderPivotTable();
                        else {
                            if (this.Type == "Default") {

                                var output = this.getDefaultOutput();
                                if ((output != "Table") && (output != "PivotTable")) {
                                    this.RealType = "Chart";
                                    this.RealChartType = output;
                                }
                                else
                                    this.RealType = output;

                                if (this.RealType == "Table") {
                                    this.Paging = true;
                                    this.PageSize = 10;
                                    this.tryToRenderTable();
                                }
                                else {
                                    if (this.RealType == "PivotTable") {
                                        this.Paging = true;
                                        this.PageSize = 10;
                                        this.tryToRenderPivotTable();
                                    }
                                    else
                                        this.tryToRenderChart();
                                }

                            }

                            else
                                this.tryToRenderChart();
                        }
                    }
                }
                else
                    this.renderError(getMessage("QViewerGenNotImplemented"));
            }
            else
                this.renderFlashError();
        }
        else
            this.getContainerControl().style.display = "none";
    }
   
    this.baseUrl = function() {
        return location.href.substr(0, location.href.lastIndexOf('/') + 1);
    }

    this.VerifyCustomProperties = function() {
        if (this.AxesStr == undefined) this.AxesStr = "";
        if (this.ParametersStr == undefined) this.ParametersStr = "";
        if (this.FormatStr == undefined) this.FormatStr = "";
    }

    this.isGeneXusPreview = function() {
        return (window.external.Text != undefined);
    }

    this.GetJavaBaseUrl = function(staticContent) {
        var baseUrl = new String(document.location);
        var i = baseUrl.lastIndexOf("/");
        baseUrl = baseUrl.substring(0, i);
        if (staticContent)
        {
            i = baseUrl.lastIndexOf("/");
            baseUrl = baseUrl.substring(0, i);
            baseUrl += this.staticDirectory();
        }
        else
            baseUrl += "/";
        return baseUrl;
    }

    this.staticDirectory = function() {
        if (gx.staticDirectory != "")
            return gx.staticDirectory;
        else
            return this.getCookie('StaticContent');
    }

    this.getHtmlColor = function(color) {
        var htmlColor;
        if ((typeof (color) == "string") || (typeof (color) == "number")) {
            if (gx.color.toHex) {
                if (color == -1)                                // -1 = null color
                    htmlColor = "";
                else
                    htmlColor = "#" + gx.color.toHex(color);       // GeneXus X Ev. 1
            }
            else
                htmlColor = "#" + gxToHex(color)               // GeneXus X
        }
        else
            htmlColor = (color == undefined ? "#000000" : color.Html);
        return htmlColor;
    }
    
    this.parseCSSColor = function(color) {
        if (color.substring(0,3) == "rgb")
        {
            var values = color.replace("rgb","").replace("(","").replace(")","").split(",");
            var numColor = gx.color.rgb(parseInt(values[0]), parseInt(values[1]), parseInt(values[2]));
            return this.getHtmlColor(numColor);
        }
        else
            return color;
    }

    this.foolCache = function() {
        var currentTime = new Date();
        var miliSecs = currentTime.getTime();
        return miliSecs;
    }

    this.DoDynamicRefresh = function() {

        var my_refreshgroup = this.AutoRefreshGroup;

        if ((my_refreshgroup != undefined) && (my_refreshgroup != null) && (my_refreshgroup != "") && (this.trim(my_refreshgroup) != "")) {

            for (t = 0; t < QueryViewerCollection.length; t++) {
                var ucqueryviewer = QueryViewerCollection[t];
                if (ucqueryviewer.userControlId() != this.userControlId()) {

                    if (my_refreshgroup == ucqueryviewer.AutoRefreshGroup) {
                        // In same Refresh Group
                        var metadata = this.GetMetadata(); 
                        if ((this.ObjectId == ucqueryviewer.ObjectId) || (this.ObjectName == ucqueryviewer.ObjectName)) {
                            if (((this.RealType == ucqueryviewer.RealType) && (this.RealType == "PivotTable")) || ((this.RealType == ucqueryviewer.RealType) && (this.RealType == "Table")) || ((this.RealType != ucqueryviewer.RealType) && ((ucqueryviewer.RealType == "PivotTable") || (ucqueryviewer.RealType == "Table"))))
                                ucqueryviewer.SetMetadataForPivotTable(this);
                            else
                                ucqueryviewer.SetMetadataExecutingQuery(metadata);
                        }
                        else {
                            ucqueryviewer.SetMetadataExecutingDifferentQuery(metadata); 
                        }

                    } //  if (my_refreshgroup == ucqueryviewer.AutoRefreshGroup)
                } //  if (ucqueryviewer.ContainerName + "_" + ucqueryviewer.ControlName != this.ContainerName + "_" + this.ControlName

            } // for
        } //  if ((my_refreshgroup != undefined) && (my_refreshgroup != null) && (my_refreshgroup != "") && (this.trim(my_refreshgroup) != ""))

    }  // method

    this.selectXPathNode = function(xmlDoc, xpath) {
        var nodes;
        var node;
        if (xmlDoc.evaluate) {    // Firefox, Chrome, Opera and Safari
            nodes = xmlDoc.evaluate(xpath, xmlDoc, null, XPathResult.ANY_TYPE, null);  
            node = nodes.iterateNext();
         }   
        else {                   // Internet Explorer
            nodes = xmlDoc.selectNodes(xpath);
            node = (nodes.length > 0 ? nodes[0] : null);
        }
        return node;
    }
    
    this.onDragAndDropEvent = function(data) {
        var position;
        if (this.RealType == "PivotTable") {
            // Dynamic Refresh
            this.DoDynamicRefresh();
            if (this.isGeneXusPreview()) window.external.Text = data;
            if (this.DragAndDrop) {
                var xml_doc = this.xmlDocument(data);
                var Node = this.selectXPathNode(xml_doc, "/DATA");
                this.DragAndDropData.Name = Node.getAttribute("name");
                position = Node.getAttribute("position");
                this.DragAndDropData.Axis = (position == "rows" ? "Row" : (position == "columns" ? "Column" : "Page"));
                this.DragAndDrop();
            }
        }
    }

    this.onAggregatorChangedEvent = function(data) {
        var aggregator;
        if (this.RealType == "PivotTable") {
            if (this.AggregationChanged) {
                var xml_doc = this.xmlDocument(data);
                var Node = this.selectXPathNode(xml_doc, "/DATA");
                this.AggregationChangedData.Name = Node.getAttribute("name");
                aggregator = Node.getAttribute("aggregator");
                this.AggregationChangedData.Aggregation = (aggregator == "sum" ? "Sum" : (aggregator == "average" ? "Average" : (aggregator == "count" ? "Count" : (aggregator == "maximum" ? "Max" : "Min"))));
                this.AggregationChanged();
            }
        }
    }

    this.onValuesChangedEvent = function(data) {
        // Dynamic Refresh
        this.DoDynamicRefresh();
        if (this.FilterChanged) {
            var xml_doc = this.xmlDocument(data);
            var Node = this.selectXPathNode(xml_doc, "/DATA");
            this.FilterChangedData.Name = Node.getAttribute("name");
            this.FilterChangedData.SelectedValues = [];
            var valueIndex=-1;
            for (var i=0; i<Node.childNodes.length; i++)
                if (Node.childNodes[i].nodeName == "VALUE")
                {
                    valueIndex++;
                    this.FilterChangedData.SelectedValues[valueIndex] = Node.childNodes[i].firstChild.nodeValue;
                }
            this.FilterChanged();
        }
    }

    this.onItemClickEvent = function(data, isDoubleClick) {
        var location;
        var eventData;
        if ((this.ItemClick && !isDoubleClick)|| (this.ItemDoubleClick && isDoubleClick)) {
            eventData = (isDoubleClick ? eventData = this.ItemDoubleClickData : this.ItemClickData);
            var xml_doc = this.xmlDocument(data);
            var Node1 = this.selectXPathNode(xml_doc, "/DATA/ITEM");
            var Node2 = this.selectXPathNode(xml_doc, "/DATA/CONTEXT/RELATED");
            var Node3 = this.selectXPathNode(xml_doc, "/DATA/CONTEXT/FILTERS");
            eventData.Name = Node1.getAttribute("name");
            location = Node1.getAttribute("location");
            eventData.Axis = (location == "rows" ? "Row" : (location == "columns" ? "Column" : (location == "pages" ? "Page" : "Data")));
            eventData.Value = (Node1.firstChild != null ? Node1.firstChild.nodeValue : "");
            eventData.Context = this.loadItems(Node2);
            eventData.Filters = this.loadItems(Node3);
            if (isDoubleClick)
                this.ItemDoubleClick();
            else
                this.ItemClick();
        }
    }

    this.loadItems = function(Node) {
        var Items = [];
        if (Node != null) {
            var itemIndex = -1;
            for (var i=0; i<Node.childNodes.length; i++)
            {
                if (Node.childNodes[i].nodeName == "ITEM") {
                    itemIndex++;
                    Items[itemIndex] = {};
                    Items[itemIndex].Name = Node.childNodes[i].getAttribute("name");
                    Items[itemIndex].Values = [];
                    var valueIndex = -1;
                    // Seek VALUES node
                    var valuesNode = Node.childNodes[i];     // ITEM
                    for (var j=0; j< Node.childNodes[i].childNodes.length; j++)
                        if (Node.childNodes[i].childNodes[j].nodeName == "VALUES")
                        {
                            valuesNode = Node.childNodes[i].childNodes[j];
                            break;
                        }
                    // Seek VALUE nodes
                    for (var j=0; j< valuesNode.childNodes.length; j++)
                        if (valuesNode.childNodes[j].nodeName == "VALUE")
                        {
                            valueIndex++;    
                            Items[itemIndex].Values[valueIndex] = (valuesNode.childNodes[j].firstChild != null ? valuesNode.childNodes[j].firstChild.nodeValue : "");
                        }
                }
            }
        }
        return Items;
    }
    
    this.onResizeEvent = function(ctl, info) {
        if (gx.lang.gxBoolean(this.AutoResize)) {
            switch (this.AutoResizeType) {

                case "Horizontal":
                    ctl.setScrollPolicy('off', 'auto');
                    var dim = info.data.split(';');
                    ctl.width = dim[0];
                    break;

                case "Vertical":
                    ctl.setScrollPolicy('auto', 'off');
                    var dim = info.data.split(';');
                    ctl.height = dim[1];
                    break;
                default:
                    var dim = info.data.split(';');
                    ctl.width = dim[0];
                    ctl.height = dim[1];
                    break;
            }
        }
    }

    this.AdjustSize = function()    // Para las salidas que no soportan AutoResize
    {
        if (gx.lang.gxBoolean(this.AutoResize)) {
            this.Width = "580";
            this.Height = "470";
        }
    }

    this.getSessionKey = function() {
        var sessionKey;
        try {
            if (this.getGXVersion() == "10.0")
                sessionKey = GXGetHidden("GX_AJAX_KEY").toLowerCase();          // GeneXus X
            else
                sessionKey = gx.sec.key.toLowerCase();                          // GeneXus X Ev. 
        }
        catch (e) {
            sessionKey = "";        // En Ruby no hay encriptación
        };
        return sessionKey;
    }

    function getmetaContents(mn) {
        var m = document.getElementsByTagName('meta');
        for (i = 0; i < m.length; i++)
            if (m[i].name == mn) return m[i].content;
    }

    this.getGXVersion = function() {
        var gxVersion = getmetaContents("Version");
        gxVersion = gxVersion.substring(0, 4).replace("_", ".");
        return gxVersion;
    }

    this.getGenerator = function() {
        var gen;
        if (gx.gen.isDotNet())
            gen = "C#";
        else if (gx.gen.ruby)
            gen = "Ruby";
        else
            gen = "Java";
        return gen;
    }

    this.fixSize = function(size) {
        return size.replace("px", "");
    }

    this.userControlId = function() {
        return this.ContainerName + "_" + this.ControlName;        // Nombre único y diferente al contenedor
    }

    // ---------------------------------------- Error ----------------------------------------

    this.DetectFlashPlayer = function() 
    {
        // Versión mínima requerida por la PivotTable (FusionCharts requiere una versión menor)
        var requiredMajorVersion = 10;
        var requiredMinorVersion = 0;
        var requiredRevision = 0;
        var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
        return hasReqestedVersion;
    }

    this.renderFlashError = function() 
    {
        var errMsg;
        if (this.isGeneXusPreview())
            errMsg = getMessage("QViewerFlashRequiredGX");
        else
            errMsg = getMessage("QViewerFlashRequiredRuntime");
        this.renderError(errMsg);
    }

    this.renderError = function(errMsg) 
    {
        if (this.isGeneXusPreview())                // Preview en GeneXus (se muestra en el output)
            window.external.Text = errMsg;
        else                                        // Aplicación generada
        {           
            this.AdjustSize(); 
            var buffer = "<table height=" + this.fixSize(this.Height) + " width =" + this.fixSize(this.Width) + " style=\"border-right: silver thin solid; border-top: silver thin solid; border-left: silver thin solid; border-bottom: silver thin solid; font-size: " + this.FontSize + "px; color: " + this.getHtmlColor(this.FontColor) + "; font-family: " + this.FontFamily + "\"><tbody><tr><td align=center>" + getMessage("QViewerError") + ": " + errMsg + "</td></tr></tbody></table>";
		    this.setHtml(buffer);
		}
	}

    this.getErrorFromText = function(resultText)
    {
        if (resultText == "<Result OK=\"True\"></Result>")
            return "";              // No hubo error
        else
            return resultText.replace("<Result OK=\"False\"><Dsc>", "").replace("</Dsc></Result>", "");
    }

    this.anyError = function(resultText) 
    {
        return (resultText.indexOf("<Result OK=\"False\"><Dsc>") == 0);
    }

    // --------------------------------------- General ---------------------------------------

    this.getDefaultOutput = function() {
        var src = this.getDefaultOutputURL();
        var output = "";
        var postInfo = this.DefaultOutputPostInfo();
        var xmlHttp = this.getXMLHttpRequest();
        xmlHttp.open("POST", src, false); // sync
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttp.send(postInfo);
        output = xmlHttp.responseText;
        return output;
    }

    this.getDefaultOutputURL = function() {
        var urlParam;
        if (this.GenType == "") this.GenType = "C#";
        var foolCache = this.foolCache();   // Para que el explorador no cachee los resultados de los servicios

        switch (this.GenType) {
            case "C#":
                return this.baseUrl() + "agxpl_getdefaultoutput.aspx?" + foolCache;
            case "Java":
                return this.GetJavaBaseUrl(false) + "agxpl_getdefaultoutput?" + foolCache;

            case "Ruby":
                return this.baseUrl() + "gxruby/GXplorerServices.gxpl_getdefaultoutput?" + foolCache;
            default:
                return "";
        }
    }
    
    this.replaceCssClasses = function(xml) {
        var replaceMarker = "gxpl_cssReplace(";
        while ((posIni = xml.indexOf(replaceMarker)) >= 0){
            posFin = xml.indexOf(")", posIni);
            className = xml.substring(posIni + replaceMarker.length, posFin);
            style = this.getCSSStyle(className);
            toReplace = xml.substring(posIni, posFin+1);
            xml = xml.replace(toReplace, style);
        }
        return xml;
    }
    
    this.getCSSStyle = function(className) {
      	if (CSSStyles[className] != undefined) 
	    	return CSSStyles[className];
    	else {
    	    styleObj = this.loadCSSStyle(className);
    	    if (styleObj != undefined)
    	    {
    	        styleTransformed = this.transformCSSStyle(styleObj)
    	        CSSStyles[className] = styleTransformed;
    	        return styleTransformed;
    	    }
    	    else
    	        return "";
    	}
    }
    
    this.loadCSSStyle = function(className) {
        var css;
        var cssName = gx.theme + ".css";
        var cssFound = false;
        var styleObj;
        for (var i=0; i<document.styleSheets.length; i++)
            if (document.styleSheets[i].href.indexOf(cssName) >= 0) {
                cssFound = true;
                css = document.styleSheets[i];
                break;
            }
        if (cssFound)
            if (css.cssRules)
                crossRules = css.cssRules;
            else if (css.rules)
                crossRules = css.rules;
            for (var i=0; i<crossRules.length; i++) {
                var rule = crossRules[i];
                if (rule.selectorText.toLowerCase().indexOf("." + className.toLowerCase()) == 0)
                    styleObj = rule.style;
            }
        return styleObj;
    }
    
    this.transformCSSStyle = function(styleObj) {
        var strAux = "";
        if (styleObj.color != "")              strAux += (strAux == "" ? "" : ";") + "color:"            + this.parseCSSColor(styleObj.color);
        if (styleObj.backgroundColor != "")    strAux += (strAux == "" ? "" : ";") + "backgroundColor:"  + this.parseCSSColor(styleObj.backgroundColor);
        if (styleObj.borderStyle != "")        strAux += (strAux == "" ? "" : ";") + "borderStyle:"      + styleObj.borderStyle;
        if (styleObj.borderWidth != "")        strAux += (strAux == "" ? "" : ";") + "borderThickness:"  + styleObj.borderWidth.replace("pt", "").replace("px", "");
        if (styleObj.borderColor != "")        strAux += (strAux == "" ? "" : ";") + "borderColor:"      + this.parseCSSColor(styleObj.borderColor);
        //if (styleObj.paddingLeft != "")        strAux += (strAux == "" ? "" : ";") + "paddingLeft:"      + styleObj.paddingLeft.replace("pt", "").replace("px", "");
        //if (styleObj.paddingRight != "")       strAux += (strAux == "" ? "" : ";") + "paddingRight:"     + styleObj.paddingRight.replace("pt", "").replace("px", "");
        //if (styleObj.paddingTop != "")         strAux += (strAux == "" ? "" : ";") + "paddingTop:"       + styleObj.paddingTop.replace("pt", "").replace("px", "");
        //if (styleObj.paddingBottom != "")      strAux += (strAux == "" ? "" : ";") + "paddingBottom:"    + styleObj.paddingBottom.replace("pt", "").replace("px", "");
        if (styleObj.fontFamily != "")         strAux += (strAux == "" ? "" : ";") + "fontFamily:"       + styleObj.fontFamily.replace(/"/g,"").replace(/'/g,""); 
        if (styleObj.fontSize != "")           strAux += (strAux == "" ? "" : ";") + "fontSize:"         + styleObj.fontSize.replace("pt", "").replace("px", "");
        if (styleObj.fontWeight != "")         strAux += (strAux == "" ? "" : ";") + "fontWeight:"       + styleObj.fontWeight;
        if (styleObj.fontStyle != "")          strAux += (strAux == "" ? "" : ";") + "fontStyle:"        + styleObj.fontStyle;
        if (styleObj.textDecoration != "")     strAux += (strAux == "" ? "" : ";") + "textDecoration:"   + styleObj.textDecoration;
        //if (styleObj.textAlign != "")          strAux += (strAux == "" ? "" : ";") + "textAlign:"        + styleObj.textAlign;
        
        // Faltan
        //		backgroundAlpha		= "1"			// 0 .. 1
        //		cornerRadius		= "0" 			// 0 .. n
        //		dropShadowEnabled	= "true"		// true | false
        //		shadowDirection		= "right"		// left | right | center
        return strAux;
    }
    
    // ---------------------------------------- Table ----------------------------------------

    this.tryToRenderTable = function() 
    {
		this.tryToRenderPivotTable();    // same render
	}
		
    // --------------------------------------Pivot Table -------------------------------------
   
    this.GetPivotURLControl = function()
    {
        switch (this.GenType)
        {
            case "C#":
                return "QueryViewer/xpertPivot/xpertPivot.swf"
                
            case "Java":
                return this.GetJavaBaseUrl(true) + "QueryViewer/xpertPivot/xpertPivot.swf";
            case "Ruby":
                return "QueryViewer/xpertPivot/xpertPivot.swf"
            default:
                return "QueryViewer/xpertPivot/xpertPivot.swf"
        }
    }

    this.BelongAnyAutoRefreshGroup = function(){
        var my_refreshgroup = this.AutoRefreshGroup;
        return ((my_refreshgroup != undefined) && (my_refreshgroup != null) && (my_refreshgroup != "") && (this.trim(my_refreshgroup) != ""));
    }
    

    this.tryToRenderPivotTable = function() {
        var errMsg = "";

        // Si hay que traer el estado salvado de la metadata se trae
        if ((this.RememberLayout) && (this.isfirstshow) && (this.BelongAnyAutoRefreshGroup()))
            this.loadQueryAxesAndParametersState();

        // Ejecuto el primer servicio y verifico que no haya habido error
        var d1 = new Date();
        var t1 = d1.getTime();
        var resText = this.calculatePivottableMetadata();
        var d2 = new Date();
        var t2 = d2.getTime();
        if (!this.anyError(resText)) {
            pivotTableMetadata = resText;
            if (!this.isfirstshow)
                this.SetMetadataPivotStringXMLState(pivotTableMetadata);
            // Ejecuto el segundo servicio y verifico que no haya habido error
            var resText = this.calculatePivottableData();
            var d3 = new Date();
            var t3 = d3.getTime();
            if (!this.anyError(resText)) {
                pivotTableData = resText;
                this.saveQueryAxesAndParametersState();
                if (this.debugServices)
                    this.renderPivotServices(pivotTableMetadata, pivotTableData, t2 - t1, t3 - t2);
                else
                    this.renderPivotTable_JS(pivotTableMetadata, pivotTableData);
            }
            else {
                errMsg = this.getErrorFromText(resText);
                this.renderError(errMsg);
            }
        }
        else {
            errMsg = this.getErrorFromText(resText);
            this.renderError(errMsg);
        }
    }

    this.calculatePivottableMetadata = function() {
        var src = this.getPivotTableMetadataURL();
        var xml = "";
        var postInfo = this.PivottableMetadataPostInfo();
        var xmlHttp = this.getXMLHttpRequest();
        xmlHttp.open("POST", src, false); // sync
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttp.send(postInfo);
        xml = this.replaceCssClasses(xmlHttp.responseText);
        return xml;
    }

    this.calculatePivottableData = function() {
        var src = this.getPivotTableDataURL();
        var xml = "";
        var postInfo = this.PivottableDataPostInfo();
        var xmlHttp = this.getXMLHttpRequest();
        xmlHttp.open("POST", src, false); // sync
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttp.send(postInfo);
        xml = xmlHttp.responseText;
        return xml;
    }

    this.getColorsForPivotOrTable = function(backColor) {
        var colors = new Array(4);
        var colorsdefault = new Array(4);

        for (i = 0; i < 4; i++) {
            colors[i] = backColor;
            colorsdefault[i] = true;
        }

        for (i = 0; this.Axes[i] != undefined; i++) {
            if (this.Axes[i].Format != undefined) {
                if (this.Axes[i].Format.Color != undefined) {
                    if (this.Axes[i].Format.Color != "") {
                        if (this.Axes[i].Type != undefined) {
                            if (this.Axes[i].Type != "") {
                                switch (this.Axes[i].Type) {
                                    case "Row":
                                        if (colorsdefault[1])
                                            colors[1] = this.Axes[i].Format.Color;
                                        break;
                                    case "Column":
                                        if (colorsdefault[2])
                                            colors[2] = this.Axes[i].Format.Color;
                                        break;
                                    case "Page":
                                        if (colorsdefault[0])
                                            colors[0] = this.Axes[i].Format.Color;
                                        break;

                                    case "Data":

                                        if (colorsdefault[3])
                                            colors[3] = this.Axes[i].Format.Color;
                                        break;
                                }

                            }
                        }
                    }
                }
            }
        }

        return colors;
    }

    this.renderPivotTable_JS = function(pivotTableMetadata, pivotTableData) {
        var UCId = this.userControlId();
        this.pivotTableMetadata = pivotTableMetadata;
        this.pivotTableData = pivotTableData;
        var cssName = "xpertCube.css";
        var language = (gx.languageCode == "German" ? "ger" : gx.languageCode);
        var emptyCell = "";
        var backColor = "#FFFFFF";
        var container = this.getContainerControl();
        var autorefresh = true;
        var verticalPageSize = (this.Paging ? this.PageSize : 0);
        var horizontalPageSize = (this.Paging ? this.PageSize : 0);
        var urlControl = this.GetPivotURLControl();

        var colors = this.getColorsForPivotOrTable(backColor);

        swf(UCId,
            urlControl,
            this.Left, this.Top, this.fixSize(this.Width), this.fixSize(this.Height), '',
            function(ctl) {
                if (ctl.configServices) ctl.configServices('', '', '', cssName, language, emptyCell, (QueryViewerCollection_index[ctl.id].RealType == "Table"), autorefresh, verticalPageSize, horizontalPageSize, 'GET', false, !gx.lang.gxBoolean(QueryViewerCollection_index[ctl.id].HideMeasuresPropertiesBox), QueryViewerCollection_index[ctl.id].ExportHeader, QueryViewerCollection_index[ctl.id].ExportHeaderHeight,!gx.lang.gxBoolean(QueryViewerCollection_index[ctl.id].DisableExpandCollapse))
                if (ctl.configStyle) ctl.configStyle(QueryViewerCollection_index[ctl.id].FontFamily, QueryViewerCollection_index[ctl.id].FontSize, QueryViewerCollection_index[ctl.id].getHtmlColor(QueryViewerCollection_index[ctl.id].FontColor), colors[0], QueryViewerCollection_index[ctl.id].FontFamily, QueryViewerCollection_index[ctl.id].FontSize, QueryViewerCollection_index[ctl.id].getHtmlColor(QueryViewerCollection_index[ctl.id].FontColor), colors[1], QueryViewerCollection_index[ctl.id].FontFamily, QueryViewerCollection_index[ctl.id].FontSize, QueryViewerCollection_index[ctl.id].getHtmlColor(QueryViewerCollection_index[ctl.id].FontColor), colors[2], QueryViewerCollection_index[ctl.id].FontFamily, QueryViewerCollection_index[ctl.id].FontSize, QueryViewerCollection_index[ctl.id].getHtmlColor(QueryViewerCollection_index[ctl.id].FontColor), colors[3], QueryViewerCollection_index[ctl.id].FontFamily, QueryViewerCollection_index[ctl.id].FontSize, QueryViewerCollection_index[ctl.id].getHtmlColor(QueryViewerCollection_index[ctl.id].FontColor), colors[3])
                if (ctl.loadFrom) ctl.loadFrom(QueryViewerCollection_index[ctl.id].ObjectName);    // No está cargando de acá. Es solo para setear el nombre correcto en los diálogos de exportación
                if (ctl.setInitialMetadata) ctl.setInitialMetadata(QueryViewerCollection_index[ctl.id].pivotTableMetadata);
                if (ctl.setData) ctl.setData(QueryViewerCollection_index[ctl.id].pivotTableData);
                if (ctl.refresh) ctl.refresh();
            },
            {   itemClick: function(ctl, info) { QueryViewerCollection_index[ctl.id].onItemClickEvent(info.data, false); },
                itemDoubleClick: function(ctl, info) { QueryViewerCollection_index[ctl.id].onItemClickEvent(info.data, true); },
                dragAndDrop: function(ctl, info) { QueryViewerCollection_index[ctl.id].onDragAndDropEvent(info.data); },
                aggregatorChanged: function(ctl, info) { QueryViewerCollection_index[ctl.id].onAggregatorChangedEvent(info.data); },
                valuesChanged: function(ctl, info) { QueryViewerCollection_index[ctl.id].onValuesChangedEvent(info.data); },
                popupClick: function(ctl, info) { },
                onResized: function(ctl, info) { QueryViewerCollection_index[ctl.id].onResizeEvent(ctl, info); }
            },
            container
        );
    }

    this.getPivotTableDataURL = function() {
        var urlParam;
        if (this.GenType == "") this.GenType = "C#";
        var foolCache = this.foolCache();   // Para que el explorador no cachee los resultados de los servicios

        switch (this.GenType) {
            case "C#":
                return this.baseUrl() + "agxpl_getdataforpivottable.aspx?" + foolCache;
            case "Java":
                return this.GetJavaBaseUrl(false) + "agxpl_getdataforpivottable?" + foolCache;

            case "Ruby":
                return this.baseUrl() + "gxruby/GXplorerServices.gxpl_getdataforpivottable?" + foolCache;
            default:
                return "";
        }
    }

    this.getPivotTableMetadataURL = function() {
        var urlParam;
        if (this.GenType == "") this.GenType = "C#";
        var foolCache = this.foolCache();   // Para que el explorador no cachee los resultados de los servicios

        switch (this.GenType) {
            case "C#":
                return this.baseUrl() + "agxpl_getmetadataforpivottable.aspx?" + foolCache;
            case "Java":
                return this.GetJavaBaseUrl(false) +  "agxpl_getmetadataforpivottable?" + foolCache;
            case "Ruby":
                return this.baseUrl() + "gxruby/GXplorerServices.gxpl_getmetadataforpivottable?" + foolCache;
            default:
                return "";
        }
    }
    
    this.renderPivotServices = function(xml1, xml2, time1, time2) 
    {
        var xml1Encoded = gx.html.encode(xml1, true, true);
        var xml2Encoded = gx.html.encode(xml2, true, true);
        this.AdjustSize(); 
        var buffer1 = "<div style=\"overflow:auto; border-right: silver thin solid; border-top: silver thin solid; border-left: silver thin solid; border-bottom: silver thin solid; width: " + this.Width + "px; height: " + parseInt(this.Height)/2 + "px; font-size: " + this.FontSize + "px; color: " + this.getHtmlColor(this.FontColor) + "; font-family: " + this.FontFamily + "\">" + xml1Encoded + "</div>";
        buffer1 += "Time: " + time1/1000 + " seconds";
        var buffer2 = "<div style=\"overflow:auto; border-right: silver thin solid; border-top: silver thin solid; border-left: silver thin solid; border-bottom: silver thin solid; width: " + this.Width + "px; height: " + parseInt(this.Height)/2 + "px; font-size: " + this.FontSize + "px; color: " + this.getHtmlColor(this.FontColor) + "; font-family: " + this.FontFamily + "\">" + xml2Encoded + "</div>";
        buffer2 += "Time: " + time2/1000 + " seconds";
	    this.setHtml(buffer1+buffer2);
	}
    
    // ---------------------------------------- Chart ----------------------------------------


    this.applyFiltersInXMLChart = function(ChartXml) {
        var xmlDoc;
        if (!this.BelongAnyAutoRefreshGroup())
            return ChartXml;
        
        if ((this.Axes == null) || (this.Axes == undefined) || (this.Axes == 0) || (this.Axes.length == 0))
            return ChartXml;

        xmlDoc = this.xmlDocument(ChartXml);

        if (this.getSingleElementByTagName(xmlDoc.documentElement, "dataset") == null)
            return this.applyFiltersInXMLChartSingleSerie(xmlDoc);
        else
            return this.applyFiltersInXMLChartMultiSerie(xmlDoc);
    }

    this.trim = function(str) {
        if (!str || typeof str != 'string')
            return null;
        return str.replace(/^[\s]+/, '').replace(/[\s]+$/, '').replace(/[\s]{2,}/, ' ');
    }

    this.GetAxisByName = function(Axes, AxisTitle) {
        // precondicion el axis esta en la collectiion de axis
        encontre = false;
        i = 0;
        while ((!encontre) && (i < Axes.length)) {

            encontre = this.trim(Axes[i].Title) == this.trim(AxisTitle);
            if (!encontre)
                i++;
        }
        if (encontre)
            return Axes[i];
        else 
            return null;
    }

    this.GetCategoriesChartOrder = function(Axes, categoriesStr) {
        var categories = {};
        var Axis;
        var h1 = 0;
        for (h = 0; h < categoriesStr.length; h++) {
            Axis = this.GetAxisByName(Axes, categoriesStr[h]);
            if (Axis != null) {
                categories[h1] = Axis;
                h1++;
            }
        }
        return categories;
    }

    this.IsValidValue = function(value, axis) {

        if ((axis.Filter == null) || (axis.Filter == undefined))
            return false;


        if ((axis.Filter.Values == null) || (axis.Filter.Values == undefined))
            return false;

        if (axis.Filter.Values.length == 0)
            return false;


        encontre = false;
        i1 = 0;

        while ((!encontre) && (i1 < axis.Filter.Values.length)) {
            encontre = this.trim(value) == this.trim(axis.Filter.Values[i1]);
            if (!encontre)
                i1++;

        }
        return encontre;
    }

    this.IsValidRow = function(axesvalue, categories) {
        var values = axesvalue.split(",");
        isvalid = true;
        i2 = 0;
        while ((isvalid) && (categories[i2] != undefined)) {
            isvalid = this.IsValidValue(values[i2], categories[i2]);
            i2++;
        }
        return isvalid;
    }

    this.applyFiltersInXMLChartSingleSerie = function(xmlDoc) {
        var xaxis = xmlDoc.documentElement.getAttribute("xAxisName");
        var yaxis = xmlDoc.documentElement.getAttribute("yAxisName");
        var categoriesStr = xaxis.split(",");
        var categories = this.GetCategoriesChartOrder(this.Axes, categoriesStr);

        var metadata = this.GetMetadataFromChart(xmlDoc);
        var xml = "";

        var xml_index = [];
        var xml_values = [];
        var xml_color = [];
        xml_i = 0;

        xml = "<graph xAxisName=" + '"' + xaxis + '"' + " yAxisName=" + '"' + yaxis + '"' + " baseFont=" + '"' + metadata["baseFont"] + '"' + " baseFontSize=" + '"' + metadata["baseFontSize"] + '"' + " baseFontColor=" + '"' + metadata["baseFontColor"] + '"' + " rotateNames=" + '"' + metadata["rotateNames"] + '"' + " showValues=" + '"' + metadata["showValues"] + '"' + " numberSuffix=" + '"' + metadata["numberSuffix"] + '"' + " decimalPrecision=" + '"' + metadata["decimalPrecision"] + '"' + " yAxisMinValue=" + '"' + metadata["yAxisMinValue"] + '"' + " yAxisMaxValue=" + '"' + metadata["yAxisMaxValue"] + '"' + " showNames=" + '"' + metadata["showNames"] + '"' + " formatNumberScale=" + '"' + metadata["formatNumberScale"] + '"' + ">";

        var setnodes = this.getMultipleElementsByTagName(xmlDoc.documentElement, "set");

        for (u = 0; u < setnodes.length; u++) {
            var name = setnodes[u].getAttribute("name");
            var value = setnodes[u].getAttribute("value");
            var color = setnodes[u].getAttribute("color");

            if (this.IsValidRow(name, categories)) {
                if (xml_values[name] == undefined) {
                    // inserto valor nuevo
                    xml_index[xml_i] = name;
                    xml_values[name] = value;
                    xml_color[name] = color;
                    xml_i++;
                }
                else {
                    //adiciono valor al existente
                    val = xml_values[name];
                    number_val = parseFloat(val.replace(",", "."));
                    newval = value;
                    number_newval = parseFloat(newval.replace(",", "."));
                    number_total = number_val + number_newval;
                    xml_values[name] = number_total + '';
                }

            }


        }

        for (k = 0; k < xml_index.length; k++) {

                n = xml_index[k];
                xml += "<set name=" + '"' + n + '"' + " value=" + '"' + xml_values[n] + '"' + " color=" + '"' + xml_color[n] + '"' + "></set>";
        }



        xml += "</graph>";
        return xml;
    }

    this.applyFiltersInXMLChartMultiSerie = function(xmlDocument) {

        var xaxis = xmlDocument.documentElement.getAttribute("xAxisName");
        var categoriesStr = xaxis.split(",");
        var categories = this.GetCategoriesChartOrder(this.Axes, categoriesStr);

        var metadata = this.GetMetadataFromChart(xmlDocument);

        var xml = "<graph xAxisName=" + '"' + xaxis + '"' + " baseFont=" + '"' + metadata["baseFont"] + '"' + " baseFontSize=" + '"' + metadata["baseFontSize"] + '"' + " baseFontColor=" + '"' + metadata["baseFontColor"] + '"' + " rotateNames=" + '"' + metadata["rotateNames"] + '"' + " showValues=" + '"' + metadata["showValues"] + '"' + " numberSuffix=" + '"' + metadata["numberSuffix"] + '"' + " decimalPrecision=" + '"' + metadata["decimalPrecision"] + '"' + " yAxisMinValue=" + '"' + metadata["yAxisMinValue"] + '"' + " yAxisMaxValue=" + '"' + metadata["yAxisMaxValue"] + '"' + " formatNumberScale=" + '"' + metadata["formatNumberScale"] + '"' + ">";

        var categoriesnode = this.getSingleElementByTagName(xmlDocument.documentElement, "categories");
        var categoriescollection = this.getMultipleElementsByTagName(categoriesnode, "category");

        var categories_by_key = [];
        var categories_by_index = [];
        for (u2 = 0; u2 < categoriescollection.length; u2++) {


            var name = categoriescollection[u2].getAttribute("name");
            if (this.IsValidRow(name, categories)) {
                if (categories_by_key[name] == undefined) {
                    //valor nuevo
                    var valuearryay = [];
                    valuearryay.push(u2);
                    categories_by_key[name] = valuearryay;
                    categories_by_index.push(name);

                }
                else {
                    // valor ya existente
                    var valuearryay = categories_by_key[name];
                    valuearryay.push(u2);
                    categories_by_key[name] = valuearryay;

                }

            }
        }

        xml += "<categories>";
        for (c1 = 0; c1 < categories_by_index.length; c1++) {
            var namevalue = categories_by_index[c1];
            xml += "<category name=" + '"' + namevalue + '"' + "></category>";
        }
        xml += "</categories>";



        var datasetcollection = this.getMultipleElementsByTagName(xmlDocument.documentElement, "dataset");

        for (u3 = 0; u3 < datasetcollection.length; u3++) {

            var dataset_u3 = datasetcollection[u3];
            var seriesName = dataset_u3.getAttribute("seriesName");
            var parentYAxis = dataset_u3.getAttribute("parentYAxis");
            var color = dataset_u3.getAttribute("color");


            xml += "<dataset seriesName=" + '"' + seriesName + '"' + " parentYAxis=" + '"' + parentYAxis + '"' + " color=" + '"' + color + '"' + " >"
            var setvaluescollection = this.getMultipleElementsByTagName(dataset_u3, "set");

            for (c1 = 0; c1 < categories_by_index.length; c1++) {

                var namevalue = categories_by_index[c1];
                var array_index = categories_by_key[namevalue];


                var totalserie = 0;
                for (h3 = 0; h3 < array_index.length; h3++) {

                    var index = array_index[h3];
                    var newvalue = setvaluescollection[index].getAttribute("value");
                    var valuefloat = parseFloat(newvalue.replace(",", "."));
                    totalserie = totalserie + valuefloat;
                }

                xml += "<set value=" + '"' + totalserie + '"' + "></set>";
            }

            xml += "</dataset>";
        }

        xml += "</graph>"
        return xml;

    }

    this.DecordeValuesCollection = function(ValuesCollection) {

        var result = [];
        var i = 0;

        for (i = 0; i < ValuesCollection.length; i++) {
            result.push(decodeURIComponent(ValuesCollection[i]));
        }
        return result;


    }
    this.GetAxesCollectionFromJSON = function(AxesJSON) {
        var axesresult = [];
        var i = 0;

        for (i = 0; i < AxesJSON.RuntimeFields.length; i++) {
            var axis = {};
            axis.Name = decodeURIComponent(AxesJSON.RuntimeFields[i].Name);
            axis.Title = decodeURIComponent(AxesJSON.RuntimeFields[i].Caption);
            axis.Filter = {};
            axis.Filter.Type = AxesJSON.RuntimeFields[i].Filter.Type;
            if (AxesJSON.RuntimeFields[i].Filter.Values != undefined)
                axis.Filter.Values = this.DecordeValuesCollection(AxesJSON.RuntimeFields[i].Filter.Values);
            if (AxesJSON.RuntimeFields[i].Axis.Type == "Rows") {
                axis.Type = "Row";
            }
            else {
                if (AxesJSON.RuntimeFields[i].Axis.Type == "Columns") {
                    axis.Type = "Column";
                }
                else {

                    if (AxesJSON.RuntimeFields[i].Axis.Type == "Pages") {
                        axis.Type = "Page";
                    }
                    else {
                        if (AxesJSON.RuntimeFields[i].Axis.Type == "Hidden") {
                            axis.Type = "NotShow";
                        }
                    }
                }
            }
            axesresult.push(axis);
        }  // for

        return axesresult;

    }

    this.GetParameterCollectionFromJSON = function(ParametersJSON) {
        var parametersresult = [];
        var i = 0;
        for (i = 0; i < ParametersJSON.RuntimeParameters.length; i++) {
            var p = {};
            p.Name = decodeURIComponent(ParametersJSON.RuntimeParameters[i].Name);
            p.Value = decodeURIComponent(ParametersJSON.RuntimeParameters[i].Value);
            parametersresult.push(p);
        }

        return parametersresult;
    }


    this.loadQueryAxesAndParametersState = function() {
        if (this.BelongAnyAutoRefreshGroup()) {
            var path = window.location.pathname;

            var cookieparameterID = path + "_" + this.userControlId() + "_" + this.ObjectId + "_" + this.ObjectName + "Parameters";
            var cookieAxesID = path + "_" + this.userControlId() + "_" + this.ObjectId + "_" + this.ObjectName + "Axes";
            var parametersJSONString = this.readCookie(cookieparameterID);
            var AxesJSONString = this.readCookie(cookieAxesID);

            if (!((parametersJSONString == null) || (parametersJSONString == undefined) || (this.trim(parametersJSONString)) == "{}")) {
                var parametersJSON = eval('(' + parametersJSONString + ')');
                this.Parameters = this.GetParameterCollectionFromJSON(parametersJSON);
            }

            if (!((AxesJSONString == null) || (AxesJSONString == undefined) || (this.trim(AxesJSONString) == "{}"))) {
                var AxesJSON = eval('(' + AxesJSONString + ')');
                this.Axes = this.GetAxesCollectionFromJSON(AxesJSON)
            }

        }

    }

    this.saveQueryAxesAndParametersState = function() {
        if (this.BelongAnyAutoRefreshGroup()) {
            var parametersJSON = "{" + this.RuntimeParametersJSON() + "}";
            var fieldJSON = "{" + this.RuntimeFieldsJSONWithFilter() + "}";
            var path = window.location.pathname;

            var cookieparameterID = path + "_" + this.userControlId() + "_" + this.ObjectId + "_" + this.ObjectName + "Parameters";
            var cookieAxesID = path + "_" + this.userControlId() + "_" + this.ObjectId + "_" + this.ObjectName + "Axes";
            var days = 365;

            this.createCookie(cookieparameterID, parametersJSON, days);
            this.createCookie(cookieAxesID, fieldJSON, days);
        }
    }

    this.tryToRenderChart = function() {

        var errMsg = "";
        var chartData = "";
        var seriesCount;

        // Si hay que traer el estado salvado de la metadata se trae
        if ((this.RememberLayout) && (this.isfirstshow) && (this.BelongAnyAutoRefreshGroup()))
            this.loadQueryAxesAndParametersState();

        // Ejecuto el primer servicio y verifico que no haya habido error
        var resText = this.getSeriesCount();
        if (!this.anyError(resText)) {
            seriesCount = resText;
            this.chartSeriesCount = seriesCount;
            // Ejecuto el segundo servicio y verifico que no haya habido error
            var d1 = new Date();
            var t1 = d1.getTime();
            var resText = this.getChartData();
            var d2 = new Date();
            var t2 = d2.getTime();
            if (!this.anyError(resText)) {
                chartData = this.applyFiltersInXMLChart(resText);
                this.chartXmlData = chartData;
                this.saveQueryAxesAndParametersState();
                //chartData = resText;
                //ChartXml[this.ContainerName + "_" + this.ControlName] = chartData;
                if (this.debugServices)
                    this.renderChartServices(chartData, t2 - t1);
                else
                    this.renderChart_JS(seriesCount, chartData);
            }
            else {
                errMsg = this.getErrorFromText(resText);
                this.renderError(errMsg);
            }
        }
        else {
            errMsg = this.getErrorFromText(resText);
            this.renderError(errMsg);
        }
    }

    this.renderChart_JS = function(seriesCount, chartData) 
    {
        var UCId = this.userControlId();
        // Check for not valid charts
        if ((this.RealChartType == "Pie" || this.RealChartType == "Pie3D" || this.RealChartType == "Doughnut" || this.RealChartType == "Funnel") && (seriesCount != "1"))
            this.renderError("Too many series for a " + this.RealChartType + " chart");
        else {
            this.AdjustSize();
            var swfPath = this.getSwfFilePath(seriesCount);
            var chart1 = new FusionCharts(swfPath, UCId, this.fixSize(this.Width), this.fixSize(this.Height), "0", "0");
            chart1.setDataXML(chartData);
            chart1.render(this.getContainerControl().id);
        }
    }

    this.getSwfFilePath = function(seriesCount)
    {
        if (this.GenType == "") this.GenType = "C#";
        switch (this.GenType)
        {
            case "C#":                
                return "QueryViewer/FusionCharts/" + this.getSwfFileName(seriesCount);
            case "Java":
                return this.GetJavaBaseUrl(true) +  "QueryViewer/FusionCharts/" + this.getSwfFileName(seriesCount);
            case "Ruby":
                return "QueryViewer/FusionCharts/" + this.getSwfFileName(seriesCount);
            default:
                return "";
        }         
    }

    this.getChartDataURL = function() {
        var urlParam;
        if (this.GenType == "") this.GenType = "C#";
        var foolCache = this.foolCache();   // Para que el explorador no cachee los resultados de los servicios

        switch (this.GenType) {
            case "C#":
                return this.baseUrl() + "agxpl_getdataforchart.aspx?" + foolCache;
            case "Java":
                return this.GetJavaBaseUrl(false) + "agxpl_getdataforchart?" + foolCache;

            case "Ruby":
                return this.baseUrl() + "gxruby/GXplorerServices.gxpl_getdataforchart?" + foolCache;
            default:
                return "";
        }
    }

    this.getSeriesCountURL = function() {
        var urlParam;
        if (this.GenType == "") this.GenType = "C#";
        var foolCache = this.foolCache();   // Para que el explorador no cachee los resultados de los servicios

        switch (this.GenType) {
            case "C#":
                return this.baseUrl() + "agxpl_getseriescount.aspx?" + foolCache;
            case "Java":
                return this.GetJavaBaseUrl(false) + "agxpl_getseriescount?" + foolCache;
            case "Ruby":
                return this.baseUrl() + "gxruby/GXplorerServices.gxpl_getseriescount?" + foolCache;
            default:
                return "";
        }
    }
    
    this.getSeriesCount = function() {
        var src = this.getSeriesCountURL();
        var cnt = "";
        var postInfo = this.SeriesCountPostInfo();
        var xmlHttp = this.getXMLHttpRequest();
        xmlHttp.open("POST", src, false); // sync
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttp.send(postInfo);
        cnt = xmlHttp.responseText;
        return cnt;
    }

    this.getChartData = function() {
        var src = this.getChartDataURL();
        var xml = "";
        var postInfo = this.ChartDataPostInfo();
        var xmlHttp = this.getXMLHttpRequest();
        xmlHttp.open("POST", src, false); // sync
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttp.send(postInfo);
        xml = xmlHttp.responseText;
        return xml;
    }

    this.getQueryParametersURL = function() {
        var urlParam;
        if (this.GenType == "") this.GenType = "C#";
        var foolCache = this.foolCache();   // Para que el explorador no cachee los resultados de los servicios

        switch (this.GenType) {
            case "C#":
                return this.baseUrl() + "agxpl_getqueryparameters.aspx?" + foolCache;
            case "Java":
                return this.GetJavaBaseUrl(false) + "agxpl_getqueryparameters?" + foolCache;
            case "Ruby":
                return this.baseUrl() + "gxruby/GXplorerServices.gxpl_getqueryparameters?" + foolCache;
            default:
                return "";
        }
    }

    this.getQueryParameters = function() {
        var src = this.getQueryParametersURL();
        var xml = "";
        var postInfo = this.getQueryParametersPostInfo();
        var xmlHttp = this.getXMLHttpRequest();
        xmlHttp.open("POST", src, false); // sync
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttp.send(postInfo);
        output = xmlHttp.responseText;
        return output;
    }
    this.getSwfFileName = function(seriesCount) 
    {
        if (seriesCount == "")
            seriesCount = this.getSeriesCount();
        var swf = "";
        switch (this.RealChartType) {
            case "Column":
                if (seriesCount == "1")
                    swf = "FCF_Column2D.swf";
                else
                    swf = "FCF_MSColumn2D.swf";
                break;
            case "Column3D":
                if (seriesCount == "1")
                    swf = "FCF_Column3D.swf";
                else
                    swf = "FCF_MSColumn3D.swf";
                break;
            case "StackedColumn":
                if (seriesCount != "1")
                    swf = "FCF_StackedColumn2D.swf";	
                else
                    swf = "FCF_Column2D.swf";       // "Stacked" ignored
                break;
            case "StackedColumn3D":
                if (seriesCount != "1")
                    swf = "FCF_StackedColumn3D.swf";	
                else
                    swf = "FCF_Column3D.swf";       // "Stacked" ignored
                break;
            case "Bar":
                if (seriesCount == "1")
                    swf = "FCF_Bar2D.swf";
                else
                    swf = "FCF_MSBar2D.swf";
                break;
            case "StackedBar":
                if (seriesCount != "1")
                    swf = "FCF_StackedBar2D.swf";	
                else
                    swf = "FCF_Bar2D.swf";          // "Stacked" ignored
                break;
            case "Area":
                if (seriesCount == "1")
                    swf = "FCF_Area2D.swf";
                else
                    swf = "FCF_MSArea2D.swf";
                break;
            case "StackedArea":
                if (seriesCount != "1")
                    swf = "FCF_StackedArea2D.swf";	
                else
                    swf = "FCF_Area2D.swf";         // "Stacked" ignored
                break;
            case "Line":                    
                if (seriesCount == "1")
                    swf = "FCF_Line.swf";	
                else
                    swf = "FCF_MSLine.swf";	
                break;
            case "Pie":
                swf = "FCF_Pie2D.swf";	
                break;
            case "Pie3D":
                swf = "FCF_Pie3D.swf";	
                break;
            case "Doughnut":
                swf = "FCF_Doughnut2D.swf";	
                break;
            case "Funnel":
                swf = "FCF_Funnel.swf";
                break;
            case "ColumnLine":
                if (seriesCount != "1")
                    swf = "FCF_MSColumn2DLineDY.swf";
                else
                    swf = "FCF_Column2D.swf";       // "Line" ignored
                break;
            case "Column3DLine":
                if (seriesCount != "1")
                    swf = "FCF_MSColumn3DLineDY.swf";
                else
                    swf = "FCF_Column3D.swf";       // "Line" ignored
                break;
            default:
                if (seriesCount == "1")
                    swf = "FCF_Column2D.swf";
                else
                    swf = "FCF_MSColumn2D.swf";
                break;
        }
        return swf;
    }

    this.renderChartServices = function(xml, time) 
    {
        var xmlEncoded = gx.html.encode(xml, true, true);
        this.AdjustSize(); 
        var buffer = "<div style=\"overflow:auto; border-right: silver thin solid; border-top: silver thin solid; border-left: silver thin solid; border-bottom: silver thin solid; width: " + this.Width + "px; height: " + this.Height + "px; font-size: " + this.FontSize + "px; color: " + this.getHtmlColor(this.FontColor) + "; font-family: " + this.FontFamily + "\">" + xmlEncoded + "</div>";
        buffer += "Time: " + time/1000 + " seconds";
	    this.setHtml(buffer);
	}
        
    // ---------------------------------------- Ajax ----------------------------------------

	this.getQueryParametersPostInfo = function() {
	    var str = "";
	    str += '{';
	    str += (this.ParentObject.PackageName != '' ? '"ApplicationNamespace":"' + this.ParentObject.PackageName + '"' + ',' : '');
	    str += '"ObjectName":"' + this.ObjectName + '"';
	    str += (this.ObjectInfo != '' ? ',' + '"ObjectInfo":' + this.ObjectInfo : '');
	    str += '}';
	    return "Data=" + encodeURIComponent(str);
	}

    this.DefaultOutputPostInfo = function() {
        var str = "";
        str += '{';
        str += (this.ParentObject.PackageName != '' ? '"ApplicationNamespace":"' + this.ParentObject.PackageName + '"' + ',' : '');
        str += '"ObjectName":"' + this.ObjectName + '"';
        str += (this.ObjectInfo != '' ? ',' + '"ObjectInfo":' + this.ObjectInfo : '');
        str += '}';
        return "Data=" + encodeURIComponent(str);
    }

    this.SeriesCountPostInfo = function() {
        var str = "";
        var runtimeFieldsJSON = this.RuntimeFieldsJSON();
        str += '{';
        str += (this.ParentObject.PackageName != '' ? '"ApplicationNamespace":"' + this.ParentObject.PackageName + '"' + ',' : '');
        str += '"ObjectName":"' + this.ObjectName + '"';
        str += (this.QueryInfo != '' ? ',' + '"QueryInfo":' + this.QueryInfo : '');
        str += (runtimeFieldsJSON != '' ? ',' + runtimeFieldsJSON : '');
        str += '}';
        return "Data=" + encodeURIComponent(str);
    }

    this.ChartDataPostInfo = function() {
        var str = "";
        var runtimeFieldsJSON = this.RuntimeFieldsJSON();
        var runtimeParametersJSON = this.RuntimeParametersJSON()
        var chartFormatJSON = this.ChartFormatJSON();
        str += '{';
        str += (this.ParentObject.PackageName != '' ? '"ApplicationNamespace":"' + this.ParentObject.PackageName + '"' + ',' : '');
        str += '"ObjectName":"' + this.ObjectName + '"';
        str += (this.QueryInfo != '' ? ',' + '"QueryInfo":' + this.QueryInfo : '');
        str += (runtimeFieldsJSON != '' ? ',' + runtimeFieldsJSON : '');
        str += (runtimeParametersJSON != '' ? ',' + runtimeParametersJSON : '');
        str += ',';
        str += '"ChartType":"' + this.RealChartType + '"';
        str += (chartFormatJSON != '' ? ',' + chartFormatJSON : '');
        str += ',';
        str += '"FontFamily":"' + this.FontFamily + '"';
        str += ',';
        str += '"FontColor":"' + this.getHtmlColor(this.FontColor).replace("#", "") + '"';
        str += ',';
        str += '"FontSize":"' + this.FontSize + '"';
        str += ',';
        str += '"RotateNames":"' + (this.XAxisLabels == "Vertically" ? "1" : "0") + '"';
        str += ',';
        str += '"ShowValues":"' + (gx.lang.gxBoolean(this.ShowValues) ? "1" : "0") + '"';
        str += ',';
        str += '"AllowAxesOrderChange":' + this.AllowChangeAxesOrder;
        str += ',';
        str += '"UseCache":' + this.UseCache;
        str += '}';
        return "Data=" + encodeURIComponent(str);
    }

    this.PivottableMetadataPostInfo = function() {
        var str = "";
        var runtimeFieldsJSON = this.RuntimeFieldsJSON();
        str += '{';
        str += (this.ParentObject.PackageName != '' ? '"ApplicationNamespace":"' + this.ParentObject.PackageName + '"' + ',' : '');
        str += '"ObjectName":"' + this.ObjectName + '"';
        str += (this.QueryInfo != '' ? ',' + '"QueryInfo":' + this.QueryInfo : '');
        str += (runtimeFieldsJSON != '' ? ',' + runtimeFieldsJSON : '');
        str += ',';
        str += '"TableType":"' + this.RealType + '"';
        str += ',';
        str += '"AllowAxesOrderChange":' + this.AllowChangeAxesOrder;
        str += ',';
        str += '"RememberLayout":' + this.RememberLayout;
        str += '}';
        return "Data=" + encodeURIComponent(str);
    }

    this.PivottableDataPostInfo = function() {
        var str = "";
        var runtimeParametersJSON = this.RuntimeParametersJSON();
        str += '{';
        str += (this.ParentObject.PackageName != '' ? '"ApplicationNamespace":"' + this.ParentObject.PackageName + '"' + ',' : '');
        str += '"ObjectName":"' + this.ObjectName + '"';
        str += (this.QueryInfo != '' ? ',' + '"QueryInfo":' + this.QueryInfo : '');
        str += (runtimeParametersJSON != '' ? ',' + runtimeParametersJSON : '');
        str += ',';
        str += '"UseCache":' + this.UseCache;
        str += '}';
        return "Data=" + encodeURIComponent(str);
    }

    this.RuntimeParametersJSON = function() {
        var strParameters = '';
        var existParameters = false;
        for (i = 0; this.Parameters[i] != undefined; i++) {
            existParameters = true;
            strParameters += (strParameters != '' ? ',' : '');
            strParameters += '{';
            strParameters += '"Name":"' + this.Parameters[i].Name + '"';
            strParameters += ',';
            strParameters += '"Value":"' + encodeURIComponent(this.Parameters[i].Value) + '"';
            strParameters += '}';
        }
        if (existParameters) strParameters = '"RuntimeParameters":[' + strParameters + ']';
        return strParameters;
    }

    this.ChartFormatJSON = function() {
        var strFormat = '';
        var strColors = '';
        var existColors = false;
        if (this.Format.ChartValuesColors != undefined) {
            for (i = 0; this.Format.ChartValuesColors[i] != undefined; i++) {
                existColors = true;
                strColors += (strColors != '' ? ',' : '');
                strColors += '{';
                strColors += '"Value":"' + encodeURIComponent(this.Format.ChartValuesColors[i].Value) + '"';
                strColors += ',';
                strColors += '"Color":"' + this.getHtmlColor(this.Format.ChartValuesColors[i].Color) + '"';
                strColors += '}';
            }
        }
        if (existColors) {
            strColors = '"Colors":[' + strColors + ']';
            strFormat = '"ChartFormat":{' + strColors + '}';
        }
        return strFormat;
    }

    this.ValuesStylesJSON = function(axis) {
        var strStyles = '';
        var existStyles = false;
        if (axis.Format != undefined) {
            if (axis.Format.ValuesStyles != undefined) {
                for (var i = 0; axis.Format.ValuesStyles[i] != undefined; i++) {
                    existStyles = true;
                    strStyles += (strStyles != '' ? ',' : '');
                    strStyles += '{';
                    strStyles += '"Value":"' + encodeURIComponent(axis.Format.ValuesStyles[i].Value) + '"';
                    strStyles += ',';
                    strStyles += '"Style":"' + encodeURIComponent(axis.Format.ValuesStyles[i].StyleOrClass) + '"';
                    strStyles += ',';
                    strStyles += '"Propagate":' + (axis.Format.ValuesStyles[i].ApplyToFileOrColumn ? "true" : "false");
                    strStyles += '}';
                }
            }
        }
        if (existStyles) strStyles = '"ValuesStyles":[' + strStyles + ']';
        return strStyles;
    }

    this.ConditionalStylesJSON = function(axis) {
        var strStyles = '';
        var existStyles = false;
        if (axis.Format != undefined) {
            if (axis.Format.ConditionalStyles != undefined) {
                for (var i = 0; axis.Format.ConditionalStyles[i] != undefined; i++) {
                    existStyles = true;
                    strStyles += (strStyles != '' ? ',' : '');
                    strStyles += '{';
                    strStyles += '"Operator":"' + axis.Format.ConditionalStyles[i].Operator + '"';
                    strStyles += ',';
                    strStyles += '"Value1":"' + encodeURIComponent(axis.Format.ConditionalStyles[i].Value1) + '"';
                    if (axis.Format.ConditionalStyles[i].Operator == "IN")
                    {
                        strStyles += ',';
                        strStyles += '"Value2":"' + encodeURIComponent(axis.Format.ConditionalStyles[i].Value2) + '"';
                    }
                    strStyles += ',';
                    strStyles += '"Style":"' + encodeURIComponent(axis.Format.ConditionalStyles[i].StyleOrClass) + '"';
                    strStyles += '}';
                }
            }
        }
        if (existStyles) strStyles = '"ConditionalStyles":[' + strStyles + ']';
        return strStyles;
    }
    
    this.RuntimeFieldsJSONWithFilter = function() {
    // metodo provisorio 
        var strFields = '';
        var strValues = '';
        var existFields;
        var existValues;
        var picture;
        var color;
        var style;
        var subtotals;
        var CanDragToPages;
        var orderType;
        var expandCollapseType;
        var filterType;
        existFields = false;
        for (i = 0; this.Axes[i] != undefined; i++) {
            existFields = true;
            strFields += (strFields != '' ? ',' : '');
            strFields += '{';
            picture = '';
            color = '';
            style = '';
            subtotals = '';
            CanDragToPages = '';
            orderType = '';
            expandCollapseType = '';
            filterType = '';
            var valuesStyles = this.ValuesStylesJSON(this.Axes[i]);
            var conditionalStyles = this.ConditionalStylesJSON(this.Axes[i]);
            if (this.Axes[i].Format != undefined) {
                picture = this.Axes[i].Format.Picture;
                color = this.getHtmlColor(this.Axes[i].Format.Color);
                style = this.Axes[i].Format.Style;
                subtotals = this.Axes[i].Format.Subtotals;
                CanDragToPages = this.Axes[i].Format.CanDragToPages;
            }
            if (this.Axes[i].AxisOrder != undefined) {
                orderType = this.Axes[i].AxisOrder.Type;
            }
            if (this.Axes[i].ExpandCollapse != undefined) {
                expandCollapseType = this.Axes[i].ExpandCollapse.Type;
            }
            if (this.Axes[i].Filter != undefined) {
                filterType = "ShowSomeValues";  // No se lee porque estaba viniendo undefined
            }
            
            strFields += '"Name":"' + encodeURIComponent(this.Axes[i].Name) + '"';
            strFields += ',';
            strFields += '"Caption":"' + encodeURIComponent(this.Axes[i].Title) + '"';
            strFields += ',';
            var t = this.Axes[i].Type;
            strFields += '"Axis":{"Type":"' + (t == "Row" ? "Rows" : (t == "Column" ? "Columns" : (t == "Page" ? "Pages" : (t == "NotShow" ? "Hidden" : t)))) + '"}';
            strFields += ',';
            strFields += '"Picture":"' + encodeURIComponent(picture) + '"';
            strFields += ',';
            strFields += '"Color":"' + color + '"';
            strFields += ',';
            strFields += '"Style":"' + style + '"';
            strFields += ',';
            strFields += '"Subtotals":"' + subtotals + '"';
            strFields += ',';
            strFields += '"CanDragToPages":"' + CanDragToPages + '"';
            if (orderType != '') {
                var sdtOrderType = this.SdtWithValuesJSON("Order", orderType, "Custom", this.Axes[i].AxisOrder.Values);
                strFields += (sdtOrderType != '' ? ',' + sdtOrderType : '');
            }
            if (expandCollapseType != '') {
                var sdtExpandCollapse = this.SdtWithValuesJSON("ExpandCollapse", expandCollapseType, "ExpandSomeValues", this.Axes[i].ExpandCollapse.Values);
                strFields += (sdtExpandCollapse != '' ? ',' + sdtExpandCollapse : '');
            }
            if (filterType != '') {
                var sdtFilter = this.SdtWithValuesJSONWithOutEncode("Filter", filterType, "ShowSomeValues", this.Axes[i].Filter.Values);
                strFields += (sdtFilter != '' ? ',' + sdtFilter : '');
            }
            strFields += (valuesStyles != '' ? ',' + valuesStyles : '');
            strFields += (conditionalStyles != '' ? ',' + conditionalStyles : '');
            strFields += '}';
            
        }
        if (existFields) strFields = '"RuntimeFields":[' + strFields + "]";
        return strFields;
    }

    this.SdtWithValuesJSON = function(sdtName, actualType, typeWithValues, values) {
        var strAux = '';
        if (actualType != '') {
            strAux += '"' + sdtName + '":';
            strAux += '{';
            strAux += '"Type":"' + actualType + '"';
            strValues = "";
            if ((actualType == typeWithValues) && (values != undefined) && (values != null)){
                existValues = false;
                for (j = 0; values[j] != undefined; j++) {
                    existValues = true;
                    strValues += (strValues != '' ? ',' : '');
                    strValues += '"' + encodeURIComponent(values[j]) + '"';
                }
                if (existValues) strValues = ',' + '"Values":[' + strValues + ']';
            }
            strAux += strValues;
            strAux += '}';
        }
        return strAux;
    }

    this.SdtWithValuesJSONWithOutEncode= function(sdtName, actualType, typeWithValues, values) {
        var strAux = '';
        if (actualType != '') {
            strAux += '"' + sdtName + '":';
            strAux += '{';
            strAux += '"Type":"' + actualType + '"';
            strValues = "";
            if ((actualType == typeWithValues) && (values != undefined) && (values != null)) {
                existValues = false;
                for (j = 0; values[j] != undefined; j++) {
                    existValues = true;
                    strValues += (strValues != '' ? ',' : '');
                    strValues += '"' + values[j] + '"';
                }
                if (existValues) strValues = ',' + '"Values":[' + strValues + ']';
            }
            strAux += strValues;
            strAux += '}';
        }
        return strAux;
    }
 
    this.RuntimeFieldsJSON = function() {
        var strFields = '';
        var strValues = '';
        var existFields;
        var existValues;
        var picture;
        var color;
        var style;
        var subtotals;
        var CanDragToPages;
        var orderType;
        var expandCollapseType;
        var filterType;        
        existFields = false;
        for (i = 0; this.Axes[i] != undefined; i++) {
            existFields = true;
            strFields += (strFields != '' ? ',' : '');
            strFields += '{';
            picture = '';
            color = '';
            style = '';
            subtotals = '';
            CanDragToPages = '';
            orderType = '';
            expandCollapseType = '';
            filterType = '';    
            var valuesStyles = this.ValuesStylesJSON(this.Axes[i]);        
            var conditionalStyles = this.ConditionalStylesJSON(this.Axes[i]);        
            if (this.Axes[i].Format != undefined) {
                picture = this.Axes[i].Format.Picture;
                color = this.getHtmlColor(this.Axes[i].Format.Color);
                style = this.Axes[i].Format.Style;
                subtotals = this.Axes[i].Format.Subtotals;
                CanDragToPages = this.Axes[i].Format.CanDragToPages;
            }
            if (this.Axes[i].AxisOrder != undefined) {
                orderType = this.Axes[i].AxisOrder.Type;
            }
            if (this.Axes[i].ExpandCollapse != undefined) {
                expandCollapseType = this.Axes[i].ExpandCollapse.Type;
            }
            if (this.Axes[i].Filter != undefined) {
                filterType = this.Axes[i].Filter.Type;
            }
            strFields += '"Name":"' + encodeURIComponent(this.Axes[i].Name) + '"';
            strFields += ',';
            strFields += '"Caption":"' + encodeURIComponent(this.Axes[i].Title) + '"';
            strFields += ',';
            var t = this.Axes[i].Type;
            strFields += '"Axis":{"Type":"' + (t == "Row" ? "Rows" : (t == "Column" ? "Columns" : (t == "Page" ? "Pages" : (t == "NotShow" ? "Hidden" : t)))) + '"}';
            strFields += ',';
            strFields += '"Picture":"' + encodeURIComponent(picture) + '"';
            strFields += ',';
            strFields += '"Color":"' + color + '"';
            strFields += ',';
            strFields += '"Style":"' + style + '"';
            strFields += ',';
            strFields += '"Subtotals":"' + subtotals + '"';
            strFields += ',';
            strFields += '"CanDragToPages":"' + CanDragToPages + '"';
            if (orderType != '')
            {
                var sdtOrderType = this.SdtWithValuesJSON("Order", orderType, "Custom", this.Axes[i].AxisOrder.Values);
                strFields += (sdtOrderType != '' ? ',' + sdtOrderType : '');
            }
            if (expandCollapseType != '')
            {
                strFields += ',';
                strFields += '"ExpandCollapse":';
                strFields += '{';
                strFields += '"Type":"' + expandCollapseType + '"';
                strFields += '}';
            }
            if (filterType != '')
            {
                var sdtFilter = this.SdtWithValuesJSON("Filter", filterType, "ShowSomeValues", this.Axes[i].Filter.Values);
                strFields += (sdtFilter != '' ? ',' + sdtFilter : '');
            }
            strFields += (valuesStyles != '' ? ',' + valuesStyles : '');
            strFields += (conditionalStyles != '' ? ',' + conditionalStyles : '');
            strFields += '}';
        }
        if (existFields) strFields = '"RuntimeFields":[' + strFields + "]";
        return strFields;
    }

    this.xmlDocument = function(text) {
        var xmlDoc;
        if (window.DOMParser) {
            parser = new DOMParser();
            xmlDoc = parser.parseFromString(text, "text/xml");
        }
        else // Internet Explorer
        {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.loadXML(text);
        }
        return xmlDoc;
    }

    this.getXMLHttpRequest = function() {
        if (window.XMLHttpRequest) {
            return new window.XMLHttpRequest;
        }
        else {
            try {
                return new ActiveXObject("MSXML2.XMLHTTP.3.0");
            }
            catch (ex) {
                return null;
            }
        }
    }
}
