/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

// DataBrowserQuery.js

var responseResult = null;

// This function activates Execute button
function enableExecuteBtn(flagEnable) {
  if (flagEnable) {
    $('#btnExecuteQuery').prop("disabled", false);
    if ($('#btnExecuteQuery').hasClass("grey")) {
      $('#btnExecuteQuery').addClass("blue");
      $('#btnExecuteQuery').removeClass("grey");
    }
  } else {
    $('#btnExecuteQuery').prop("disabled", true);
    if ($('#btnExecuteQuery').hasClass("blue")) {
      $('#btnExecuteQuery').addClass("grey");
      $('#btnExecuteQuery').removeClass("blue");
    }
  }
}

// This function is called when query editor content changes
function onQueryTextChange() {
  var queryString = $('#dataBrowserQueryText').val();
  if (!isEmpty(queryString)) {
    enableExecuteBtn(true);
  } else {
    enableExecuteBtn(false);
  }
}

// This function clears query editor 
function clearDBQuery(){
  $('#dataBrowserQueryText').val('');
  onQueryTextChange();
}

// This function executes query written in query editor and displays results
function executeDBQuery(){
  // Disable Execute button
  enableExecuteBtn(false);

  var queryText = $('#dataBrowserQueryText').val();
  var selectedMemberNames = "";
  
  if(isEmpty(queryText)){
    alert("Please enter query to execute..");
    return;
  }
  
  // Determine selected members query to be execute on 
  if($("#membersList").html() != ""){
    var selectedMembers = $( "input[type=checkbox][name=Member]:checked" );
    for(var i=0; i< selectedMembers.length; i++){
      if(selectedMemberNames == ""){
        selectedMemberNames = selectedMembers[i].value;
      }else{
        selectedMemberNames += ","+selectedMembers[i].value;
      }
    }
  }
  
  // TODO 
  // As of now, member names are creating problem due to ':' character in 
  // member names. hence query based upon member names are not supported.
  // following line of code should be removed when solution to this problem is 
  // in place.
  //selectedMemberNames = "";
  
  requestData = {
        query:queryText,
        members:selectedMemberNames,
        limit:0
      };

  // Display Loading/Busy symbol
  $("#loadingSymbol").show();

  // Delete previous query result, if exists.
  if(!isEmpty($('#memberAccordion').html())){
    deleteExistingResultGrids();
    $('#memberAccordion').html('');
  }

  $.getJSON("dataBrowserQuery", requestData, function(data) {
    
    if(data != undefined && data != null){
      if(data.error != undefined && data.error != null){
        
        // Delete previous query result, if exists.
        /*if(!isEmpty($('#memberAccordion').html())){
          deleteExistingResultGrids();
          $('#memberAccordion').html('');
        }*/
        
        var errorText = data.error;
        errorText = encodeMemberName(errorText);
        
        $('#memberAccordion').append("<span>"+errorText+"</span>");

      }else if(data.message != undefined && data.message != null){

        // Delete previous query result, if exists.
        /*if(!isEmpty($('#memberAccordion').html())){
          deleteExistingResultGrids();
          $('#memberAccordion').html('');
        }*/

        var messageText = data.message;
        messageText = encodeMemberName(messageText);

        $('#memberAccordion').append("<span>"+messageText+"</span>");

      }else{
        //console.log("data.result.length"+data.result.length);
        // Convert received data into expected format
        responseResult = convertRawResponseToExpectedFormat(data);
        
        // Delete previous query result, if exists.
        /*if(!isEmpty($('#memberAccordion').html())){
          deleteExistingResultGrids();
          $('#memberAccordion').html('');
        }*/
        
        // Create html for newly executed query
        createHtmlForQueryResults();
        
        // Apply accordion Behavior 
        accordion();
        accordionNested();
        /*custom scroll bar*/
        $('.ScrollPaneBlock').jScrollPane();
        
        // Populate result grids
        if(!isEmpty($('#memberAccordion').html())){
          populateResultGrids();
        }
        //$('.queryHistoryScroll-pane').jScrollPane();/*Custome scroll*/
        
      }
      // Update queries list in history panel
      updateQueryHistory("view","");
    }
    
    // Hide Loading/Busy symbol
    $("#loadingSymbol").hide();

    // enable Execute button
    enableExecuteBtn(true);

  }).error(resErrHandler);
  

}

