package View;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

import Controller.Controller;
import Model.Situation;
import Model.Word;
import Model.Meaning;

/**
 * Class for the Panel on the right. It consists of 2 table.
 * In the first table the focused words are displayed together with some properties and can be removed from the set of focused words
 * In the second the words of the current utterance are displayed with their properties and can be added to the focused words.
 * 
 * @author simon
 *
 */

public class SidePanel extends MyPanel {
	
	private static final long serialVersionUID = 1L;

	JTable focusTable;
	MyTableModel focusModel;
	JTable utteranceTable;
	MyTableModel utteranceModel;
	
	JLabel focusLabel;
	JLabel utteranceLabel;
	
	//maximal number of rows that can be shown in the 2 pannels
	static final int maxRows = 20;
	
	//next free row in the focused word panel
	private int nextRowFocused = 0;
	
	//next free row in the utterance panel
	private int nextRowUtterance = 0;
	
	/**
	 * The constructor creates the two tables an places them on the Panel
	 * @param controller
	 */
	
	public SidePanel(Controller controller){
		
		super(controller);
		
		this.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.weightx = 1.0;
        c.weighty = 0.05;
        c.fill = GridBagConstraints.BOTH;
        c.gridwidth=1;
    	c.gridx = 0;
    	c.gridy = 0;
    	
    	JLabel focused=new JLabel("Focused Words");
    	focusLabel=focused;
    	add(focused,c);
    	
    	c.gridy = GridBagConstraints.RELATIVE;
    	c.weighty = 0.45;
    	
    	//creating the focus table
    	
    	String[] columnNames = {"","Word","Frequency","Meaning", "Probability"};
    	
		Object[][] data = new Object[maxRows][columnNames.length];

		
		focusModel=new MyTableModel(columnNames, data,true);
		
		
		// JTable with a different Cell Renderer to display the buttons and not just the toString() representation
		JTable table = new JTable(focusModel){
			public TableCellRenderer getCellRenderer(int row, int column) {
				TableColumn tableColumn = getColumnModel().getColumn(column);
				TableCellRenderer renderer = tableColumn.getCellRenderer();
				if (renderer == null) {
					Class c = getColumnClass(column);
					if( c.equals(Object.class) )
					{
						Object o = getValueAt(row,column);
						if( o != null )
							c = getValueAt(row,column).getClass();
					}
					renderer = getDefaultRenderer(c);
				}
				return renderer;
			}
			
			public TableCellEditor getCellEditor(int row, int column) {
				TableColumn tableColumn = getColumnModel().getColumn(column);
				TableCellEditor editor = tableColumn.getCellEditor();
				if (editor == null) {
					Class c = getColumnClass(column);
					if( c.equals(Object.class) )
					{
						Object o = getValueAt(row,column);
						if( o != null )
							c = getValueAt(row,column).getClass();
					}
					editor = getDefaultEditor(c);
				}
				return editor;
			}
			
		};
		
		table.setDefaultRenderer( JComponent.class, new JComponentCellRenderer() );
		table.setDefaultEditor( JComponent.class, new JComponentCellEditor() );
		table.getColumnModel().getColumn(0).setPreferredWidth(28);
		
		focusTable=table;

		JScrollPane scrollPane = new JScrollPane(table);
		table.setFillsViewportHeight(true);
		
		JPanel container=new JPanel();
		container.setLayout(new BorderLayout());
		container.add(table.getTableHeader(), BorderLayout.PAGE_START);
		container.add(table, BorderLayout.CENTER);
		
		this.add(container,c);

		//creating the utterance table
		c.weighty = 0.05;
		
		JLabel utterance=new JLabel("Utterance Words");
		utteranceLabel= utterance;
    	add(utterance,c);
    	
    	c.weighty = 0.45;
    	
    	//creating the utterance table
    	String[] columnNames2 = {"","Word","Frequency","Meaning","Probability"};
    	
		Object[][] data2 = new Object[maxRows][columnNames2.length];

		utteranceModel=new MyTableModel(columnNames2, data2,true);
		
		JTable table2 =new JTable(utteranceModel){
			public TableCellRenderer getCellRenderer(int row, int column) {
				TableColumn tableColumn = getColumnModel().getColumn(column);
				TableCellRenderer renderer = tableColumn.getCellRenderer();
				if (renderer == null) {
					Class c = getColumnClass(column);
					if( c.equals(Object.class) )
					{
						Object o = getValueAt(row,column);
						if( o != null )
							c = getValueAt(row,column).getClass();
					}
					renderer = getDefaultRenderer(c);
				}
				return renderer;
			}
			
			public TableCellEditor getCellEditor(int row, int column) {
				TableColumn tableColumn = getColumnModel().getColumn(column);
				TableCellEditor editor = tableColumn.getCellEditor();
				if (editor == null) {
					Class c = getColumnClass(column);
					if( c.equals(Object.class) )
					{
						Object o = getValueAt(row,column);
						if( o != null )
							c = getValueAt(row,column).getClass();
					}
					editor = getDefaultEditor(c);
				}
				return editor;
			}
			
		};
		
		
		table2.setDefaultRenderer( JComponent.class, new JComponentCellRenderer() );
		table2.setDefaultEditor( JComponent.class, new JComponentCellEditor() );
		table2.getColumnModel().getColumn(0).setPreferredWidth(28);
		
		((JLabel)table2.getDefaultRenderer(String.class)).setHorizontalAlignment(JLabel.LEFT);
		
		utteranceTable=table2;
		JScrollPane scrollPane2 = new JScrollPane(table2);
		table2.setFillsViewportHeight(true);
		
		JPanel container2=new JPanel();
		container2.setLayout(new BorderLayout());
		container2.add(table2.getTableHeader(), BorderLayout.PAGE_START);
		container2.add(table2, BorderLayout.CENTER);
		
		this.add(container2,c);
		
	}
	
