<? 
/*
 DemoChoice: Ranked Choice Web Polls
 Instant Runoff with Self-Apportionment
 Copyright (C) 2008 Dave Robinson
 These are straightforward PHP translations of methods from the C++ version.
 The C++ version is more thoroughly commented.
 They are kept in a separate file to allow incirsatally to be called within loops
 (functions can't be redeclared)
*/

function GetPos(&$Ballot,$whichcand)
{
 global $Cands;
 $ThePos=0;
  while ($ThePos<count($Ballot['Ranklist']) && $Ballot['Ranklist'][$ThePos]!=$whichcand)
   $ThePos++;
 if ($ThePos==count($Ballot['Ranklist'])) $ThePos=$Cands;
 return $ThePos;
}

 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;
  }
 } 

 function newmax($Surplus, $Histo)
 {
  global $Votons;
  $votonsincluded=0;
  $ballotsincluded=0;
  $remain=0;
  $tempmax=$Votons;
  $prevmax=$Votons;
  
  for ($i=0; $i<count($Histo)-1; $i++)
  {
   $tempmax=$Histo[$i][0];
   if ($tempmax>$prevmax) break;
   $votonsincluded+=$ballotsincluded*($prevmax-$tempmax);
   if ($votonsincluded>$Surplus) break;
   $ballotsincluded+=$Histo[$i][1];
   $prevmax=$tempmax;
  } 
  if ($votonsincluded<$Surplus)
  {
   $tempmax=0;
   $votonsincluded+=$ballotsincluded*$prevmax;
  }
  if ($votonsincluded>$Surplus)
  {
   // interpolate
   if ($ballotsincluded!=0)
   {
    $tempmax+=floor(($votonsincluded-$Surplus)/$ballotsincluded);
    $remain=($votonsincluded-$Surplus)%$ballotsincluded;
    if ($remain!=0) $tempmax++;
   }
  }
  return $tempmax;
 }

?>
