// Lightstreamer Monitor Console Demo
// Table Management for the Log Section

//////////////// Utilities to Handle Splitting of Long Messages

  // Utility class, to split text at a configurable row length
  // Note: setting setPushedHtmlEnabled(true) on the visual table is needed
  // in order to render the splitting; however, any HTML markup in the original
  // text is quoted
  function StringBreaker(limit) {
    this.limit = limit;
    this.patternS = "(";
    for (var i = 0; i < limit; i++) {
      this.patternS += "\\S";
    }
    this.pattern = new RegExp(this.patternS + ")", "g");
    // for Konqueror and Safari use &shy; instead of <wbr>
    // (on the other hand Opera requires a "wbr:after" stylesheet definition)
    this.shy = (navigator.vendor == 'KDE' || navigator.userAgent.toLowerCase().indexOf("safari") != -1)
    this.repl = this.shy ? "$1&shy;" : "$1:;-=W";
  }

  // insert soft breaks in long text
  StringBreaker.prototype.breakString = function(source) {
    var target = source.replace(this.pattern, this.repl);
    target = target.replace(/</g, "&lt;");
    if (!this.shy) {
      target = target.replace(/:;-=W/g, "<wbr>");
    }
    return target;
  };

  //StringBreaker instance for THREAD fields
  var sbThread = new StringBreaker(5);
  //StringBreaker instance for MESSAGE fields
  var sbMessage = new StringBreaker(20);
  //StringBreaker instance for CLIENT.NAME fields
  var sbHostname = new StringBreaker(5);


//////////////// Scriptaculous Configuration for History-Limit Slider

  // number of admitted rows on scroll tables
  var limitRows = 50;

  var rowValues = new Array();
  for (var x = 1; x <= 1000; x+=10) {
    if (x == 11) {
      x = 10;
    }
    rowValues[rowValues.length] = x;
  }

  new Control.Slider('handleSelectLimit','selectLimit',{sliderValue:limitRows,values:rowValues,step:10,increment:10,range:$R(1,1000),
    onSlide:function(v){
      var txt = v.toString();
      if (txt.length == 1) {
        document.getElementById("nowLimit").innerHTML = "0" + txt ;
      } else {
        document.getElementById("nowLimit").innerHTML = v;
      }
    },
    onChange:function(v){
      this.onSlide(v);
      if (limitRows != v) {
        errorsTable.setMaxDynaRows(v);
        warningsTable.setMaxDynaRows(v);
        activitiesTable.setMaxDynaRows(v);
        limitRows = v;
      }
    }
  });


//////////////// Handling of the Filtering Notification Led

  var lostPhase = 0;

  function checkUpdateCount(item, info) {
    // the "COUNTER" field is a progressive update counter provided by the Data
    // Adapter for each log-related item, which starts at subscription time.
    // If any index is missed, then some updates were lost (this is possible
    // as the log-related items are subscribed to with filtering enabled)
    
    var oldCounter = info.getOldValue("COUNTER");
    var newCounter = info.getNewValue("COUNTER");
    if (oldCounter != null && newCounter != null) {
      if (Number(newCounter) > (Number(oldCounter) + 1)) {
        lostPhase++;
        var currLed = document.getElementById("luSignal").src;
        if (currLed != null && currLed.indexOf("led_on.gif") == -1) {
          document.getElementById("luSignal").src = "images/led_on.gif";
        }
        setTimeout("ledOff("+lostPhase+")",1000);
          // the led will be switched off in one second, provided that no more
          // filtering occurs in the meantime
      }
    }
  }

  function ledOff(callPhase) {
    if (callPhase == lostPhase) {
      document.getElementById("luSignal").src = "images/led_off.gif";
    }
  }


