<? 
/*
DemoChoice: Ranked Choice Web Polls
Copyright (C) 2001 Dave Robinson
See DemoChoice-Readme.txt for license information
Displays results in bar chart form for a given poll
*/

$rmax=getrandmax();
$Digits=0;
$pageconst=1000;
$dopage=true;
$ShowType="";
$TypeQuery="?type=";

if (array_key_exists("thickdot",$HTTP_GET_VARS))
{ $dotfile="dotline2.gif"; }
else
{ $dotfile="dotline.gif"; }
 
if (array_key_exists("charmax",$HTTP_GET_VARS))
{ $CharMax=1*$HTTP_GET_VARS["charmax"]; }
else
{ $CharMax=40; } 

if (array_key_exists("barht",$HTTP_GET_VARS))
{ $BarHeight=1*$HTTP_GET_VARS["barht"]; }
else
{ $BarHeight=12; } 

if (array_key_exists("cellpad",$HTTP_GET_VARS))
{ $CellPad=1*$HTTP_GET_VARS["cellpad"]; }
else
{ $CellPad=1; } 


$ThisFile="irsaresults.php";

require("dcconfigload.php");
require("irsaresultload.php");
$BalCt=$result['Ballots'];
$Cands=$result['Candidates'];
$Votons=$result['VotonsPerBallot'];
$WonInRound=$result['WonInRound'];
$Sort=$result['SortKey'];
$Sort[$Cands]=$Cands;
$Rnds=count($result['Round']);

$whotemp="";
if (array_key_exists("who",$HTTP_GET_VARS))
{
 $whotemp=rawurlencode($HTTP_GET_VARS['who']);
 $whotemp=str_replace("%40","@",$whotemp);
}
if ($NoRunningTally && $pwd!="" && $whotemp==$pwd) $NoRunningTally=false;
if ($Resultpwd && $pwd!="" && $whotemp!=$pwd) $NoRunningTally=true;

$page=0;

if (array_key_exists("nubal",$HTTP_POST_VARS))
{
 $NuBal['Ranklist']=array();
 $NuBalTemp=explode(",",$HTTP_POST_VARS["nubal"]);
 foreach ($NuBalTemp as $j)
  if ($j>=0 && $j<$Cands) array_push($NuBal['Ranklist'],$j);
 if (count($NuBal['Ranklist'])>0) $ValidBallot=true;
 else $ValidBallot=false;
} else $ValidBallot=false;

 function update(&$Ballot)
 {
  global $Cands,$Votons,$Maxima,$WonInRound;
  $Recycleto=$Cands;
  $VotonsLeft=$Votons;
  $LastWonInRound=0;
  $CandsRanked=count($Ballot['Ranklist']);
  for ($i=0; $i<=$Cands; $i++) $Ballot['wt'][$i]=0;
  $i=0;
  $j=0;
  while ($i<$CandsRanked && $VotonsLeft>0)
  {
   $j=$Ballot['Ranklist'][$i];
   if ($WonInRound[$j]==0)
   {
    if ($Maxima[$j]==0) { $i++; continue; }
    else 
    {
     $Ballot['wt'][$j]+=$VotonsLeft; $VotonsLeft=0;
    } 
   }
   else if ($LastWonInRound<$WonInRound[$j])
   {
    if ($VotonsLeft>$Maxima[$j])
    {
     $Ballot['wt'][$j]+=$Maxima[$j]; $VotonsLeft-=$Maxima[$j];
    } 
    else
    {
     $Ballot['wt'][$j]+=$VotonsLeft; $VotonsLeft=0;
    } 
    if ($Recycleto==$Cands) $Recycleto=$j; 
    $LastWonInRound=$WonInRound[$j];  
   }
   $i++;
  }
  if ($VotonsLeft>0)
  {
   $Ballot['wt'][$Recycleto]+=$VotonsLeft;
  }
 }

if (array_key_exists("barmax",$HTTP_GET_VARS))
{ $BarMax=1*$HTTP_GET_VARS["barmax"]; }
else
{ if ($ValidBallot) $BarMax=350; else $BarMax=500; }

