<?php

$population=4200;
$popWidth=120;
$contactPerPerson=10; // number of contacts per person
$changeToGetSick=5;   // when you contact someone change to get infected
$changeToDie=3;       // when you are infected, change to die
$daysSick=10;         // days sick

$dead=-9;
$immune=-1;
$healthy=0;

function sick($personA, $personB) { // personA meets personB
  if ($personA > 0 AND $personB == 0) {  // personA is sick and personB not
    $random=rand(1,100);
    if ( $random <= $GLOBALS['changeToGetSick'] ) { // infection!
      // echo "Someone get sick";
      $personB=$GLOBALS['daysSick'];
    }
  }
  if ($personB > 0 AND $personA == 0) { // personB is sick and personA not
    $random=rand(1,100);
    if ( $random <= $GLOBALS['changeToGetSick'] ) { // infection!
      // echo "Someone get sick";
      $personA=$GLOBALS['daysSick'];
    }
  }
  return array($personA, $personB); // return personA and personB new status
}

function checkContacts(&$arrayPopulation, &$arrayContact) { // have everyone have contact
  for($i=0; $i<count($arrayPopulation);$i++) {
    $personA=$arrayPopulation[$i];
    for($j=0; $j<count($arrayContact[$i]);$j++){
      list($arrayPopulation[$i], $arrayPopulation[$arrayContact[$i][$j]]) = sick($personA, $arrayPopulation[$arrayContact[$i][$j]]);
    }
  }
}

function passTime(&$arrayPopulation) {
  for($i=0; $i<count($arrayPopulation);$i++) {
    if ( $arrayPopulation[$i] == 1 ) { // end of sick period
      if ( rand(1,100)<=$GLOBALS['changeToDie'] ) { // check if dead
        // echo "Someone Died<br>";
        $arrayPopulation[$i] = $GLOBALS['dead'];
      } else { // if not dead then become immune
        $arrayPopulation[$i]=$GLOBALS['immune']; // Immune
      }
    }
    if ( $arrayPopulation[$i] > 1 ) {
      $arrayPopulation[$i]--; // Healing slowly...
    }
  } // end for
}

function printPopulation($arrayPopulation) {
    echo '<pre>';
    for($i=0; $i<count($arrayPopulation);$i++) {
      if ($arrayPopulation[$i] > 0 ) {
        echo '<span style=\'color:orange\'>s</span>';
      }
      if ($arrayPopulation[$i] == 0 ) {
        echo '<span style=\'color:grey\'>-</span>';
      }
      if ($arrayPopulation[$i] == -9 ) {
        echo '<span style=\'color:red\'>x</span>';
      }
      if ($arrayPopulation[$i] == -1 ) {
        echo '<span style=\'color:green\'>o</span>';
      }
      if ( ($i+1) % $GLOBALS['popWidth'] == 0) {
        echo "<br>";
      }
    }
    echo '</pre>';
}

function init(&$arrayPopulation, &$arrayContact, &$numberSick) {
  $arrayPopulation=[]; // status of population -1 immun, 0 healthy, 1 sick
  $arrayContacts=[];   // contacts per person.
  $numberSick=[];

  $arrayPopulation = array_fill(0, $GLOBALS['population'], $GLOBALS['healthy']);
  $arrayPopulation[rand(0,$GLOBALS['population']-1)]=$GLOBALS['daysSick']; // one random person sick
  // $arrayPopulation[rand(0,$GLOBALS['population']-1)]=$GLOBALS['daysSick']; // one random person sick

  // set contacts per person
  for($j=0; $j<$GLOBALS['population']; $j++) {
    $theseContacts=[];
    for($i=0; $i<$GLOBALS['contactPerPerson']; $i++) {
      $random=rand(1,9);
      switch ($random) {

        case 1:
          $offSet = $j - $GLOBALS['popWidth']-1;
          break;
        case 2:
          $offSet = $j - $GLOBALS['popWidth'];
          break;
        case 3:
          $offSet = $j - $GLOBALS['popWidth']+1;
          break;

        case 4:
          $offSet = $j - 1;
          break;
        case 5:
          $offSet = $j + 1;
          break;

        case 6:
          $offSet = $j + $GLOBALS['popWidth']+1;
          break;
        case 7:
          $offSet = $j +$GLOBALS['popWidth']-1;
          break;
        case 8:
          $offSet = $j + $GLOBALS['popWidth'];
          break;

        case 9:
          $offSet = rand(0, $GLOBALS['population']-1);
          break;

      }
      if ( $offSet > 0 && $offSet < $GLOBALS['population'] ) {
         $theseContacts[]=$offSet; // contact is neighbour
      } else {
        $theseContacts[]=rand(0,$GLOBALS['population']-1); // when fell of grid, person has travelled
      }
      // $theseContacts[]=rand(0,$GLOBALS['population']-1);
    }
    $arrayContact[$j]=$theseContacts;
  }
}

