package interfacing;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JPanel;

import javax.swing.*;

/**
 * 
 * 
 * This class is a generic JPanel containing properties that can be set or
 * edited
 * 
 * @author Majd Kokaly
 */
public class PropertiesJPanel extends JPanel {
	private static final long serialVersionUID = 1L;

	/** Number of properties the panel controls */
	private int properties;

	/** The main panel that contains the labels and the fields */
	private JPanel mainPanel;

	/** The Layout used to control the mainPanel */
	private GridBagLayout gridBagLayout;

	/** This object constrains the laying out of objects */
	private GridBagConstraints gbConstraints;

	/** The array of components in the panel. By default it is JTextField() */
	private Component[] components;

	/** The array of labels in the panel. */
	private JLabel[] labels;

	/** The array of strings that stores the string of values. */
	private String[] values;


	/**
	 * @param properties
	 *            is the number of properties controlled by the panel
	 */
	public PropertiesJPanel(int properties) {
		this.properties = properties;
		gbConstraints = new GridBagConstraints();
		gbConstraints.fill = GridBagConstraints.NONE;
		gbConstraints.anchor = GridBagConstraints.WEST;
		gbConstraints.insets = new Insets(0, 0, 0, 10);

		this.setLayout(new BorderLayout());

		mainPanel = new JPanel();
		gridBagLayout = new GridBagLayout();
		mainPanel.setLayout(gridBagLayout);

		components = new Component[properties];
		labels = new JLabel[properties];

		values = new String[properties];

		for (int i = 0; i < properties; i++) {
			// Creating the components
			components[i] = new JTextField(10);
			// Creating the labels
			labels[i] = new JLabel("property " + i);

			// Setting the cell containing the label and adding it.
			gbConstraints.gridx = 0;
			gbConstraints.gridy = i;
			mainPanel.add(labels[i], gbConstraints);

			// Setting the cell containing the component and adding it.
			gbConstraints.gridx = 1;
			mainPanel.add(components[i], gbConstraints);
		}
		// Setting the submit button and adding it.
		gbConstraints.gridx = 0;
		gbConstraints.gridy = properties;
		gbConstraints.gridwidth = 2;
		gbConstraints.anchor = GridBagConstraints.CENTER;
		gbConstraints.anchor = GridBagConstraints.WEST;

		mainPanel.setMaximumSize(new Dimension(700, 400));
		this.add(mainPanel, BorderLayout.CENTER);
	}

	/**
	 * @param strings
	 *            is the array of properties names controlled by the panel
	 */
	public PropertiesJPanel(String[] labelStrings, String[] tips) {
		this.properties = labelStrings.length;
		gbConstraints = new GridBagConstraints();
		gbConstraints.fill = GridBagConstraints.NONE;
		gbConstraints.anchor = GridBagConstraints.NORTH;
		gbConstraints.insets = new Insets(3, 3, 3, 10);

		this.setLayout(new FlowLayout());

		mainPanel = new JPanel();
		gridBagLayout = new GridBagLayout();
		mainPanel.setLayout(gridBagLayout);

		components = new Component[properties];
		labels = new JLabel[properties];
		values = new String[properties];

		for (int i = 0; i < properties; i++) {
			// Creating the components
			components[i] = new JTextField(10);
			// Creating the labels
			labels[i] = new JLabel(labelStrings[i]);
			if (tips != null)
				labels[i].setToolTipText(tips[i]);
			
			
			// Setting the cell containing the label and adding it.
			gbConstraints.gridx = 0;
			gbConstraints.gridy = i;
			mainPanel.add(labels[i], gbConstraints);

			// Setting the cell containing the component and adding it.
			gbConstraints.gridx = 1;
			mainPanel.add(components[i], gbConstraints);
			

		}
		// Setting the submit button and adding it.
		gbConstraints.gridx = 0;
		gbConstraints.gridy = properties;
		gbConstraints.gridwidth = 2;
		gbConstraints.anchor = GridBagConstraints.CENTER;
		gbConstraints.anchor = GridBagConstraints.WEST;

		mainPanel.setMaximumSize(new Dimension(700, 400));
		this.add(mainPanel, BorderLayout.CENTER);
		this.setAlignmentY(JPanel.TOP_ALIGNMENT);

	}