$MaxVote=0;
for ($RndNum=0; $RndNum<$Rnds; $RndNum++)
{
 for ($CndNum=0; $CndNum<$Cands; $CndNum++)
 {
  if ($result['Round'][$RndNum]['Tally'][$CndNum]>$MaxVote)
  { $MaxVote=$result['Round'][$RndNum]['Tally'][$CndNum]; } 
 } 
} 
if ($result['Round'][0]['Enough']>$MaxVote)
{ $MaxVote=$result['Round'][0]['Enough']; } 

 $VotesCounted=0;
 $DepthMax=0;
 $DepthSum=0;
 for ($i=0; $i<$Cands; $i++)
 {
  if ($Status[$i]>0)
  { $VotesCounted+=$result['Round'][$Rnds-1]['Tally'][$i]; } 
  if ($result['Depth'][$i]>$DepthMax)
  { $DepthMax=$result['Depth'][$i]; }
  $DepthSum+=$result['Depth'][$i];  
 } 

 $PluralCounted=0;
 for ($i=0; $i<$Seats; $i++)
 { $PluralCounted+=$result['Round'][0]['Tally'][$Sort[$i]]; } 

function Dither($dithval)
{
 global $rmax;
 $dithint=intval($dithval);
 $dithfrac=$dithval-$dithint;
 if ((rand()/$rmax)<$dithfrac)
 { $dithint++; }
 return $dithint>0?$dithint:0;
} 

srand(1);
for ($i0=0; $i0<=$Cands; $i0++)
{
 $ColorStr[$i0]="#";
 for ($i1=1; $i1<=3; $i1++)
 { $ColorStr[$i0]=$ColorStr[$i0].dechex(intval((rand()/$rmax)*16))."0"; } 
} 

function PrintTitle()
{
 global $TitleLines, $Title, $Seats, $BalCt, $Votons;
 echo "<center><table cellspacing=4><tr><td align=center><b>DemoChoice Web Poll";
 if ($TitleLines>0)
 {
  echo ": ";
  for ($i=0; $i<$TitleLines; $i++)
  {
   echo $Title[$i];
   if ($i>0) { echo "<br>"; } else { echo " "; }
  }
 }
 echo "</b></td></tr><tr><td align=center>";
 echo $Seats." candidate";
 if ($Seats>1) { echo "s"; } 
 echo " will be elected with ".($BalCt>0?$BalCt:0)." ballot";
 if ($BalCt!=1) { echo "s"; }
 echo " cast";
 echo " (".$Votons." votons each)";
 echo ".</td></tr></table></center>";
}
//--------------------------------------------Start of output
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>DemoChoice Results</title>
<STYLE type="text/css">	
	H6 {page-break-after: always}