//////////////// Subscription and Update Management for the Error Message Table

  var errorsGroup = ["monitor_log_error"];
  var errorsSchema = ["TIME","MESSAGE","THREAD","COUNTER"];

  // create a DynaScrollTable
  var errorsTable = new DynaScrollTable(errorsGroup, errorsSchema, "DISTINCT");

  errorsTable.setDataAdapter("MONITOR");
  errorsTable.setUpwardScroll(true);
  errorsTable.setAutoScroll("ELEMENT", "errTBody");
  errorsTable.setMaxDynaRows(limitRows);
  errorsTable.setPushedHtmlEnabled(true);
  errorsTable.setRequestedBufferSize(5);
  errorsTable.onItemUpdate = checkUpdateCount;
  
  // define visual effects and formatting
  errorsTable.onChangingValues = function(domNode, VisualUpdateInfo) {
    if (VisualUpdateInfo != null) {
      VisualUpdateInfo.setHotTime(0);
      VisualUpdateInfo.setRowStyle("lscolderr", "lscolderr");

      // format long values
      var value = VisualUpdateInfo.getServerValue("MESSAGE");
      if (value != null) {
        value = sbMessage.breakString(value);
        VisualUpdateInfo.setFormattedValue("MESSAGE", value);
      }

      value = VisualUpdateInfo.getServerValue("THREAD");
      if (value != null) {
        value = sbThread.breakString(value);
        VisualUpdateInfo.setFormattedValue("THREAD", value);
      }
    }
  };

  // bind the table to the corresponding HTML template
  pushPage.addTable(errorsTable, "errors");


//////////////// Subscription and Update Management for the Warning Message Table

  var warningsGroup = ["monitor_log_warning"];
  var warningsSchema = ["TIME","MESSAGE","THREAD","COUNTER"];

  // create a DynaScrollTable
  var warningsTable = new DynaScrollTable(warningsGroup, warningsSchema, "DISTINCT");

  warningsTable.setDataAdapter("MONITOR");
  warningsTable.setUpwardScroll(true);
  warningsTable.setAutoScroll("ELEMENT","warTBody");
  warningsTable.setMaxDynaRows(limitRows);
  warningsTable.setPushedHtmlEnabled(true);
  warningsTable.setRequestedBufferSize(5);
  warningsTable.onItemUpdate = checkUpdateCount;

  // define visual effects and formatting
  warningsTable.onChangingValues = function(domNode, VisualUpdateInfo) {
    if (VisualUpdateInfo != null) {
      VisualUpdateInfo.setHotTime(0);
      VisualUpdateInfo.setRowStyle("lscoldwar", "lscoldwar");

      // format long values
      var value = VisualUpdateInfo.getServerValue("MESSAGE");
      if (value != null) {
        value = sbMessage.breakString(value);
        VisualUpdateInfo.setFormattedValue("MESSAGE", value);
      }

      value = VisualUpdateInfo.getServerValue("THREAD");
      if (value != null) {
        value = sbThread.breakString(value);
        VisualUpdateInfo.setFormattedValue("THREAD", value);
      }
    }
  };

  // bind the table to the corresponding HTML template
  pushPage.addTable(warningsTable, "warnings");


//////////////// Subscription and Update Management for the Activity Message Table

  var activitiesGroup = ["monitor_log_info"];
  var activitiesSchema = ["TIME","CLIENT.IP","CLIENT.NAME","MESSAGE","COUNTER"];

  // create a DynaScrollTable
  var activitiesTable = new DynaScrollTable(activitiesGroup, activitiesSchema, "DISTINCT");

  activitiesTable.setDataAdapter("MONITOR");
  activitiesTable.setUpwardScroll(true);
  activitiesTable.setAutoScroll("ELEMENT","actTBody");
  activitiesTable.setMaxDynaRows(limitRows);
  activitiesTable.setPushedHtmlEnabled(true);
  activitiesTable.setRequestedBufferSize(5);
  activitiesTable.onItemUpdate = checkUpdateCount;

  // define visual effects and formatting
  activitiesTable.onChangingValues = function(domNode, VisualUpdateInfo) {
    if (VisualUpdateInfo != null) {
      VisualUpdateInfo.setHotTime(0);
      VisualUpdateInfo.setRowStyle("lscoldact", "lscoldact");

      // format long values
      var value = VisualUpdateInfo.getServerValue("MESSAGE");
      if (value != null) {
        value = sbMessage.breakString(value);
        VisualUpdateInfo.setFormattedValue("MESSAGE", value);
      }

      value = VisualUpdateInfo.getServerValue("THREAD");
      if (value != null) {
        value = sbThread.breakString(value);
        VisualUpdateInfo.setFormattedValue("THREAD", value);
      }
    }
  };

  // bind the table to the corresponding HTML template
  pushPage.addTable(activitiesTable, "activities");
