<?php

$cache = resin_create_distcache("resin:admin:graph");

$p_hash = htmlspecialchars($_REQUEST['h']);

$p_submit = $_REQUEST['submit'];
$p_graph = htmlspecialchars($_REQUEST['user-meters']);
$p_period = htmlspecialchars($_REQUEST['p']);
if ($_REQUEST['period'])
  $p_period = htmlspecialchars($_REQUEST['period']);

$p_servers = explode(" ", htmlspecialchars($_REQUEST['server-set']));
$user = quercus_servlet_request()->getRemoteUser();

$user_item = $cache->get($user);
$is_refresh = false;

if ($p_graph) {
  $p_hash = $user_item['user-graphs'][$p_graph];
  $p_submit = null;

  if ($_POST['remove']) {
    unset($user_item['user-graphs'][$p_graph]);
    $cache->put($user, $user_item);
  }

  $is_refresh = true;
}

if ($p_hash && ! $p_submit) {
  $item = $cache->get($p_hash);
  $p_name = $item['name'];
  $p_checks = $item['checks'];
}
else if ($p_submit) {
  $is_refresh = true;

  $p_name = htmlspecialchars($_REQUEST['name']);
  $p_checks = array_map(htmlspecialchars, $_REQUEST['checks']);

  $item = array("name"=>$p_name,
                "checks"=>$p_checks);

  $ser = serialize($item);
  $p_hash = dechex(crc32($ser));

  $cache->put($p_hash, $item);

  if ($p_submit) {
    $user_graphs = $user_item['user-graphs'];
    if ($user_graphs == null) {
      $user_graphs = array();
    }

    $user_graphs[$p_name] = $p_hash;
    $user_item['user-graphs'] = $user_graphs;

    $cache->put($user, $user_item);
  }
}

$query = "&h=${p_hash}&p=${p_period}";

require_once "WEB-INF/php/inc.php";

if (! admin_init($query, false)) {
  return;
}

$stat = get_stats_service();

if (! require_professional()) {
  return;
} else if (! $stat) {
  echo "<div class=\"req-pro-message\">This feature requires &lt;resin:AdminServices/> in resin.xml</div>\n";
  return;
}

echo "<h1>";
echo gettext('Graphs');
echo print_help("Graphs");
echo "</h1>\n";

$names = array();

$full_height = 500;
$full_width = 600;

$mbean_server = $g_mbean_server;

if (! $p_period) {
  $p_period = (60 * 60);
}

$self_index = sprintf("%02d", $g_server->SelfServer->ClusterIndex);

if ($p_servers == null) {
  $p_servers = array($self_index);
}

foreach ($p_checks as $check) {
  foreach ($p_servers as $server) {
    if ($server == 'self')
      $server = $self_index;
      
    $p_names[] = "$server|$check";
  }
}

if (! $p_name)
  $p_name = $p_names[0];

echo "<div id='canvas-warning'><p>";
echo gettext('<b>Note:</b> this page requires HTML 5 canvas support.  You may need to use Firefox 3.5 or other HTML 5-capable browser to see the graphs properly.');
echo "</p></div>\n";

$user_graphs = $user_item['user-graphs'];

echo "<div id='graph-content'>\n";
echo ' <div style="float:left;width:75%;text-align:center;">';
echo "  <div class='graph' style='display:inline-block;text-align:left;'></div>";
echo ' </div>';
echo ' <div style="float:right;width:24%;border:1px solid black;padding:2px;">';
display_new_graph_form();
echo ' </div>';
echo ' <div style="clear:both;"></div>';
echo '</div>';

display_footer($g_page, javascript_main_graph());