</STYLE>
</head>
<body bgcolor=white text=black style="font-family: arial;">
&nbsp;<br>
<? 
if (($result['Ballots']>0) && !$NoRunningTally)
{
 $ZeroSkip=0;
 ?><a name="FirstRound">&nbsp;</a><?
 for ($RndNum=0; $RndNum<$Rnds; $RndNum++)
 {
  $SkipZero=true;
  for($i2=0; $i2<count($result['Round'][$RndNum]['Transfer']); $i2++)
  {
   if (!(($result['Round'][$RndNum]['Tally'][$result['Round'][$RndNum]['Transfer'][$i2]['Candidate']]==0 &&
          $result['Round'][$RndNum]['Transfer'][$i2]['Action']=="ELIM") ||
         ($WonInRound[$result['Round'][$RndNum]['Transfer'][$i2]['Candidate']]<$RndNum+1 &&
          $result['Round'][$RndNum]['Transfer'][$i2]['Action']=="ELECTED")))
   $SkipZero=false;
  }
  if ($SkipZero && $RndNum<$Rnds-1) { $ZeroSkip++; continue; }

  $wonsofar=0;
  $CandsLeft=0;
  for ($i2=0; $i2<$Cands; $i2++)
  {
   if ($result['Round'][$RndNum]['Tally'][$i2]>=$result['Round'][$RndNum]['Enough']) $wonsofar++;
   if ($result['Round'][$RndNum]['Tally'][$i2]>0  || $result['Round'][$RndNum]['Maxima'][$i2]) $CandsLeft++;
  }

  ?><a name=Round<? echo $RndNum+1-$ZeroSkip; ?>>&nbsp;</a><?

  if ($RndNum==$Rnds-1) { echo "<a name=final>&nbsp;</a>"; }
  
  if ($CandsLeft==$Seats)
  {
   $ThreshSize=Dither($result['Round'][$RndNum]['Ideal']*$BarMax/$MaxVote);
   $CThreshSize=Dither($result['Round'][$RndNum]['Ideal']*$CharMax/$MaxVote);
  } 
  else
  {
   $ThreshSize=Dither($result['Round'][$RndNum]['Enough']*$BarMax/$MaxVote);
   $CThreshSize=Dither($result['Round'][$RndNum]['Enough']*$CharMax/$MaxVote);
  }

  PrintTitle();
?>
<p>
<a href="#FirstRound">First Round</a> |
<?
  if ($RndNum<$Rnds-1) { ?><a href="#Round<? echo $RndNum-$ZeroSkip+2; ?>"><b>Next Round</b></a> | <? } 
  ?><a href="#final">Final Round</a> | <?
  if ($RndNum>0) { ?><a href="#Round<?=$RndNum-$ZeroSkip; ?>">Previous Round</a> | <? } 
?>
<a href="#depth">Depth</a> |
<? if ($Seats>1) { ?><a href="#slices">Slices</a> | <? } ?>
<a href="<? echo $InfoFile; ?>">How it works</a> |
<a href="<? echo $HomeFile; ?>">Main Page</a>
<hr>
<table border=0 cellspacing=0 width="100%" cellpadding=<? echo $CellPad; ?>><tr><td>
<table border=0 cellspacing=0 cellpadding=<? echo $CellPad; ?>>
 <tr>
  <td width="25%"><b>Round <? echo $RndNum+1-$ZeroSkip; ?></b></td>
  <td align=right>&nbsp;Votons&nbsp;</td>
  <td>&nbsp;</td>
  <td>
   <table border=0 cellspacing=0 cellpadding=0>
    <tr>
     <td><?
      $CharStr="";
      for ($ichar=1; $ichar<=$CThreshSize; $ichar++)
      { $CharStr.="-"; } 
     ?><img border=0 height=<? echo $BarHeight; ?> width=<? echo max(1,$ThreshSize-10); ?>
        src=shim.gif alt="<? echo $CharStr; ?>"></td>
     <td><? echo round(100.0*$result['Round'][$RndNum][($CandsLeft==$Seats)?'Ideal':'Enough']/
                 ($result['Votons']-$result['Round'][$RndNum]['Tally'][$Cands]),1); ?>%</td>
    </tr>
   </table>
  </td>
 </tr>
<?
  for ($CndNum=0; $CndNum<=$Cands; $CndNum++)
  {
   if ($result['Round'][$RndNum]['Tally'][$Sort[$CndNum]]>0)
   {
    $BarSize=Dither($result['Round'][$RndNum]['Tally'][$Sort[$CndNum]]*$BarMax/$MaxVote);
    $CharSize=Dither($result['Round'][$RndNum]['Tally'][$Sort[$CndNum]]*$CharMax/$MaxVote);
?>
 <tr>
  <td><? echo $Name[$Sort[$CndNum]]; ?>&nbsp;</td>
  <td align=right><? echo $result['Round'][$RndNum]['Tally'][$Sort[$CndNum]]."&nbsp;"; ?></td>
  <td align=right><?
    if (!($Sort[$CndNum]==$Cands))
    {
     echo "(".number_format($result['Round'][$RndNum]['Tally'][$Sort[$CndNum]]*100.0/
           ($result['Votons']-$result['Round'][$RndNum]['Tally'][$Cands]),1)."%)&nbsp;";
    }
    else { echo "&nbsp;"; }
 ?></td>
  <td>
   <table border=0 cellspacing=0 cellpadding=0>
   <tr>
    <td bgcolor="<?=$ColorStr[$Sort[$CndNum]] ?>">
<?
    if ($BarSize<$ThreshSize)
    { 
     $CharStr="";
     for ($ichar=1; $ichar<=$CharSize; $ichar++)
     { $CharStr.=chr(65+$Sort[$CndNum]); }

?><img border=0 height=<? echo $BarHeight; ?> width=<? echo $BarSize; ?>
  src=shim.gif alt="<? echo $CharStr; ?>"></td><td><? 

     $CharStr="";
     for ($ichar=1; $ichar<=($CThreshSize-$CharSize); $ichar++) { $CharStr.=chr(95); } 

?><img border=0 height=<? echo $BarHeight; ?> width=<? echo $ThreshSize-$BarSize; ?> src=shim.gif 
  alt="<? echo $CharStr; ?>"></td><td><?

     if ($CndNum<$Cands)
     { ?><img border=0 height=<? echo $BarHeight; ?> src=<?=$dotfile; ?> alt=":"><? }
     else
     { ?><img border=0 width=1 height=<? echo $BarHeight; ?> src=shim.gif alt=" "><? }

?></td>
<td><img border=0 height=<? echo $BarHeight; ?> width=<? echo $BarMax-$ThreshSize; ?> src=shim.gif alt=" "><?

    } // barsize<ThreshSize
    else
    { 
     $CharStr="";
     for ($ichar=1; $ichar<=$CThreshSize; $ichar++)
     { $CharStr.=chr(65+$Sort[$CndNum]); } 

?><img border=0 width=<? echo $ThreshSize; ?> src=shim.gif alt="<? echo $CharStr; ?>"></td>
<td bgcolor="<?=$ColorStr[$Sort[$CndNum]] ?>"><?
 
     if ($CndNum<$Cands)
     { ?><img border=0 height=<? echo $BarHeight; ?> src=<?=$dotfile; ?> alt=":"><? }
     else
     { ?><img border=0 width=1 height=<? echo $BarHeight; ?> src=shim.gif alt=" "><? }

?></td><td bgcolor="<?=$ColorStr[$Sort[$CndNum]] ?>"><? 

     $CharStr="";
     for ($ichar=1; $ichar<=($CharSize-$CThreshSize); $ichar++) { $CharStr.=chr(65+$Sort[$CndNum]); } 

?><img border=0 height=<? echo $BarHeight; ?> width=<? echo $BarSize-$ThreshSize; ?>
 src=shim.gif alt="<? echo $CharStr; ?>"></td>
<td><img border=0 height=<? echo $BarHeight; ?> width=<? echo $BarMax-$BarSize; ?> src=shim.gif alt=" "><?

    } // else barsize >=ThreshSize
?></td>
    </tr>
   </table>
  </td>
 </tr>
<?
  } // vote > 0 
 } //CndNum

?><tr>
<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
<td><img border=0 height=10 width=<? echo $BarMax; ?> src=shim.gif alt=" "></td>
</tr><?
 
  if ($RndNum<$Rnds-1)
  {
   //Do XferMatrix

?>
<tr>
<td><b>Results</b></td>
<td colspan=2>&nbsp;</td>
<?
   if (count($result['Round'][$RndNum]['Transfer'])==0)
   {
    ?><td>No transfers</td></tr><?
   }
   else
   for ($x=0;$x<count($result['Round'][$RndNum]['Transfer']);$x++)
   {
    if ($x==0)
    {
     ?><td><b>Redistributed Votes</b> (to these colors)</td></tr> <?
    }
    if ($Excl[$result['Round'][$RndNum]['Transfer'][$x]['Candidate']]==true) continue;
    if ($result['Round'][$RndNum]['Transfer'][$x]['Action']=="ELECTED" &&
        $WonInRound[$result['Round'][$RndNum]['Transfer'][$x]['Candidate']]!=$RndNum+1)
     continue;
    if ($result['Round'][$RndNum]['Transfer'][$x]['Action']=="ELIM" &&
        $result['Round'][$RndNum]['Tally'][$result['Round'][$RndNum]['Transfer'][$x]['Candidate']]==0)
     continue;

?>
<tr><td><? echo $Name[$result['Round'][$RndNum]['Transfer'][$x]['Candidate']]; ?></td>
<? 

    if ($result['Round'][$RndNum]['Transfer'][$x]['Action']=="ELIM")
    { echo "<td colspan=2>Defeated</td>"; }
    else
    {
     if ($WonInRound[$result['Round'][$RndNum]['Transfer'][$x]['Candidate']]==$RndNum+1)
      echo "<td colspan=2>Elected</td>";
      else echo "<td colspan=2>Equalized</td>";
    }
 
?>
<td>
 <table border=0 cellspacing=0 cellpadding=0>
  <tr><? 

    for ($i0=0; $i0<=$Cands; $i0++)
    {
     if ($result['Round'][$RndNum]['Transfer'][$x]['Count'][$i0]>0)
     {
      $BarSize=Dither($result['Round'][$RndNum]['Transfer'][$x]['Count'][$i0]*$BarMax/$MaxVote);
      $CharSize=Dither($result['Round'][$RndNum]['Transfer'][$x]['Count'][$i0]*$CharMax/$MaxVote);
      $CharStr="";
      for ($ichar=1; $ichar<=$CharSize; $ichar++) { $CharStr.=chr(65+$i0); } 
?>
<td bgcolor="<? echo $ColorStr[$i0]; ?>"><img border=0 height=<? echo $BarHeight; ?>
 width=<? echo $BarSize; ?> src=shim.gif alt="<? echo $CharStr; ?>"></td>
<? 
     } // if 
    } // for
    echo "</tr></table></td></tr>";
   } // for each xfer
  } // done with xfers
  else
  {  //if final round

?>
<tr>
<td><b>Results</b></td>
<td colspan=3>&nbsp;</td>
</tr>
<? 

   for ($i0=0; $i0<$Cands; $i0++)
   {
    if ($result['Round'][$RndNum]['Tally'][$i0]>0)
    {
     ?><tr><td><? echo $Name[$i0]; ?></td><td colspan=2><? 
     if ($result['Round'][$RndNum]['Transfer'][$x]['Action']=="ELIM")
     { echo "Defeated"; }
     else
     { echo "Elected"; } 
     ?></td><td>&nbsp;</td></tr><? 
    } //Votematrix > 0
   } //i0
  } //final round

?><tr>
<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
<td><img border=0 height=10 width=<? echo $BarMax; ?> src=shim.gif alt=" "></td>
</tr><?

// -----------------------histograms
  if ($RndNum<$Rnds && $Seats>1)
  {
   $HistosToShow=0;
   $HistoHt=30;
   $HistoBalSumMax=0;
   for ($i=0; $i<count($result['Round'][$RndNum]['Transfer']); $i++)
   {
    if ($result['Round'][$RndNum]['Transfer'][$i]['Action']=='ENOUGH' ||
        $result['Round'][$RndNum]['Transfer'][$i]['Action']=='ENOUGH_1ST' ||
        $result['Round'][$RndNum]['Transfer'][$i]['Action']=='IDEAL' ||
        $result['Round'][$RndNum]['Transfer'][$i]['Action']=='IDEAL_1ST' ||
        ($result['Round'][$RndNum]['Transfer'][$i]['Action']=='ELECTED' &&
         $WonInRound[$result['Round'][$RndNum]['Transfer'][$i]['Candidate']]==$RndNum+1 &&
         $result['Round'][$RndNum]['Tally'][$result['Round'][$RndNum]['Transfer'][$i]['Candidate']]>=
         $result['Round'][$RndNum][($CandsLeft==$Seats)?'Ideal':'Enough']))
      $HistosToShow++;
    $HistoBalSum=0;
    for ($j=0; $j<count($result['Round'][$RndNum]['Transfer'][$i]['Histogram']); $j++)
     $HistoBalSum+=$result['Round'][$RndNum]['Transfer'][$i]['Histogram'][$j][1];
    if ($HistoBalSum>$HistoBalSumMax) $HistoBalSumMax=$HistoBalSum;
   }
   if ($HistoBalSumMax==0) $HistoBalSumMax=1;

   if ($HistosToShow>0)
   {
?>
 <tr>
  <td>
   <b>Histograms</b>
  </td>
  <td align=right>
   &nbsp;Surplus&nbsp;
  </td>
  <td align=middle>
   &nbsp;New Max&nbsp;
  </td>

  <td>
   Votons: Ballots
  </td>
 </tr>
<?
    for ($i=0; $i<count($result['Round'][$RndNum]['Transfer']); $i++)
    {
     if (!($result['Round'][$RndNum]['Transfer'][$i]['Action']=='ENOUGH' ||
         $result['Round'][$RndNum]['Transfer'][$i]['Action']=='ENOUGH_1ST' ||
         $result['Round'][$RndNum]['Transfer'][$i]['Action']=='IDEAL' ||
        ($result['Round'][$RndNum]['Transfer'][$i]['Action']=='ELECTED' &&
         $WonInRound[$result['Round'][$RndNum]['Transfer'][$i]['Candidate']]==$RndNum+1 &&
         $result['Round'][$RndNum]['Tally'][$result['Round'][$RndNum]['Transfer'][$i]['Candidate']]>=
         $result['Round'][$RndNum][($CandsLeft==$Seats)?'Ideal':'Enough']) ||
         $result['Round'][$RndNum]['Transfer'][$i]['Action']=='IDEAL_1ST')) continue;
     $HistoWho=$result['Round'][$RndNum]['Transfer'][$i]['Candidate'];
     $HistoMax=$result['Round'][$RndNum+1]['Maxima'][$HistoWho];
     ?>
 <tr>
  <td>
   <? echo $Name[$HistoWho]; ?>
  </td>
  <td align=right>
   <? echo $result['Round'][$RndNum]['Tally'][$HistoWho]-
           $result['Round'][$RndNum][($CandsLeft==$Seats)?'Ideal':'Enough']; ?>
  </td>
  <td align=middle>
   <? echo $HistoMax; ?>
  </td>
  <td>
   <table border=1 cellspacing=0 cellpadding=3>
    <tr>
<?
     for ($j=0; $j<count($result['Round'][$RndNum]['Transfer'][$i]['Histogram']); $j++)
     {
      $BinHt=$result['Round'][$RndNum]['Transfer'][$i]['Histogram'][$j][0];
      $BinWidth=$result['Round'][$RndNum]['Transfer'][$i]['Histogram'][$j][1];
      if ($BinHt<=0 || $BinWidth<=0) continue;
?>
     <td>
<?
      if ($BinHt>$HistoMax) echo "<font color=red>";
      echo $BinHt;
      if ($BinHt>$HistoMax) echo "</font>";
      echo ": ".$BinWidth;
?>
     </td>
<?
     } // each histo bin
?>
    </tr>
   </table>
  </tr>
<?
    } // each transfer element 
   } // some HistosToShow
  } // rndnum<Rnds for histogram

?></table></td><?

  if ($ValidBallot)
  { 

?><td>
In this round, your ballot counts for:<p>
<table border cellspacing=0 cellpadding=3>
<?
 
   $Maxima=$result['Round'][$RndNum]['Maxima'];
   update($NuBal);
   foreach ($NuBal['Ranklist'] as $i0)
   {
    echo "<tr><td>";
    if ($NuBal['wt'][$i0]==0) echo "&nbsp;";
    else echo $NuBal['wt'][$i0];
    echo "</td><td>".$Name[$i0]."</td></tr>";
   } 
   if ($Weight[$Cands]>0)
   {
    echo "<tr><td>"; 
    echo $NuBal['wt'][$Cands];
    echo "</td><td>".$Name[$Cands]."</td></tr>";
   }
   echo "</table><p></td>";
  } // if validballot

?></tr>
</table>
<?       
//------------------------Chart captions  ---- should walk through xfer array and comment
  
?><hr><p style="margin-left: 3%; font-face: times; font-size: smaller; margin-right: 3%;"><?

  if ($RndNum==0)
  {
?>
Each ballot initially counts <?=$Votons ?> votons toward its highest-ranked eligible choice.  However, in future rounds, a reduced maximum number of votons per ballot may be imposed on a candidate.  This allows voters for popular winners (or for eliminated losers) to help unelected candidates or candidates elected later.  If there are no such candidates, the votons go back to the first winner, or count toward &quot;none of these&quot; if there are no ranked winners.<br><br>
The number of votons per ballot is equal to Seats(Seats+1), which ensures that winners can always be kept between Enough votes to win and the Ideal Number of votes.<br>
If all winners have at least &quot;Enough&quot; votons, it is impossible to elect too many candidates.  This number is Ballots*(Seats)+1.<br>
If any winner has more than the &quot;Ideal Number&quot;, equal to Ballots*(Seats+1), it is impossible to elect enough candidates.  However, if all have exactly that number, every voter is equally represented.<br>
The dotted line on the graph represents <?
  echo ($CandsLeft==$Seats)?"the Ideal Number":"Enough votons"; ?>.<br>
<?
  } // RndNum==0
  $HasEnough=false;
  $HasEnough1=false;
  $HasIdeal=false;
  $HasIdeal1=false;
  $HasElim=false;
  $HasElected1=false;
  $HasTie=false;
  for ($i=0; $i<count($result['Round'][$RndNum]['Transfer']); $i++)
  {
   switch ($result['Round'][$RndNum]['Transfer'][$i]['Action'])
   {
    case 'ENOUGH': $HasEnough=true; break;
    case 'ENOUGH_1ST': $HasEnough1=true; break;
    case 'IDEAL': $HasIdeal=true; break;
    case 'IDEAL_1ST': $HasIdeal1=true; break;
    case 'ELIM': $HasElim=true; break;
    case 'ELECTED': if ($RndNum<$Rnds-1 &&
         $WonInRound[$result['Round'][$RndNum]['Transfer'][$i]['Candidate']]==$RndNum+1 &&
         $result['Round'][$RndNum]['Tally'][$result['Round'][$RndNum]['Transfer'][$i]['Candidate']]>=
         $result['Round'][$RndNum][($CandsLeft==$Seats)?'Ideal':'Enough']) $HasElected1=true;
   }
   if ($result['Round'][$RndNum]['Transfer'][$i]['Tie']) $HasTie=true;
  }
  if ($Seats>1 && ($HasElected1 || $HasIdeal || $HasIdeal1 || $HasEnough || $HasEnough1))
  {
?>
The histogram shows how many ballots count a given number of votons toward a winner.  It is used to determine how much to lower the maximum.  Ballots that count more than the maximum (because they cannot count for lower-ranked candidates) are not included.  The maximum is reduced one unit at a time, reducing the surplus by a number of votons equal to the number of ballots in the affected histogram bins.  This process stops just before too many would be transferred.  At this point, the affected bins are shown in red.<br>
All candidates may reduce their maxima when a newly elected can do so for the first time, or after an elimination.<br>
When only winners remain, they may reduce toward the Ideal Number when someone can do so for the first time, or in the round after that.<br> <br>
<?   
  }

  if ($HasElim)
  {
?>No elected candidates could reduce their maxima, so candidates were eliminated instead.<br><?
   if ($HasTie)
   {
?>There was a tie among last-place candidates, and they could not all be eliminated, so one was chosen randomly.<br><?
   }
   else
   {
?>The last-place candidate is eliminated, or possibly a group of them, if the sum of their votes is lower than any other candidate.<br><?
   }
  }
  if ($HasElected1)
  {
?>
There is a newly elected candidate whose maximum could not be reduced.  The surplus is lower than the number of ballots in the first histogram bin (the ballots counting the most votons toward the candidate), so they cannot all transfer a voton without exceeding the surplus.<br>
<?
  }
  if ($HasIdeal1 || $HasIdeal)
  {
?>
Only winners remain, so the dotted line is raised to the Ideal Number.<br>
<?
  }
  if ($RndNum==$Rnds-1)
  {
?>No further maximum reductions are allowed, so the count is complete.  All winners should be near the Ideal Number of votes.  Usually most ballots count toward their highest-ranked winner.  Some count for two winners, but rarely more than that.  See the  <a href="#slices">slice report</a>.  The <a href="#depth">depth report</a> shows the contribution of lower choices to the result.  The "none of these" pile is an accurate measure of unsatisfied voters.<br>
<?
  }
  else
  {
?>
Go to the <a href="#Round<?=$RndNum+2; ?>">next round</a>
<?
  }
?>
</p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<?
 } //round loop

 echo "<a name=depth>&nbsp;</a>";
 PrintTitle();

?>
<p>
<a href="<? if($page>0) echo $ThisFile."&amp;page=1"; ?>#Round1">First Round</a> |
<a href="#final">Final Round</a> |
 Depth |
<? if ($Seats>1) { ?><a href="#slices">Slices</a> | <? } ?>
<a href="<? echo $InfoFile; ?>">How it works</a> |
<a href="<? echo $HomeFile; ?>">Main Page</a>
<hr>
<b>Ballot Depth:</b> This shows how much the lower rankings on ballots contributed to the winning
candidate<? if ($Seats>1) { echo "s"; } ?>.<p>
<table border=0 cellspacing=0 cellpadding=<? echo $CellPad; ?>>
 <tr>
  <td width="5%">Rank</td>
  <td colspan=2>Fraction of votes for winner<? if ($Seats>1) { echo "s"; } ?></td>
 </tr> 
<?

 $SkipCt=0;
 if ($DepthMax==0) {$DepthMax=1;}
 for ($i0=0; $i0<($Cands-$Seats-$ExclCt); $i0++)
 {
  $BarSize=Dither($result['Depth'][$i0]*$BarMax/$DepthMax);
  $CharSize=Dither($result['Depth'][$i0]*$CharMax/$DepthMax);
  $CharStr="";
  for ($ichar=1; $ichar<=$CharSize; $ichar++) { $CharStr.=chr(88); } 
  if (($result['Depth'][$i0]/$DepthMax)>=0.0005)
  {
   echo "<tr><td>".($i0+1);
   $Suffixnum=($i0+1)%10;
   if ((($i0+1)>10) && (($i0+1)<14)) { $Suffixnum=0; } 
   if ($Suffixnum==1) {echo "st";} 
   if ($Suffixnum==2) {echo "nd";} 
   if ($Suffixnum==3) {echo "rd";} 
   if (($Suffixnum>3) || ($Suffixnum==0)) {echo "th";} 
   ?>&nbsp;</td><td width="5%" align=right><?
   echo number_format($result['Depth'][$i0]*100.0/$DepthSum,1)."%&nbsp;</td><td>";
   if ($result['Depth'][$i0]>0)
   {

?>
<table border=0 cellspacing=0 cellpadding=0>
 <tr>
  <td bgcolor="<? echo $ColorStr[$i0]; ?>"><img border=0 height=<? echo $BarHeight; ?> 
   width=<? echo $BarSize; ?> src=shim.gif alt="<? echo $CharStr; ?>"></td>
 </tr>
</table>
<? 

   } // depth > 0
   else
   { echo "&nbsp;"; } 
   echo "</td></tr>"; 
  } // depth vs depthmax
 } // for each depth index
?>
</table>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
&nbsp;
<? 
 if ($Seats>1)
 {
  echo "<a name=slices>&nbsp;</a>";
  PrintTitle();

?>
<p>
<a href="<? if($page>0) echo $ThisFile."&amp;page=1"; ?>#Round1">First Round</a> |
<a href="#final">Final Round</a> |
<a href="#depth"> Depth</a> |
Slices |
<a href="<? echo $InfoFile; ?>">How it works</a> |
<a href="<? echo $HomeFile; ?>">Main Page</a>
<hr>
<b>Slices:</b> This shows the distribution of how many winners a ballot counted for.<p>
<table border=0 cellspacing=0 cellpadding=<? echo $CellPad; ?>>
 <tr>
  <td width="5%">Slices</td>
  <td colspan=2>Percentage of ballots with that many slices</td>
 </tr> 
<?
  $SkipCt=0;
  $SliceMax=0;
  $SliceSum=0;
  for ($i0=0; $i0<$Seats; $i0++)
  {
   $SliceSum+=$result['Slices'][$i0];
   if ($result['Slices'][$i0]>$SliceMax) $SliceMax=$result['Slices'][$i0];
  }
  if ($SliceMax==0) {$SliceMax=1;}
  for ($i0=0; $i0<$Seats; $i0++)
  {
   $BarSize=Dither($result['Slices'][$i0]*$BarMax/$SliceMax);
   $CharSize=Dither($result['Slices'][$i0]*$CharMax/$SliceMax);
   $CharStr="";
   for ($ichar=1; $ichar<=$CharSize; $ichar++) { $CharStr.=chr(88); } 
   if (($result['Slices'][$i0]/$SliceMax)>=0.0005)
   {
    echo "<tr><td>".($i0+1);
    ?>&nbsp;</td><td width="5%" align=right><?
    echo number_format($result['Slices'][$i0]*100.0/$SliceSum,1)."%&nbsp;</td><td>";
    if ($result['Slices'][$i0]>0)
    { 

?>
<table border=0 cellspacing=0 cellpadding=0>
 <tr>
  <td bgcolor="<? echo $ColorStr[$i0]; ?>"><img border=0 height=<? echo $BarHeight; ?> 
   width=<? echo $BarSize; ?> src=shim.gif alt="<? echo $CharStr; ?>"></td>
 </tr>
</table>
<? 

    } // depth > 0
    else
    { echo "&nbsp;"; } 
    echo "</td></tr>"; 
   } // depth vs depthmax
  } // for each depth index
?>
</table>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
&nbsp;
<? 
 } // seats > 1 so show slices
}
else //no votes
{
 PrintTitle();
 if ($NoRunningTally)
 {
  echo "<p><hr><p><center>Results are not available until polling is over on ";
  echo date("F d, Y",$ExpireTime).".</center>";
 }
 else
 { echo "<p><hr><p><center>No votes have been cast yet.</center>"; }
 ?><p><center><a href="<? echo $HomeFile; ?>">Main Page</a></center><?
} // no votes 

?>
<p>
</body>
</html>
