<?php

use codeagent\treemap\Treemap;
use codeagent\treemap\presenter\ImagePresenter;
use codeagent\treemap\presenter\NodeInfo;
use codeagent\treemap\Gradient;

// ---
// --- Local fonctions
// ---
function rgb2hex($rgb) {
   $hex = "#";
   $hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT);
   $hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT);
   $hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT);

   return $hex; // returns the hex value including the number sign (#)
}

function hex2rgb($color){
    $color = str_replace('#', '', $color);
    if (strlen($color) != 6){ return array(0,0,0); }
    $rgb = array();
    for ($x=0;$x<3;$x++){
        $rgb[$x] = hexdec(substr($color,(2*$x),2));
    }
    return $rgb;
}

function tri($a, $b) {
    if ($a['value'] == $b['value']) return 0;
    return ($a['value'] < $b['value']) ? 1 : -1;
}

class topisto_treemap
{
  private static function getRGB($methode, $gradient, $factor)
  {
    switch($methode)
    {
      case 0:
        $rgb = [rand(0,255),rand(0,255),rand(0,255)];
        break;

      case 1:
        $rgb = [80,80,80];
        break;

      case 2:
        $factor=rand(0,100);
        $rgb = [255,255,255];
        if ($factor < 50 ) $rgb = [255,0,0];
        if ($factor < 25 ) $rgb = [0,0,255];
        if ($factor < 10 ) $rgb = [255,255,0];
        break;

      case 3:
        $rgb  = hex2rgb($gradient[1]->color($factor));
        break;

      case 4:
        $rgb  = hex2rgb($gradient[2]->color($factor));
        break;

      case 999:
        $rgb  = hex2rgb($gradient[3]->color($factor));
        break;

      default:  
        $rgb  = hex2rgb($gradient[0]->color($factor));
    }

    return $rgb;
  }

  public static function DrawBlock($the_block, $vImage, $x, $y, $width, $height, $methode, $type=1)
  {
    $full_area = $width * $height;
    if ($full_area == 0) $full_area = 1;

    $data = blockchain::getTransactionData($the_block, $type);

    usort($data, 'tri');

    $n=0;
    $i=count($data)-1;
    while($i>41) $n+=$data[$i--]['value'];
    $n=intval(round(($n * 1.0) / count($data)));

    $data = array_slice($data, 0, 42);
    $data[] = ["hash" => "0000000000000000000000000000000000000000000000000000000000000000", "value" => $n];

    usort($data, 'tri');


    $vBgColor = imagecolorallocate($vImage, 10, 10, 10);
    imagefilledrectangle($vImage, $x, $y, $x+$width, $y+$height, $vBgColor);

    // quelques gradient de couleurs ...
    $rgb1 = [rand(0,255),rand(0,255),rand(0,255)];
    $rgb2 = [rand(0,255),rand(0,255),rand(0,255)];

    $gradient   = [];
    $gradient[] = new Gradient(['0.0' => '#f75557', '0.5' => '#646a82', '1.0' => '#5ad87b']);
    $gradient[] = new Gradient(['0.0' => '#FF69B4', '1.0' => '#FF5555']);
    $gradient[] = new Gradient(['0.0' => rgb2hex($rgb1), '1.0' => rgb2hex($rgb2)]);
    $gradient[] = new Gradient(['0.0' => '#FFFFFF', '1.0' => '#000000']);

    if ($type == 4)
    {
      // Cas particulier pour la récompense
      $reward = 0;
      foreach($data as $v) $reward += $v['value'];
      $pct = $reward / 5000000000.0;
      $w  = round($width * $pct);
      $h  = round($height * $pct);
      $x1 = $x + (($width/2) - ($w /2));
      $y1 = $y + (($height/2) - ($h /2));
      $rgb = self::getRGB($methode, $gradient, $pct*100);
      $vFgColor = imagecolorallocate($vImage, $rgb[0], $rgb[1], $rgb[2]);
      $rgb = self::getRGB(999, $gradient, $pct*100);
      $vBgColor = imagecolorallocate($vImage, $rgb[0], $rgb[1], $rgb[2]);
      if (($h < 2)&&($w< 2))
      {
        imagesetpixel($vImage, $x1, $y1, $vFgColor);
      } else {
       $x2 = $x1 + $w;
       $y2 = $y1 + $h;
       imagefilledrectangle($vImage, $x1, $y1, $x2, $y2, $vFgColor);
       imagerectangle($vImage, $x1, $y1, $x2, $y2, $vBgColor);
      }
    } else {
      $treemap = new Treemap($data, $width, $height);
      $map = $treemap->getMap();
      $m = count($map);
      $flag_contour = true;
      for($mm = 0; $mm < $m; $mm++)
      {
        $tx     = $map[$mm];
        $factor = (($tx['_rectangle']->width * $tx['_rectangle']->height) / $full_area)*100.0;

        $x1 = $x + $tx['_rectangle']->left;
        $y1 = $y + $tx['_rectangle']->top;

        // if (($x1 == ($x+$width))||($x1 == ($y+$height))) break;
      
        $rgb = self::getRGB($methode, $gradient, $factor);
        // Pas de noir absolu
        if (($rgb[0]+$rgb[1]+$rgb[2]) == 0)
          $vFgColor = imagecolorallocate($vImage, 10, 10, 10);
        else
          $vFgColor = imagecolorallocate($vImage, $rgb[0], $rgb[1], $rgb[2]);

        $rgb = self::getRGB(999, $gradient, $factor);
        $vBgColor = imagecolorallocate($vImage, $rgb[0], $rgb[1], $rgb[2]);

        $x2 = $x1 + $tx['_rectangle']->width;
        $y2 = $y1 + $tx['_rectangle']->height;

        if ($x1 > ($x+$width))  $x1 = ($x+$width);
        if ($y1 > ($y+$height)) $y1 = ($y+$height);
        if ($x2 > ($x+$width))  $x2 = ($x+$width);
        if ($y2 > ($y+$height)) $y2 = ($y+$height);

        imagefilledrectangle($vImage, $x1, $y1, $x2, $y2, $vFgColor);
        if ((($x2-$x1) > 2)||(($y2-$y1) > 2)) 
          imagerectangle($vImage, $x1, $y1, $x2, $y2, $vBgColor);
      
      }
    }
  }
}

?>