// This function displays error if occurred 
function resErrHandler(data){
  // Check for unauthorized access
  if (data.status == 401) {
    // redirect user on Login Page
    window.location.href = "login.html?error=UNAUTH_ACCESS";
  }else{
    console.log(data);
  }
}

// This function creates complete result panel html
function createHtmlForQueryResults(){
  var memberResults = responseResult.result;

  if(memberResults.length > 0){

    if(memberResults[0].member != undefined || memberResults[0].member != null){
      //console.log("member wise results found..");      
      for(var i=0; i<memberResults.length; i++){
        //console.log(memberResults[i].member);
        $('#memberAccordion').append(createHtmlForMember(memberResults[i]));
      }
    }else{
      //console.log("cluster level results found..");
      var accordionContentHtml = "";
      accordionContentHtml = createClusterAccordionContentHtml(memberResults);
      var resultHtml = "<div class=\"accordion-content2\">"+ accordionContentHtml +"</div>";
      $('#memberAccordion').append(resultHtml);
    }
  }else{
    $('#memberAccordion').append("<span> No Results Found...</span>");
  }
}

// This function create/generate single member's html
function createHtmlForMember(memberData){
  
  var accordionContentHtml = "";
  accordionContentHtml = createMemberAccordionContentHtml(memberData);
  // Convert angular brackets ('<', '>') using HTML character codes 
  var memberTitle = memberData.member[1].replace(/\<+/g, '&#60').replace(/\>+/g, '&#62');
  var memberHtml = 
            "<div class=\"listing\">" +
              "<div class=\"heading\">" +
                "<span class=\"title\">"+ memberTitle + "</span>" +
              "</div>" +
              "<div class=\"accordion-content\">"+ accordionContentHtml +
              "</div>" +
            "</div>";
  
  return memberHtml;
}

// This function creates/generates member's accordion content html
function createMemberAccordionContentHtml(memberData){
  
  var memName = encodeMemberName(memberData.member[1]);
  var requiredHeight = determineAccordionContentHeight(memberData.result);
  var memberAccordionContentHtml = "";
  memberAccordionContentHtml += 
                "<div class=\"ScrollPaneBlock\" style=\"height: "+requiredHeight+"px;\">" +
                  "<div id=\"memberDetails_"+memName+"\" class=\"accordionNested\">";
  
  var memberResults = memberData.result;
  for(var i=0; i<memberResults.length; i++){
    var htmlTableId = generateTableIdForObjectsTable(memberData.member[1], memberResults[i].objectType);
    var ScrollPaneBlockHeight = 40;
    var resultsLength = memberResults[i].objectResults.length;
    if(resultsLength > 0 && resultsLength < 6){
      ScrollPaneBlockHeight += resultsLength * 30;
    }else{
      ScrollPaneBlockHeight = 200;
    }
    memberAccordionContentHtml += 
                    "<div class=\"n-listing\">" +
                      "<div class=\"n-heading\">" +
                        "<span class=\"n-title\">"+memberResults[i].objectType+"</span>" +
                      "</div>" +
                      "<div class=\"n-accordion-content\">" +
                        "<div class=\"widthfull-100per\">" +
                            "<table id=\""+ htmlTableId +"\"></table>" +
                        "</div>" +
                      "</div>" +
                    "</div>";
  }
  
  memberAccordionContentHtml += 
                  "</div>" +
                "</div>";
  
  return memberAccordionContentHtml ;
  
}

