<?php

class ColorHelper
{
  const MAX_RGB_DISTANCE = 441.67295593006372;
  
  /**
   * puts r b g components to array
   * @param byte $r
   * @param byte $g
   * @param byte $b
   * @return array(r,g,b)
   */
  public static function rgb($r,$g,$b)
  {
    return array('r'=>$r,'g'=>$g,'b'=>$b);
  }

  /**
   *
   * @param array(r,g,b) $rgb1
   * @param array(r,g,b) $rgb2
   * @return float
   */
  public static function rgbDistance($rgb1,$rgb2)
  {
    $r1 = $rgb1['r'];
    $g1 = $rgb1['g'];
    $b1 = $rgb1['b'];
    $r2 = $rgb2['r'];
    $g2 = $rgb2['g'];
    $b2 = $rgb2['b'];

    $rdiff = pow($r2 - $r1,2);
    $gdiff = pow($g2 - $g1,2);
    $bdiff = pow($b2 - $b1,2);

    $diff = $rdiff + $bdiff + $gdiff;

    $distance = sqrt($diff);

    return $distance;
  }

  /**
   *
   * @param long $colorComponent
   * @return array(r,g,b)
   */
  static public function kriaColorToRGB($colorComponent)
  {
    $hls = self::kriaColorToHLS($colorComponent);
    $rgb = ColorHelper::HSLToRGBArray($hls['h'], $hls['s'], $hls['l']);
    return $rgb;
  }

  /**
   *
   * @param long $colorComponent
   * @return array(h,l,s,w)
   */
  static public function kriaColorToHLS($colorComponent)
  {
    $colorVal = $colorComponent + 0;

    $h = ($colorVal & 0xFF000000) >> 24;
    $l = ($colorVal & 0xFF0000  ) >> 16;
    $s = ($colorVal & 0xFF00    ) >> 8;
    $w = ($colorVal & 0xFF      );

    return array(
        'h'=>$h,
        'l'=>$l,
        's'=>$s,
        'w'=>$w,
    );
  }

  /**
   * @param long $colorComponent
   * @return array(code,weight)
   */
  static public function formatHTML($colorComponent)
  {
    $hls = self::kriaColorToHLS($colorComponent);
    $rgb = ColorHelper::HSLToRGB($hls['h'], $hls['s'], $hls['l']);
    $htmlCol['code'] = ColorHelper::RGBToHTML($rgb);
    $htmlCol['weight'] = $hls['w'];

    return $htmlCol;
  }

  /**
   *
   * @param string $vehicleColor
   * @return string[]
   */
  static public function MainVehicleColor($vehicleColor)
  {
    $colorArrayFalse = array();

    if($vehicleColor == '')
      return $colorArrayFalse;

    $theColors = explode(";",$vehicleColor);

    if(count($theColors) <= 0)
      return $colorArrayFalse;

    $wMax = -1;
    $hMax = 0;
    $sMax = 0;
    $lMax = 0;

    $ind = 0;

    foreach ($theColors as $Col)
    {
      $colorVal = intval($Col);

      $h = ($colorVal & 0xFF000000) >> 24;
      $l = ($colorVal & 0xFF0000  ) >> 16;
      $s = ($colorVal & 0xFF00    ) >> 8;
      $w = ($colorVal & 0xFF      );

      $rgb = ColorHelper::HSLToRGB($h, $s, $l);
      $htmlCol = ColorHelper::RGBToHTML($rgb);

      $colorArray[$ind] = $htmlCol;
      $colorArrayW[$ind] = $w;

      $ind++;
    }


    array_multisort($colorArrayW, SORT_DESC, $colorArray);

    return $colorArray;
  }