	public void setLabelText(int i, String label) {
		labels[i].setText(label);
		this.repaint();
	}
	
	/**
	 * This method set the "ith" component to Component c
	 * @param i is the number of component to be changed
	 * @param c is the component itself
	 */
	public void replaceValueComponent(int i, Component c) {
		mainPanel.remove(components[i]);
		// Adding the new component
		gbConstraints.gridx = 1;
		gbConstraints.gridy = i;
		components[i] = c;
		mainPanel.add(components[i], gbConstraints);

		this.repaint();
	}
	
	
	/**
	 * 
	 * @param i the number of component
	 * @return a String of the Type name (e.g JTextField)
	 */
	public String getType(int i) {
		return components[i].getClass().toString();
	}
	
	/**
	 * This method get A String of the value of the component i
	 * @param i the number of component
	 * @return the value as a String
	 */
	public String getValue(int i) {
		if (components[i] instanceof JTextField) {
			return ((JTextField) components[i]).getText();
		}
		if (components[i] instanceof JCheckBox) {
			return ((JCheckBox) components[i]).isSelected() + "";
		}
		if (components[i] instanceof JComboBox) {
			return ((JComboBox) components[i]).getSelectedItem().toString();
		}

		return "";
	}
	
	

	/**
	 * This method sets the value of the component i
	 * @param i the number of component
	 * @value the value to be set
	 */
	public void setValue(int i, String value) {
		if (components[i] instanceof JTextField) {

			((JTextField) components[i]).setText(value);
			return;
		}
		if (components[i] instanceof JCheckBox) {
			if (value.equalsIgnoreCase("true"))
				((JCheckBox) components[i]).setSelected(true);
			else
				((JCheckBox) components[i]).setSelected(false);
			return;

		}
		if (components[i] instanceof JComboBox) {
			for (int j = 0; j < ((JComboBox) components[i]).getModel()
					.getSize(); j++) {
				if (((JComboBox) components[i]).getModel().getElementAt(j)
						.toString().equalsIgnoreCase(value)) {
					((JComboBox) components[i]).setSelectedIndex(j);
					return;
				}
			}

			((JComboBox) components[i]).setSelectedIndex(0);
		}

	}
	
	/**
	 * This method clear component i
	 * @param i what component to clear
	 * 
	 */
	public void clearField(int i) {
		if (components[i] instanceof JTextField) {
			((JTextField) components[i]).setText("");
		}
		if (components[i] instanceof JCheckBox) {
			((JCheckBox) components[i]).setSelected(false);
		}
		if (components[i] instanceof JComboBox) {
			((JComboBox) components[i]).setSelectedIndex(0);
		}
	}
	
	/**
	 * This method clear all the fields
	 */
	public void clearFields() {
		for (int i = 0; i < properties; i++) {
			this.clearField(i);
		}
	}

	public void printTypes() {
		for (int i = 0; i < properties; i++) {
			System.out.println(components[i].getClass().toString());
		}
	}

	public void printComponents() {
		for (int i = 0; i < properties; i++) {
			System.out.println(mainPanel.getComponent(i).toString());
		}
	}

	public void printValues() {
		for (int i = 0; i < properties; i++) {
			System.out.println(values[i]);
		}
	}
	
	/**
	 * This fills the array values[] with the values of component
	 */
	private void refreshValues() {
		for (int i = 0; i < properties; i++) {
			values[i] = this.getValue(i);
		}
	}
	
	public String[] getValues() {
		refreshValues();
		return values;
	}

}