//This function creates/generates cluster's accordion content html
function createClusterAccordionContentHtml(clusterResults){
  var requiredHeight = determineAccordionContentHeight(clusterResults);
  var memberAccordionContentHtml = "";
  memberAccordionContentHtml += 
             "<div class=\"ScrollPaneBlock\" style=\"height: "+requiredHeight+"px;\">" +
               "<div id=\"clusterDetails\" class=\"accordionNested\">";

  for(var i=0; i<clusterResults.length; i++){
    var htmlTableId = generateTableIdForObjectsTable("", clusterResults[i].objectType);
    var ScrollPaneBlockHeight = 40;
    var resultsLength = clusterResults[i].objectResults.length;
    if(resultsLength > 0 && resultsLength < 6){
      ScrollPaneBlockHeight += resultsLength * 30;
    }else{
      ScrollPaneBlockHeight = 200;
    }
    memberAccordionContentHtml += 
                 "<div class=\"n-listing\">" +
                   "<div class=\"n-heading\">" +
                     "<span class=\"n-title\">"+clusterResults[i].objectType+"</span>" +
                   "</div>" +
                   "<div class=\"n-accordion-content\">" +
                     "<div class=\"widthfull-100per\">" +
                         "<table id=\""+ htmlTableId +"\"></table>" +
                     "</div>" +
                   "</div>" +
                 "</div>";
  }

  memberAccordionContentHtml += 
               "</div>" +
             "</div>";

  return memberAccordionContentHtml ;

}

// Function to find/determine the required height of accordion container
function determineAccordionContentHeight(result){
  var numObjects = result.length;
  // determine height of single grid/table
  var height = 0;
  for(var i=0; i<numObjects; i++){
    var numObjectEntries = result[i].objectResults.length;
    if(numObjectEntries > 0 
        && numObjectEntries < 6){
      if(height < 210){
        height = 60 + numObjectEntries * 30;
      }
    }else{
      height = 210;
    }
  }

  // Add additional height required for accordin headers
  height += numObjects * 30;
  return height;

}

// Function to generates id of html table in which results grid is contained
function generateTableIdForObjectsTable(memberName, objectName){
  // Remove all dots (.) in the string and also replace "[]" by "BxBr"
  var objName = objectName.replace(/\.+/g, '').replace("[]", 'BxBr');
  var memName = encodeMemberName(memberName);
  // form html table id
  var tableId = "table-"+memName+"-"+objName;
  
  return tableId;
}

// Function to generates encoded member name
function encodeMemberName(memberName){
  var memName = memberName.replace(/\.+/g, '');
  memName = memName.replace(/\(+/g, '-');
  memName = memName.replace(/\)+/g, '-');
  memName = memName.replace(/\<+/g, '-');
  memName = memName.replace(/\>+/g, '-');
  memName = memName.replace(/\:+/g, '-');
  
  return memName;
}

// This function populates query results into jqgrid tables 
function populateResultGrids(){
  
  var memberResults = responseResult.result;

  if(memberResults.length == 0){
    return;
  }

  if(memberResults[0].member != undefined || memberResults[0].member != null){
    for(var i=0; i<memberResults.length; i++){
      
      var memberResult = memberResults[i].result;
      var memberName = memberResults[i].member[1];
      for(var j=0; j<memberResult.length; j++){
        var htmlTableId = generateTableIdForObjectsTable(memberName, memberResult[j].objectType);
        
        if($('#'+htmlTableId)){
          createResultGrid(memberName, memberResult[j]);
        }else{
          console.log("Not Found : "+htmlTableId);
        }
      }
    }
  }else{
      
      var memberResult = memberResults;
      var memberName = "";
      for(var j=0; j<memberResult.length; j++){
        var htmlTableId = generateTableIdForObjectsTable(memberName, memberResult[j].objectType);
        
        if($('#'+htmlTableId)){
          createResultGrid(memberName, memberResult[j]);
        }else{
          console.log("Not Found : "+htmlTableId);
        }
      }
  }
}

// Function to delete previous queries results from UI
function deleteExistingResultGrids(){
  if(responseResult == undefined || responseResult == null){
    return;
  }
  
  var memberResults = responseResult.result;

  if(memberResults.length == 0){
    return;
  }

  if(memberResults[0].member != undefined || memberResults[0].member != null){
    for(var i=0; i<memberResults.length; i++){
      
      var memberResult = memberResults[i].result;
      var memberName = memberResults[i].member[1];
      for(var j=0; j<memberResult.length; j++){
        var htmlTableId = generateTableIdForObjectsTable(memberName, memberResult[j].objectType);
        
        if($('#'+htmlTableId)){
          $('#'+htmlTableId).jqGrid('GridDestroy');
        }else{
          console.log("Not Found : "+htmlTableId);
        }
      }
    }
  }else{
    var memberResult = memberResults;
    var memberName = "";
    for(var j=0; j<memberResult.length; j++){
      var htmlTableId = generateTableIdForObjectsTable(memberName, memberResult[j].objectType);
      
      if($('#'+htmlTableId)){
        $('#'+htmlTableId).jqGrid('GridDestroy');
      }else{
        console.log("Not Found : "+htmlTableId);
      }
    }
  }
}