function display_graph_selection()
{
  global $p_period;
  global $p_hash;
  global $user_item;
  global $g_next_url;
  global $g_server;
  global $self_index;
  global $g_periods;

  echo "<form name='def_graph' method='post' action='${g_next_url}'>";
  echo "<table>\n";

  echo "<tr><th scope='row' style='text-align:right'><label for='user-meters'>";
  echo gettext('Meter Set');
  echo "</label>: </th>\n";

  echo "<td><select name='user-meters' onchange='javascript:document.forms.def_graph.submit();' id='user-meters'>\n";

  $selected = false;
  foreach ($user_item['user-graphs'] as $name => $hash) {
    echo "<option ";
    if ($p_hash == $hash) {
      $selected = true;
      echo " selected";
    }
    echo " value='{$name}'>{$name}</option>\n";
  }
  if (! $selected)
    echo "<option selected='selected'>--------</option>\n";
  else
  	echo "<option>--------</option>\n";
  

  echo "</select>\n";

  $self_index = sprintf("%02d", $g_server->SelfServer->ClusterIndex);
  $cluster_size = count($g_server->Cluster->Servers);
  for ($i = 0; $i < $cluster_size; $i++) {
    if ($i > 0)
      $all .= ' ';

    $all .= sprintf("%02d", $i);
  }
  
	echo "<input type='hidden' name='server-self' value='${self_index}'/>\n";
  echo "<input type='hidden' name='server-all' value='${all}'/>\n";

  echo "</td></tr>\n";
  
  echo "<tr><th scope='row' style='text-align:right'><label for='period'>";
  echo gettext('Time');
  echo "</label>: </th>\n ";

  echo "<td><select name='period' id='period'>\n";
  
	foreach ($g_periods as $select_period => $name) {
		echo "     <option value='${select_period}'";
		if ($p_period == $select_period) {
			echo "selected='selected'";
		}
		echo ">${name}</option>\n";
	}

  echo "</select>\n";
  echo "</td></tr>\n";
  
  echo "<tr><th scope='row' style='text-align:right'><label for='server-set'>";
  echo gettext('Server Set');
  echo "</label>: </th>\n";

  echo "<td><select name='server-set' id='server-set'>\n";

  echo "<option value='self'";

  if ($_REQUEST['server-set'] == 'self')
    echo " selected";

  echo ">" . gettext('This Server') . "</option>\n";

  echo "<option value='cluster'";

  if ($_REQUEST['server-set'] == 'cluster')
    echo " selected";

  echo ">" . gettext('All servers, multi-graph') . "</option>\n";

  echo "<option value='combined'";

  if ($_REQUEST['server-set'] == 'combined')
    echo " selected";

  echo ">" . gettext('All servers, single graph') . "</option>\n";

  echo "</select>\n";
  
  echo "</td></tr>\n";
  echo "</table>\n";

  echo "</form>";
}

function display_new_graph_form() 
{
  global $p_period;
  global $p_hash;
  global $p_graph;
  global $p_names;
  global $g_next_url;
  global $g_mbean_server;

  display_graph_selection();

  $stat = $g_mbean_server->lookup("resin:type=StatService");

  if (! $stat)
    return;

  $full_names = $stat->statisticsNames();

  $names = array();
  $servers = array();
  foreach ($full_names as $name) {
    $values = preg_split('/[|]/', $name);

    $server = array_shift($values);

    if (! in_array($server, $servers)) {
      $servers[] = $server;
    }
    
    $section_array = null;
    $section_array[] = array_shift($values);
    $section_array[] = array_shift($values);

    $section = join($section_array, '|');

    $name = join($values, '|');

    $names = $sections[$section];
    if (! in_array($name, $names))
      $names[] = $name;
    $sections[$section] = $names;
  }

  // server
  echo "<div>";
  echo "<form name='name_form' method='post' action='${g_next_url}'>";
  echo "<input type='hidden' name='submit' value='true'/>\n";
  echo "<h2><span id='meter-switch' class='switch'></span>" . gettext('Meters') . "</h2>";
  echo "<button id='clear-graph' style='margin: 0 1em'>" . gettext('Clear Meters') . "</button>";

  $i = 0;

  ksort($sections);
  echo "<ul class='meters'>";
  foreach ($sections as $section => $names) {
    $i++;
    echo "<li class='meter-section'>";
    
    $section_id = "meter-" . crc32($section);
    echo "<span class='switch' id='$section_id'>$section</span>";

    sort($names);
    echo "<ul class='toggle-meter-switch toggle-$section_id'>";
    foreach ($names as $name) {
      echo "<li><input class='meter' type='checkbox' name='checks[]' ";

      $regexp = str_replace('|', '[|]', "/[0-9][0-9]|{$section}|{$name}/");

      if (preg_grep($regexp, $p_names)) {
        echo "checked ";
      }
      
      $id = str_replace(array(' ', '|', '%'), '', "$section|$name");
        
      echo "value='$section|$name' id='$id'/><label for='$id'>$name</label><br/>\n";
      echo "</li>\n";
    }
    echo "</ul>";
    echo "</li>";
  }
  echo "</ul>";

  echo "<div style='text-align:right'>\n";
  echo "<div id='validation-notice' class='ui-state-error ui-corner-all' style='display:none'></div>\n";

  echo "<label for='name'>";
  echo gettext('Meter Set Name');
  echo ":</label>\n";

  echo "<input name='name' style='width: 50%;' id='name'/>";
  echo "<input type='submit' value='" . gettext('Save Meters') . "'/><br/>\n";
  echo "</div>\n";

  echo "</form>\n";
  echo "</div>\n";
}

