<?php

class PageMain extends Page
{
  var $Months;
  var $GraphTimeRanges;

  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Months = array('', 'Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září',
      'Říjen', 'Listopad', 'Prosinec');

    $this->GraphTimeRanges = array(
      'hour' => array(
        'caption' => 'Hodina',
        'period' => 3600,
      ),
      'day' => array(
        'caption' => 'Den',
        'period' => 3600 * 24,
      ),
      'week' => array(
        'caption' => 'Týden',
        'period' => 3600 * 24 * 7,
      ),
      'month' => array(
        'caption' => 'Měsíc',
        'period' => 3600 * 24 * 30,
      ),
      'year' => array(
        'caption' => 'Rok',
        'period' => 3600 * 24 * 365,
      ),
      'years' => array(
        'caption' => 'Desetiletí',
        'period' => 3600 * 24 * 365 * 10,
      ),
      'all' => array(
        'caption' => 'Vše',
        'period' => -1,
      ),
    );
    $this->Time = time();
  }

  function GetTimeRange(): string
  {
    if (!array_key_exists($_SESSION['Period'], $this->GraphTimeRanges))
      $_SESSION['Period'] = 'day';

    $Result = $this->GraphTimeRanges[$_SESSION['Period']]['period'];
    if ($Result == -1)
    {
      $Measure = $this->LoadMeasure($_SESSION['Measure']);
      $FirstValue = $this->GetFirstMeasure($Measure);
      $LastValue = $this->GetLastMeasure($Measure);
      $Result = $LastValue['Time'] - $FirstValue['Time'];
    }
    return $Result;
  }

  function EditTime($Time): string
  {
    $Output = '<form style="display: inline;" action="?Operation=SetTime&amp;Time='.$Time.'" method="post">';
    $TimeParts = getdate($_SESSION[$Time]);

    // Day selection
    $Output .= '<select name="Day">';
    for ($I = 1; $I < 32; $I++)
    {
      if ($I == $TimeParts['mday']) $Selected = ' selected="1"'; else $Selected = '';
      $Output .= '<option value="'.$I.'"'.$Selected.'>'.$I.'</option>';
    }
    $Output .= '</select>. ';

    // Month selection
    $Output .= '<select name="Month">';
    foreach ($this->Months as $Index => $Month)
    {
      if ($Index == $TimeParts['mon']) $Selected = ' selected="1"'; else $Selected = '';
      if ($Index > 0) $Output .= '<option value="'.$Index.'"'.$Selected.'>'.$Month.'</option>';
    }
    $Output .= '</select>. ';

    // Year selection
    $Output .= '<select name="Year">';
    for ($I = 2000; $I <= date("Y"); $I++)
    {
      if ($I == $TimeParts['year']) $Selected = ' selected="1"'; else $Selected = '';
      $Output .= '<option value="'.$I.'"'.$Selected.'>'.$I.'</option>';
    }
    $Output .= '</select> &nbsp;&nbsp; ';

    // Hour selection
    $Output .= '<select name="Hour">';
    for ($I = 0; $I < 24; $I++)
    {
      if ($I == $TimeParts['hours']) $Selected = ' selected="1"'; else $Selected = '';
      $Output .= '<option value="'.$I.'"'.$Selected.'>'.$I.'</option>';
    }
    $Output .= '</select> : ';

    // Minute selection
    $Output .= '<select name="Minute">';
    for ($I = 0; $I < 60; $I++)
    {
      if ($I == $TimeParts['minutes']) $Selected = ' selected="1"'; else $Selected = '';
      $Output .= '<option value="'.$I.'"'.$Selected.'>'.$I.'</option>';
    }
    $Output .= '</select> ';

    $Output .= '<input type="submit" value="Nastavit">';
    $Output .= '</form>';
    $Output .= ' <form style="display: inline;" action="?Operation=SetTimeNow&amp;Time='.$Time.'" method="post">';
    $Output .= '<input type="submit" value="Aktuální čas">';
    $Output .= '</form>';

    return $Output;
  }

  function GetFirstMeasure($Measure): array
  {
    $Result2 = $this->Database->select($Measure['DataTable'], '`Time`, `Avg`', '(`Measure`='.$Measure['Id'].') AND (`Level`=0) ORDER BY `Time` ASC LIMIT 1');
    if ($Result2->num_rows > 0)
    {
      $Row = $Result2->fetch_array();
      $LastMeasureTime = MysqlDateTimeToTime($Row['Time']);
      $LastMeasureValue = $Row['Avg'];
    } else {
      $LastMeasureTime = $this->Time;
      $LastMeasureValue = 0;
    }
    return array('Time' => $LastMeasureTime, 'Value' => $LastMeasureValue);
  }

  function GetLastMeasure($Measure): array
  {
    $Result2 = $this->Database->select($Measure['DataTable'], '`Time`, `Avg`', '(`Measure`='.$Measure['Id'].') AND (`Level`=0) ORDER BY `Time` DESC LIMIT 1');
    if ($Result2->num_rows > 0)
    {
      $Row = $Result2->fetch_array();
      $LastMeasureTime = MysqlDateTimeToTime($Row['Time']);
      $LastMeasureValue = $Row['Avg'];
    } else {
      $LastMeasureTime = $this->Time;
      $LastMeasureValue = 0;
    }
    return array('Time' => $LastMeasureTime, 'Value' => $LastMeasureValue);
  }

  function LoadMeasure($Id): array
  {
    $DbResult = $this->Database->select('Measure', '*', '( `Enabled`=1) AND (`Id`='.$Id.') AND ((`PermissionView`="all") OR (`PermissionView`="'.
      gethostbyaddr($_SERVER['REMOTE_ADDR']).'"))');
    $DbRow = $DbResult->fetch_array();
    return $DbRow;
  }

  /* Produce table with available measures */
  function ShowMeasureTable(): string
  {
    $PrefixMultiplier = new PrefixMultiplier();
    $Output = '<table border="1" cellspacing="0" cellpadding="2" style="font-size: small; margin: 0px auto;">';
    $Output .= '<tr><th>Měřená veličina</th><th>Poslední hodnota</th><th>Čas posledního měření</th><th>Interpolace</th><th>Poznámky</th>';
    if (array_key_exists('Debug', $_GET)) $Output .= '<th>Počet položek</th><th>Čas vykonání</th>';
    $Output .= '</tr>';
    $Result = $this->Database->select('Measure', '*', '( `Enabled`=1) AND ((`PermissionView`="all") OR (`PermissionView`="'.
      gethostbyaddr($_SERVER['REMOTE_ADDR']).'")) ORDER BY `Description`');
    while ($Measure = $Result->fetch_array())
    {
      $StopWatchStart = GetMicrotime();
      if (array_key_exists('Debug', $_GET))
      {
        $DbResult = $this->Database->select($Measure['DataTable'], 'COUNT(*)', '`Measure`='.$Measure['Id']);
        $RowCount = $DbResult->fetch_array();
        $RowCount = $RowCount[0];
      }
      $Result2 = $this->Database->select($Measure['DataTable'], '`Time`, `Avg`', '(`Measure`='.
        $Measure['Id'].') AND (`Level`=0) ORDER BY `Time` DESC LIMIT 1');
      if ($Result2->num_rows > 0)
      {
        $Row = $Result2->fetch_array();
        $LastMeasureTime = date('j.n.Y G:i:s', MysqlDateTimeToTime($Row['Time']));
        $LastMeasureValue = $PrefixMultiplier->Add($Row['Avg'], $Measure['Unit']);
      } else {
        $LastMeasureTime = '&nbsp;';
        $LastMeasureValue = '&nbsp;';
      }
      if ($Measure['Continuity'] == 1) $Interpolate = 'Ano'; else $Interpolate = 'Ne';
      if ($Measure['Info'] == '') $Measure['Info'] = '&nbsp;';
      $GenerationTime = floor((GetMicrotime() - $StopWatchStart) * 1000  ) / 1000;
      $Output .= '<tr><td style="text-align: left"><a href="?Measure='.$Measure['Id'].
        '&amp;Differential=0">'.$Measure['Description'].'</a></td><td align="center">'.
        $LastMeasureValue.'</td><td align="center">'.$LastMeasureTime.'</td><td align="center">'.
        $Interpolate.'</td><td>'.$Measure['Info'].'</td>';
      if (array_key_exists('Debug', $_GET))
        $Output .= '<td>'.$RowCount.'</td><td>'.$GenerationTime.'</td>';
      $Output .= '</tr>';
    }
    $Output .= '</table>';
    return $Output;
  }

  function ShowGraph(): string
  {
    $Output = '<strong>Graf:</strong><br>';
    $Output .= '<img alt="Graf" src="Graph.php?Measure='.$_SESSION['Measure'].'&amp;From='.
      $_SESSION['TimeStart'].'&amp;To='.$_SESSION['TimeEnd'].
      '&amp;Width=750&amp;Height=200&amp;Differential='.
      $_SESSION['Differential'].'" width="750" height="200"><br>';
    $Output .= '<a href="?Measure='.$_SESSION['Measure'].'&amp;TimeStart='.
      $_SESSION['TimeStart'].'&amp;TimeEnd='.$_SESSION['TimeEnd'].
      '&amp;TimeSpecify=1&amp;Differential='.$_SESSION['Differential'].
      '">Odkaz na vybraný graf</a><br/>';
    return $Output;
  }

  function ShowTimeRange(): string
  {
    $Output = '';

    if (!array_key_exists('Operation', $_GET)) $_GET['Operation'] = '';
    switch ($_GET['Operation'])
    {
      case 'SetTime':
        if (array_key_exists('Time', $_GET) and array_key_exists('Month', $_POST) and array_key_exists('Day', $_POST) and
        array_key_exists('Year', $_POST) and array_key_exists('Hour', $_POST) and array_key_exists('Minute', $_POST))
        {
          if (($_GET['Time'] == 'TimeStart') or ($_GET['Time'] == 'TimeEnd'))
          {
            $_SESSION[$_GET['Time']] = mktime($_POST['Hour'], $_POST['Minute'], 0, $_POST['Month'],
                $_POST['Day'], $_POST['Year']);
          }
        }
        break;
      case 'SetTimeNow':
        if (array_key_exists('Time', $_GET))
        {
          if (($_GET['Time'] == 'TimeStart') or ($_GET['Time'] == 'TimeEnd'))
          {
            $_SESSION[$_GET['Time']] = $this->Time;
          }
        }
        break;

    }
    $Output .= '<strong>Časový úsek:</strong><br>';

    // Show graph time range menu
    if ($_SESSION['TimeSpecify'] == 0)
    {
      $Output .= 'Délka úseku: ';
      foreach ($this->GraphTimeRanges as $Index => $Item)
        $Output .= '<a href="?Period='.$Index.'">'.$Item['caption'].'</a>&nbsp;';
      $Output .= '<br>';
      $Output .= '<a href="?TimeSpecify=1">Přesnější nastavení...</a><br>';
    } else {
      $Output .= '<table cellspacing="0" cellpadding="2" border="0" style="margin: 0px auto;">';
      $Output .= '<tr><td>Počátek:</td><td>'.$this->EditTime('TimeStart').'</td></tr>';
      $Output .= '<tr><td>Konec:</td><td>'.$this->EditTime('TimeEnd').'</td></tr>';
      $Output .= '</table>';
      $Output .= '<a href="?TimeSpecify=0">Jednoduché nastavení...</a><br>';
    }
    $Output .= 'Posun: <a href="?Move=LeftEnd">|&lt;</a> <a href="?Move=Left">&lt;</a> '.
      '<a href="?Move=Right">&gt;</a> <a href="?Move=RightEnd">&gt;|</a> <a href="?Move=Now">Nyní</a><br>';
    $Output .= '<br/>';
    return $Output;

  }

  function HandleURL(): void
  {
    foreach ($this->System->Config['DefaultVariables'] as $Index => $Variable)
    {
      if (!array_key_exists($Index, $_SESSION)) $_SESSION[$Index] = $Variable;
      //if (array_key_exists($Index, $_GET)) $_SESSION[$Index] = $_GET[$Index];
      //if (array_key_exists($Index, $_POST)) $_SESSION[$Index] = $_POST[$Index];
      //$$Index = $_SESSION[$Index];
    }
    if (array_key_exists('Period', $_GET))
    {
      $_SESSION['Period'] = $_GET['Period'];
      // Update time start according time period
      if ($_SESSION['Period'] == 'all')
      {
        $Measure = $this->LoadMeasure($_SESSION['Measure']);
        $FirstValue = $this->GetFirstMeasure($Measure);
        $LastValue = $this->GetLastMeasure($Measure);
        $_SESSION['TimeStart'] = $FirstValue['Time'];
        $_SESSION['TimeEnd'] = $LastValue['Time'];
      } else
      {
        $_SESSION['TimeStart'] = $_SESSION['TimeEnd'] - $this->GetTimeRange();
      }
    }
    if (array_key_exists('TimeStart', $_GET))
    {
      $_SESSION['TimeStart'] = $_GET['TimeStart'];
    }
    if (array_key_exists('TimeEnd', $_GET))
    {
      $_SESSION['TimeStart'] = $_GET['TimeEnd'];
    }
    if (array_key_exists('Differential', $_GET))
    {
      $_SESSION['Differential'] = $_GET['Differential'];
    }
    if (array_key_exists('Measure', $_GET))
    {
      $_SESSION['Measure'] = $_GET['Measure'];
    }
    if (array_key_exists('TimeSpecify', $_GET))
    {
      if (($_SESSION['TimeSpecify'] == 1) and ($_GET['TimeSpecify'] == 0))
      {
        $_SESSION['TimeEnd'] = $this->Time - 60;
        $_SESSION['TimeStart'] = $_SESSION['TimeEnd'] - $this->GetTimeRange();
      }
      $_SESSION['TimeSpecify'] = $_GET['TimeSpecify'];
    }

    if (array_key_exists('Move', $_GET))
    {
      $Move = $_GET['Move'];
      if ($Move == 'Left')
      {
        $_SESSION['TimeStart'] = $_SESSION['TimeStart'] - $this->GetTimeRange();
        $_SESSION['TimeEnd'] = $_SESSION['TimeEnd'] - $this->GetTimeRange();
      } else
      if ($Move == 'Right')
      {
        $_SESSION['TimeStart'] = $_SESSION['TimeStart'] + $this->GetTimeRange();
        $_SESSION['TimeEnd'] = $_SESSION['TimeEnd'] + $this->GetTimeRange();
      } else
      if ($Move == 'Now')
      {
        $_SESSION['TimeEnd'] = $this->Time - 60;
        $_SESSION['TimeStart'] = $_SESSION['TimeEnd'] - $this->GetTimeRange();
      } else
      if ($Move == 'LeftEnd')
      {
        $Measure = $this->LoadMeasure($_SESSION['Measure']);
        $FirstValue = $this->GetFirstMeasure($Measure);
        $_SESSION['TimeStart'] = $FirstValue['Time'];
        $_SESSION['TimeEnd'] = $_SESSION['TimeStart'] + $this->GetTimeRange();
      } else
      if ($Move == 'RightEnd')
      {
        $Measure = $this->LoadMeasure($_SESSION['Measure']);
        $LastValue = $this->GetLastMeasure($Measure);
        $_SESSION['TimeEnd'] = $LastValue['Time'];
        $_SESSION['TimeStart'] = $_SESSION['TimeEnd'] - $this->GetTimeRange();
      }
    }
  }

  function Show(): string
  {
    global $Config;

    $Debug = 0;
    $this->HandleURL();

    $Output = '<div style="text-align: center"><div class="Title">'.$Config['Web']['Title'].'</div>';

    $Result = $this->Database->select('Measure', 'Id', '(`Enabled`=1) AND '.
      '((`PermissionView`="all") OR (`PermissionView`="'.gethostbyaddr($_SERVER['REMOTE_ADDR']).'")) '.
      'AND (`Id`='.($_SESSION['Measure'] * 1).')');
    if ($Result->num_rows == 0)
      $_SESSION['Measure'] = $Config['DefaultVariables']['Measure'];

    $Output .= $this->ShowTimeRange();
    $Output .= $this->ShowGraph();
    $Output .= '<br/>';
    $Output .= $this->ShowMeasureTable();
    $Output .= '</div>';
    return $Output;
  }
}