// Function to create single results grid
function createResultGrid(member, memberResultObject){
  var objectType = memberResultObject.objectType;
  // make a copy of memberResultObject.objectResults
  var objectResults = jQuery.extend(true, [], memberResultObject.objectResults);
  var htmlTableId = generateTableIdForObjectsTable(member, objectType);
  
  // TODO Following code section should be removed once to string representation 
  // is finalized in same scenario 
  // If results set is java primitive collection of HashMap then following 
  // custom representation is needed
  /*var customObjectResults = new Array();
  if(objectType.indexOf("java.util.HashMap") != -1){
    // generate customized objectResults
    for(var cnt=0; cnt<objectResults.length; cnt++){
      var uid = objectResults[cnt].uid;
      delete objectResults[cnt].uid;
      var newEntry = {"uid":uid, "result":["java.util.HashMap",objectResults[cnt]]};
      customObjectResults.push(newEntry);
    }
    // replace existing objectResults by new customObjectResults
    objectResults = customObjectResults;
  }*/
  
  // Determine table columns
  var columnName = [];
  var columnModel = [];
  for(var cnt=0; cnt<objectResults.length; cnt++){
    for(key in objectResults[cnt]){
      if(-1 == columnName.indexOf(key)){
        // add column and column model only if not present
        columnName.push(key);
        columnModel.push({name:key, index:key, width:150});
      }
    }
  }
  
  // set custom column widths if less columns
  if(columnModel.length == 2){
    for(var c=0; c<columnModel.length; c++){
      columnModel[c].width = 660;
    }
  }else if(columnModel.length == 3){
    for(var c=0; c<columnModel.length; c++){
      columnModel[c].width = 330;
    }
  }else if(columnModel.length == 4){
    for(var c=0; c<columnModel.length; c++){
      columnModel[c].width = 220;
    }
  }
  
  // Delete jqgrid if already exists
  $("#"+htmlTableId).jqGrid('GridDestroy');
  
  // Determine Grid's Height
  var gridheight = 30;
  if(objectResults.length > 0 && objectResults.length < 6){
    gridheight += objectResults.length * 26;
  }else{
    gridheight = 160;
  }
  
  // Create jqgrid 
  jQuery("#"+htmlTableId).jqGrid({
                  datatype: "local",
                  width : 668,
                  height: gridheight,
                  shrinkToFit : false,
                  colNames:columnName,
                  colModel:columnModel,
                  ondblClickRow:displayPopUpObjectExplorer,
                  gridComplete : function() {
                    $(".jqgrow").css({
                      cursor : 'default'
                    });

                    var gridList = $('#gview_'+htmlTableId);
                    var gridListChild = gridList.children('.ui-jqgrid-bdiv');

                    gridListChild.unbind('jsp-scroll-x');
                    gridListChild.bind('jsp-scroll-x', function(event,
                        scrollPositionX, isAtLeft, isAtRight) {
                      var mRList = $('#gview_'+htmlTableId);
                      var mRLC = mRList.children('.ui-jqgrid-hdiv').children(
                          '.ui-jqgrid-hbox');
                      mRLC.css("position", "relative");
                      mRLC.css('right', scrollPositionX);
                    });
                  },
                  resizeStop : function(width, index) {

                    var gridList = $('#gview_'+htmlTableId);
                    var gridListChild = gridList.children('.ui-jqgrid-bdiv');
                    var api = gridListChild.data('jsp');
                    api.reinitialise();

                    gridList = $('#gview_'+htmlTableId);
                    gridListChild = gridList.children('.ui-jqgrid-bdiv');
                    gridListChild.unbind('jsp-scroll-x');
                    gridListChild.bind('jsp-scroll-x', function(event,
                        scrollPositionX, isAtLeft, isAtRight) {
                      var mRList = $('#gview_'+htmlTableId);
                      var mRLC = mRList.children('.ui-jqgrid-hdiv').children(
                          '.ui-jqgrid-hbox');
                      mRLC.css("position", "relative");
                      mRLC.css('right', scrollPositionX);
                    });
                  }
          });
  
  // Hide "uid" column as it contains program generated unique id of row
  $("#"+htmlTableId).jqGrid('hideCol',columnName[columnName.indexOf("uid")]);
  
  // Remove type details from values
  for(var i=0; i<objectResults.length; i++){
    for(key in objectResults[i]){
      var arrVals = objectResults[i][key];
      if(arrVals != null && arrVals != undefined){
        if($.isArray(arrVals)){
          if(arrVals.length == 2){
            if(typeof (arrVals[1]) == "object"){ // if object, display its type as value
              objectResults[i][key] = arrVals[0];
            }else{ // else display its value
              objectResults[i][key] = arrVals[1];
            }
          }else{ // if ArrayList object, display its type as value
            objectResults[i][key] = arrVals[0];
          }
        }
      } 
    }
  }

  // Clear grid before populating rows into it
  $("#"+htmlTableId).jqGrid('clearGridData');
  $("#"+htmlTableId).jqGrid('addRowData',columnName[columnName.indexOf("uid")],objectResults);
}

