package graphics.charts;

import gui.ClosableJFrame;

import javax.swing.*;
import java.awt.*;

/**
 * BarGraph implements the Paintable interface to draw a bar
 * graphics.graph on a frame. Requires an instance of DoubleData in order
 * to be constructed.<BR>
 * Global variables:
 * <UL>
 * <LI> DoubleData: instance of DoubleData so the graphics.graph is drawn
 *     with the proper data
 *  <LI> barwidth: an arbitrary width for each bar in the bar graphics.graph
 * </UL>
 *
 * @author  Allison McHenry
 * @author  Douglas Lyon, PhD
 * @since   JDK 1.3
 */


public class BarGraph extends JComponent
    implements Paintable {

//GLOBAL VARIABLES
  private DoubleData dd;
  private int barwidth = 6;

//CONSTRUCTORS



  /**
   *    Constructor used if only height and width should be set, using defaults for all
   *    global variables. Probably would only use this as a test case.
   *    @param w    Image width (not frame width)
   *    @param h    Image height (not frame height)
   */
  public BarGraph(DoubleData _dd) {
    dd = _dd;
    setSize(dd.getWidth(), dd.getHeight());
  }

  public Dimension getPreferredSize() {
    return new Dimension(dd.getWidth(), dd.getHeight());
  }

  public Dimension getMinimumSize() {
    return new Dimension(dd.getWidth(), dd.getHeight());
  }

  /**
   *    Sets the arbitrary width of the bars.
   *
   *    @param _barwidth Width of each bar
   */
  public void setBarWidth(int _barwidth) {
    barwidth = _barwidth;
  }



//UTILITY METHODS

  /**
   *    Actually paints this data from DoubleData onto an image. The DrawUtil class is a
   *    generic utilities class containing all methods which actually
   *    handle the painting.
   *
   *    @param g    Graphics context for drawing
   *    @see        drawGraph
   *    @see        DrawUtil.#drawAxes2
   *    @see        DrawUtil.#drawXAxisLabel
   *    @see        DrawUtil.#drawYAxisLabel
   *    @see        DrawUtil.#drawTitle
   */
  public void paint(Graphics g) {

    DrawUtil du = new DrawUtil(dd);
    Ticks t = new Ticks(dd, getSize());
    t.setNumberOfTicks(10, 10);
    ;
    t.paint(g);
    //du.drawGrid(g);
    drawGraph(g);
    //du.drawXAxisLabel(g);
    //du.drawYAxisLabel(g);
    du.drawTitle(g);
  }


  /**
   *    Draws the bars for the bar graphics.graph. The height of the bars
   *    is determined by the values in the Y array. The values in
   *    the X array are irrelevant.
   *
   *    @param g    Graphics context for drawing
   *    @see        paint
   *    @see        DoubleData.#getYAxisCoord
   *    @see        DoubleData.#getYIncrement
   *    @see        getXCoord
   *    @see        getYCoord
   *    @see        java.awt.#fillRect
   */
  private void drawGraph(Graphics g) {

    int barheight = 0;
    g.setColor(Color.red);
    int x;
    int y;
    int width = dd.getWidth();

    double yOrigin = dd.getYAxisCoord();
    double yNums[] = dd.getYVals();
    int pxPerY = (int) dd.getYIncrement();

    System.out.println("width=" + width);

    for (int j = 0; j < yNums.length; j++) {
      x = (int) getXCoord(j + 1, (dd.getIncrement(width, yNums.length)));

      y = (int) getYCoord(yNums[j], pxPerY);

      //center the bar
      x = x - (barwidth);

      if (y > yOrigin) { // ie Y is a negative value
        barheight = y - (int) yOrigin;
        y = (int) yOrigin;
      } else {
        barheight = (int) Math.abs(yOrigin - y);
      }

      System.out.println("x=" + x);
      System.out.println("y=" + y);
      System.out.println("barwidth=" + barwidth);
      System.out.println("barheight=" + barheight);
      g.fillRect(x, y, barwidth, barheight);
    }
  }

  /**
   *    Method used to by the bar graphics.graph to calculate where on the x axis
   *    to start drawing the rectangle for the graphics.graph: the increment * the
   *    x value
   *
   *    @return xCoord              The X coordinate of the top left corner of this bar
   *    @see                        drawGraph
   */

  private double getXCoord(double numX, int xPixelsWide) {
    double xCoord = numX * xPixelsWide;
    return xCoord;
  }

  /**
   *    Method used to by the bar graphics.graph to calculate where on the y axis
   *    to start drawing the rectangle for the graphics.graph( the increment * the y value)
   *   subtracted from the y origin because the zero value for Y is the top of the screen
   *
   *    @return yCoord              The Y coordinate of the top left corner of this bar
   *    @see                        drawGraph
   */
  private double getYCoord(double numY, int yPixelsHigh) {
    double yOrigin = dd.getYAxisCoord();
    double yCoord = yOrigin - (numY * yPixelsHigh);
    return yCoord;
  }

  public static void main(String args[]) {
    ClosableJFrame cf = new ClosableJFrame();
    Container c = cf.getContentPane();
    DoubleData dd = new DoubleData(200, 200);
    double yVals[] = {10, -20, -40, 80};
    dd.setYVals(yVals);
    BarGraph bg = new BarGraph(dd);
    bg.setBarWidth(6);
    c.add(bg);
    c.setLayout(
        new FlowLayout());
    cf.setBackground(Color.white);
    cf.setSize(200, 200);
    cf.setVisible(true);
  }


}