package ui.view;

import javax.swing.JPanel;
import javax.swing.JTextPane;

import classes.TrackedDataSet;
import ui.controller.Control;
import ui.model.Model;

import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.text.StyledDocument;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.GroupLayout.Alignment;

import java.awt.GridLayout;

public class StatisticGraphPanel extends JPanel {

	private static final long serialVersionUID = 1L;

	// Model/Controller
	private Model model;
	private Control controller;

	// Components
	private StatisticGraph sGraph;
	private final JLabel graphNameLabel;
	private final JLabel maximumLabel = new JLabel("0");
	private JPanel topPanel = new JPanel();
	private JButton closeButton = new JButton("X");
	private JButton savImgButton = new JButton("Save as Image");

	// Variables
	String graphName;
	private final JPanel legendPanel = new JPanel();
	private JPanel that;
	private Hashtable<String, StatisticGraphPanel> graphHashtable;

	/**
	 * Constructor.
	 * 
	 * @param mod
	 *            the Model
	 * @param cont
	 *            the Controller
	 */
	public StatisticGraphPanel(Model mod, Control cont, String name, Hashtable<String, StatisticGraphPanel> gHt) {
		super();
		this.model = mod;
		this.controller = cont;
		this.sGraph = new StatisticGraph(mod, cont);
		this.graphName = name;
		this.graphHashtable = gHt;
		setLayout(new BorderLayout(0, 0));

		// ******************** Component Propertys ***************//
		// Graph
		// this.setPreferredSize(new Dimension(280, 300));
		sGraph.setPreferredSize(new Dimension(280, 180));
		sGraph.setMinimumSize(new Dimension(100, 150));
		// this.setMaximumSize(new Dimension(1000, 1000));

		// Graph Name
		graphNameLabel = new JLabel(graphName);
		graphNameLabel.setHorizontalTextPosition(JLabel.CENTER);

		// Panel on top (Name and Close Button)
		topPanel.setLayout(new BorderLayout(0, 0));
		topPanel.add(graphNameLabel, BorderLayout.WEST);
		topPanel.add(closeButton, BorderLayout.EAST);
		topPanel.add(savImgButton, BorderLayout.CENTER);
		savImgButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				BufferedImage img = new BufferedImage(that.getWidth(), that.getHeight(), BufferedImage.TYPE_INT_RGB);
				that.print(img.getGraphics());
				try {
					JFileChooser fileChooser = new JFileChooser();
					if (fileChooser.showSaveDialog(new JFrame()) == JFileChooser.APPROVE_OPTION) {
						String file = fileChooser.getSelectedFile().getPath();
						ImageIO.write(img, "jpg", new File(file + ".jpg"));
					}
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

			}
		});
		topPanel.setBorder(null);

		// Maximum Label
		maximumLabel.setVerticalAlignment(SwingConstants.TOP);
		maximumLabel.setMinimumSize(new Dimension(30, 10));

		// Legend Panel
		legendPanel.setLayout(new GridLayout(0, 5, 0, 0));

		// ******************** Component Listener ****************//

		that = this;
		closeButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JPanel parent = (JPanel) that.getParent();
				for (int i = 0; i < parent.getComponentCount(); i++) {
					if (parent.getComponent(i).equals(that)) {
						parent.remove(parent.getComponent(i + 1));
						break;
					}
				}
				graphHashtable.remove(graphName);
				parent.remove(that);
				parent.updateUI();
			}
		});

		// ******************** add everything ********************//
		this.add(sGraph);
		this.add(topPanel, BorderLayout.NORTH);
		this.add(maximumLabel, BorderLayout.WEST);
		this.add(legendPanel, BorderLayout.SOUTH);

	}

	/**
	 * Adds the Set to the Graph.
	 * 
	 * @param set
	 */
	public void addObjec(TrackedDataSet set) {
		sGraph.addObject(set);
		String property = "";
		switch (set.getProperty()) {
		case TrackedDataSet.CONSUMPTION:
			property = "consumption";
			break;
		case TrackedDataSet.PRODUCTION:
			property = "production";
			break;
		case TrackedDataSet.ACTIVATED_ELEMENTS:
			property = "active elements";
			break;
		case TrackedDataSet.ON_OFF:
			property = "on//off";
			break;
		case TrackedDataSet.TOTAL_PRODUCTION:
			property = "total production";
			break;
		case TrackedDataSet.TOTAL_CONSUMPTION:
			property = "total consumption";
			break;
		case TrackedDataSet.PERCENT_SUPPLIED:
			property = "Percentage of supplied";
			break;
		case TrackedDataSet.PERCENT_NOT_SUPPLIED:
			property = "Percentage of not supplied";
			break;
		case TrackedDataSet.PERCENT_PARTIAL_SUPPLIED:
			property = "Percentage of partial supplied";
			break;
		default:
			break;
		}
		JLabel b;
		if (set.getCpsObject() != null) {
			b = new JLabel(set.getCpsObject().getID() + ", " + set.getCpsObject().getName() + ": " + property);
		} else {
			b = new JLabel(property);
		}
		b.setBackground(set.getColor());
		int color = Math.max(Math.max(set.getColor().getRed(), set.getColor().getGreen()), set.getColor().getBlue());
		if (color <= 128) {
			b.setForeground(Color.WHITE);
		}

		b.setOpaque(true);
		b.addMouseListener(new MouseAdapter() {

			@Override
			public void mousePressed(MouseEvent e) {
				if (MouseEvent.BUTTON3 == e.getButton()) {
					for (int i = 0; i < legendPanel.getComponentCount(); i++) {
						if (legendPanel.getComponent(i).equals(e.getComponent())) {
							legendPanel.remove(i);
							sGraph.removeObject(i);
							that.updateUI();
						}
					}
				}
			}
		});
		legendPanel.add(b);
		sGraph.calcMaximum();
		that.updateUI();
	}

	/**
	 * Set the Maximum Label
	 *
	 * @param max
	 */
	public void setMaximumLabel(double max) {
		maximumLabel.setText(Double.toString(max));
	}

	/**
	 * Get the name of the Graph.
	 * 
	 * @return the name of the Graph
	 */
	public String getGraphName() {
		return this.graphName;
	}

}
