package graphics.carl;

// package mosaics ;

import graphics.carl.runComponents.RunTextField;

import java.awt.*;

import gui.run.RunButton;

//import Jgui.*;

public class Main
    extends CloseFrame {
  //Image aBuffer = createImage(400,400);
  private javax.swing.JPanel panControls;
  private javax.swing.JPanel panDisplay;
  private PointArray lppArray;
  private ColorArray cArray;

  private int shuffleBundle = 1;

  private RunTextField txt_shuffle;
  private RunTextField txt_rings;
  private RunTextField txt_rays;

  private int rings = 9;
  private int rays = 24;
  private boolean radially = true;

  private int iOffset = 0;
  private boolean timerON = false;
  private java.awt.geom.Point2D.Float p2 =
      new java.awt.geom.Point2D.Float();
  private java.awt.geom.Point2D.Float p1 =
      new java.awt.geom.Point2D.Float();
  private java.awt.geom.Ellipse2D e2d =
      new java.awt.geom.Ellipse2D.Float();
  private java.awt.Color color1;
  private java.awt.Color color2;
  private java.awt.GradientPaint gp;

  //------------------------
  // Constructor
  //------------------------
  Main() {
    super("Log Polar JFrame");
    java.awt.Container c = getContentPane();

    // Construct default arrays ------
    newArray(getRings(), getRays(), isRadially());

    // Set up display JPanel----------------
    setupDisplay();
    //panDisplay.setPreferredSize(new Dimension(300,300) );

    // ----- Set up control JPanel -----------------
    setupControlPanel();

    // ----------------------------------------
    getPanControls().add(new ResetRaysButton(this)
    );

    // ----------------------------------------
    getPanControls().add(new ShuffleButton());

    // ----------------------------------------
    setTxt_shuffle(new shuffleTextfield());
    getPanControls().add(getTxt_shuffle());

    // ----------------------------------------
    getPanControls().add(new RingRaysButton(this)
    );

    // ----------------------------------------
    setTxt_rings(new RingNumberTextField(this));
    getPanControls().add(getTxt_rings());

    // ----------------------------------------
    setTxt_rays(new RaysTextField(this));
    getPanControls().add(getTxt_rays());

    getPanControls().add(new BackGroundColorButton(this)
    );

    getPanControls().add(
        new TimerToggleButton(this)
    );

    getPanControls().add(
        new ConcentricRadialButton(this)
    );

    // ----- Add panels to JFrame, and show ---------
    addPanelsToFrameAndShow(c);

  } // End constructor ----------------------

  private void setupDisplay() {
    setPanDisplay(new PanPanel(this));
    getPanDisplay().setBackground(java.awt.Color.darkGray);
  }

  private void setupControlPanel() {
    setPanControls(new javax.swing.JPanel());
    getPanControls().setOpaque(false); // avoid repainting background
    getPanControls().setBackground(java.awt.Color.lightGray);
    getPanControls().setLayout(new java.awt.FlowLayout());
  }

  private void addPanelsToFrameAndShow(java.awt.Container c) {
    setSize(400, 400);
    getPanDisplay().setLayout(new java.awt.FlowLayout());
    getPanControls().setLayout(new java.awt.FlowLayout());
    c.setLayout(new java.awt.GridLayout(0, 1));
    c.add(getPanDisplay());
    CloseFrame pf = new CloseFrame("controls");
    pf.setSize(200, 200);
    pf.getContentPane().add(getPanControls());
    pf.setVisible(true);
    show();
  }


  public void newArray(int _rings, int _rays, boolean _radial) {
    java.awt.Dimension d = getSize();
    int w = d.width;
    int h = d.height;
    double r = w / 2; //to do, use size of screen
    // to compute the inner radius
    setLppArray(new PointArray(_rings, _rays,
                               new java.awt.geom.Point2D.Float(300f, 300f), 20f));
    setCArray(new ColorArray(_rings, _rays, _radial));
  } // --------------------------------------


  public void cycleColor() {
    setIOffset(getIOffset() + 1);
    getPanDisplay().repaint();
  }

  public void toggleTimer() {
    if (isTimerON()) {
      getMyTimer().stop();
      setTimerON(false);
//              iOffset = 0;
      return;
    }
    setTimerON(true);
    getMyTimer().start();
    repaint();
  }

  private javax.swing.Timer myTimer = new javax.swing.Timer(100,
                                                            new TimerCycleColor(this)
  );

  // ----------------------------------------
  public void draw(java.awt.Graphics g) {
    java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
    float x, y, r;
    int rays = getLppArray().get_rayCount();
    int rings = getLppArray().get_ringCount();
    setRenderingHints(g2);

    //Draw circlets
    drawCirclets(rays, rings, g2);
  } // End draw()

  private void setRenderingHints(java.awt.Graphics2D g2) {
    java.awt.RenderingHints qualityHints;
    qualityHints = new
        java.awt.RenderingHints(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setRenderingHints(qualityHints);
  }

  private void drawCirclets(int rays, int rings, java.awt.Graphics2D g2) {
    float x;
    float y;
    float r;
    for (int i_ray = 0; i_ray < rays; i_ray++) {
      drawRings(rings, i_ray, rays, g2);
    }
  }

  private void drawRings(int rings, int i_ray, int rays, java.awt.Graphics2D g2) {
    float x;
    float y;
    float r;
    for (int i_ring = 0; i_ring < rings; i_ring++) {
      x = getLppArray().getPts()[i_ring][i_ray].x;
      y = getLppArray().getPts()[i_ring][i_ray].y;
      r = getLppArray().getRadii()[i_ring];
      e2d.setFrame(
          x - r, y - r, 2f * r, 2f * r);
//                  g2.setPaint(cArray.colorArray[i_ring][i_ray]);
      p2.setLocation(x - r, y + r);
      p1.setLocation(x + r, y + r);
      color1 = getCArray().getColorArray()[i_ring][(i_ray + getIOffset()) % rays];
      color2 = getCArray().getColorArray()[i_ring][(i_ray + getIOffset() + rays / 6) % rays];
//                  color2 = color1.brighter().brighter().brighter();
//

      g2.setPaint(java.awt.Color.white);
      g2.draw(e2d);
      //        g2.setPaint(color1);
      gp
          = new java.awt.GradientPaint(p1, color1, p2, color2);
      g2.setPaint(gp);
      g2.fill(e2d);
//              GradientPaint gp = new GradientPaint(p1, color1, p2, color2);

      //    GradientPaint(Point2D pt1, Color color1, Point2D pt2, Color color2, boolean cyclic)

    }
  }

  public static void main(String args[]) {
    Main logpJFrame = new Main();
  }

  public javax.swing.JPanel getPanControls() {
    return panControls;
  }

  public void setPanControls(javax.swing.JPanel panControls) {
    this.panControls = panControls;
  }

  public javax.swing.JPanel getPanDisplay() {
    return panDisplay;
  }

  public void setPanDisplay(javax.swing.JPanel panDisplay) {
    this.panDisplay = panDisplay;
  }

  public PointArray getLppArray() {
    return lppArray;
  }

  public void setLppArray(PointArray lppArray) {
    this.lppArray = lppArray;
  }

  public ColorArray getCArray() {
    return cArray;
  }

  public void setCArray(ColorArray cArray) {
    this.cArray = cArray;
  }

  public int getShuffleBundle() {
    return shuffleBundle;
  }

  public void setShuffleBundle(int shuffleBundle) {
    this.shuffleBundle = shuffleBundle;
  }

  public RunTextField getTxt_shuffle() {
    return txt_shuffle;
  }

  public void setTxt_shuffle(RunTextField txt_shuffle) {
    this.txt_shuffle = txt_shuffle;
  }

  public RunTextField getTxt_rings() {
    return txt_rings;
  }

  public void setTxt_rings(RunTextField txt_rings) {
    this.txt_rings = txt_rings;
  }

  public RunTextField getTxt_rays() {
    return txt_rays;
  }

  public void setTxt_rays(RunTextField txt_rays) {
    this.txt_rays = txt_rays;
  }

  public int getRings() {
    return rings;
  }

  public void setRings(int rings) {
    this.rings = rings;
  }

  public int getRays() {
    return rays;
  }

  public void setRays(int rays) {
    this.rays = rays;
  }

  public boolean isRadially() {
    return radially;
  }

  public void setRadially(boolean radially) {
    this.radially = radially;
  }

  public int getIOffset() {
    return iOffset;
  }

  public void setIOffset(int iOffset) {
    this.iOffset = iOffset;
  }

  public boolean isTimerON() {
    return timerON;
  }

  public void setTimerON(boolean timerON) {
    this.timerON = timerON;
  }

  public javax.swing.Timer getMyTimer() {
    return myTimer;
  }

  public void setMyTimer(javax.swing.Timer myTimer) {
    this.myTimer = myTimer;
  }

  class ShuffleButton extends RunButton {

    public ShuffleButton() {
      super("Shuffle by:");
    }

    public void run() {
      getCArray().shuffleRays(getShuffleBundle());
      getPanDisplay().repaint();
    }
  }

  class shuffleTextfield extends RunTextField {
    public shuffleTextfield() {
      super("1", 6);
    }

    public void run() {
      setShuffleBundle(Integer.parseInt(getText()));
    }
  }

}