/// Evolver Copyright 2000, Morgan McGuire
/// matrix@alum.mit.edu   http://graphics3d.com/matrix
import java.awt.Color;

public final class HueShift extends TwoArgumentOperator implements ELOperator 
{
  public void apply(ELMatrix argument[], ELMatrix out, ELEnvironment environment)
  {
    checkArguments(argument);

    ELMatrix in = argument[0];
    ELMatrix angleArg = argument[1];
    float angle = (float)(angleArg.average(0) / 2.0);

    // For extra performance, pull the arrays into locals so we avoid
    // excess dereferences.
    float red[] = out.red;
    float grn[] = out.grn;
    float blu[] = out.blu;

    float ared[] = in.red;
    float agrn[] = in.grn;
    float ablu[] = in.blu;

    final float hsv[] = new float[3];

    for(int i = out.numElements - 1; i >= 0; i--) {
      int r = ared[i] > 0 ? (int)(ared[i] * 256) : 0;
      if (r == 256) {
        r = 255;
      }

      int g = agrn[i] > 0 ? (int)(agrn[i] * 256) : 0;
      if (g == 256) {
        g = 255;
      }

      int b = ablu[i] > 0 ? (int)(ablu[i] * 256) : 0;
      if (b == 256) {
        b = 255;
      }

      Color.RGBtoHSB(r, g, b, hsv);

      hsv[0] = hsv[0] + angle;

      int c = Color.HSBtoRGB(hsv[0], hsv[1], hsv[2]);

      red[i] = ((c & 0x00FF0000) >> 16) / 256.0f;
      grn[i] = ((c & 0x0000FF00) >> 8) / 256.0f;
      blu[i] = ((c & 0x000000FF)) / 256.0f;
    }
  }

  public String name()
  {
    return "HueShift";
  }

  public String description()
  {
      return "Shift the overall hue of the first arg by average red value of the second arg";
  }  

  protected String iconString()
  {
    return "HueS";
  }
}
