<?php
 // Skript pro generování grafu stromové struktury sítě do PNG obrázku
include('../Common/Global.php');

if(array_key_exists('debug', $_GET)) $debug = $_GET['debug'];
else $debug = 0;
$TopHostName = 'nix-router';
// $debug = 0;

// === Zpětné vyvážení stromu do hloubky =======================================
function balance($id, $level, &$vlast, &$vleft, &$vpred, &$vfirst, &$vnext, &$tbound, &$width, $limit) 
{
  global $debug, $bbound;
  
  if(!array_key_exists($id, $vfirst)) $vfirst[$id] = 0;
  if($i = $vfirst[$id]) 
  {
    //if ($debug==2) echo $id.':'.@$i.','.@$vpred[$i].'-'.@$vleft[@$vpred[$i]]."\n";
    if (($vlast[$id] > 0) && ($vleft[$id] > $vleft[$vlast[$id]])) 
    {
      $diff=$vleft[$id]-$vleft[$vlast[$id]];
      $i=$vfirst[$id];
      if ($vleft[$id] >= $tbound[$level]) 
      {
        $tbound[$level] = $vleft[$id] + 2;
        if ($vleft[$id] > $width) $width = $vleft[$id];
      }
    } else {
      $diff=0;
      if ($vpred[$i]&&($vleft[$i]<=$vleft[$vpred[$i]])) 
      {
        $diff=$vleft[$i]-$vleft[$vpred[$i]]+2;
      } else $i = 0;
    }
    while ($i>0) 
    {
      $vleft[$i]+=$diff;
      $limit = balance($i,$level+1, $vlast,$vleft,$vpred, $vfirst,$vnext,$tbound, $width, $limit) + 2;
      if(!array_key_exists($i, $vnext)) $vnext[$i] = 0;
      $i = $vnext[$i];
    }
  }
}

// === Generování rovinné stromové struktury ===================================
function gentree($mode)                         // depth-first algorithm
{                        
  global $debug, $TopHostName, $Database;
  
  // --- Inicializace ----------------------------------------------------------
  $tbound = array();                               // Hranice pozic jednotlivých úrovní
  $tranger = array();                              // Hranicni prvek
  $position = array();                             // Pozice aktuálního prvku na dané úrovni
  $vfirst = array();                               // První potomek prvku
  $vlast = array();                                // Poslední potomek prvku
  $vnext = array();                                // Následující sourozenec
  $vleft = array();                                // Pozice prvku zleva
  $vtop = array();                                 // Pozice prvku shora
  $vpred = array();                                // Vedlejsi prvek na řádku
  
  $index = 0;                                    // Index aktuálního prvku
  $curr = 0;                                     // Aktuální prvek
  $level = 0;                                    // Aktuální úroveň hloubky ve stromu
  $width = 0;                                    // Šířka stromu
  $height = 0;                                   // Hloubka stromu

  $parent[$level] = 0;                             // Rodič dané úrovně
  $position[$level] = 0;                           // Aktuální pozice prvku na dané úrovni
  $count[$level] = 0;                              // Počet prvků na dané úrovni
  
  $maxindex = 0;
  $tbound[$level] = 0;
  $tranger[$level] = 0;
   
  // --- Hlavní cyklus ---------------------------------------------------------
  do 
  {
  // --- Proveď databázový dotaz -----------------------------------------------
    $query = 'SELECT * FROM hosts WHERE used=1 AND ';
    if ($level == 0) 
    { 
      $query .= 'name = "'.$TopHostName.'" ORDER BY id'; 
    } else 
    {
      $query .= ' parent = '.$parent[$level].' ORDER BY id';
    }
    if ($mode) $query.=' DESC';
    $query .= ' LIMIT '.$position[$level].',1';
    //echo($query.'<br>');
    $DbResult = $Database->query($query);
    $item = $DbResult->fetch_array();
    //print_r($item);
    if($item) 
    {
  // --- Zpracování položky z DB -----------------------------------------------
      if($position[$level] > 0) 
      {
        $vnext[$curr] = $item['id']; // Neprvní položka, nastav předchozí
      }
      $curr = $item['id'];
      if ($curr > $maxindex) $maxindex = $curr;
      if ($position[$level] == 0) $vfirst[$parent[$level]]=$curr; // První položka, nastav první
      $vlast[$parent[$level]] = $curr;
      $vtop[$curr] = $level;
      if(!array_key_exists($level, $tbound)) $tbound[$level] = 0;
      $vleft[$curr] = $tbound[$level];
      if(!array_key_exists($level, $tranger)) $tranger[$level] = 0;
      $vpred[$curr] = $tranger[$level];
      $tranger[$level] = $curr;
      if (($debug == 3) && ($level == 8)) echo $curr.',';
      $position[$level]++;
      $count[$level]++;
  // --- Zjisti existenci potomků ----------------------------------------------
      $DbResult = $Database->query('SELECT COUNT(*) FROM hosts WHERE used=1 AND parent = '.$curr);
      $childcnt = $DbResult->fetch_array();
      if ($childcnt[0] > 0) 
      {    
        // Uzelový vrchol
        if(array_key_exists($level + 1, $tbound))                  
          if($tbound[$level + 1] > $vleft[$curr]) $vleft[$curr] = $tbound[$level + 1];
      }
      $tbound[$level] = $vleft[$curr] + 2;
      if ($vleft[$curr] > $width) $width = $vleft[$curr];
      if ($childcnt[0] > 0) 
      {
        $level++;
        if ($level > $height) $height = $level;
        $parent[$level] = $curr;
        $position[$level] = 0;
        $count[$level] = 0;
      } else $index++;                            // Listový vrchol
    } else 
    {
  // --- Zarovnávání prvků kvůli vzhledu
      if(!array_key_exists($vfirst[$parent[$level]], $vleft)) $vleft[$vfirst[$parent[$level]]] = 0;
      if(!array_key_exists($parent[$level], $vleft)) $vleft[$parent[$level]] = 0;
      if ($vleft[$vfirst[$parent[$level]]] > $vleft[$parent[$level]]) 
      {
        $vleft[$parent[$level]] = $vleft[$vfirst[$parent[$level]]];
        if ($vleft[$parent[$level]]+2>$tbound[$level-1]) $tbound[$level-1] = $vleft[$parent[$level]]+2;
      }
      balance($parent[$level],$level, $vlast,$vleft,$vpred,$vfirst,$vnext,$tbound, $width, 0);
      if ($position[$level]==1) 
      {
        $vleft[$vfirst[$parent[$level]]] = $vleft[$parent[$level]];
      }
      $level--;
      if(!array_key_exists($level, $parent)) $parent[$level] = 0;
      if(!array_key_exists($parent[$level], $vlast)) $vlast[$parent[$level]] = 0;
      $curr = $vlast[$parent[$level]];
      
      if(!array_key_exists($level, $tbound)) $tbound[$level] = 0;
      if(!array_key_exists($level + 1, $tbound)) $tbound[$level + 1] = 0;
      if($tbound[$level] > $tbound[$level + 1]) $tbound[$level + 1] = $tbound[$level];
    }
  } while($level >= 0);
  $data = compact('tbound', 'count', 'tbound', 'vfirst', 'vlast', 'vtop', 'vleft', 'height', 'width', 'index', 'maxindex');
  return($data);
};

