<? // Skript pro generování grafu stromové struktury sítě do PNG obrázku
include('../db.php');
DB_Init('localhost','root','','is');


if(array_key_exists('debug', $_GET)) $debug = $_GET['debug'];
else $debug = 0;
$TopHostName = 'NIX-ROUTER';

// === Zpětné vyvážení stromu do hloubky =======================================
function balance($id, $level, &$vlast, &$vleft, &$vpred, &$vfirst, &$vnext, &$tbound, &$width, $limit) {
  global $debug, $bbound;
  if ((@$vlast[$id]>0)&&(@$vleft[$id]>@$vleft[$vlast[$id]])) { // ||($vleft[$vfirst[$id]]<$limit))
    $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];
    }
//    if (($vleft[$i]+$diff)<=$vleft[$vpred[$i]]) {
//      $diff=$vleft[$i]-$vleft[$vpred[$i]]+2;
//      echo $vleft[$i]+$diff.','.$vleft[$vpred[$i]."\N";
//    }
  } else {
    $diff=0;
    $i=0;
  }
    while ($i>0) {
      $vleft[$i]+=$diff;
    	$limit = balance($i,$level+1, $vlast,$vleft,$vpred, $vfirst,$vnext,$tbound, $width, $limit) + 2;
    	$i=@$vnext[$i];
    }
  return @$vleft[@$vlast[@$id]]+2;
}

// === Generování rovinné stromové struktury ===================================
function gentree($mode) {                        // depth-first algorithm
global $debug, $TopHostName;
  // --- 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
  
  // --- Hlavní cyklus ---------------------------------------------------------
  do {
  // --- Proveď databázový dotaz -----------------------------------------------
    $query = 'SELECT * FROM hosts WHERE ';
    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';
    DB_Query($query);
    $item = DB_Row();
    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;
      $vleft[$curr] = @$tbound[$level];
      $vpred[$curr] = @$tranger[$level];
      $tranger[$level] = $curr;
      $position[$level]++;
      $count[$level]++;
  // --- Zjisti existenci potomků ----------------------------------------------
      DB_Query("SELECT COUNT(*) FROM hosts WHERE parent = ".$curr);
      $childcnt = DB_Row();
      if ($childcnt[0]>0) {                      // Uzelový vrchol
        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 (@$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--;
      $curr=@$vlast[$parent[$level]];
      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++) $vleft[$i]=.2+(@$vleft[$i]+($datawidth-@$data['vleft'][$i]))/2;

$spacex=32;
$spacey=68;
$halfx=$spacex/2;
$halfy=$spacey/2;
// === Načtení pomocných obrázků ===============================================
$im_comp = @imagecreatefrompng('images/comp.png');
$im_dev = @imagecreatefrompng('images/device.png');
// === Generování obrázku ======================================================
$im = @imagecreate(($width+1.6)*$spacex, ($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;
}

DB_Query("SELECT * FROM hosts");
while ($item = DB_Row()) {
  $id = $item['id'];
  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 (@$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);
    }
    $ip=explode('.',$item['IP']);
    if (@$ip[3]<100) { $image=$im_comp; } else $image=$im_dev;  
    if(($ip[0] != 192) and ($ip[0] != 168)) { 
      $image = $im_dev;   
    }
    if($item['IP'] == '') { 
      $color = $gray;
      $image = $im_dev;
    } else {
      if ($ip[3]<100) {
        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);
    imagestring($im,2,xpos($id)+($spacex-strlen($item['name'])*imagefontwidth(2))/2,$vtop[$id]*$spacey+31+imagefontheight(2),$item['name'],$color);
  }    
}

// === Sestavení výsledného souboru ============================================
if(!$debug)
{
  header("Content-type: image/png");
  header("Cache-Control: no-cache");	// Dynamický graf, nekešovat
  imagepng($im);
  imagedestroy($im);
  imagedestroy($im_comp);
  imagedestroy($im_dev);
}
?>