// Function that displays object explorer in pop up
function displayPopUpObjectExplorer(rowId, rowIndex, columnIndex, event){
  //console.log("Row clicked: "+rowId+" "+rowIndex+" "+columnIndex+" "+event);
  
  var rowIdSplits = rowId.split('*');
  var selMember = null
  var selMemObject = null;
  var selMemObjectRow = null;
  var selectedRowData = null;
  
  if(rowIdSplits.length == 2){
    selMemObject = rowIdSplits[0];
    selMemObjectRow = rowIdSplits[1];
  }else if(rowIdSplits.length == 3){
    selMember = rowIdSplits[0];
    selMemObject = rowIdSplits[1];
    selMemObjectRow = rowIdSplits[2];
  }else{
    console.log("Incomplete inputs ");
    return;
  }
  
  var resResults = responseResult.result;
  var memberResults = null;
  var memberObjectResults = null;
  
  if(rowIdSplits.length == 2){
    memberResults = resResults;
  }else if(rowIdSplits.length == 3){
    for(var i=0; i< resResults.length; i++){
      if(resResults[i].member[1] == selMember){
        memberResults = resResults[i].result;
        break;
      }
    }
  }
  
  for(var i=0; i< memberResults.length; i++){
    // replace "[]" by "BxBr"
    var objType = memberResults[i].objectType.replace("[]", 'BxBr');
    if(objType == selMemObject){
      memberObjectResults = memberResults[i].objectResults;
      break;
    }
  }
  
  for(var i=0; i< memberObjectResults.length; i++){
    /*if(memberObjectResults[i].ID[1] == selMemObjectRow){
      selectedRowData = memberObjectResults[i];
      break;
    }*/
    if(memberObjectResults[i].uid == rowId){
      selectedRowData = memberObjectResults[i];
      break;
    }
  }
  
  var popUpData = formDataForPopUpGrid(selectedRowData);
  
  // clear pop grid data
  gridElement.jqGrid('clearGridData');
  // add pop grid new data
  gridElement[0].addJSONData({
    total : 1,
    page : 1,
    records : popUpData.length,
    rows : popUpData
  });
  
  // Display pop up grid
  $('#gridPopup').show();
  $('.ui-jqgrid-bdiv').jScrollPane();

  // Attaching handler to each row in object explorer to update vertical
  // scrollbar when user expands/collapse tree grid row
  $('div.tree-plus').click(function() {
    $('.ui-jqgrid-bdiv').jScrollPane();
  });
                  
  // Get the screen height and width
  var maskHeight = $(document).height();
  var maskWidth = $(window).width();

  //Set heigth and width to mask to fill up the whole screen
  $('#mask').css({'width':maskWidth,'height':maskHeight});
  
  //transition effect             
  $('#mask').fadeIn(1000);        
  $('#mask').fadeTo("fast",0.8);  

  //Get the window height and width
  var winH = $(window).height();
  var winW = $(window).width();

  //Set the popup window to center
  $('#gridPopup').css('top',  winH/2-$('#gridPopup').height()/2);
  $('#gridPopup').css('left', winW/2-$('#gridPopup').width()/2);

}

