package graphics.charts;

import gui.ClosableJFrame;

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

/**
 * LineGraph implements the Paintable interface to draw a line
 * graphics.graph on a frame. <BR>
 * Global variables:
 * <UL>
 * <LI> DoubleData: instance of DoubleData so the graphics.graph is drawn
 *     with the proper data
 * </UL>
 *
 * @author  Allison McHenry
 * @author  Douglas Lyon, PhD
 * @since   JDK 1.3
 */

public class LineGraph extends JComponent
    implements Paintable {

//GLOBAL VARIABLES
  private DoubleData dd;

//CONSTRUCTORS
  /**
   *    Default constructor, used to instantiate an instance of LineGraph by
   *    the testing class
   *
   *    @param _dd      instance of DoubleData used to draw the graphics.graph
   */
  public LineGraph(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());
  }

//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        DrawUtil.#drawGrid
   *    @see        DrawUtil.#drawTicks
   *    @see        DrawUtil.#drawAxes2
   *    @see        DrawUtil.#drawXAxisLabel
   *    @see        DrawUtil.#drawYAxisLabel
   *    @see        DrawUtil.#drawTitle
   *    @see        DrawUtil.#drawLine
   */
  public void paint(Graphics g) {
    DrawUtil du = new DrawUtil(dd);
    Ticks t = new Ticks(dd, getSize());
    t.paint(g);
    drawGraph(g);
    du.drawXAxisLabel(g);
    du.drawYAxisLabel(g);
    du.drawTitle(g);

    System.out.println("Successfully drawing line graphics.graph");
  }


  /**
   *    Draws the line for the line graphics.graph.
   *
   *    @param g    Graphics context for drawing
   *    @see        LineGraph.#paint
   *    @see        DoubleData.#getXScreenCoords2
   *    @see        DoubleData.#getYScreenCoords2
   *    @see        java.awt.#drawPolyline
   */
  private void drawGraph(Graphics g) {
    // actual code
    g.setColor(Color.red);
    Polygon p = getPolygon();
    g.drawPolyline(p.xpoints, p.ypoints, p.npoints);

  }

  /**
   *    Method used to by the line graphics.graph to convert entered X data
   *    to data appropriate for drawing on the screen
   *    (incremented to fit in the available screen size, corrected for offset, etc)
   *
   *    @return Xs                  The new data array
   *    @see                        LineGraph.#drawGraph
   */

  private int[] getXScreenCoords() {
    double[] xVals = dd.getXVals();
    int xLength = xVals.length;
    int width = dd.getWidth();
    double deltaX = dd.getDeltaX();
    double xOrigin = dd.getXAxisCoord();
    double xIncrement = dd.getIncrementNew(xVals, width);
    double maxX = dd.getMax(xVals);

    int Xs[] = new int[xLength];

    if (maxX > 0) {
      for (int i = 0; i < xLength; i++) {
        Xs[i] = (int) (xIncrement * xVals[i]) + (int) xOrigin;

      }
    } else {
      for (int i = 0; i < xLength; i++) {
        Xs[i] = width - ((int) (xIncrement * xVals[i]));

      }
    }
    return Xs;

  }

  /**
   *    Method used to by the line graphics.graph to convert entered Y data
   *    to data appropriate for drawing on the screen
   *    (incremented to fit in the available screen size, corrected for offset, etc)
   *
   *    @return Ys                  The new data array
   *    @see                        LineGraph.#drawGraph
   */
  private int[] getYScreenCoords() {
    double[] yVals = dd.getYVals();
    int height = dd.getHeight();
    int yLength = yVals.length;
    double deltaY = dd.getDeltaY();
    double yIncrement = dd.getYIncrement();
    int Ys[] = new int[yLength];
    double maxY = dd.getMax(yVals);

    double yOrigin = dd.getYAxisCoord();

    for (int i = 0; i < yLength; i++) {
      Ys[i] = (int) (yOrigin - (yVals[i] * yIncrement)); // +Y_OFFSET
    }

    return Ys;

  }

  private Polygon getPolygon() {
    return new Polygon(getXScreenCoords(),
                       getYScreenCoords(), getXScreenCoords().length);
  }

  public static void main(String args[]) {
    ClosableJFrame cf = new ClosableJFrame();
    Container c = cf.getContentPane();
    double numberOfPoints = 100;
    double eps = (2 * Math.PI + .1) / numberOfPoints;
    double theta = 0;
    double x[] = new double[(int) numberOfPoints];
    double y[] = new double[x.length];
    for (int i = 0; i < x.length; i++) {
      x[i] = Math.cos(theta);
      y[i] = Math.sin(theta);
      theta = theta + eps;
    }

    //double xes[] = new double[]{-10,-20,-30,-40};
    //double yes[] = new double[] {10,20,30,40};
    DoubleData dd = new DoubleData(200, 200);
    dd.setXLabel("x label");
    dd.setYLabel("y label");
    dd.setXVals(x);
    dd.setYVals(y);
    LineGraph lg = new LineGraph(dd);
    c.add(lg);
    c.setLayout(
        new FlowLayout());
    c.setBackground(Color.white);
    cf.setSize(200, 200);
    cf.setVisible(true);
  }

}