// === Vytvoř stromy a spoj je =================================================
extract(gentree(0));
// exit();
$data = gentree(1);
$datawidth = $data['width'];
for($i = 0; $i <= $maxindex; $i++)
{ 
  if(!array_key_exists($i, $vleft)) $vleft[$i] = 0;
  if(!array_key_exists($i, $data['vleft'])) $data['vleft'][$i] = 0;
  $vleft[$i] = .2 + ($vleft[$i] + ($datawidth - $data['vleft'][$i])) / 2;
}

$spacex = 32;
$spacey = 68;
$halfx = $spacex / 2;
$halfy = $spacey / 2;

// Preload icon images
$IconList = array();
$DbResult = $Database->query('SELECT * FROM HostType');
while($HostType = $DbResult->fetch_assoc()) 
  $IconList[$HostType['Id']] = imagecreatefrompng('images/'.$HostType['IconName'].'.png');

// === Generování obrázku ======================================================
$im = imagecreate(($datawidth + $width + 3.2) * $halfx, ($height + 1) * $spacey);
$background_color = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
$red = imagecolorallocate($im, 255, 0, 0);
$green = imagecolorallocate($im, 0, 128, 0);
$blue = imagecolorallocate($im, 100, 100, 255);
$gray = imagecolorallocate($im, 160, 160, 160);

function xpos($id) 
{
  global $vleft, $spacex;
  return($vleft[$id] * $spacex);
}

$DbResult = $Database->query('SELECT * FROM hosts JOIN HostType ON HostType.Id = hosts.type WHERE hosts.used=1');
while($item = $DbResult->fetch_array()) 
{
  $id = $item['id'];
  if(!array_key_exists($id, $vtop)) $vtop[$id] = 0;
  if(($vtop[$id] > 0) || ($item['name'] == $TopHostName)) 
  {
    if($vtop[$id] > 0) imageline($im, xpos($id) + $halfx, $vtop[$id] * $spacey, xpos($id) + $halfx, $vtop[$id] * $spacey + 8, $black);
    if(!array_key_exists($id, $vfirst)) $vfirst[$id] = 0;
    if($vfirst[$id] > 0) 
    {
      imageline($im, xpos($vfirst[$id]) + $halfx, $vtop[$id] * $spacey + $spacey, xpos($vlast[$id]) + $halfx, $vtop[$id] * $spacey + $spacey, $black);
      imageline($im, xpos($id) + $halfx, ($vtop[$id] + 1) * $spacey - 10, xpos($id) + $halfx, ($vtop[$id] + 1) * $spacey, $black);
    }
    
    $image = $IconList[$item['type']];
    if($item['IP'] == '')
    {
      $color = $gray;
    } else
    if($item['ShowOnline'] == 1)
    {
      if($item['online'] == 1) $color = $green; else $color = $black;
    } else
    {
      if($item['online'] == 1) $color = $green; else $color = $red;
    }
//      $text='IP: '.$ip[0];
//      imagestring($im,2,xpos($id)+($spacex-strlen($text)*imagefontwidth(2))/2,$vtop[$id]*$spacey+24+imagefontheight(2),$text,$black);
    imagecopy($im, $image, xpos($id) + $halfx - 15, $vtop[$id] * $spacey + 12, 0, 0, 30, 30);
//    imagerectangle($im,xpos($id)+$halfx-6,$vtop[$id]*$spacey+16,xpos($id)+$halfx+6,$vtop[$id]*$spacey+28,$color);
    if($debug) 
    {
      imagestring($im, 2, xpos($id) + ($spacex - strlen($item['id']) * imagefontwidth(2)) / 2, $vtop[$id] * $spacey + 31 + imagefontheight(2), $item['id'], $color);
    } else 
      imagestring($im, 2, xpos($id) + ($spacex - strlen($item['name']) * imagefontwidth(2)) / 2, $vtop[$id] * $spacey + 31 + imagefontheight(2), strtoupper($item['name']), $color);
  }
}

// === Sestavení výsledného souboru ============================================
if(!($debug > 1))
{
  header('Content-type: image/png');
  header('Cache-Control: no-cache');
  imagepng($im);
  imagedestroy($im);
}

?>