// *** main ***

// read data from previous run from file or init if no data file exists
if ( file_exists('corona.json') ) {
  $arrayPopulation = json_decode(file_get_contents('corona.json'), true)['population'];
  $arrayContact = json_decode(file_get_contents('corona.json'), true)['contacts'];
  $numberSick = json_decode(file_get_contents('corona.json'), true)['sick'];
} else {
  init($arrayPopulation, $arrayContact, $numberSick);
}

// did wwe get a parameter?
if ( isset($_GET['step']) ) {
  $step=(int)$_GET['step'];
} else {
  $step=1;
}

// Calculate steps
for($i=0; $i<$step; $i++) {
  checkContacts($arrayPopulation, $arrayContact);
  passTime($arrayPopulation);
  $counts = array_count_values($arrayPopulation);
  $h = (array_key_exists($GLOBALS['healthy'], $counts)) ? $counts[$GLOBALS['healthy']] : '0';
  $d = (array_key_exists($GLOBALS['dead'], $counts)) ? $counts[$GLOBALS['dead']] : '0';
  $m = (array_key_exists($GLOBALS['immune'], $counts)) ? $counts[$GLOBALS['immune']] : '0';
  $p = $GLOBALS['population'];
  $s = $p - $h - $d - $m;
  $numberSick[]=$s;
}
// write result
file_put_contents("corona.json",json_encode(['population' => $arrayPopulation, 'contacts' => $arrayContact, 'sick' => $numberSick]));

// *** output section - of MVC, the view part ***
?>

<!DOCTYPE HTML>
<html>
<head>
<script>
window.onload = function () {

var data = <?php echo json_encode($numberSick, JSON_NUMERIC_CHECK); ?>;
data = data.map(function (row, index) {
    return {
        x: index,
        y: row
    };
});

var chart = new CanvasJS.Chart("chartContainer", {
    title: {
        text: "Simulation"
    },
    axisY: {
        title: "Sick"
    },
    data: [{
        type: "line",
        dataPoints: data
    }]
});
chart.render();

}
</script>
</head>
<body>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>



<?php
printPopulation($arrayPopulation); // print grid
?>

<table cellpadding=10>
  <tr>
    <td>
      <?php
      echo '<table border=0 cellpadding=10>';
      echo '<tr><td>Population:</td><td>'.$p.'</td><td> 100%</td><tr>';
      echo '<tr><td>Heatlhy:</td><td>'.$h.'</td><td>'.number_format(100*$h/$p,1).'%</td><tr>';
      echo '<tr><td>Sick:</td><td>'.$s.'</td><td>'.number_format(100*$s/$p,1).'%</td><tr>';
      echo '<tr><td>Dead:</td><td>'.$d.'</td><td>'.number_format(100*$d/$p,1).'%</td><tr>';
      echo '<tr><td>Immune:</td><td>'.$m.'</td><td>'.number_format(100*$m/$p,1).'%</td><tr>';
      echo '</table>';
      //print_r($numberSick);
      ?>
  </td>
    <td> <div id="chartContainer" style="height: 250px; width: 50%;"></div> </td>
  </tr>
</table>

<br><br>
<button onClick="window.location.href='corona.php';">Next 1 ></button>
&nbsp;
<button onClick="window.location.href='corona.php?step=3';">Next 3 >></button>
&nbsp;
<button onClick="window.location.href='reset.php';">Reset</button>

</body>
</html>
