package graphics.carl;

/*  class:              graphics.carl.ColorArray
 *  principal output:   colorArray[ringCount][rayCount]
 *
 *  Generates 2-D rectangular array of colors.
 *  Array index order is [ring][ray] = [column][row] =[x][y]
 *      (Cartesian order, transpose of row-column matrix order).
 *  Default constructor uniformly samples hue spectrum
 *      at max saturation & brightness, by ray
 *      ( = row = second index = y-coord).
 *
 *  Methods for other arrangements and shuffling of colors
 *  Methods for getters
 *
 *  ----------------------------------
 *  Modified Oct 16 2001, Carl Weiman
 */

//package mosaics;  //To be packaged after development


public class ColorArray {
  private int ringCount, rayCount;
  private java.awt.Color[][] colorArray;    // Principal product of this class
  private java.awt.Color[] tempColors;      // Internal buffer to generate and shuffle colors
  private boolean radial = true;    // Determines radial vs concentric color pattern

  //------------
  // Constructor
  //------------

  public ColorArray(int _rings, int _rays, boolean _radial) {
    ringCount = _rings;
    rayCount = _rays;
    radial = _radial;

    colorArray = new java.awt.Color[ringCount][rayCount];
    if (radial)
      tempColors = new java.awt.Color[rayCount];
    else
      tempColors = new java.awt.Color[ringCount];
    rainbow();      // Populate tempColor array with rainbow spectrum
    assignColors(); // Distribute tempColors to colorArray
  }

  //----------------------------------------------------
  public void assignColors() {
    if (radial) {
      for (int i_ray = 0; i_ray < rayCount; i_ray++) {
        colorArray[0][i_ray] = tempColors[i_ray];
        for (int i_ring = 1; i_ring < ringCount; i_ring++) {
          colorArray[i_ring][i_ray] = colorArray[0][i_ray];
        }
      }
    } else {
      for (int i_ring = 0; i_ring < ringCount; i_ring++) {
        colorArray[i_ring][0] = tempColors[i_ring];
        for (int i_ray = 1; i_ray < rayCount; i_ray++) {
          colorArray[i_ring][i_ray] = colorArray[i_ring][0];
        }
      }
    }
    System.out.println("1st color:" + tempColors[0]);
    System.out.println("last color:" + tempColors[tempColors.length - 1]);
  }

  //---------
  //  Getters
  //---------

  public java.awt.Color[][] get_colorArray() {
    return colorArray;
  }

  public java.awt.Color getColori(int _ring, int _ray) {
    return colorArray[_ring % ringCount][_ray % rayCount];
  }

  public boolean get_radial() {
    return radial;
  }

  public int get_rayCount() {
    return rayCount;
  }

  public int get_ringCount() {
    return ringCount;
  }

  public String toString() {        // Show your colors
    String str;
    str = new String("  ");
    for (int i_ray = 0; i_ray < rayCount; i_ray++) {
      str += "\n";
      for (int i_ring = 0; i_ring < ringCount; i_ring++) {
        str += "  " + colorArray[i_ring][i_ray].toString();
      }
    }
    return str;
  }

  //--------


  public void shuffleRays(int m) {
    String debug;
    int k;
    java.awt.Color holdColor1, holdColor2;
    for (int i_ray = 0; i_ray < rayCount; i_ray += m) {
      holdColor1 = colorArray[0][i_ray];
      k = m * (((int) (Math.random() * (float) rayCount)) / m);
      holdColor2 = colorArray[0][k];

      for (int j = 0; j < m; j++) {
        //          debug = "";
        //          debug += " m= "+m+" i_ray = "+i_ray+" k= "+k+" j= "+j;
        //          debug += "  holdColor1=" + holdColor1 ;
        //          System.out.println( debug );
        if ((i_ray + j) < rayCount)
          for (int i_ring = 0; i_ring < ringCount; i_ring++)
            colorArray[i_ring][i_ray + j] = holdColor2;
        if ((k + j) < rayCount)
          for (int i_ring = 0; i_ring < ringCount; i_ring++)
            colorArray[i_ring][k + j] = holdColor1;
      }
    }
  }

  //--------------------------------------------------//
  // ComputeServer interpolated colors over entire spectrum //
  // -------------------------------------------------//
  public void rainbow() {
    float coeff = 0;
    for (int i = 0; i < tempColors.length; i++) {
      coeff = 3.0f * (float) i / (float) tempColors.length;

      if (coeff <= 1f) //interpolate r-g
        tempColors[i] = interpRG(coeff);

      else if (coeff <= 2f) //interpolate g-b
        tempColors[i] = interpGB(coeff - 1f);

      else //interpolate b-r
        tempColors[i] = interpBR(coeff - 2f);
    }
    tempColors[0] = java.awt.Color.white;
    tempColors[1] = java.awt.Color.black;
  } // end rainbow

  //-----------------------------
  // color interpolation services
  //-----------------------------
  private static java.awt.Color interpRG(float alpha) {
    float red, green, blue;
    red = (1.0f - alpha) * 255.0f;
    green = alpha * 255f;
    return new java.awt.Color((int) red, (int) green, 0);
  }

  private static java.awt.Color interpGB(float alpha) {
    float red, green, blue;
    green = (1.0f - alpha) * 255.0f;
    blue = alpha * 255f;
    return new java.awt.Color(0, (int) green, (int) blue);
  }

  private static java.awt.Color interpBR(float alpha) {
    float red, green, blue;
    blue = (1.0f - alpha) * 255.0f;
    red = alpha * 255f;
    return new java.awt.Color((int) red, 0, (int) blue);
  }

  //--------------------------------------
  // main method for testing purposes only
  //--------------------------------------
  public static void main(String args[]) {
    ColorArray myLUT;
    String str_nc;
    int nc;
    myLUT = new ColorArray(3, 4, true);
    System.out.println(myLUT);
    myLUT.shuffleRays(3);
//      System.out.println(myLUT);

  } // end main

  public int getRingCount() {
    return ringCount;
  }

  public void setRingCount(int ringCount) {
    this.ringCount = ringCount;
  }

  public int getRayCount() {
    return rayCount;
  }

  public void setRayCount(int rayCount) {
    this.rayCount = rayCount;
  }

  public java.awt.Color[][] getColorArray() {
    return colorArray;
  }

  public void setColorArray(java.awt.Color[][] colorArray) {
    this.colorArray = colorArray;
  }

  public java.awt.Color[] getTempColors() {
    return tempColors;
  }

  public void setTempColors(java.awt.Color[] tempColors) {
    this.tempColors = tempColors;
  }

  public boolean isRadial() {
    return radial;
  }

  public void setRadial(boolean radial) {
    this.radial = radial;
  }

} // end class graphics.carl.ColorArray