Index: /trunk/Classes.php
===================================================================
--- /trunk/Classes.php	(revision 63)
+++ /trunk/Classes.php	(revision 63)
@@ -0,0 +1,17 @@
+<?php
+
+$Classes = array(
+  'Measure' => array(
+    'Name' =>           array('Type' => 'String', 'Caption' => 'Zkratka', 'Default' => 'measure'),
+    'Title' =>          array('Type' => 'String', 'Caption' => 'Název', 'Default' => 'Měření'),
+    'Description' =>    array('Type' => 'String', 'Caption' => 'Popis', 'Default' => 'Měření veličiny'),
+    'Unit' =>           array('Type' => 'String', 'Caption' => 'Jednotka', 'Default' => ''),
+    'Continuity' =>     array('Type' => 'Boolean', 'Caption' => 'Spojitost', 'Default' => '0'),
+    'Period' =>         array('Type' => 'Integer', 'Caption' => 'Perioda měření', 'Default' => '60'),
+    'PermissionAdd' =>  array('Type' => 'String', 'Caption' => 'Oprávnění k měření', 'Default' => 'localhost.localdomain'),
+    'PermissionView' => array('Type' => 'String', 'Caption' => 'Oprávnění k prohlížení', 'Default' => 'all'),
+    'Enabled' =>        array('Type' => 'Boolean', 'Caption' => 'Povolení', 'Default' => '1'),
+    'DataType' =>       array('Type' => 'String', 'Caption' => 'Typ datových položek', 'Default' => 'int'),
+    'DataTable' =>      array('Type' => 'String', 'Caption' => 'Tabulka měřených dat', 'Default' => 'data'),
+  ),
+);
Index: /trunk/Global.php
===================================================================
--- /trunk/Global.php	(revision 63)
+++ /trunk/Global.php	(revision 63)
@@ -0,0 +1,118 @@
+<?php
+
+session_start();
+$FileName = dirname(__FILE__).'/config.php';
+if(file_exists($FileName)) include_once($FileName);
+else {
+  die('Configuration file "'.$FileName.'" not found.');
+}
+include_once('Version.php');
+include_once('Types.php');
+include_once('Classes.php');
+include_once('Packages/Common/Common.php');
+include_once('Measure.php');
+
+$PrefixMultiplier = new PrefixMultiplier();
+$ErrorHandler = new ErrorHandler();
+$ErrorHandler->ShowError = $Config['Web']['ShowError'];
+$ErrorHandler->Start();
+$Database = new Database();
+$Database->Connect($Config['Database']['Host'], $Config['Database']['User'],
+  $Config['Database']['Password'], $Config['Database']['Database']);
+$Database->Prefix = $Config['Database']['Prefix'];
+$Database->charset($Config['Database']['Charset']);
+$Database->ShowSQLError = $Config['Web']['ShowSQLError'];
+$Database->ShowSQLQuery = $Config['Web']['ShowSQLQuery'];
+
+// SQL injection hack protection
+foreach($_POST as $Index => $Item) $_POST[$Index] = addslashes($Item);
+foreach($_GET as $Index => $Item) $_GET[$Index] = addslashes($Item);
+
+function HumanDate($Time)
+{
+  return(date('j.n.Y', $Time));
+}
+
+function GetMicrotime()
+{
+  list($Usec, $Sec) = explode(" ", microtime());
+  return ((float)$Usec + (float)$Sec);
+}
+
+function ShowPage($Content)
+{
+  global $Config, $ReleaseTime, $Revision;
+
+  $Output = '<?xml version="1.0" encoding="'.$Config['Web']['Charset'].'"?>'."\n".
+  '<!DOCTYPE html>'.
+  '<html>'.
+  '<head>'.
+  '<meta http-equiv="Content-Language" content="cs"/>'.
+  '<meta http-equiv="content-type" content="text/html; charset='.$Config['Web']['Charset'].'" />'.
+  '<meta name="robots" content="all" />'.
+  '<title>'.$Config['Web']['Title'].'</title>'.
+  '<link rel="StyleSheet" href="style/style.css" type="text/css" media="all"/>'.
+  '</head><body>';
+  $Output .= $Content;
+  $Output .= '<br/><div style="text-align: center; font-size: small;">Verze: '.$Revision.' ('.HumanDate($ReleaseTime).')'.
+    ' &nbsp; <a href="http://svn.zdechov.net/trac/statistic/browser/trunk">Zdrojový kód</a> &nbsp; '.
+    '<a href="http://svn.zdechov.net/trac/statistic/log/trunk?verbose=on">Historie změn</a></div>';
+  $Output .= '</body></html>';
+  echo($Output);
+}
+
+function MakeLink($Target, $Title)
+{
+  return('<a href="'.$Target.'">'.$Title.'</a>');
+}
+
+function Table($Table)
+{
+  $Result = '<table cellspacing="0" class="BasicTable">';
+  $Result .= '<tr>';
+  foreach($Table['Header'] as $Item)
+    $Result .= '<th>'.$Item.'</th>';
+  $Result .= '</tr>';
+  foreach($Table['Rows'] as $Row)
+  {
+    $Result .= '<tr>';
+    foreach($Row as $Item)
+      $Result .= '<td>'.$Item.'</td>';
+    $Result .= '</tr>';
+  }
+  $Result .= '</table>';
+  return($Result);
+}
+
+function ShowEditTable($ClassName, $Values)
+{
+  global $Classes, $Types;
+  $Class = $Classes[$ClassName];
+  $Table = array(
+    'Header' => array('Položka', 'Hodnota'),
+    'Rows' => array(),
+  );
+
+  foreach($Class as $Index => $Item)
+  {
+    if(!array_key_exists($Index, $Values)) $Values[$Index] = $Item['Default'];
+    switch($Item['Type'])
+    {
+      case 'Boolean':
+        if($Values[$Index] == 0) $Checked = ''; else $Checked = ' checked="yes"';
+        $Edit = '<input type="checkbox" name="'.$Index.'"'.$Checked.'>';
+        break;
+      case 'String':
+        $Edit = '<input type="text" name="'.$Index.'" value="'.$Values[$Index].'">';
+        break;
+      case 'Integer':
+        $Edit = '<input type="text" name="'.$Index.'" value="'.$Values[$Index].'">';
+        break;
+      default:
+        $Edit = 'Neznámý typ';
+    }
+    array_push($Table['Rows'], array($Item['Caption'], $Edit));
+  }
+  $Output = '<h3>Tabulka '.$ClassName.'</h3>'.Table($Table).MakeLink('?Operation=Add2', 'Přidat');
+  return($Output);
+}
Index: /trunk/Graph.php
===================================================================
--- /trunk/Graph.php	(revision 63)
+++ /trunk/Graph.php	(revision 63)
@@ -0,0 +1,197 @@
+<?php
+
+include('Global.php');
+
+if(array_key_exists('Debug', $_GET)) $Debug = $_GET['Debug'];
+  else $Debug = 0;
+
+if(!array_key_exists('From',$_GET)) die('Musíte zadat čas počátku');
+$StartTime = addslashes($_GET['From']);
+if(!array_key_exists('To',$_GET)) die('Musíte zadat čas konce');
+$EndTime = addslashes($_GET['To']);
+if($EndTime < $StartTime) $EndTime = $StartTime + 60;
+$TimeDifference = $EndTime - $StartTime;
+if(!array_key_exists('Measure', $_GET)) die('Musíte zadat měřenou veličinu');
+$MeasureId = addslashes($_GET['Measure']);
+if(!array_key_exists('Width', $_GET)) $Width = $DefaultWidth;
+else $Width = addslashes($_GET['Width']);
+if(!array_key_exists('Height', $_GET)) $Height = $DefaultHeight;
+else $Height = addslashes($_GET['Height']);
+if(!array_key_exists('Differential', $_GET)) $Differential = $Config['DefaultVariables']['Differential'];
+else $Differential = addslashes($_GET['Differential']);
+$VerticalLinesCount = round($Height / ($FontSize + 4));
+
+$StopWatchStart = GetMicrotime();
+
+$Measure = new Measure($Database);
+$Measure->Load($MeasureId);
+$Measure->DivisionCount = $Config['DivisionCount'];
+$Measure->LevelReducing = $Config['LevelReducing'];
+$Measure->MaxLevel = $Config['MaxLevel'];
+$Measure->ReferenceTime = $Config['ReferenceTime'];
+$Measure->Differential = $Differential;
+
+$Level = floor(log(($EndTime - $StartTime) / $Measure->DivisionCount / 60) / log($Measure->LevelReducing)) - 1;
+if($Level < 0) $Level = 0;
+if($Level > $Measure->MaxLevel) $Level = $Measure->MaxLevel;
+
+$Points = $Measure->GetValues($StartTime, $EndTime, $Level);
+
+if($Debug) echo('Points count: '.count($Points).'<br>');
+//if($Debug) foreach($Points as $Index => $Item)
+//  echo($Index.': '.$Item['min'].'<br>');
+
+// Calculate total max, avg, min value
+$MaxValue = -1000000000000000000;
+$AvgValue = 0;
+$MinValue = 1000000000000000000;
+foreach($Points as $Index => $Item)
+{
+  //$Points[$Index]['min'] =  $Points[$Index]['min'] / $Measure['Divider'];
+  //$Points[$Index]['avg'] =  $Points[$Index]['avg'] / $Measure['Divider'];
+  //$Points[$Index]['max'] =  $Points[$Index]['max'] / $Measure['Divider'];
+  if($Points[$Index]['avg'] > $MaxValue) $MaxValue = $Points[$Index]['avg'];
+  if($Points[$Index]['avg'] < $MinValue) $MinValue = $Points[$Index]['avg'];
+  if($Points[$Index]['max'] > $MaxValue) $MaxValue = $Points[$Index]['max'];
+  if($Points[$Index]['min'] < $MinValue) $MinValue = $Points[$Index]['min'];
+  $AvgValue = $AvgValue + $Points[$Index]['avg'];
+}
+//$MinValue = round($MinValue * $Measure['Divider']) / $Measure['Divider'];
+//$MaxValue = round($MaxValue * $Measure['Divider']) / $Measure['Divider'];
+$AvgValue = $AvgValue / count($Points); //round(* $Measure['Divider']) / $Measure['Divider'];
+
+// Generate polygon and recalculate y values to fit graph height
+$PointsMin = array(0, $Height - 1);
+$PointsAvg = array(0, $Height - 1);
+$PointsMax = array(0, $Height - 1);
+if(($MaxValue - $MinValue) == 0) $MaxValue = $MinValue + 1;
+{
+  foreach($Points as $Index => $Item)
+  {
+    $PointsMin[] = $Index * $Width / $Measure->DivisionCount;
+    $PointsMin[] = $Height - 1 - ($Points[$Index]['min'] - $MinValue) / ($MaxValue - $MinValue) * $Height * $K;
+    $PointsAvg[] = $Index * $Width / $Measure->DivisionCount;
+    $PointsAvg[] = $Height - 1 - ($Points[$Index]['avg'] - $MinValue) / ($MaxValue - $MinValue) * $Height * $K;
+    $PointsMax[] = $Index * $Width / $Measure->DivisionCount;
+    $PointsMax[] = $Height - 1 - ($Points[$Index]['max'] - $MinValue) / ($MaxValue - $MinValue) * $Height * $K;
+    //echo($Index.' - '.$Item.' '.$Points[$Index].'<br>');
+  }
+}
+$PointsMin[] = $Width - 1;
+$PointsMin[] = $Height - 1;
+$PointsAvg[] = $Width - 1;
+$PointsAvg[] = $Height - 1;
+$PointsMax[] = $Width - 1;
+$PointsMax[] = $Height - 1;
+$PointsMin[] = $Width - 1;
+$PointsMin[] = $Height - 1;
+$PointsAvg[] = $Width - 1;
+$PointsAvg[] = $Height - 1;
+$PointsMax[] = $Width - 1;
+$PointsMax[] = $Height - 1;
+
+
+//array_unshift($Points, $Height - 1);
+//array_unshift($Points, 0);
+//$Points[] = $Width - 1;
+//$Points[] = $Height - 1;
+
+// Generate image
+if(!$Debug)
+{
+  Header("Content-type: image/png");
+  Header("Cache-Control: no-cache");	// Dynamic graph - no cache
+  $Image = @imagecreate($Width, $Height);
+  $BackgroundColor = imagecolorallocate($Image, 255, 255, 255);
+  $Black = imagecolorallocate($Image, 0, 0, 0);
+  $White = imagecolorallocate($Image, 255, 255, 255);
+  $Gray = imagecolorallocate($Image, 200, 200, 200);
+  $DarkGray = imagecolorallocate($Image, 100, 100, 100);
+  $LightBlue = imagecolorallocate($Image, 150, 150, 255);
+  $Blue = imagecolorallocate($Image, 0, 0, 255);
+  $LightRed = imagecolorallocate($Image, 255, 150, 150);
+  $Red = imagecolorallocate($Image, 255, 0, 0);
+  $Green = imagecolorallocate($Image, 0, 200, 0);
+  $LightGreen = imagecolorallocate($Image, 150, 255, 150);
+
+  imagefilledpolygon($Image, $PointsMax, count($PointsMax) / 2, $LightRed);
+  imagefilledpolygon($Image, $PointsAvg, count($PointsAvg) / 2, $LightGreen);
+  imagefilledpolygon($Image, $PointsMin, count($PointsMin) / 2, $LightBlue);
+
+  $TimeMarks = array(1, 60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30, 60*60*24*365, 60*60*24*365*10);
+
+  $TimeRange = $EndTime - $StartTime;
+  $TimeMarksIndex = 0;
+  while(($TimeRange / $TimeMarks[$TimeMarksIndex]) > 1) $TimeMarksIndex += 1;
+  if($TimeMarksIndex < 2) $TimeMarksIndex = 2;
+  $MajorTimeMarks = $TimeMarks[$TimeMarksIndex - 1];
+  $MinorTimeMarks = $TimeMarks[$TimeMarksIndex - 2];
+
+  $TimeShift = $Measure->AlignTime($StartTime, $MajorTimeMarks) - $StartTime;
+  //imagestring($Image, 10, 40, 50, $TimeShift, $Black);
+
+  // Zobraz měřítko Y
+  $VerticalLinesDistance = $Height / $VerticalLinesCount;
+  for($I=1; $I<=$VerticalLinesCount; $I++)
+  {
+    $Y = $Height - 1 - ($VerticalLinesDistance * $I);
+    for($X=1; $X < $Width; $X = $X + 3) imagesetpixel($Image, $X, $Y, $Gray);
+    //imageline($Image, 30, $Y, $Width-1, $Y, IMG_COLOR_STYLED);
+  }
+
+  $TimeShift = $Measure->AlignTime($StartTime, $MinorTimeMarks) - $StartTime;
+
+  // Zobraz měřítko X
+  $LastTextEnd = 0;
+  for($Time = $StartTime; $Time < $EndTime; $Time += $MajorTimeMarks)
+  {
+    $X = round(($Time - $StartTime + $TimeShift) / $TimeRange * $Width) % $Width;
+    //imageline($Image, 30, $Y, $Width-1, $Y, IMG_COLOR_STYLED);
+    if(($MajorTimeMarks > 60*60*24)) $Text = date('j.n.Y', $Time + $TimeShift);
+      else $Text = date('j.n.Y G:i', $Time + $TimeShift);
+    $BoundBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
+    if($LastTextEnd < ($X - ($BoundBox[2] - $BoundBox[0] + 20) / 2))
+    {
+      for($Y=0; $Y < $Height; $Y = $Y + 1) imagesetpixel($Image, $X, $Y, $Gray);
+      imagettftext($Image, $FontSize, 0, $X - ($BoundBox[2] - $BoundBox[0]) / 2,  $Height - 2, $Black, $FontFile, $Text);
+      $LastTextEnd = $X + ($BoundBox[2] - $BoundBox[0]) / 2;
+    }
+    else for($Y=0; $Y < $Height; $Y = $Y + 3) imagesetpixel($Image, $X, $Y, $Gray);
+  }
+
+  // Popisky osy Y
+  for($I = 1; $I <= $VerticalLinesCount; $I++)
+  {
+    $Y = $Height - 1 - ($VerticalLinesDistance * $I);
+    //$Y = $Height - 1 - ($VerticalLinesDistance * $I / ($MaxValue - $MinValue) * $K * $Height);
+    $Text = $PrefixMultiplier->Add(round(($I * $VerticalLinesDistance / $Height /
+      $K * ($MaxValue - $MinValue) + $MinValue)), $Measure->Data['Unit'], 3);
+    $BoundBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
+    if(($Y - ($BoundBox[5] - $BoundBox[1]) / 2) > 10)
+      imagettftext($Image, $FontSize, 0, 2,  $Y - ($BoundBox[5] - $BoundBox[1]) / 2, $Black, $FontFile, $Text);
+  }
+  $GenerationTime = floor((GetMicrotime() - $StopWatchStart) * 1000  ) / 1000;
+
+  $Left = $Width - 10;
+  $Text = "    Max. ".$PrefixMultiplier->Add($MaxValue, $Measure->Data['Unit']);
+  $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
+  $Left -= ($BoundingBox[2] - $BoundingBox[0]);
+  imagettftext($Image, $FontSize, 0, $Left, 14, $Red, $FontFile, $Text);
+
+  $Text = "    Avg.  ".$PrefixMultiplier->Add($AvgValue, $Measure->Data['Unit'], 4);
+  $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
+  $Left -= ($BoundingBox[2] - $BoundingBox[0]);
+  imagettftext($Image, $FontSize, 0, $Left, 14, $Green, $FontFile, $Text);
+
+  $Text = "    Min.  ".$PrefixMultiplier->Add($MinValue, $Measure->Data['Unit']);
+  $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
+  $Left -= ($BoundingBox[2] - $BoundingBox[0]);
+  imagettftext($Image, $FontSize, 0, $Left, 14, $Blue, $FontFile, $Text);
+  //imagestring($Image, 2, 70, 20, 'Vygenerováno za '.$GenerationTime.' sekund', $Black);
+  //imagestring($Image, 2, 50, 30, 'Level: '.$Level, $Black);
+
+  imagettftext($Image, $FontSize, 0, 70, 14, $Black, $FontFile, $Measure->Data['Description']);
+  imagerectangle($Image, 0, 0, $Width - 1, $Height - 1, $Black);   // Frame border
+  imagepng($Image);
+  imagedestroy($Image);
+}
Index: /trunk/Measure.php
===================================================================
--- /trunk/Measure.php	(revision 63)
+++ /trunk/Measure.php	(revision 63)
@@ -0,0 +1,443 @@
+<?php
+
+include_once('Point.php');
+
+class Measure
+{
+  var $Data;
+  var $ValueTypes;
+  var $LevelReducing;
+  var $Database;
+  var $MaxLevel;
+  var $ReferenceTime;
+  var $Differential;
+  var $DivisionCount;
+
+  function __construct($Database)
+  {
+    $this->Id = 0;
+    $this->ValueTypes = array('min', 'avg', 'max');
+    $this->Database = &$Database;
+    $this->LevelReducing = 5;
+    $this->MaxLevel = 4;
+    $this->ReferenceTime = 0;
+    $this->Differential = 0;
+    $this->DivisionCount = 500;
+  }
+
+  function TimeSegment($Level)
+  {
+    return(pow($this->LevelReducing, $Level) * 60);
+  }
+
+  function StatTableName($Level)
+  {
+    if($Level == 0) return('data');
+      else return('data_cache');
+  }
+
+  function AlignTime($Time, $TimeSegment)
+  {
+    return(round(($Time - $this->ReferenceTime) / $TimeSegment) * $TimeSegment +
+      $this->ReferenceTime);
+  }
+
+  function Load($Id)
+  {
+    $Result = $this->Database->select('measure', '*', 'Id='.$Id);
+    if($Result->num_rows > 0)
+    {
+      $this->Data = $Result->fetch_array();
+      if($this->Data['Continuity'] == 0) $this->Data['ContinuityEnabled'] = 0;  // non continuous
+        else $this->Data['ContinuityEnabled'] = 2;    // continuous graph
+    } else die('Měřená veličina nenalezena');
+  }
+
+  function AddValue($Value)
+  {
+    $Time = time();
+
+    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
+      '(`level`=0) ORDER BY `time` DESC LIMIT 2');
+    if($Result->num_rows == 0) $this->Database->insert($this->Data['DataTable'],
+      array('min' => $Value, 'avg' => $Value, 'max' => $Value, 'level' => 0,
+      'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time), 'continuity' => 0));
+    else if($Result->num_rows == 1) $this->Database->insert($this->Data['DataTable'],
+      array('min' => $Value, 'avg' => $Value, 'max' => $Value, 'level' => 0,
+      'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time),
+      'continuity' => 1));
+    else {
+      $LastValue = $Result->fetch_array();
+      $NextToLastValue = $Result->fetch_array();
+      if(($Time - MysqlDateTimeToTime($LastValue['time'])) < 0.75 * $this->Data['Period'])
+      {
+      }
+      else
+      {
+        if(($Time - MysqlDateTimeToTime($LastValue['time'])) < 1.25 * $this->Data['Period']) $Continuity = 1;
+          else $Continuity = 0;
+        if(($LastValue['avg'] == $NextToLastValue['avg']) and ($LastValue['avg'] == $Value) and
+          ($LastValue['continuity'] == 1) and ($Continuity == 1))
+        {
+          $this->Database->update($this->Data['DataTable'], '(time="'.$LastValue['time'].'") AND '.
+          '(level=0) AND (measure='.$this->Data['Id'].')', array('time' => TimeToMysqlDateTime($Time)));
+        } else
+        {
+          $this->Database->insert($this->Data['DataTable'], array('min' => $Value,
+            'avg' => $Value, 'max' => $Value, 'level' => 0, 'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time),
+            'continuity' => $Continuity));
+        }
+      }
+    }
+
+    // Update levels
+    for($Level = 1; $Level <= $this->MaxLevel; $Level++)
+    {
+      $TimeSegment = $this->TimeSegment($Level);
+      $EndTime = $this->AlignTime($Time, $TimeSegment);
+      //if($EndTime < $Time) $EndTime = $EndTime + $TimeSegment;
+      $StartTime = $EndTime - $TimeSegment;
+
+      // Load values in time range
+      $Values = array();
+      $Result = $this->Database->select($this->Data['DataTable'], '*', '(`time` > "'.TimeToMysqlDateTime($StartTime).'") AND '.
+        '(`time` < "'.TimeToMysqlDateTime($EndTime).'") AND '.
+        '(`measure`='.$this->Data['Id'].') AND (`level`='.($Level - 1).') ORDER BY `time`');
+      while($Row = $Result->fetch_array())
+      {
+        $Row['time'] = MysqlDateTimeToTime($Row['time']);
+        $Values[] = $Row;
+      }
+      //array_pop($Values);
+
+      // Load subsidary values
+      $Values = array_merge(
+        $this->LoadLeftSideValue($Level - 1, $StartTime),
+        $Values,
+        $this->LoadRightSideValue($Level - 1, $EndTime));
+
+      $Point = $this->ComputeOneValue($StartTime, $EndTime, $Values, $Level);
+
+      $this->Database->delete($this->Data['DataTable'], '(time > "'.TimeToMysqlDateTime($StartTime).'") AND
+        (time < "'.TimeToMysqlDateTime($EndTime).'") AND measure='.$this->Data['Id'].' AND level='.$Level);
+      $Continuity = $Values[1]['continuity'];
+      $this->Database->insert($this->Data['DataTable'], array('level' => $Level, 'measure' => $this->Data['Id'], 'min' => $Point['min'],
+        'avg' => $Point['avg'], 'max' => $Point['max'], 'continuity' => $Continuity,
+        'time' => TimeToMysqlDateTime($StartTime + ($EndTime - $StartTime) / 2)));
+
+    }
+  }
+
+  /* Compute one value for upper time level from multiple values */
+  function ComputeOneValue($LeftTime, $RightTime, $Values, $Level)
+  {
+    $NewValue = array('min' => +1000000000000000000, 'avg' => 0, 'max' => -1000000000000000000);
+
+    // Trim outside parts
+    foreach($this->ValueTypes as $ValueType)
+    {
+      $Values[0][$ValueType] = Interpolation(NewPoint($Values[0]['time'], $Values[0][$ValueType]),
+        NewPoint($Values[1]['time'], $Values[1][$ValueType]), $LeftTime);
+    }
+    $Values[0]['time'] = $LeftTime;
+    foreach($this->ValueTypes as $ValueType)
+    {
+      $Values[count($Values) - 1][$ValueType] = Interpolation(NewPoint($Values[count($Values) - 2]['time'],
+        $Values[count($Values) - 2][$ValueType]),
+        NewPoint($Values[count($Values) - 1]['time'], $Values[count($Values) - 1][$ValueType]),
+        $RightTime);
+    }
+    $Values[count($Values) - 1]['time'] = $RightTime;
+
+    // Perform computation
+    foreach($this->ValueTypes as $ValueType)
+    {
+      // Compute new value
+      for($I = 0; $I < (count($Values) - 1); $I++)
+      {
+        if($ValueType == 'avg')
+        {
+          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled']);
+            else if($this->Differential == 0)
+            {
+              $NewValue[$ValueType] = $NewValue[$ValueType] + ($Values[$I + 1]['time'] - $Values[$I]['time']) *
+                (($Values[$I + 1][$ValueType] - $Values[$I][$ValueType]) / 2 + $Values[$I][$ValueType]);
+            } else {
+              $NewValue[$ValueType] = $NewValue[$ValueType] + ($Values[$I + 1]['time'] - $Values[$I]['time']) *
+               (($Values[$I + 1][$ValueType] - $Values[$I][$ValueType]) / 2);
+            }
+        }
+        else if($ValueType == 'max')
+        {
+          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled'])
+          {
+            if(0 > $NewValue[$ValueType]) $NewValue[$ValueType] = 0;
+          }
+          else
+          {
+            if($this->Differential == 0)
+            {
+              if($Values[$I + 1][$ValueType] > $NewValue[$ValueType]) $NewValue[$ValueType] = $Values[$I + 1][$ValueType];
+            } else {
+              $Difference = $Values[$I + 1][$ValueType] - $Values[$I][$ValueType];
+              if($Difference > $NewValue[$ValueType]) $NewValue[$ValueType] = $Difference;
+            }
+          }
+        }
+        else if($ValueType == 'min')
+        {
+          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled'])
+          {
+            if(0 < $NewValue[$ValueType]) $NewValue[$ValueType] = 0;
+          } else {
+            if($this->Differential == 0)
+            {
+              if($Values[$I + 1][$ValueType] < $NewValue[$ValueType]) $NewValue[$ValueType] = $Values[$I + 1][$ValueType];
+            } else {
+              $Difference = $Values[$I + 1][$ValueType] - $Values[$I][$ValueType];
+              if($Difference < $NewValue[$ValueType]) $NewValue[$ValueType] = $Difference;
+            }
+          }
+        }
+      }
+      $NewValue[$ValueType] = $NewValue[$ValueType];
+    }
+    //if(($RightTime - $LeftTime) > 0)
+    if($this->Data['Cumulative'] == 0)
+    {
+      $NewValue['avg'] = $NewValue['avg'] / ($RightTime - $LeftTime);
+    }
+    return($NewValue);
+  }
+
+  function GetTimeRange($Level)
+  {
+    // Get first and last time
+    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
+      '(`level`='.$Level.') ORDER BY `time` LIMIT 1');
+    if($Result->num_rows > 0)
+    {
+      $Row = $Result->fetch_array();
+      $AbsoluteLeftTime = MysqlDateTimeToTime($Row['time']);
+    } else $AbsoluteLeftTime = 0;
+
+    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
+      '(`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
+    if($Result->num_rows > 0)
+    {
+      $Row = $Result->fetch_array();
+      $AbsoluteRightTime = MysqlDateTimeToTime($Row['time']);
+    } else $AbsoluteRightTime = 0;
+
+    return(array('left' => $AbsoluteLeftTime, 'right' => $AbsoluteRightTime));
+  }
+
+  function LoadRightSideValue($Level, $Time)
+  {
+    $Result = array();
+    $DbResult = $this->Database->select($this->Data['DataTable'], '*', '(time > "'.TimeToMysqlDateTime($Time).'") AND (measure='.$this->Data['Id'].') AND (level='.$Level.') ORDER BY time ASC LIMIT 1');
+    if($DbResult->num_rows > 0)
+    {
+      $Row = $DbResult->fetch_array();
+      $Row['time'] = MysqlDateTimeToTime($Row['time']);
+      return(array($Row));
+    }
+    else
+    {
+      //$Time = $Values[count($Values)-1]['time'] + 60;
+      //array_push($Values, array('time' => $Time, 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
+      $Result[] = array('time' => ($Time + $this->TimeSegment($Level)), 'min' => 0,
+        'avg' => 0, 'max' => 0, 'continuity' => 0);
+      $DbResult = $this->Database->select($this->Data['DataTable'], '*',
+        '(`time` < "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
+        'AND (`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
+      if($DbResult->num_rows > 0)
+      {
+        $Row = $DbResult->fetch_array();
+        array_unshift($Result, array('time' => (MysqlDateTimeToTime($Row['time']) + 10),
+          'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
+      }
+      return($Result);
+    }
+  }
+
+  function LoadLeftSideValue($Level, $Time)
+  {
+    $Result = array();
+    $DbResult = $this->Database->select($this->Data['DataTable'], '*',
+      '(`time` < "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
+      'AND (`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
+    if($DbResult->num_rows > 0)
+    {
+      $Row = $DbResult->fetch_array();
+      $Row['time'] = MysqlDateTimeToTime($Row['time']);
+      return(array($Row));
+    } else {
+      //$Time = $Values[0]['time'] - 60;
+      //array_unshift($Values, array('time' => $Time, 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
+      $Result[] = array('time' => ($Time - $this->TimeSegment($Level)), 'min' => 0,
+        'avg' => 0, 'max' => 0, 'continuity' => 0);
+
+      $DbResult = $this->Database->select($this->Data['DataTable'], '*',
+        '(`time` > "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
+        'AND (`level`='.$Level.') ORDER BY `time` ASC LIMIT 1');
+      if($DbResult->num_rows > 0)
+      {
+        $Row = $DbResult->fetch_array();
+        array_push($Result, array('time' => (MysqlDateTimeToTime($Row['time']) - 10),
+          'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
+      }
+      return($Result);
+    }
+  }
+
+  function GetValues($TimeFrom, $TimeTo, $Level)
+  {
+  //$AbsoluteTime = GetTimeRange($this->DataId);
+
+//  if(($TimeFrom > $AbsoluteLeftTime) and ($TimeStart < $AbsoluteRightTime) and
+//    ($TimeTo > $AbsoluteLeftTime) and ($TimeTo < $AbsoluteRightTime))
+//  {
+
+    // Load values in time range
+    $Result = $this->Database->select($this->Data['DataTable'], '`time`, `min`, `avg`, `max`, `continuity`',
+      '(`time` > "'.TimeToMysqlDateTime($TimeFrom).'") AND '.
+      '(`time` < "'.TimeToMysqlDateTime($TimeTo).'") AND '.
+      '(`measure`='.$this->Data['Id'].') AND (`level`='.$Level.') ORDER BY `time`');
+    $Values = array();
+    while($Row = $Result->fetch_array())
+    {
+      $Values[] = array('time' => MysqlDateTimeToTime($Row['time']), 'min' => $Row['min'], 'avg' => $Row['avg'], 'max' => $Row['max'], 'continuity' => $Row['continuity']);
+    }
+   // array_pop($Values);
+
+    $Points = array();
+    if(count($Values) > 0)
+    {
+      $Values = array_merge(
+        $this->LoadLeftSideValue($Level, $TimeFrom),
+        $Values,
+        $this->LoadRightSideValue($Level, $TimeTo));
+
+      $StartIndex = 0;
+      $Points = array();
+      for($I = 0; $I < $this->DivisionCount; $I++)
+      {
+        $TimeStart = $TimeFrom + (($TimeTo - $TimeFrom) / $this->DivisionCount) * $I;
+        $TimeEnd = $TimeFrom + (($TimeTo - $TimeFrom) / $this->DivisionCount) * ($I+1);
+
+        $EndIndex = $StartIndex;
+        while($Values[$EndIndex]['time'] < $TimeEnd) $EndIndex = $EndIndex + 1;
+        $SubValues = array_slice($Values, $StartIndex, $EndIndex - $StartIndex + 1);
+        $Points[] = $this->ComputeOneValue($TimeStart, $TimeEnd, $SubValues, $Level);
+        $StartIndex = $EndIndex - 1;
+      }
+    } else $Points[] = array('min' => 0, 'avg' => 0, 'max' => 0);
+    return($Points);
+  }
+
+  function RebuildMeasureCache()
+  {
+    echo('Velicina '.$this->Data['Name']."<br>\n");
+    if($this->Data['Continuity'] == 0) $this->Data['ContinuityEnabled'] = 0;  // non continuous
+      else $this->Data['ContinuityEnabled'] = 2;    // continuous graph
+
+    // Clear previous items
+    $DbResult = $this->Database->select($this->Data['DataTable'], 'COUNT(*)', '(`level`>0) AND (`measure`='.$this->Data['Id'].')');
+    $Row = $DbResult->fetch_array();
+    echo("Mazu starou cache (".$Row[0]." polozek)...");
+    $this->Database->delete($this->Data['DataTable'], '(`level`>0) AND (`measure`='.$this->Data['Id'].')');
+    echo("<br>\n");
+
+    for($Level = 1; $Level <= $this->MaxLevel; $Level++)
+    {
+      echo('Uroven '.$Level."<br>\n");
+      $TimeRange = $this->GetTimeRange($Level - 1);
+      $TimeSegment = $this->TimeSegment($Level);
+      $StartTime = $this->AlignTime($TimeRange['left'], $TimeSegment) - $TimeSegment;
+      $EndTime = $this->AlignTime($TimeRange['right'], $TimeSegment);
+      $BurstCount = 500;
+      echo('For 0 to '.round(($EndTime - $StartTime) / $TimeSegment / $BurstCount)."<br>\n");
+      for($I = 0; $I <= round(($EndTime - $StartTime) / $TimeSegment / $BurstCount); $I++)
+      {
+        echo($I.' ');
+        $StartTime2 = $StartTime + $I * $BurstCount * $TimeSegment;
+        $EndTime2 = $StartTime + ($I + 1) * $BurstCount * $TimeSegment;
+        $Values = array();
+        $DbResult = $this->Database->select($this->Data['DataTable'], '*', '(`time` > "'.TimeToMysqlDateTime($StartTime2).'") AND (`time` < "'.
+          TimeToMysqlDateTime($EndTime2).'") AND (`measure`='.$this->Data['Id'].') AND (`level`='.($Level - 1).') ORDER BY `time`');
+        while($Row = $DbResult->fetch_array())
+        {
+          $Row['time'] = MysqlDateTimeToTime($Row['time']);
+          $Values[] = $Row;
+        }
+
+        if(count($Values) > 0)
+        {
+          $Values = array_merge(
+            $this->LoadLeftSideValue($Level - 1, $StartTime2),
+            $Values,
+            $this->LoadRightSideValue($Level - 1, $EndTime2));
+
+          $StartIndex = 0;
+          for($B = 0; $B < $BurstCount; $B++)
+          {
+            echo('.');
+            $StartTime3 = $StartTime2 + (($EndTime2 - $StartTime2) / $BurstCount) * $B;
+            $EndTime3 = $StartTime2 + (($EndTime2 - $StartTime2) / $BurstCount) * ($B + 1);
+
+            $EndIndex = $StartIndex;
+            while($Values[$EndIndex]['time'] < $EndTime3) $EndIndex = $EndIndex + 1;
+            $SubValues = array_slice($Values, $StartIndex, $EndIndex - $StartIndex + 1);
+            if(count($SubValues) > 2)
+            {
+              $Point = $this->ComputeOneValue($StartTime3, $EndTime3, $SubValues, $Level);
+              $Continuity = $SubValues[1]['continuity'];
+              $this->Database->insert($this->Data['DataTable'], array('level' => $Level, 'measure' => $this->Data['Id'],
+                'min' => $Point['min'], 'avg' => $Point['avg'], 'max' => $Point['max'],
+                'continuity' => $Continuity, 'time' => TimeToMysqlDateTime($StartTime3 + ($EndTime3 - $StartTime3) / 2)));
+            }
+            $StartIndex = $EndIndex - 1;
+          }
+        }
+        // Load values in time range
+        //array_pop($NextValues);
+      }
+      echo("Uroven dokoncena<br>\n");
+      $DbResult = $this->Database->select($this->Data['DataTable'], 'COUNT(*)',
+        '(`level`='.$Level.') AND (`measure`='.$this->Data['Id'].')');
+      $Row = $DbResult->fetch_array();
+      echo("Vlozeno ".$Row[0]." polozek.<br>\n");
+    }
+  }
+
+  function RebuildAllMeasuresCache()
+  {
+    $Result = $this->Database->select('measure', 'Id');
+    while($Row = $Result->fetch_array())
+    {
+      $Measure = new Measure();
+      $Measure->Load($Row['Id']);
+      $Measure->RebuildMeasureCache();
+      echo('Velicina id '.$Row['Id'].' dokoncena<br/>');
+    }
+  }
+
+  function InitMeasureDataTable()
+  {
+    $this->Database->query('CREATE TABLE `data_'.$this->Data['Name'].'` (
+      `Time` TIMESTAMP NOT NULL ,
+      `Avg` '.$this->Data['DataType'].' NOT NULL ,
+      `Continuity` BOOL NOT NULL
+      ) ENGINE = MYISAM ;');
+
+    $this->Database->query('CREATE TABLE `data_'.$this->Data['Name'].'_cache` (
+`Time` TIMESTAMP NOT NULL ,
+`Level` TINYINT NOT NULL ,
+`Min` '.$this->Data['DataType'].' NOT NULL ,
+`Avg` '.$this->Data['DataType'].' NOT NULL ,
+`Max` '.$this->Data['DataType'].' NOT NULL ,
+`Continuity` BOOL NOT NULL
+) ENGINE = MYISAM ;');
+  }
+}
Index: /trunk/Point.php
===================================================================
--- /trunk/Point.php	(revision 63)
+++ /trunk/Point.php	(revision 63)
@@ -0,0 +1,26 @@
+<?php
+
+class Point
+{
+  var $X;
+  var $Y;
+
+  function __construct($X, $Y)
+  {
+    $this->X = $X;
+    $this->Y = $Y;
+  }
+}
+
+function NewPoint($X, $Y)
+{
+  $Point = new Point($X, $Y);
+  return($Point);
+}
+
+/* Linear interpolation between two points */
+function Interpolation(Point $P1, Point $P2, $X)
+{
+  $Y = ($P2->Y - $P1->Y) / ($P2->X - $P1->X) * ($X - $P1->X) + $P1->Y;
+  return($Y);
+}
Index: /trunk/Types.php
===================================================================
--- /trunk/Types.php	(revision 63)
+++ /trunk/Types.php	(revision 63)
@@ -0,0 +1,13 @@
+<?php
+
+$Types = array(
+  'Boolean' => array(
+  
+  ),
+  'String' => array(
+  
+  ),
+  'Integer' => array(
+  
+  ),
+);
Index: /trunk/Version.php
===================================================================
--- /trunk/Version.php	(revision 62)
+++ /trunk/Version.php	(revision 63)
@@ -1,4 +1,4 @@
 <?php
 
-$Revision = 62;
+$Revision = 63;
 $ReleaseTime = strtotime('2016-01-01');
Index: /trunk/add.php
===================================================================
--- /trunk/add.php	(revision 62)
+++ /trunk/add.php	(revision 63)
@@ -1,5 +1,5 @@
 <?php
 
-include('global.php');
+include('Global.php');
 
 if(array_key_exists('MeasureId', $_GET) and array_key_exists('Value', $_GET))
Index: /trunk/admin.php
===================================================================
--- /trunk/admin.php	(revision 62)
+++ /trunk/admin.php	(revision 63)
@@ -1,4 +1,4 @@
 <?php
-include('global.php');
+include('Global.php');
 
 if(array_key_exists('Operation', $_GET)) $Operation = $_GET['Operation']; else $Operation = '';
Index: unk/classes.php
===================================================================
--- /trunk/classes.php	(revision 62)
+++ 	(revision )
@@ -1,17 +1,0 @@
-<?php
-
-$Classes = array(
-  'Measure' => array(
-    'Name' =>           array('Type' => 'String', 'Caption' => 'Zkratka', 'Default' => 'measure'),
-    'Title' =>          array('Type' => 'String', 'Caption' => 'Název', 'Default' => 'Měření'),
-    'Description' =>    array('Type' => 'String', 'Caption' => 'Popis', 'Default' => 'Měření veličiny'),
-    'Unit' =>           array('Type' => 'String', 'Caption' => 'Jednotka', 'Default' => ''),
-    'Continuity' =>     array('Type' => 'Boolean', 'Caption' => 'Spojitost', 'Default' => '0'),
-    'Period' =>         array('Type' => 'Integer', 'Caption' => 'Perioda měření', 'Default' => '60'),
-    'PermissionAdd' =>  array('Type' => 'String', 'Caption' => 'Oprávnění k měření', 'Default' => 'localhost.localdomain'),
-    'PermissionView' => array('Type' => 'String', 'Caption' => 'Oprávnění k prohlížení', 'Default' => 'all'),
-    'Enabled' =>        array('Type' => 'Boolean', 'Caption' => 'Povolení', 'Default' => '1'),
-    'DataType' =>       array('Type' => 'String', 'Caption' => 'Typ datových položek', 'Default' => 'int'),
-    'DataTable' =>      array('Type' => 'String', 'Caption' => 'Tabulka měřených dat', 'Default' => 'data'),
-  ),
-);
Index: unk/create_groups.php
===================================================================
--- /trunk/create_groups.php	(revision 62)
+++ 	(revision )
@@ -1,16 +1,0 @@
-<?php
-
-include('stat_functions.php');
-include('db.php');
-DB_Init('localhost', 'root', '', 'statistic');
-
-$Measures = array();
-DB_Select('stat_measure', '*');
-while($Measures[] = DB_Row());
-array_pop($Measures);
-
-foreach($Measures as $Measure)
-{
-  echo('Velicina '.$Measure['name']."\n");
-  for($Level=)         
-}
Index: unk/global.php
===================================================================
--- /trunk/global.php	(revision 62)
+++ 	(revision )
@@ -1,117 +1,0 @@
-<?php
-
-session_start();
-$FileName = dirname(__FILE__).'/config.php';
-if(file_exists($FileName)) include_once($FileName);
-else {
-  die('Configuration file "'.$FileName.'" not found.');
-}
-include_once('Version.php');
-include_once('types.php');
-include_once('classes.php');
-include_once('Packages/Common/Common.php');
-$PrefixMultiplier = new PrefixMultiplier();
-$ErrorHandler = new ErrorHandler();
-$ErrorHandler->Start();
-$ErrorHandler->ShowError = $Config['Web']['ShowError'];
-include_once('stat_functions.php');
-$Database = new Database();
-$Database->Connect($Config['Database']['Host'], $Config['Database']['User'],
-  $Config['Database']['Password'], $Config['Database']['Database']);
-$Database->Prefix = $Config['Database']['Prefix'];
-$Database->charset($Config['Database']['Charset']);
-$Database->ShowSQLError = $Config['Web']['ShowSQLError'];
-$Database->ShowSQLQuery = $Config['Web']['ShowSQLQuery'];
-
-// SQL injection hack protection
-foreach($_POST as $Index => $Item) $_POST[$Index] = addslashes($Item);
-foreach($_GET as $Index => $Item) $_GET[$Index] = addslashes($Item);
-
-function HumanDate($Time)
-{
-  return(date('j.n.Y', $Time));
-}
-
-function GetMicrotime()
-{
-  list($Usec, $Sec) = explode(" ", microtime());
-  return ((float)$Usec + (float)$Sec);
-}
-
-function ShowPage($Content)
-{
-  global $Config, $ReleaseTime, $Revision;
-
-  $Output = '<?xml version="1.0" encoding="'.$Config['Web']['Charset'].'"?>'."\n".
-  '<!DOCTYPE html>'.
-  '<html>'.
-  '<head>'.
-  '<meta http-equiv="Content-Language" content="cs"/>'.
-  '<meta http-equiv="content-type" content="text/html; charset='.$Config['Web']['Charset'].'" />'.
-  '<meta name="robots" content="all" />'.
-  '<title>'.$Config['Web']['Title'].'</title>'.
-  '<link rel="StyleSheet" href="style/style.css" type="text/css" media="all"/>'.
-  '</head><body>';
-  $Output .= $Content;
-  $Output .= '<br/><div style="text-align: center; font-size: small;">Verze: '.$Revision.' ('.HumanDate($ReleaseTime).')'.
-    ' &nbsp; <a href="http://svn.zdechov.net/trac/statistic/browser/trunk">Zdrojový kód</a> &nbsp; '.
-    '<a href="http://svn.zdechov.net/trac/statistic/log/trunk?verbose=on">Historie změn</a></div>';
-  $Output .= '</body></html>';
-  echo($Output);
-}
-
-function MakeLink($Target, $Title)
-{
-  return('<a href="'.$Target.'">'.$Title.'</a>');
-}
-
-function Table($Table)
-{
-  $Result = '<table cellspacing="0" class="BasicTable">';
-  $Result .= '<tr>';
-  foreach($Table['Header'] as $Item)
-    $Result .= '<th>'.$Item.'</th>';
-  $Result .= '</tr>';
-  foreach($Table['Rows'] as $Row)
-  {
-    $Result .= '<tr>';
-    foreach($Row as $Item)
-      $Result .= '<td>'.$Item.'</td>';
-    $Result .= '</tr>';
-  }
-  $Result .= '</table>';
-  return($Result);
-}
-
-function ShowEditTable($ClassName, $Values)
-{
-  global $Classes, $Types;
-  $Class = $Classes[$ClassName];
-  $Table = array(
-    'Header' => array('Položka', 'Hodnota'),
-    'Rows' => array(),
-  );
-
-  foreach($Class as $Index => $Item)
-  {
-    if(!array_key_exists($Index, $Values)) $Values[$Index] = $Item['Default'];
-    switch($Item['Type'])
-    {
-      case 'Boolean':
-        if($Values[$Index] == 0) $Checked = ''; else $Checked = ' checked="yes"';
-        $Edit = '<input type="checkbox" name="'.$Index.'"'.$Checked.'>';
-        break;
-      case 'String':
-        $Edit = '<input type="text" name="'.$Index.'" value="'.$Values[$Index].'">';
-        break;
-      case 'Integer':
-        $Edit = '<input type="text" name="'.$Index.'" value="'.$Values[$Index].'">';
-        break;
-      default:
-        $Edit = 'Neznámý typ';
-    }
-    array_push($Table['Rows'], array($Item['Caption'], $Edit));
-  }
-  $Output = '<h3>Tabulka '.$ClassName.'</h3>'.Table($Table).MakeLink('?Operation=Add2', 'Přidat');
-  return($Output);
-}
Index: unk/graph.php
===================================================================
--- /trunk/graph.php	(revision 62)
+++ 	(revision )
@@ -1,197 +1,0 @@
-<?php
-
-include('global.php');
-
-if(array_key_exists('Debug', $_GET)) $Debug = $_GET['Debug'];
-  else $Debug = 0;
-
-if(!array_key_exists('From',$_GET)) die('Musíte zadat čas počátku');
-$StartTime = addslashes($_GET['From']);
-if(!array_key_exists('To',$_GET)) die('Musíte zadat čas konce');
-$EndTime = addslashes($_GET['To']);
-if($EndTime < $StartTime) $EndTime = $StartTime + 60;
-$TimeDifference = $EndTime - $StartTime;
-if(!array_key_exists('Measure', $_GET)) die('Musíte zadat měřenou veličinu');
-$MeasureId = addslashes($_GET['Measure']);
-if(!array_key_exists('Width', $_GET)) $Width = $DefaultWidth;
-else $Width = addslashes($_GET['Width']);
-if(!array_key_exists('Height', $_GET)) $Height = $DefaultHeight;
-else $Height = addslashes($_GET['Height']);
-if(!array_key_exists('Differential', $_GET)) $Differential = $Config['DefaultVariables']['Differential'];
-else $Differential = addslashes($_GET['Differential']);
-$VerticalLinesCount = round($Height / ($FontSize + 4));
-
-$StopWatchStart = GetMicrotime();
-
-$Measure = new Measure($Database);
-$Measure->Load($MeasureId);
-$Measure->DivisionCount = $Config['DivisionCount'];
-$Measure->LevelReducing = $Config['LevelReducing'];
-$Measure->MaxLevel = $Config['MaxLevel'];
-$Measure->ReferenceTime = $Config['ReferenceTime'];
-$Measure->Differential = $Differential;
-
-$Level = floor(log(($EndTime - $StartTime) / $Measure->DivisionCount / 60) / log($Measure->LevelReducing)) - 1;
-if($Level < 0) $Level = 0;
-if($Level > $Measure->MaxLevel) $Level = $Measure->MaxLevel;
-
-$Points = $Measure->GetValues($StartTime, $EndTime, $Level);
-
-if($Debug) echo('Points count: '.count($Points).'<br>');
-//if($Debug) foreach($Points as $Index => $Item)
-//  echo($Index.': '.$Item['min'].'<br>');
-
-// Calculate total max, avg, min value
-$MaxValue = -1000000000000000000;
-$AvgValue = 0;
-$MinValue = 1000000000000000000;
-foreach($Points as $Index => $Item)
-{
-  //$Points[$Index]['min'] =  $Points[$Index]['min'] / $Measure['Divider'];
-  //$Points[$Index]['avg'] =  $Points[$Index]['avg'] / $Measure['Divider'];
-  //$Points[$Index]['max'] =  $Points[$Index]['max'] / $Measure['Divider'];
-  if($Points[$Index]['avg'] > $MaxValue) $MaxValue = $Points[$Index]['avg'];
-  if($Points[$Index]['avg'] < $MinValue) $MinValue = $Points[$Index]['avg'];
-  if($Points[$Index]['max'] > $MaxValue) $MaxValue = $Points[$Index]['max'];
-  if($Points[$Index]['min'] < $MinValue) $MinValue = $Points[$Index]['min'];
-  $AvgValue = $AvgValue + $Points[$Index]['avg'];
-}
-//$MinValue = round($MinValue * $Measure['Divider']) / $Measure['Divider'];
-//$MaxValue = round($MaxValue * $Measure['Divider']) / $Measure['Divider'];
-$AvgValue = $AvgValue / count($Points); //round(* $Measure['Divider']) / $Measure['Divider'];
-
-// Generate polygon and recalculate y values to fit graph height
-$PointsMin = array(0, $Height - 1);
-$PointsAvg = array(0, $Height - 1);
-$PointsMax = array(0, $Height - 1);
-if(($MaxValue - $MinValue) == 0) $MaxValue = $MinValue + 1;
-{
-  foreach($Points as $Index => $Item)
-  {
-    $PointsMin[] = $Index * $Width / $Measure->DivisionCount;
-    $PointsMin[] = $Height - 1 - ($Points[$Index]['min'] - $MinValue) / ($MaxValue - $MinValue) * $Height * $K;
-    $PointsAvg[] = $Index * $Width / $Measure->DivisionCount;
-    $PointsAvg[] = $Height - 1 - ($Points[$Index]['avg'] - $MinValue) / ($MaxValue - $MinValue) * $Height * $K;
-    $PointsMax[] = $Index * $Width / $Measure->DivisionCount;
-    $PointsMax[] = $Height - 1 - ($Points[$Index]['max'] - $MinValue) / ($MaxValue - $MinValue) * $Height * $K;
-    //echo($Index.' - '.$Item.' '.$Points[$Index].'<br>');
-  }
-}
-$PointsMin[] = $Width - 1;
-$PointsMin[] = $Height - 1;
-$PointsAvg[] = $Width - 1;
-$PointsAvg[] = $Height - 1;
-$PointsMax[] = $Width - 1;
-$PointsMax[] = $Height - 1;
-$PointsMin[] = $Width - 1;
-$PointsMin[] = $Height - 1;
-$PointsAvg[] = $Width - 1;
-$PointsAvg[] = $Height - 1;
-$PointsMax[] = $Width - 1;
-$PointsMax[] = $Height - 1;
-
-
-//array_unshift($Points, $Height - 1);
-//array_unshift($Points, 0);
-//$Points[] = $Width - 1;
-//$Points[] = $Height - 1;
-
-// Generate image
-if(!$Debug)
-{
-  Header("Content-type: image/png");
-  Header("Cache-Control: no-cache");	// Dynamic graph - no cache
-  $Image = @imagecreate($Width, $Height);
-  $BackgroundColor = imagecolorallocate($Image, 255, 255, 255);
-  $Black = imagecolorallocate($Image, 0, 0, 0);
-  $White = imagecolorallocate($Image, 255, 255, 255);
-  $Gray = imagecolorallocate($Image, 200, 200, 200);
-  $DarkGray = imagecolorallocate($Image, 100, 100, 100);
-  $LightBlue = imagecolorallocate($Image, 150, 150, 255);
-  $Blue = imagecolorallocate($Image, 0, 0, 255);
-  $LightRed = imagecolorallocate($Image, 255, 150, 150);
-  $Red = imagecolorallocate($Image, 255, 0, 0);
-  $Green = imagecolorallocate($Image, 0, 200, 0);
-  $LightGreen = imagecolorallocate($Image, 150, 255, 150);
-
-  imagefilledpolygon($Image, $PointsMax, count($PointsMax) / 2, $LightRed);
-  imagefilledpolygon($Image, $PointsAvg, count($PointsAvg) / 2, $LightGreen);
-  imagefilledpolygon($Image, $PointsMin, count($PointsMin) / 2, $LightBlue);
-
-  $TimeMarks = array(1, 60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30, 60*60*24*365, 60*60*24*365*10);
-
-  $TimeRange = $EndTime - $StartTime;
-  $TimeMarksIndex = 0;
-  while(($TimeRange / $TimeMarks[$TimeMarksIndex]) > 1) $TimeMarksIndex += 1;
-  if($TimeMarksIndex < 2) $TimeMarksIndex = 2;
-  $MajorTimeMarks = $TimeMarks[$TimeMarksIndex - 1];
-  $MinorTimeMarks = $TimeMarks[$TimeMarksIndex - 2];
-
-  $TimeShift = $Measure->AlignTime($StartTime, $MajorTimeMarks) - $StartTime;
-  //imagestring($Image, 10, 40, 50, $TimeShift, $Black);
-
-  // Zobraz měřítko Y
-  $VerticalLinesDistance = $Height / $VerticalLinesCount;
-  for($I=1; $I<=$VerticalLinesCount; $I++)
-  {
-    $Y = $Height - 1 - ($VerticalLinesDistance * $I);
-    for($X=1; $X < $Width; $X = $X + 3) imagesetpixel($Image, $X, $Y, $Gray);
-    //imageline($Image, 30, $Y, $Width-1, $Y, IMG_COLOR_STYLED);
-  }
-
-  $TimeShift = $Measure->AlignTime($StartTime, $MinorTimeMarks) - $StartTime;
-
-  // Zobraz měřítko X
-  $LastTextEnd = 0;
-  for($Time = $StartTime; $Time < $EndTime; $Time += $MajorTimeMarks)
-  {
-    $X = round(($Time - $StartTime + $TimeShift) / $TimeRange * $Width) % $Width;
-    //imageline($Image, 30, $Y, $Width-1, $Y, IMG_COLOR_STYLED);
-    if(($MajorTimeMarks > 60*60*24)) $Text = date('j.n.Y', $Time + $TimeShift);
-      else $Text = date('j.n.Y G:i', $Time + $TimeShift);
-    $BoundBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
-    if($LastTextEnd < ($X - ($BoundBox[2] - $BoundBox[0] + 20) / 2))
-    {
-      for($Y=0; $Y < $Height; $Y = $Y + 1) imagesetpixel($Image, $X, $Y, $Gray);
-      imagettftext($Image, $FontSize, 0, $X - ($BoundBox[2] - $BoundBox[0]) / 2,  $Height - 2, $Black, $FontFile, $Text);
-      $LastTextEnd = $X + ($BoundBox[2] - $BoundBox[0]) / 2;
-    }
-    else for($Y=0; $Y < $Height; $Y = $Y + 3) imagesetpixel($Image, $X, $Y, $Gray);
-  }
-
-  // Popisky osy Y
-  for($I = 1; $I <= $VerticalLinesCount; $I++)
-  {
-    $Y = $Height - 1 - ($VerticalLinesDistance * $I);
-    //$Y = $Height - 1 - ($VerticalLinesDistance * $I / ($MaxValue - $MinValue) * $K * $Height);
-    $Text = $PrefixMultiplier->Add(round(($I * $VerticalLinesDistance / $Height /
-      $K * ($MaxValue - $MinValue) + $MinValue)), $Measure->Data['Unit'], 3);
-    $BoundBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
-    if(($Y - ($BoundBox[5] - $BoundBox[1]) / 2) > 10)
-      imagettftext($Image, $FontSize, 0, 2,  $Y - ($BoundBox[5] - $BoundBox[1]) / 2, $Black, $FontFile, $Text);
-  }
-  $GenerationTime = floor((GetMicrotime() - $StopWatchStart) * 1000  ) / 1000;
-
-  $Left = $Width - 10;
-  $Text = "    Max. ".$PrefixMultiplier->Add($MaxValue, $Measure->Data['Unit']);
-  $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
-  $Left -= ($BoundingBox[2] - $BoundingBox[0]);
-  imagettftext($Image, $FontSize, 0, $Left, 14, $Red, $FontFile, $Text);
-
-  $Text = "    Avg.  ".$PrefixMultiplier->Add($AvgValue, $Measure->Data['Unit'], 4);
-  $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
-  $Left -= ($BoundingBox[2] - $BoundingBox[0]);
-  imagettftext($Image, $FontSize, 0, $Left, 14, $Green, $FontFile, $Text);
-
-  $Text = "    Min.  ".$PrefixMultiplier->Add($MinValue, $Measure->Data['Unit']);
-  $BoundingBox = imagettfbbox($FontSize, 0, $FontFile, $Text);
-  $Left -= ($BoundingBox[2] - $BoundingBox[0]);
-  imagettftext($Image, $FontSize, 0, $Left, 14, $Blue, $FontFile, $Text);
-  //imagestring($Image, 2, 70, 20, 'Vygenerováno za '.$GenerationTime.' sekund', $Black);
-  //imagestring($Image, 2, 50, 30, 'Level: '.$Level, $Black);
-
-  imagettftext($Image, $FontSize, 0, 70, 14, $Black, $FontFile, $Measure->Data['Description']);
-  imagerectangle($Image, 0, 0, $Width - 1, $Height - 1, $Black);   // Frame border
-  imagepng($Image);
-  imagedestroy($Image);
-}
Index: /trunk/index.php
===================================================================
--- /trunk/index.php	(revision 62)
+++ /trunk/index.php	(revision 63)
@@ -1,4 +1,4 @@
 <?php
-include('global.php');
+include('Global.php');
 
 $Debug = 0;
@@ -65,6 +65,6 @@
 }
 
-$Months = array('', 'Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 
-  'Říjen', 'Listopad', 'Prosinec'); 
+$Months = array('', 'Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září',
+  'Říjen', 'Listopad', 'Prosinec');
 
 $GrafTimeRanges = array(
@@ -103,5 +103,5 @@
 }
 
-if($_SESSION['TimeSpecify'] == 0) 
+if($_SESSION['TimeSpecify'] == 0)
 {
   $_SESSION['TimeEnd'] = time() - 60;
@@ -111,14 +111,14 @@
 $Output = '<div style="text-align: center"><div class="Title">'.$Config['Web']['Title'].'</div>';
 
-if(!array_key_exists('Operation', $_GET)) $_GET['Operation'] = ''; 
+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))  
+      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'], 
+          $_SESSION[$_GET['Time']] = mktime($_POST['Hour'], $_POST['Minute'], 0, $_POST['Month'],
             $_POST['Day'], $_POST['Year']);
           $$_GET['Time'] = $_SESSION[$_GET['Time']];
@@ -127,5 +127,5 @@
     break;
   case 'SetTimeNow':
-    if(array_key_exists('Time', $_GET)) 
+    if(array_key_exists('Time', $_GET))
     {
       if(($_GET['Time'] == 'TimeStart') or ($_GET['Time'] == 'TimeEnd'))
@@ -145,7 +145,7 @@
   $Output .= 'Délka úseku: ';
   foreach($GrafTimeRanges as $Index => $Item)
-    $Output .= '<a href="?Period='.$Index.'">'.$Item['caption'].'</a>&nbsp;'; 
+    $Output .= '<a href="?Period='.$Index.'">'.$Item['caption'].'</a>&nbsp;';
   $Output .= '<br>';
-  $Output .= '<a href="?TimeSpecify=1">Přesnější nastavení...</a><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;">';
@@ -153,5 +153,5 @@
   $Output .= '<tr><td>Konec:</td><td>'.EditTime('TimeEnd').'</td></tr>';
   $Output .= '</table>';
-  $Output .= '<a href="?TimeSpecify=0">Jednoduché nastavení...</a><br>';  
+  $Output .= '<a href="?TimeSpecify=0">Jednoduché nastavení...</a><br>';
 }
 $Output .= '<br>';
@@ -162,5 +162,5 @@
 
 $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 .= '<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>';
 
Index: /trunk/measure_scripts/monitor_sample.php
===================================================================
--- /trunk/measure_scripts/monitor_sample.php	(revision 62)
+++ /trunk/measure_scripts/monitor_sample.php	(revision 63)
@@ -30,3 +30,2 @@
   sleep(58);  // 60(measure period) - 2(disk utilization)
 }
-?>
Index: /trunk/measure_scripts/system.php
===================================================================
--- /trunk/measure_scripts/system.php	(revision 62)
+++ /trunk/measure_scripts/system.php	(revision 63)
@@ -164,5 +164,2 @@
   return($UptimeParts[0]);
 }
-
-
-?>
Index: unk/rebuild.php
===================================================================
--- /trunk/rebuild.php	(revision 62)
+++ 	(revision )
@@ -1,8 +1,0 @@
-<?php
-
-include('global.php');
-
-$Measure = GetMeasureById(7);
-RebuildMeasureCache($Measure);
-
-//RebuildAllMeasuresCache();
Index: unk/stat_functions.php
===================================================================
--- /trunk/stat_functions.php	(revision 62)
+++ 	(revision )
@@ -1,443 +1,0 @@
-<?php
-
-include_once('Point.php');
-
-class Measure
-{
-  var $Data;
-  var $ValueTypes;
-  var $LevelReducing;
-  var $Database;
-  var $MaxLevel;
-  var $ReferenceTime;
-  var $Differential;
-  var $DivisionCount;
-
-  function __construct($Database)
-  {
-    $this->Id = 0;
-    $this->ValueTypes = array('min', 'avg', 'max');
-    $this->Database = &$Database;
-    $this->LevelReducing = 5;
-    $this->MaxLevel = 4;
-    $this->ReferenceTime = 0;
-    $this->Differential = 0;
-    $this->DivisionCount = 500;
-  }
-
-  function TimeSegment($Level)
-  {
-    return(pow($this->LevelReducing, $Level) * 60);
-  }
-
-  function StatTableName($Level)
-  {
-    if($Level == 0) return('data');
-      else return('data_cache');
-  }
-
-  function AlignTime($Time, $TimeSegment)
-  {
-    return(round(($Time - $this->ReferenceTime) / $TimeSegment) * $TimeSegment +
-      $this->ReferenceTime);
-  }
-
-  function Load($Id)
-  {
-    $Result = $this->Database->select('measure', '*', 'Id='.$Id);
-    if($Result->num_rows > 0)
-    {
-      $this->Data = $Result->fetch_array();
-      if($this->Data['Continuity'] == 0) $this->Data['ContinuityEnabled'] = 0;  // non continuous
-        else $this->Data['ContinuityEnabled'] = 2;    // continuous graph
-    } else die('Měřená veličina nenalezena');
-  }
-
-  function AddValue($Value)
-  {
-    $Time = time();
-
-    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
-      '(`level`=0) ORDER BY `time` DESC LIMIT 2');
-    if($Result->num_rows == 0) $this->Database->insert($this->Data['DataTable'],
-      array('min' => $Value, 'avg' => $Value, 'max' => $Value, 'level' => 0,
-      'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time), 'continuity' => 0));
-    else if($Result->num_rows == 1) $this->Database->insert($this->Data['DataTable'],
-      array('min' => $Value, 'avg' => $Value, 'max' => $Value, 'level' => 0,
-      'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time),
-      'continuity' => 1));
-    else {
-      $LastValue = $Result->fetch_array();
-      $NextToLastValue = $Result->fetch_array();
-      if(($Time - MysqlDateTimeToTime($LastValue['time'])) < 0.75 * $this->Data['Period'])
-      {
-      }
-      else
-      {
-        if(($Time - MysqlDateTimeToTime($LastValue['time'])) < 1.25 * $this->Data['Period']) $Continuity = 1;
-          else $Continuity = 0;
-        if(($LastValue['avg'] == $NextToLastValue['avg']) and ($LastValue['avg'] == $Value) and
-          ($LastValue['continuity'] == 1) and ($Continuity == 1))
-        {
-          $this->Database->update($this->Data['DataTable'], '(time="'.$LastValue['time'].'") AND '.
-          '(level=0) AND (measure='.$this->Data['Id'].')', array('time' => TimeToMysqlDateTime($Time)));
-        } else
-        {
-          $this->Database->insert($this->Data['DataTable'], array('min' => $Value,
-            'avg' => $Value, 'max' => $Value, 'level' => 0, 'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time),
-            'continuity' => $Continuity));
-        }
-      }
-    }
-
-    // Update levels
-    for($Level = 1; $Level <= $this->MaxLevel; $Level++)
-    {
-      $TimeSegment = $this->TimeSegment($Level);
-      $EndTime = $this->AlignTime($Time, $TimeSegment);
-      //if($EndTime < $Time) $EndTime = $EndTime + $TimeSegment;
-      $StartTime = $EndTime - $TimeSegment;
-
-      // Load values in time range
-      $Values = array();
-      $Result = $this->Database->select($this->Data['DataTable'], '*', '(`time` > "'.TimeToMysqlDateTime($StartTime).'") AND '.
-        '(`time` < "'.TimeToMysqlDateTime($EndTime).'") AND '.
-        '(`measure`='.$this->Data['Id'].') AND (`level`='.($Level - 1).') ORDER BY `time`');
-      while($Row = $Result->fetch_array())
-      {
-        $Row['time'] = MysqlDateTimeToTime($Row['time']);
-        $Values[] = $Row;
-      }
-      //array_pop($Values);
-
-      // Load subsidary values
-      $Values = array_merge(
-        $this->LoadLeftSideValue($Level - 1, $StartTime),
-        $Values,
-        $this->LoadRightSideValue($Level - 1, $EndTime));
-
-      $Point = $this->ComputeOneValue($StartTime, $EndTime, $Values, $Level);
-
-      $this->Database->delete($this->Data['DataTable'], '(time > "'.TimeToMysqlDateTime($StartTime).'") AND
-        (time < "'.TimeToMysqlDateTime($EndTime).'") AND measure='.$this->Data['Id'].' AND level='.$Level);
-      $Continuity = $Values[1]['continuity'];
-      $this->Database->insert($this->Data['DataTable'], array('level' => $Level, 'measure' => $this->Data['Id'], 'min' => $Point['min'],
-        'avg' => $Point['avg'], 'max' => $Point['max'], 'continuity' => $Continuity,
-        'time' => TimeToMysqlDateTime($StartTime + ($EndTime - $StartTime) / 2)));
-
-    }
-  }
-
-  /* Compute one value for upper time level from multiple values */
-  function ComputeOneValue($LeftTime, $RightTime, $Values, $Level)
-  {
-    $NewValue = array('min' => +1000000000000000000, 'avg' => 0, 'max' => -1000000000000000000);
-
-    // Trim outside parts
-    foreach($this->ValueTypes as $ValueType)
-    {
-      $Values[0][$ValueType] = Interpolation(NewPoint($Values[0]['time'], $Values[0][$ValueType]),
-        NewPoint($Values[1]['time'], $Values[1][$ValueType]), $LeftTime);
-    }
-    $Values[0]['time'] = $LeftTime;
-    foreach($this->ValueTypes as $ValueType)
-    {
-      $Values[count($Values) - 1][$ValueType] = Interpolation(NewPoint($Values[count($Values) - 2]['time'],
-        $Values[count($Values) - 2][$ValueType]),
-        NewPoint($Values[count($Values) - 1]['time'], $Values[count($Values) - 1][$ValueType]),
-        $RightTime);
-    }
-    $Values[count($Values) - 1]['time'] = $RightTime;
-
-    // Perform computation
-    foreach($this->ValueTypes as $ValueType)
-    {
-      // Compute new value
-      for($I = 0; $I < (count($Values) - 1); $I++)
-      {
-        if($ValueType == 'avg')
-        {
-          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled']);
-            else if($this->Differential == 0)
-            {
-              $NewValue[$ValueType] = $NewValue[$ValueType] + ($Values[$I + 1]['time'] - $Values[$I]['time']) *
-                (($Values[$I + 1][$ValueType] - $Values[$I][$ValueType]) / 2 + $Values[$I][$ValueType]);
-            } else {
-              $NewValue[$ValueType] = $NewValue[$ValueType] + ($Values[$I + 1]['time'] - $Values[$I]['time']) *
-               (($Values[$I + 1][$ValueType] - $Values[$I][$ValueType]) / 2);
-            }
-        }
-        else if($ValueType == 'max')
-        {
-          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled'])
-          {
-            if(0 > $NewValue[$ValueType]) $NewValue[$ValueType] = 0;
-          }
-          else
-          {
-            if($this->Differential == 0)
-            {
-              if($Values[$I + 1][$ValueType] > $NewValue[$ValueType]) $NewValue[$ValueType] = $Values[$I + 1][$ValueType];
-            } else {
-              $Difference = $Values[$I + 1][$ValueType] - $Values[$I][$ValueType];
-              if($Difference > $NewValue[$ValueType]) $NewValue[$ValueType] = $Difference;
-            }
-          }
-        }
-        else if($ValueType == 'min')
-        {
-          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled'])
-          {
-            if(0 < $NewValue[$ValueType]) $NewValue[$ValueType] = 0;
-          } else {
-            if($this->Differential == 0)
-            {
-              if($Values[$I + 1][$ValueType] < $NewValue[$ValueType]) $NewValue[$ValueType] = $Values[$I + 1][$ValueType];
-            } else {
-              $Difference = $Values[$I + 1][$ValueType] - $Values[$I][$ValueType];
-              if($Difference < $NewValue[$ValueType]) $NewValue[$ValueType] = $Difference;
-            }
-          }
-        }
-      }
-      $NewValue[$ValueType] = $NewValue[$ValueType];
-    }
-    //if(($RightTime - $LeftTime) > 0)
-    if($this->Data['Cumulative'] == 0)
-    {
-      $NewValue['avg'] = $NewValue['avg'] / ($RightTime - $LeftTime);
-    }
-    return($NewValue);
-  }
-
-  function GetTimeRange($Level)
-  {
-    // Get first and last time
-    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
-      '(`level`='.$Level.') ORDER BY `time` LIMIT 1');
-    if($Result->num_rows > 0)
-    {
-      $Row = $Result->fetch_array();
-      $AbsoluteLeftTime = MysqlDateTimeToTime($Row['time']);
-    } else $AbsoluteLeftTime = 0;
-
-    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
-      '(`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
-    if($Result->num_rows > 0)
-    {
-      $Row = $Result->fetch_array();
-      $AbsoluteRightTime = MysqlDateTimeToTime($Row['time']);
-    } else $AbsoluteRightTime = 0;
-
-    return(array('left' => $AbsoluteLeftTime, 'right' => $AbsoluteRightTime));
-  }
-
-  function LoadRightSideValue($Level, $Time)
-  {
-    $Result = array();
-    $DbResult = $this->Database->select($this->Data['DataTable'], '*', '(time > "'.TimeToMysqlDateTime($Time).'") AND (measure='.$this->Data['Id'].') AND (level='.$Level.') ORDER BY time ASC LIMIT 1');
-    if($DbResult->num_rows > 0)
-    {
-      $Row = $DbResult->fetch_array();
-      $Row['time'] = MysqlDateTimeToTime($Row['time']);
-      return(array($Row));
-    }
-    else
-    {
-      //$Time = $Values[count($Values)-1]['time'] + 60;
-      //array_push($Values, array('time' => $Time, 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
-      $Result[] = array('time' => ($Time + $this->TimeSegment($Level)), 'min' => 0,
-        'avg' => 0, 'max' => 0, 'continuity' => 0);
-      $DbResult = $this->Database->select($this->Data['DataTable'], '*',
-        '(`time` < "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
-        'AND (`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
-      if($DbResult->num_rows > 0)
-      {
-        $Row = $DbResult->fetch_array();
-        array_unshift($Result, array('time' => (MysqlDateTimeToTime($Row['time']) + 10),
-          'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
-      }
-      return($Result);
-    }
-  }
-
-  function LoadLeftSideValue($Level, $Time)
-  {
-    $Result = array();
-    $DbResult = $this->Database->select($this->Data['DataTable'], '*',
-      '(`time` < "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
-      'AND (`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
-    if($DbResult->num_rows > 0)
-    {
-      $Row = $DbResult->fetch_array();
-      $Row['time'] = MysqlDateTimeToTime($Row['time']);
-      return(array($Row));
-    } else {
-      //$Time = $Values[0]['time'] - 60;
-      //array_unshift($Values, array('time' => $Time, 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
-      $Result[] = array('time' => ($Time - $this->TimeSegment($Level)), 'min' => 0,
-        'avg' => 0, 'max' => 0, 'continuity' => 0);
-
-      $DbResult = $this->Database->select($this->Data['DataTable'], '*',
-        '(`time` > "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
-        'AND (`level`='.$Level.') ORDER BY `time` ASC LIMIT 1');
-      if($DbResult->num_rows > 0)
-      {
-        $Row = $DbResult->fetch_array();
-        array_push($Result, array('time' => (MysqlDateTimeToTime($Row['time']) - 10),
-          'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
-      }
-      return($Result);
-    }
-  }
-
-  function GetValues($TimeFrom, $TimeTo, $Level)
-  {
-  //$AbsoluteTime = GetTimeRange($this->DataId);
-
-//  if(($TimeFrom > $AbsoluteLeftTime) and ($TimeStart < $AbsoluteRightTime) and
-//    ($TimeTo > $AbsoluteLeftTime) and ($TimeTo < $AbsoluteRightTime))
-//  {
-
-    // Load values in time range
-    $Result = $this->Database->select($this->Data['DataTable'], '`time`, `min`, `avg`, `max`, `continuity`',
-      '(`time` > "'.TimeToMysqlDateTime($TimeFrom).'") AND '.
-      '(`time` < "'.TimeToMysqlDateTime($TimeTo).'") AND '.
-      '(`measure`='.$this->Data['Id'].') AND (`level`='.$Level.') ORDER BY `time`');
-    $Values = array();
-    while($Row = $Result->fetch_array())
-    {
-      $Values[] = array('time' => MysqlDateTimeToTime($Row['time']), 'min' => $Row['min'], 'avg' => $Row['avg'], 'max' => $Row['max'], 'continuity' => $Row['continuity']);
-    }
-   // array_pop($Values);
-
-    $Points = array();
-    if(count($Values) > 0)
-    {
-      $Values = array_merge(
-        $this->LoadLeftSideValue($Level, $TimeFrom),
-        $Values,
-        $this->LoadRightSideValue($Level, $TimeTo));
-
-      $StartIndex = 0;
-      $Points = array();
-      for($I = 0; $I < $this->DivisionCount; $I++)
-      {
-        $TimeStart = $TimeFrom + (($TimeTo - $TimeFrom) / $this->DivisionCount) * $I;
-        $TimeEnd = $TimeFrom + (($TimeTo - $TimeFrom) / $this->DivisionCount) * ($I+1);
-
-        $EndIndex = $StartIndex;
-        while($Values[$EndIndex]['time'] < $TimeEnd) $EndIndex = $EndIndex + 1;
-        $SubValues = array_slice($Values, $StartIndex, $EndIndex - $StartIndex + 1);
-        $Points[] = $this->ComputeOneValue($TimeStart, $TimeEnd, $SubValues, $Level);
-        $StartIndex = $EndIndex - 1;
-      }
-    } else $Points[] = array('min' => 0, 'avg' => 0, 'max' => 0);
-    return($Points);
-  }
-
-  function RebuildMeasureCache()
-  {
-    echo('Velicina '.$this->Data['Name']."<br>\n");
-    if($this->Data['Continuity'] == 0) $this->Data['ContinuityEnabled'] = 0;  // non continuous
-      else $this->Data['ContinuityEnabled'] = 2;    // continuous graph
-
-    // Clear previous items
-    $DbResult = $this->Database->select($this->Data['DataTable'], 'COUNT(*)', '(`level`>0) AND (`measure`='.$this->Data['Id'].')');
-    $Row = $DbResult->fetch_array();
-    echo("Mazu starou cache (".$Row[0]." polozek)...");
-    $this->Database->delete($this->Data['DataTable'], '(`level`>0) AND (`measure`='.$this->Data['Id'].')');
-    echo("<br>\n");
-
-    for($Level = 1; $Level <= $this->MaxLevel; $Level++)
-    {
-      echo('Uroven '.$Level."<br>\n");
-      $TimeRange = $this->GetTimeRange($Level - 1);
-      $TimeSegment = $this->TimeSegment($Level);
-      $StartTime = $this->AlignTime($TimeRange['left'], $TimeSegment) - $TimeSegment;
-      $EndTime = $this->AlignTime($TimeRange['right'], $TimeSegment);
-      $BurstCount = 500;
-      echo('For 0 to '.round(($EndTime - $StartTime) / $TimeSegment / $BurstCount)."<br>\n");
-      for($I = 0; $I <= round(($EndTime - $StartTime) / $TimeSegment / $BurstCount); $I++)
-      {
-        echo($I.' ');
-        $StartTime2 = $StartTime + $I * $BurstCount * $TimeSegment;
-        $EndTime2 = $StartTime + ($I + 1) * $BurstCount * $TimeSegment;
-        $Values = array();
-        $DbResult = $this->Database->select($this->Data['DataTable'], '*', '(`time` > "'.TimeToMysqlDateTime($StartTime2).'") AND (`time` < "'.
-          TimeToMysqlDateTime($EndTime2).'") AND (`measure`='.$this->Data['Id'].') AND (`level`='.($Level - 1).') ORDER BY `time`');
-        while($Row = $DbResult->fetch_array())
-        {
-          $Row['time'] = MysqlDateTimeToTime($Row['time']);
-          $Values[] = $Row;
-        }
-
-        if(count($Values) > 0)
-        {
-          $Values = array_merge(
-            $this->LoadLeftSideValue($Level - 1, $StartTime2),
-            $Values,
-            $this->LoadRightSideValue($Level - 1, $EndTime2));
-
-          $StartIndex = 0;
-          for($B = 0; $B < $BurstCount; $B++)
-          {
-            echo('.');
-            $StartTime3 = $StartTime2 + (($EndTime2 - $StartTime2) / $BurstCount) * $B;
-            $EndTime3 = $StartTime2 + (($EndTime2 - $StartTime2) / $BurstCount) * ($B + 1);
-
-            $EndIndex = $StartIndex;
-            while($Values[$EndIndex]['time'] < $EndTime3) $EndIndex = $EndIndex + 1;
-            $SubValues = array_slice($Values, $StartIndex, $EndIndex - $StartIndex + 1);
-            if(count($SubValues) > 2)
-            {
-              $Point = $this->ComputeOneValue($StartTime3, $EndTime3, $SubValues, $Level);
-              $Continuity = $SubValues[1]['continuity'];
-              $this->Database->insert($this->Data['DataTable'], array('level' => $Level, 'measure' => $this->Data['Id'],
-                'min' => $Point['min'], 'avg' => $Point['avg'], 'max' => $Point['max'],
-                'continuity' => $Continuity, 'time' => TimeToMysqlDateTime($StartTime3 + ($EndTime3 - $StartTime3) / 2)));
-            }
-            $StartIndex = $EndIndex - 1;
-          }
-        }
-        // Load values in time range
-        //array_pop($NextValues);
-      }
-      echo("Uroven dokoncena<br>\n");
-      $DbResult = $this->Database->select($this->Data['DataTable'], 'COUNT(*)',
-        '(`level`='.$Level.') AND (`measure`='.$this->Data['Id'].')');
-      $Row = $DbResult->fetch_array();
-      echo("Vlozeno ".$Row[0]." polozek.<br>\n");
-    }
-  }
-
-  function RebuildAllMeasuresCache()
-  {
-    $Result = $this->Database->select('measure', 'Id');
-    while($Row = $Result->fetch_array())
-    {
-      $Measure = new Measure();
-      $Measure->Load($Row['Id']);
-      $Measure->RebuildMeasureCache();
-      echo('Velicina id '.$Row['Id'].' dokoncena<br/>');
-    }
-  }
-
-  function InitMeasureDataTable()
-  {
-    $this->Database->query('CREATE TABLE `data_'.$this->Data['Name'].'` (
-      `Time` TIMESTAMP NOT NULL ,
-      `Avg` '.$this->Data['DataType'].' NOT NULL ,
-      `Continuity` BOOL NOT NULL
-      ) ENGINE = MYISAM ;');
-
-    $this->Database->query('CREATE TABLE `data_'.$this->Data['Name'].'_cache` (
-`Time` TIMESTAMP NOT NULL ,
-`Level` TINYINT NOT NULL ,
-`Min` '.$this->Data['DataType'].' NOT NULL ,
-`Avg` '.$this->Data['DataType'].' NOT NULL ,
-`Max` '.$this->Data['DataType'].' NOT NULL ,
-`Continuity` BOOL NOT NULL
-) ENGINE = MYISAM ;');
-  }
-}
Index: unk/types.php
===================================================================
--- /trunk/types.php	(revision 62)
+++ 	(revision )
@@ -1,13 +1,0 @@
-<?php
-
-$Types = array(
-  'Boolean' => array(
-  
-  ),
-  'String' => array(
-  
-  ),
-  'Integer' => array(
-  
-  ),
-);