function javascript_main_graph()
{
  global $g_next_url;

  $width = '800';
  $height = '600';

  $meter_set_name = gettext('Meter Set Name');
  $select_meter_prompt = gettext('Please select at least one meter for this set');
  $supply_set_name_promtp = gettext('Please input a name for this meter set');

  $javascript = <<<EOF

if (document.createElement('canvas').getContext) {
  $("div#canvas-warning").hide();
  $("div#graph-content").show();
}

function GraphManager() {
  var graphDiv = $('div.graph');

  var updateGraph = function(element, canvasHtml) {
    if (canvasHtml.indexOf("<div") == 0) {
      element.empty();
      element.append(canvasHtml);
    }
    else {
      location.reload();
    }
  };

  var highlightSections = function() {
    $("li.meter-section").each(function() {
      var switchElement = $(this).find("span.switch");
      var meterCheckedCount = 
        $(this).find("input.meter:checkbox:checked").length;

      if (meterCheckedCount > 0) 
        switchElement.css("font-weight", "bold");
      else  
        switchElement.css("font-weight", "normal");
    });
  };

  var refresh = function() {
    highlightSections();

    var server_type = $("select[name=server-set] option:selected")
                        .attr("value");

    var servers;

    if (server_type == "self") {                     
      servers = [$("input[name=server-self]")
                   .attr("value")];
    }
    else {
      servers = $("input[name=server-all]")
                .attr("value")
                .split(" ");
    }
    
    var checks = $("input.meter:checkbox:checked").map(function() {
      return $(this).attr("value");
    });

    var period = $("select[name=period] option:selected").attr("value");

    // synchronize the period in the hidden input in the Meters form
    $("input[name=period]").attr("value", period);

    var isMultiGraph = 
      ($("select[name=server-set] option:selected").attr("value") == "cluster");

    if (isMultiGraph) {
      graphDiv.empty();

      $.each(servers, function(i, server) {
        var element = $("<div></div>");
        graphDiv.append(element);

        $.post("rest.php?q=graph",
               { canvas : "graph-" + server,
                 servers : [ server ],
                 checks : checks,
                 period : period,
                 width : "${width}",
                 height : "${height}" },
               function(canvasHtml) {
                 updateGraph(element, canvasHtml);
               },
               "text/html");
      });
    }
    else {
      $.post("rest.php?q=graph",
             { canvas : "graph-" + servers.join("-"),
               servers : servers,
               checks : checks,
               period : period,
               width : "${width}",
               height : "${height}" },
             function(canvasHtml) {
               updateGraph(graphDiv, canvasHtml);
             },
             "text/html");
    }   
  };

  refresh();
  window.setInterval(refresh, 60000);

  $("input.meter:checkbox").change(refresh);
  $("form[name=def_graph] :input:not(input[type=hidden])").change(refresh);
  $("select[name=period]").change(refresh);

  $("button#clear-graph").click(function() {
    $("input.meter:checkbox:checked").each(function() {
      $(this).attr("checked", false);
    });
    refresh();
    return false;
  });

  var nameInput = $("input[name=name]");

  nameInput.attr("value", "$meter_set_name");
  nameInput.css("color", "#999");
  nameInput.focusin(function() {
    if (nameInput.attr("value") == "$meter_set_name") {
      nameInput.attr("value", "");
      nameInput.css("color", "black");
    }
  });

  nameInput.focusout(function() {
    if (nameInput.attr("value") == "") {
      nameInput.attr("value", "$meter_set_name");
      nameInput.css("color", "#999");
    }
  });

  var validationNotice = $("#validation-notice");
  nameInput.closest("form").submit( function() {
    var html = "";

    if ($("input.meter:checkbox:checked").length == 0) {
      html += "$select_meter_prompt<br/>";
    }

    if (nameInput.attr("value") == "Meter Set Name"
        || nameInput.attr("value") == "") {
      html += "$supply_set_name_promtp<br/>";
    }

    if (html != "") {
      validationNotice.html(html);
      validationNotice.show();
      return false;
    }
  });
}

new GraphManager();

EOF;

  return $javascript;
}

?>
