<?php

$tally_version = "v2.10";

/*
   Arguments:

   v=varname
      increment named variable by 1
   f=filename
      file containing the counts (default is tally.txt)
   d=varname:color[:label][,...]
      display vars list as comma-separated list of colon-separated tuples
   r=range
      display range, max count-bar width in pixels (default 400)
   m=msg
      display the message only

   If no arguments given, will just declare the functions and emit nothing.
 */

$tally_range = $r; if (! $tally_range) $tally_range = 400;
$tally_file = ($f ? $f : 'tally.txt');
$tally_var = $v;
$tally_display = $d;
$tally_message = $m;

/* read and/or modify the counts in the file */
function updatecount( $filename, $var, $incr = 1 ) {
   global $tally_file;
   if (!$filename) $filename = $tally_file;
   $fp = fopen($filename, "r+");
   if ($fp) {
      $lines = array();
      if ($var && $incr != 0)
         flock($fp, LOCK_EX);
      $found=0;
      while (($linebuf = fgets($fp)) || !feof($fp)) {
         if (strncmp($linebuf, "$var=", strlen($var)+1) == 0) {
            list($name, $count) = split('=', $linebuf, 2);
            $count += $incr;
            $linebuf = "$var=$count\n";
            $found = 1;
         }
         $lines[] = $linebuf;
      }
      if ($var && !$found) $lines[] = "$var=$incr\n";
      if ($var && $incr != 0) {
         fseek($fp, 0, SEEK_SET);
         //rewind($fp);
         fwrite($fp, join($lines, ''));
         ftruncate($fp, ftell($fp));
         flock($fp, LOCK_UN);
         sleep(1);
      }
   }
   fclose($fp);
   return $lines;
}

function tally_counts( $counts, &$which ) {
   if (! is_array($counts))
      $counts = updatecount($counts, "");
   $tally = array();
   foreach ($counts as $nameval) {
      foreach ($which as $name => $color) {
         $len = strlen($name);
         if (strncmp($nameval, "$name=", $len+1) == 0) {
            $cnt = 0 + substr($nameval, $len+1);
            $tally[$name] = $cnt;
            if ($cnt > $maxcnt) $maxcnt = 0;
         }
      }
   }
   return $tally;
}

function tally_parse_which( $str, &$which_map, &$labels_map ) {
   $pairs = split(',', $str);
   $which_map = array();
   foreach ($pairs as $nameval) {
      list($name, $color, $label) = split(':', $nameval);
      $which_map[$name] = urldecode($color);
      $labels_map[$name] = $label;
   }
}

function report_counts( $counts, &$which, $range = 400, &$labels_map = null ) {
   global $tally_file;
   if (!$counts) $counts = $tally_file;
   if (! is_array($which)) {
      // note: # in arglist comments out rest of string!
      // must encode # as %23 to pass
      tally_parse_which($which, $which_map, $labels_map);
      $which = $which_map;
   }
   $tally = tally_counts($counts, $which);
   $maxcount = 0;
   foreach ($tally as $name => $count) {
      if ($count > $maxcount) $maxcount = $count;
   }
   if ($maxcount > 0) {
      $mag = min(10, $range / $maxcount);
   }
   else
      $mag = 10;
   $html = "";
   $html .= "<table border=0 cellspacing=0 cellpadding=0><tr align=left><td\n>";
   foreach (array_keys($which) as $name) {
      $count = $tally[$name];
      $tag = '';
      if ($labels_map) $tag = $labels_map[$name];
      if (! $tag) $tag = $name;
      $width = (int)($mag * $count);
      $color = $which[$name];
      $html .= "$tag: $count<br>";
      $html .= "<table width=$width border=0 cellpadding=0 cellspacing=0>";
      $html .= "<tr><td bgcolor=$color>&nbsp;</td></tr></table\n>";
   }
   $html .= "</td></tr></table\n>";
   $tally = null;
   return $html;
}

// v=var : increment var
if ($tally_var) {
   //global $tally_file, $tally_var;
   $counts = updatecount($tally_file, $tally_var);
}

if ($tally_message) {
   $html .= "<h2>$tally_message</h2>";
   $html .= "Click 'Back' to return to the page.";
   echo $html;
}

// d=var1:color,var2:color2,...
if ($tally_display) {
   //global $tally_file, $tally_var, $tally_display;
   $html = '';
   if ($tally_var) $html .= '<h2>Thanks!</h2>';
   tally_parse_which($tally_display, $report_on, $label_on);
   $html .= report_counts('', $report_on, $tally_range, $label_on);
   echo $html;
}
// else if neither, just define the functions

?>