// Creates pop grid
function createPopUpObjectExplorer(){
  gridElement = $("#popUpExplorer");
  gridElement.jqGrid({
      datatype: "local",
      colNames:["Id","Key","Value","Type"],
      colModel:[
          {name:'id', index:'id', width:1, hidden:true, key:true},
          {name:'key', index:'key', width:220},
          {name:'value', index:'value', width:220},
          {name:'type', index:'type', width:230}
      ],
      cmTemplate: {sortable:false},
      height: '220',
      gridview: true,
      rowNum: 10000,
      sortname: 'id',
      treeGrid: true,
      treeGridModel: 'adjacency',
      treedatatype: "local",
      ExpandColumn: 'key',
  });
  
  gridElement.jqGrid('clearGridData');
  
}

// Function to prepare data for pop up object explorer
function formDataForPopUpGrid(data){
  
  var newArray = [];
  var idCounter = 1;

  function traverse(object, level, parentId) {
      for (var prop in object) {
          if (typeof(object[prop]) == "object") {
            if($.isArray(object[prop])){
              
              var arrObj = object[prop];
              if(arrObj.length == 2){
                
                if (typeof(arrObj[1]) == "object") {
                  //newArray.push({'key':prop, 'value':arrObj[1], 'type':arrObj[0]});
                  newArray.push({
                    'id':idCounter++,
                    'key':prop, 
                    'type':arrObj[0],
                    'value':"", // ignore value for composite data
                    'level':level,
                    'parent':parentId,
                    'isLeaf':false,
                    'expanded':false,
                    'loaded':true
                    });
                
                  //going on step down in the object tree!!
                  traverse(arrObj[1], level+1, idCounter-1);
                }else{
                  //newArray.push({'key':prop, 'value':arrObj[1], 'type':arrObj[0]});
                  newArray.push({
                    'id':idCounter++,
                    'key':prop, 
                    'type':arrObj[0],
                    'value':arrObj[1],
                    'level':level,
                    'parent':parentId,
                    'isLeaf':false,
                    'expanded':false,
                    'loaded':true
                    });
                }
              }else{
                //newArray.push({'key':prop, 'value':object[prop], 'type':typeof(object[prop])});
                newArray.push({
                  'id':idCounter++,
                  'key':prop, 
                  'type':typeof(object[prop]),
                  'value':object[prop],
                  'level':level,
                  'parent':parentId,
                  'isLeaf':false,
                  'expanded':false,
                  'loaded':true
                  });
                
                // todo : multiple value traversing in array
              }
            }else{
              newArray.push({
                'id':idCounter++,
                'key':prop, 
                'type':"object",
                'value':"", // ignore value for composite data
                'level':level,
                'parent':parentId,
                'isLeaf':false,
                'expanded':false,
                'loaded':true
                });
              //going on step down in the object tree!!
              traverse(object[prop], level+1, idCounter-1);
            }
              
          }else{
            //console.log(prop + " : "+object[prop]);
            if(prop != "uid"){
              newArray.push({
                  'id':idCounter++,
                  'key':prop, 
                  'type':typeof(object[prop]),
                  'value':object[prop],
                  'level':level,
                  'parent':parentId,
                  'isLeaf':false,
                  'expanded':false,
                  'loaded':true
                  });
            }
          }
      }
  }

  // start traversing into data object 
  traverse(data, 0, 0);
  
  return newArray;
}

//Function for converting raw response into expected format
function convertRawResponseToExpectedFormat(rawResponeData){
  
  if(rawResponeData == null || rawResponeData == undefined){
    return;
  }
  
  var finalResponseData = {};
  var finalResponseResults = [];
  
  if(rawResponeData.result != null || rawResponeData.result != undefined){
    var rawResponeDataResult = rawResponeData.result;
    
    for(var i=0; i<rawResponeDataResult.length; i++){
      if(rawResponeDataResult[i] != null){
        if(typeof(rawResponeDataResult[i]) == "object"){
          if($.isArray(rawResponeDataResult[i])){
            // Cluster level result set
            finalResponseResults = convertToExpectedObjectsFormat(rawResponeDataResult, "");
            break;
            
          }else if(rawResponeDataResult[i].member != null && rawResponeDataResult[i].member != undefined){
            
            var responseForMember = {};
            responseForMember.member = rawResponeDataResult[i].member[0];
            responseForMember.result = convertToExpectedObjectsFormat(rawResponeDataResult[i].result, rawResponeDataResult[i].member[0][1]);
            
            // add into final results
            finalResponseResults.push(responseForMember);
          }
        }
      }
    }
  }
  
  finalResponseData.result = finalResponseResults;
  //responseResult = finalResponseData;
  return finalResponseData;
}

