package interfacing;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.DecimalFormat;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import logging.Reporter;

/**
 * This JPanel contains a table of statistics on Job Classes. This information
 * includes { "Class ID", "Number of Jobs", "Arrival Rate", "Actual Arrival
 * Rate", "Execution Time", "Actual Execution Time", "T/O" , "Waiting Time", "Waiting
 * Time-T/O" ,"Communication Time", "Communication Time-T/O", "Response Time",
 * "Response Time-T/O" };
 */
public class JobClassesStatisticsJPanel extends JPanel {

	/**
	 * The serialVersionUID is used to universally identify this version of this
	 * class.
	 */
	private static final long serialVersionUID = 5098254999901115141L;
	/**
	 * The labels of the header row.
	 */
	private static String[] headers = { "Class ID", "Number of Jobs", "Arrival Rate", "Actual Arrival Rate",
			"Execution Time", "Actual Execution Time", "T/O", "Waiting Time", "Waiting Time-T/O", "Communication Time",
			"Communication Time-T/O", "Response Time", "Response Time-T/O" };
	/**
	 * The main frame object that contains this JPanel
	 */
	private MainFrame frame;

	/**
	 * The JTable object viewing the information in tabular form
	 */
	private JTable jTable;

	/**
	 * Every JTable in java has this model.
	 */
	private DefaultTableModel model;

	/**
	 * The JButton that refreshes the info viewed
	 */
	private JButton buttonUpdate = new JButton("Update");

	/**
	 * The JButton that saves the table on a file
	 */
	private JButton buttonSave = new JButton("Save");

	/**
	 * The folder containing the Icons
	 */
	private String iconsFolder = "Icons";

	/**
	 * The default constructor. It initializes and lays the GUI objects.
	 * 
	 * @param frame
	 *            The MainFrame object containing this JPanel
	 */
	public JobClassesStatisticsJPanel(final MainFrame frame) {
		this.frame = frame;
		this.setLayout(new BorderLayout());
		model = new DefaultTableModel();
		jTable = new JTable(model);
		JScrollPane scrollPane = new JScrollPane(jTable);
		jTable.setEnabled(false);

		JPanel buttonsPanel = new JPanel();
		buttonsPanel.add(buttonSave);
		buttonsPanel.add(buttonUpdate);

		this.buttonSave.setIcon(new ImageIcon(iconsFolder + "/" + "filesave_22.png"));
		this.buttonUpdate.setIcon(new ImageIcon(iconsFolder + "/" + "reload_22.png"));

		this.add(scrollPane, BorderLayout.CENTER);
		this.add(buttonsPanel, BorderLayout.NORTH);

		this.buttonSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					JFileChooser fileChooser = new JFileChooser();
					int returnedValue = fileChooser.showSaveDialog(((JButton) e.getSource()).getParent());
					if (returnedValue != JFileChooser.APPROVE_OPTION) {
						return;
					}

					Reporter.generateReportAboutJobClasses(frame.getMapper(), frame.getGeneratorsController(),
							fileChooser.getSelectedFile().getAbsolutePath());
				} catch (IOException ex) {
					ex.printStackTrace();
					return;
				}

			}
		});

		this.buttonUpdate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				refresh();
			}
		});
	}

	/**
	 * This method reads the statistics from the Mapper object and views them. It
	 * is triggered by the refresh JButton.
	 */
	public void refresh() {
		DecimalFormat formatter = new DecimalFormat();
		formatter.setMaximumFractionDigits(3);

		model = new DefaultTableModel(headers, frame.getMapper().getClassesTable().size());
		try {
			for (int i = 1; i <= frame.getMapper().getClassesTable().size(); i++) {
				model.setValueAt(frame.getMapper().getClassesTable().get(i).getIndex(), i - 1, 0);
				model.setValueAt(frame.getGeneratorsController().getGenerators()[i - 1].getJobsGeneratedNumber(),
						i - 1, 1);
				model.setValueAt(formatter.format(frame.getMapper().getJobClass(i).getArrivalRate()), i - 1, 2);
				model.setValueAt(formatter.format(frame.getGeneratorsController().getGenerators()[i - 1]
						.getActualRate()), i - 1, 3);
				model.setValueAt(frame.getMapper().getJobClass(i).getexecutionTime(), i - 1, 4);
				model.setValueAt(formatter.format(frame.getGeneratorsController().getGenerators()[i - 1]
						.getAcutualIterationAverage()), i - 1, 5);
				model.setValueAt(frame.getMapper().getJobsTable().getTimeOutedJobsCount(i), i - 1, 6);
				model.setValueAt(formatter
						.format(frame.getMapper().getJobsTable().getSchedulingDelayInMilliSeconds(i) / 1000), i - 1, 7);
				model.setValueAt(formatter.format(frame.getMapper().getJobsTable()
						.getSchedulingDelayInMilliSecondsIncludingTimedOut(i) / 1000), i - 1, 8);
				model.setValueAt(formatter.format(frame.getMapper().getJobsTable().getCommunicationDelayInSeconds(i)),
						i - 1, 9);
				model.setValueAt(formatter.format(frame.getMapper().getJobsTable()
						.getCommunicationDelayInSecondsIncludingTimedOut(i)), i - 1, 10);
				model.setValueAt(formatter.format(frame.getMapper().getJobsTable().getResponseTimeInSeconds(i)), i - 1,
						11);
				model.setValueAt(formatter.format(frame.getMapper().getJobsTable()
						.getResponseTimeInSecondsIncludingTimedOut(i)), i - 1, 12);
			}
		} catch (NullPointerException ex) {
			ex.printStackTrace();
			return;
		}
		jTable.setModel(model);

		this.repaint();
	}

	/**
	 * This method enables/disables the user input. This JPanel is always
	 * disabled.
	 */
	public void setEnabled(boolean enabled) {
		this.buttonSave.setEnabled(enabled);
		this.buttonUpdate.setEnabled(enabled);
	}

}