  /**
   *
   * @param array(r,g,b) $rgbArray
   * @return int rgb
   */
  static public function RGBArrayToRGBValue($rgbArray)
  {
    return $rgbArray['b'] + ($rgbArray['g'] << 0x8) + ($rgbArray['r'] << 0x10);
  }
  /**
   *
   * @param float $h
   * @param float $s
   * @param float $l
   * @return int rgb
   */
  static public function HSLToRGB($h, $s, $l)
  {
    $rgbArray = self::HSLToRGBArray($h, $s, $l);
    $RGB = self::RGBArrayToRGBValue($rgbArray);
    return $RGB;
  }
  /**
   *
   * @param float $h
   * @param float $s
   * @param float $l
   * @return array(r,g,b)
   */
  static public function HSLToRGBArray($h, $s, $l)
  {
    $h = ((float)$h) / 255.0;
    $s = ((float)$s) / 255.0;
    $l = ((float)$l) / 255.0;

    if($s == 0)
    {
      $r = $l;
      $g = $l;
      $b = $l;
    }
    else
    {
      if($l < .5)
      {
        $t2 = $l * (1.0 + $s);
      }
      else
      {
        $t2 = ($l + $s) - ($l * $s);
      }
      $t1 = 2.0 * $l - $t2;

      $rt3 = $h + 1.0/3.0;
      $gt3 = $h;
      $bt3 = $h - 1.0/3.0;

      if($rt3 < 0) $rt3 += 1.0;
      if($rt3 > 1) $rt3 -= 1.0;
      if($gt3 < 0) $gt3 += 1.0;
      if($gt3 > 1) $gt3 -= 1.0;
      if($bt3 < 0) $bt3 += 1.0;
      if($bt3 > 1) $bt3 -= 1.0;

      if(6.0 * $rt3 < 1) $r = $t1 + ($t2 - $t1) * 6.0 * $rt3;
      elseif(2.0 * $rt3 < 1) $r = $t2;
      elseif(3.0 * $rt3 < 2) $r = $t1 + ($t2 - $t1) * ((2.0/3.0) - $rt3) * 6.0;
      else $r = $t1;

      if(6.0 * $gt3 < 1) $g = $t1 + ($t2 - $t1) * 6.0 * $gt3;
      elseif(2.0 * $gt3 < 1) $g = $t2;
      elseif(3.0 * $gt3 < 2) $g = $t1 + ($t2 - $t1) * ((2.0/3.0) - $gt3) * 6.0;
      else $g = $t1;

      if(6.0 * $bt3 < 1) $b = $t1 + ($t2 - $t1) * 6.0 * $bt3;
      elseif(2.0 * $bt3 < 1) $b = $t2;
      elseif(3.0 * $bt3 < 2) $b = $t1 + ($t2 - $t1) * ((2.0/3.0) - $bt3) * 6.0;
      else $b = $t1;
    }

    $r = (int)round(255.0 * $r);
    $g = (int)round(255.0 * $g);
    $b = (int)round(255.0 * $b);

    return self::rgb($r, $g, $b);
  }

  /**
   * @param int $RGB
   * @return string #XXYYZZ
   */
  static function RGBToHTML($RGB)
  {
    $r = 0xFF & ($RGB >> 0x10);
    $g = 0xFF & ($RGB >> 0x8);
    $b = 0xFF & $RGB;

    $r = dechex($r);
    $g = dechex($g);
    $b = dechex($b);

    return "#" . str_pad($r, 2, "0", STR_PAD_LEFT) . str_pad($g, 2, "0", STR_PAD_LEFT) . str_pad($b, 2, "0", STR_PAD_LEFT);
  }
  /**
   *
   * @param array(r,g,b)
   * @return array(r,g,b)
   */
  static function InvertRGBArray($RGB)
  {
    return self::rgb(255 - $RGB['r'], 255 - $RGB['g'], 255 - $RGB['b']);
  }

  /**
   * @param string $color
   * @return array(r,g,b)
   */
  static function HTMLToRGBArray($color)
  {
    if ($color[0] == '#')
      $color = substr($color, 1);

    if (strlen($color) == 6)
      list($r, $g, $b) = array($color[0].$color[1],
          $color[2].$color[3],
          $color[4].$color[5]);
    elseif (strlen($color) == 3)
    list($r, $g, $b) = array($color[0].$color[0], $color[1].$color[1], $color[2].$color[2]);
    else
      return false;

    $r = hexdec($r); $g = hexdec($g); $b = hexdec($b);

    return array('r'=>$r, 'g'=>$g, 'b'=>$b);
  }
}