// Function for converting raw response into expected object wise results format
function convertToExpectedObjectsFormat(rawResponseResult, prefixForId){
  
  var expResponseResult = [];
  
  if(rawResponseResult != null && rawResponseResult != undefined ){
    
    for(var i=0; i< rawResponseResult.length; i++){
      if(rawResponseResult[i] != null){
        
        if(expResponseResult.length > 0){
          // search expected object type in expResponseResult
          var flagObjectFound = false;
          for(var j=0 ; j < expResponseResult.length ; j++){
            if(expResponseResult[j].objectType == rawResponseResult[i][0]){
              // required object found
              flagObjectFound = true;
              var objectResults = expResponseResult[j].objectResults;
              var type = rawResponseResult[i][0];
              var entry = rawResponseResult[i][1];

              // if entry is not object then convert it into object
              if(typeof(entry) != "object" ){
                var entryObj = {};
                entryObj[type] = rawResponseResult[i][1];
                entry = entryObj;
              }

              // add unique id for new entry
              entry.uid = generateEntryUID(prefixForId, expResponseResult[j].objectType, objectResults.length);
              
              objectResults.push(entry);
              break;
            }
          }
          
          if(!flagObjectFound){  // required object not found in expResponseResult 
            
            var objectResults = [];
            var type = rawResponseResult[i][0];
            var entry = rawResponseResult[i][1];

            // if entry is not object then convert it into object
            if(typeof(entry) != "object" ){
              var entryObj = {};
              entryObj[type] = rawResponseResult[i][1];
              entry = entryObj;
            }

            // add unique id for new entry
            entry.uid = generateEntryUID(prefixForId, type, objectResults.length);
            
            objectResults.push(entry);
            
            var newResultObject = {};
            newResultObject.objectType = type;
            newResultObject.objectResults = objectResults;
            
            expResponseResult.push(newResultObject);
          }
          
        }else{  // expResponseResult is empty
          
          var objectResults = [];
          var type = rawResponseResult[i][0];
          var entry = rawResponseResult[i][1];

          // if entry is not object then convert it into object
          if(typeof(entry) != "object" ){
            var entryObj = {};
            entryObj[type] = rawResponseResult[i][1];
            entry = entryObj;
          }

          // add unique id for new entry
          entry.uid = generateEntryUID(prefixForId, type, objectResults.length);
          
          objectResults.push(entry);
          
          var newResultObject = {};
          newResultObject.objectType = type;
          newResultObject.objectResults = objectResults;
          
          expResponseResult.push(newResultObject);
        }
        
      }
    }
  }
  
  return expResponseResult;
}

// Function to generate unique idetifier for entry
function generateEntryUID(prefixForId, type, len) {

  var uid = "";

  if(type.indexOf("[]") != -1){
    type = type.replace("[]","BxBr");
  }

  if (prefixForId != "") {
    uid = prefixForId + "*" + type + "*" + len;
  } else {
    uid = type + "*" + len;
  }

  return uid;
}

// Function that posts the query result response received to backend in order
// export it into file
function exportResult() {
 var queryText = $('#dataBrowserQueryText').val();
  var selectedMemberNames = "";

  if(isEmpty(queryText)){
    alert("Please enter query to execute..");
    return;
  }

  // Determine selected members query to be execute on
  if($("#membersList").html() != ""){
    var selectedMembers = $( "input[type=checkbox][name=Member]:checked" );
    for(var i=0; i< selectedMembers.length; i++){
      if(selectedMemberNames == ""){
        selectedMemberNames = selectedMembers[i].value;
      }else{
        selectedMemberNames += ","+selectedMembers[i].value;
      }
    }
  }

     window.open("dataBrowserExport?query=" + encodeURIComponent(queryText) + "&members=" + encodeURIComponent(selectedMemberNames), "_blank");
}
