import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.ArrayList;

public class BarGraphPanel extends JPanel
{
	private String title;
	private ArrayList<Float> predicted;
	private ArrayList<Float> goal;
	private Font font;

	public BarGraphPanel(String title, ArrayList<Float> predicted, ArrayList<Float> goal)
	{
		this.title = title;
		this.predicted = predicted;
		this.goal = goal;
		this.font = new Font("lucida sans regular", Font.PLAIN, 12);
		this.setBackground(Color.white);
	}

	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);

		Graphics2D g2 = (Graphics2D)g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setFont(font);
		FontRenderContext frc = g2.getFontRenderContext();

		int width = 800;
		int height = 565;
		int hPad = 100;
		int vPad = 100;

		float xInc = (width - (hPad + vPad)) / predicted.size();
		float yInc = (height - (hPad + vPad)) / 10f;

		//y axis
		g2.draw(new Line2D.Double(hPad, vPad, hPad, height - vPad));

		float x1 = hPad, y1 = vPad, x2 = hPad - 3, y2;

		//y axis tick marks
		for (int i = 0; i < 11; i++)
		{
			g2.draw(new Line2D.Double(x1, y1, x2, y1));
			y1 += yInc;
		}

		String text;
		LineMetrics lm;
		float xs, ys, textWidth, textHeight;
		int decrementer = 10;

		//y axis labels
		for (int i = 0; i <  11; i++)
		{
			text = String.valueOf((float)decrementer / 10);
			textWidth = (float)font.getStringBounds(text, frc).getWidth();
			lm = font.getLineMetrics(text, frc);
			textHeight = lm.getAscent();
			xs = hPad - textWidth - 7;
			ys = vPad + (i * yInc) + textHeight / 2;
			g2.drawString(text, xs, ys);
			decrementer--;
		}

		//x axis
		g2.draw(new Line2D.Double(hPad, height - vPad, width - hPad, height - vPad));

		x1 = hPad + (xInc / 2);
		y1 = height - vPad;
		y2 = y1 + 3;

		//x axis tick marks
		for (int i = 0; i < predicted.size(); i++)
		{
			g2.draw(new Line2D.Double(x1, y1, x1, y2));
			x1 += xInc;
		}

		ys = height - vPad + 5;

		//x axis labels
		for (int i = 0; i < predicted.size(); i++)
		{
			text = String.valueOf(i + 1);
			textWidth = (float)font.getStringBounds(text, frc).getWidth();
			lm = font.getLineMetrics(text, frc);
			textHeight = lm.getHeight();
			xs = hPad + (xInc / 2) + (i * xInc) - (textWidth / 2);
			g2.drawString(text, xs, ys + textHeight);
		}
		text = "Bins";
		textWidth = (float)font.getStringBounds(text, frc).getWidth();
		lm = font.getLineMetrics(text, frc);
		textHeight = lm.getHeight();
		xs = (width / 2) - (textWidth / 2);
		ys = height - (vPad / 2) + (textHeight / 2) - 10;
		g2.drawString(text, xs, ys);

		//predicted data
		float maxVal = 0;
		for (int i = 0; i < predicted.size(); i++)
		{
			if (predicted.get(i) > maxVal)
			{
				maxVal = predicted.get(i);
			}
		}

		int mw = ((width - (hPad + vPad)) / predicted.size()) / 3;
		float unit = (height - (hPad + vPad));
		if (goal.size() > 0)
		{
			x1 = hPad + (xInc / 6);
		}
		else
		{
			x1 = hPad + (xInc / 3);
		}

		g2.setColor(Color.red);
		for (int i = 0; i < predicted.size(); i++)
		{
			g2.fill(new Rectangle2D.Double(x1, height - vPad - predicted.get(i) * unit, mw, predicted.get(i) * unit));
			x1 += xInc;
		}

		//goal data
		if (goal.size() > 0)
		{
			maxVal = 0;
			for (int i = 0; i < goal.size(); i++)
			{
				if (goal.get(i) > maxVal)
				{
					maxVal = goal.get(i);
				}
			}

			x1 = hPad + (xInc / 2) + 1;

			g2.setColor(Color.blue);
			for (int i = 0; i < goal.size(); i++)
			{
				g2.fill(new Rectangle2D.Double(x1, height - vPad - goal.get(i) * unit, mw, goal.get(i) * unit));
				x1 += xInc;
			}
		}

		//chart keys
		font = font.deriveFont(10f);
		g2.setFont(font);
		text = "Predicted =";
		textWidth = (float)font.getStringBounds(text, frc).getWidth();
		lm = font.getLineMetrics(text, frc);
		textHeight = lm.getHeight();
		xs = (width / 4) - (textWidth / 2);
		ys = height - (vPad / 2) + (textHeight / 2) - 10;
		g2.setColor(Color.black);
		g2.drawString(text, xs, ys);

		g2.setColor(Color.red);
		g2.fill(new Rectangle2D.Double(xs + textWidth + 5, height - (vPad / 2) - textHeight - 2, 33.0, textHeight));

		if (goal.size() > 0)
		{
			text = "Goal =";
			textWidth = (float)font.getStringBounds(text, frc).getWidth();
			lm = font.getLineMetrics(text, frc);
			textHeight = lm.getHeight();
			xs = (width - (width / 3.5f)) - textWidth;
			ys = height - (vPad / 2) + (textHeight / 2) - 10;
			g2.setColor(Color.black);
			g2.drawString(text, xs, ys);

			g2.setColor(Color.blue);
			g2.fill(new Rectangle2D.Double(xs + textWidth + 5, height - (vPad / 2) - textHeight - 2, 33.0, textHeight));
		}

		//chart title
		font = font.deriveFont(18f);
		g2.setFont(font);
		text = title;
		textWidth = (float)font.getStringBounds(text, frc).getWidth();
		lm = font.getLineMetrics(text, frc);
		textHeight = lm.getAscent();
		xs = (width/ 2) - (textWidth / 2);
		ys = (vPad / 2) + (textHeight / 2);
		g2.setFont(font);
		g2.setColor(Color.black);
		g2.drawString(title, xs, ys);

		//y axis label
		font = font.deriveFont(12f);
		g2.setFont(font);
		text = "Value";
		textWidth = (float)font.getStringBounds(text, frc).getWidth();
		lm = font.getLineMetrics(text, frc);
		textHeight = lm.getAscent();
		xs = (hPad / 2) - (textWidth / 2) + 15;
		ys = (height / 2) - (textHeight / 2);
		g2.rotate(-Math.PI/2.0);
		g2.setFont(font);
		g2.drawString(text, -ys, xs);
	}
}