	/**
	 * This method is called if the iteration changed or words are added or removed from the focused table
	 * 
	 */
	
	public void updatePanel(){
		updateFocused();
		updateUtterance();

		JButton button=new JButton("+");
		//TODO add actionlistener which pops up a search screen for the words
		focusTable.setValueAt(button,nextRowFocused,0);
		nextRowFocused++;
	}
	
	/**
	 * This method empties the focused table and adds the information for all the words in the focused set 
	 */
	
	public void updateFocused(){
		focusModel.empty();
		nextRowFocused=0;
		Iterator<Word> it = cont.getFocusedWords().iterator();
		while (it.hasNext()){
			Word w = it.next();
			setRow(focusTable, w, nextRowFocused,"-");
			nextRowFocused++;
			if (nextRowFocused == maxRows) return;
		}
	}
		
	public void addWordToFocused(Word w){
		if (nextRowFocused == maxRows) return;
		cont.addWordToFocusedPanel(w);
	}
	
	/**
	 * This method gets the information from the words, creates the buttons and adds them into the table.	
	 * @param table The table where the contents will be put in.
	 * @param w The word from which the Information is taken
	 * @param nextRow The row in which the information will be put.
	 * @param buttonlabel	Tells the function how the button will be labeled. If its a + a listener to add it to the focused words is added, for a - the opposite is done and for everything else no listener is added.
	 */
		
	private void setRow(JTable table, final Word w, int nextRow, String buttonlabel){
		JButton button=new JButton(buttonlabel);
		if(buttonlabel.equals("-")){
			button.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent arg0) {
	                cont.removeWordFromFocusedPanel(w);
	                GUI.updatePanels();
	                repaint();
	            }
			});	
			
		}
		else if(buttonlabel.equals("+")){
			button.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent arg0) {
	                addWordToFocused(w);
	                GUI.updatePanels();
	                repaint();
	            }
			});	
		}
		
		
		table.setValueAt(button,nextRow,0);	
		table.setValueAt(w.getStringRep(), nextRow, 1);
		
		int currentIter = cont.getCurrentIteration();
		
		table.setValueAt(w.getCurrentFrequency(currentIter), nextRow, 2);
		//for 'Meaning' show the meaning with the highest probability
		Object[] values = w.getHighestMeaning(currentIter);
		//attention: values[0] can be an empty string
		table.setValueAt(values[0],nextRow, 3);
		table.setValueAt(values[1],nextRow, 4);
	}
	/**
	 * This method empties the utterance table and adds the information for the words of the current iteration
	 */
	
	public void updateUtterance(){
		utteranceModel.empty();
		nextRowUtterance = 0;
		Situation sit=cont.getSituationData();
		if(sit != null){
			List<Word> utterance = sit.getUtterance();
			
			for (Word w: utterance){
				setRow(utteranceTable, w, nextRowUtterance,"+");
				nextRowUtterance++;
				if (nextRowUtterance == maxRows) return;
			}
		}	
	}
	
	/**
	 * Class to display JComponents in the table
	 * @author simon
	 *
	 */
	
	class JComponentCellRenderer implements TableCellRenderer
	{
	    public Component getTableCellRendererComponent(JTable table, Object value,
			boolean isSelected, boolean hasFocus, int row, int column) {
	        return (JComponent)value;
	    }
	}

	
}
