package dialogPackage;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

import org.omg.CORBA._IDLTypeStub;

import tablePackage.MyTable;

import basicPackage.CollectorTrace;
import basicPackage.FlowType;
import basicPackage.VRoom;

import componentPackage.ColComponent;
import componentPackage.EComponent;
import componentPackage.VComponent;
import componentPackage.VComponentType;

import assistPackage.Datatype;
import assistPackage.Lang1;
import assistPackage.Lang2;
import assistPackage.Lang3;
import assistPackage.Selectie;
import assistPackage.VCI;

import framePackage.GridPanel;
import framePackage.Program;

/**
 * Dialoog venster waarmee je een collector kan kiezen
 * @author Jan Van den Bossche
 *
 */

public class CollectorDialog extends JDialog {
	private GridPanel _parent;
	private ColComponent _collector;
	private VComponent[] _listCol;
	private JComboBox _cbColBrand, _cbEndBrand, _cbCollector, _cbFlexible, _cbColValve, _cbOvergang, _cbEndValve;
	private JButton _btAddRoom, _btRemoveRoom, _btApply, _btEscape, _btCalculateCollector;//_btCalculateTraces;
	private JLabel _labelCollector, _labelInfo;
	private MyTable _tableCollector;
	private AbstractTableModel _modelCollector;
	private int _roomCount;
	private ActionListener _listener;
	private String[] _columnNames;
	private VComponentType _valveType;
	private boolean _collectorSpecified = false;

	public CollectorDialog(GridPanel parent) {
		super(Program.getFrame(),Lang3.getString("Dialog.collector"),true); //$NON-NLS-1$
		_parent = parent;
		_listener = new CollectorDialogListener();
		_valveType = VComponentType.getValveType(getFlowType());
		
		Selectie selectie = _parent.getCurrentSelectie();
		if (selectie != null && selectie.getComponent() != null && 
				selectie.getComponent() instanceof ColComponent){
			_collector = (ColComponent) selectie.getComponent();
			_roomCount = _collector.getCollectorTraces().size();
			_collectorSpecified = true;
		}
		else {
			_collector = new ColComponent(getFlowType());
			_collector.setName("-");
		}
				
		initializeDialog();
		selectCollector();
	}

	private void initializeDialog() {
		JPanel northPanel = new JPanel();
		northPanel.setLayout(new GridBagLayout());
		GridBagConstraints constr = new GridBagConstraints();
		constr.weightx = 0.0;
		constr.insets = new Insets(5,5,5,5);
		northPanel.add(new JLabel("merk collector"), constr);
		constr.gridy = 1;
		northPanel.add(new JLabel("merk eindventiel"), constr);
		_cbColBrand = new JComboBox(Program.getDatabase(Datatype.ACTIVE).getBrands(VComponentType.COLLECTOR));
		_cbColBrand.addItem(VComponent.ALL_BRAND);
		constr.gridx = 1;
		constr.gridy = 0;
		northPanel.add(_cbColBrand, constr);
		_cbEndBrand = new JComboBox(Program.getDatabase(Datatype.ACTIVE).getBrands(_valveType));
		_cbEndBrand.addItem(VComponent.ALL_BRAND);
		constr.gridy = 1;
		northPanel.add(_cbEndBrand, constr);
		_listCol = Program.getDatabase(Datatype.ACTIVE).getData(VComponentType.COLLECTOR);
		ColComponent col = new ColComponent(getFlowType());
		col.setName("-");
		_listCol[0] = col;
		_cbCollector = new JComboBox(_listCol);
		_cbCollector.addActionListener(_listener);
		constr.gridx = 2;
		constr.gridy = 0;
		northPanel.add(_cbCollector, constr);
		_labelCollector = new JLabel("Kies een collector");
		constr.weightx = 0.5;
		constr.gridx = 3;
		northPanel.add(_labelCollector, constr);
		_btAddRoom = new JButton("Voeg een ruimte toe");
		_btAddRoom.addActionListener(_listener);
//		if (_collectorSpecified) _btAddRoom.setEnabled(EndComponentDialog.
//				getRoomListForCollector(_collector, getFlowType()).size() > 0);
		constr.weightx = 0.0;
		constr.gridx = 4;
		northPanel.add(_btAddRoom, constr);
		_btRemoveRoom = new JButton("Verwijder een ruimte");
		_btRemoveRoom.addActionListener(_listener);
		_btRemoveRoom.setEnabled(false);
		constr.gridy = 1;
		northPanel.add(_btRemoveRoom, constr);
		this.add(northPanel, BorderLayout.NORTH);
		
		_tableCollector = new CollectorTable();
		JScrollPane pane = new JScrollPane(_tableCollector);
		this.add(pane, BorderLayout.CENTER);
		
		JPanel southPanel = new JPanel();
		southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
		_labelInfo = new JLabel("Voeg een ruimte toe of kies een collector");
		JPanel southPanel1 = new JPanel();
		southPanel1.add(_labelInfo);
		southPanel.add(southPanel1);
		
		JPanel southPanel2 = new JPanel();
		_btCalculateCollector = new JButton("Bereken collector");
		_btCalculateCollector.addActionListener(_listener);
		_btCalculateCollector.setEnabled(false);
		southPanel2.add(_btCalculateCollector);
//		_btCalculateTraces = new JButton("Bereken tracés");
//		_btCalculateTraces.addActionListener(_listener);
//		_btCalculateTraces.setEnabled(false);
//		southPanel2.add(_btCalculateTraces);
		_btApply = new JButton("Toepassen");
		_btApply.addActionListener(_listener);
		southPanel2.add(_btApply);
		_btEscape = new JButton("Annuleer");
		_btEscape.addActionListener(_listener);
		southPanel2.add(_btEscape);
		southPanel.add(southPanel2);
		
		this.add(southPanel, BorderLayout.SOUTH);
		enableButtons();
		
		this.setPreferredSize(new Dimension(1100,400));
		this.setLocation(100, 200);
		this.getRootPane().registerKeyboardAction(new ActionListener() {		
				@Override
				public void actionPerformed(ActionEvent arg0) {
					setVisible(false);
				}
			},	KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
		this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
		this.pack();		
	}

	/**
	 * Stelt een lijst samen voor een combobox
	 * @param box: een JComboBox
	 * @param type: type waarop gezocht wordt
	 * @param bore: diameter 'in' waarop gezocht wordt
	 */
	private void setComponentList(JComboBox box, VComponentType type, int bore) {
		VComponent[] temp = Program.getDatabase(Datatype.ACTIVE).getData(type);
		box.removeAllItems();
		if (type == VComponentType.VENTIEL_TOEVOER || type == VComponentType.VENTIEL_AFVOER || 
				type == VComponentType.VENTIEL_COLLECTOR)
			box.addItem(new EComponent(type, "-"));
		else box.addItem(new VComponent(type, "-"));
		for (VComponent comp : temp) {
			if (!comp.isTitle() && (type == VComponentType.VENTIEL_TOEVOER || 
					type == VComponentType.VENTIEL_AFVOER ||//bore == -1 || 
					comp.getBoreIn() == bore)){
				box.addItem(comp);
			}
		}
	}
	/**
	 * Selecteer de huidige collector in de combobox
	 */
	private void selectCollector(){
		for (VComponent col : _listCol) {
			if (col.getName().equals(_collector.getName())){
				_cbCollector.setSelectedItem(col);
				break;
			}			
		}
	}
	private class CollectorDialogListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == _btAddRoom){
				new EndComponentDialog(CollectorDialog.this).setVisible(true);
				enableButtons();
			}
			else if (e.getSource() == _btRemoveRoom){
				if (_tableCollector.getCellEditor() != null)
					_tableCollector.getCellEditor().cancelCellEditing();
				_collector.removeCollectorTrace(
						_collector.getCollectorTraces().get(_tableCollector.getSelectedRow()));
				_modelCollector.fireTableDataChanged();
				_roomCount -= 1;
				_btRemoveRoom.setEnabled(false);
				_btAddRoom.setEnabled(true);
			}
			else if (e.getSource() == _cbCollector){
				int bore = _collector.getBoreOut();
				_collector.setProperties((VComponent) _cbCollector.getSelectedItem());
				_labelCollector.setText(_collector.getDescriptionBranchCountAndBore());
				if (bore != _collector.getBoreOut()){
					setComponentList(_cbFlexible, VComponentType.SEMIFLEX_KANAAL, _collector.getBoreOut());
					setComponentList(_cbColValve, VComponentType.VENTIEL_COLLECTOR, _collector.getBoreOut());
					setComponentList(_cbOvergang, VComponentType.OVERGANG,  _collector.getBoreOut());
					if (_cbFlexible.getItemCount() > 1) {
						for (int i = 0; i < _collector.getCollectorTraces().size(); i++) {
							_tableCollector.setValueAt(_cbFlexible.getItemAt(1), i, 
									_tableCollector.getColumnIndex().getFlexible());
						}
					}
				}
			}
			else if (e.getSource() == _btCalculateCollector){
				Program.getVentilatie().calculateCollector(_parent.getFlowType(), 
						_collector, true, _cbColBrand.getSelectedItem().toString(), 
						_cbEndBrand.getSelectedItem().toString());
				_modelCollector.fireTableDataChanged();
				selectCollector();
			}
//			else if (e.getSource() == _btCalculateTraces){
//				Program.getVentilatie().calculateCollector(
//						_parent.getFlowType(), _collector, false, true);
//				_modelCollector.fireTableDataChanged();
//				selectCollector();
//			}
			else if (e.getSource() == _btApply){
				if (!Program.getVentilatie().getComponentList(getFlowType()).
						contains(_collector))
					_parent.addEndComponent(_collector);
				for (CollectorTrace trace : _collector.getCollectorTraces()) {
					trace.saveTrace(_collector.end);
				}
				_parent.reCalculateVentilation(_collector);
				CollectorDialog.this.setVisible(false);
				_parent.draw(true);
			}
			else if (e.getSource() == _cbColBrand){
				_cbCollector.removeAllItems();
				for (VComponent col : Program.getDatabase(Datatype.ACTIVE).
						getComponentsFromBrand(_cbColBrand.getSelectedItem().toString(), _collector)){
					_cbCollector.addItem(col);
				}
			}				
			else if (e.getSource() == _cbEndBrand){
				_cbEndValve.removeAllItems();
				for (VComponent comp : Program.getDatabase(Datatype.ACTIVE).
						getComponentsFromBrand(_cbColBrand.getSelectedItem().toString(), new EComponent(_valveType))){
					_cbEndValve.addItem(comp);
				}
			}				
			else if (e.getSource() == _btEscape){
				_parent.getFlowPanel().undo();
				_parent.reCalculateVentilation(_collector);
				CollectorDialog.this.setVisible(false);
			}				
		}		
	}
	/**
	 * Zet de knoppen 'Voeg ruimte toe' en 'Bereken collector' aan of uit
	 */
	private void enableButtons(){
//		boolean calculate = Program.getVentilatie().isCalculateDone(_parent.getFlowType());
		boolean enable = EndComponentDialog.getRoomListForCollector(
				_collector, getFlowType()).size() == 0;
		boolean traces = _collector.getCollectorTraces().size() > 0;
		_btAddRoom.setEnabled(!enable);
		_btCalculateCollector.setEnabled(traces);
	}
	
	public ColComponent getCollector(){
		return _collector;
	}
	public void addRoom(VRoom room){
		_collector.addCollectorTrace(room);
		_roomCount += 1;
		_modelCollector.fireTableDataChanged();
	}
	public FlowType getFlowType(){
		return _parent.getFlowType();
	}
	
	private class CollectorTable extends MyTable {
		
		public CollectorTable(){
			super();
			String valve = "valveIn";
			if (getFlowType() == FlowType.OUT) valve = "valveOut";
			String[] list = {"room","flow","valveCol","flexible","count","speed","length","transition",valve};
			_colIndex = new VCI(list, VCI.COLLECTORLIST);
			_columnNames =  new String[list.length];
			for (int i = 0; i < list.length; i++) {
				if (i == _colIndex.getRoom()) _columnNames[0] = Lang1.getString("RoomTable.name");
				else if (i == _colIndex.getValveCol() || i == _colIndex.getFlexible() || i >= _colIndex.getTransition()) 
					_columnNames[i] = Lang2.getString("CompType." + list[i]);
				else _columnNames[i] = Lang2.getString("DataTable." + list[i]);
			}
			
			_modelCollector = new CollectorModel();
			setModel(_modelCollector);
			
			int[] kolombreedte = {140,40,140,140,40,60,50,240,240};
			DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
			renderer.setHorizontalAlignment(JLabel.CENTER);  
			for (int i = 0; i < _columnNames.length; i++) {
				this.getColumnModel().getColumn(i).setPreferredWidth(kolombreedte[i]);
				 this.getColumnModel().getColumn(i).setCellRenderer(renderer);
			}

			_cbColValve = new JComboBox();
			getColumnModel().getColumn(_colIndex.getValveCol()).setCellEditor(new DefaultCellEditor(_cbColValve));
			_cbFlexible = new JComboBox();
			getColumnModel().getColumn(_colIndex.getFlexible()).setCellEditor(new DefaultCellEditor(_cbFlexible));
			_cbOvergang = new JComboBox();
			getColumnModel().getColumn(_colIndex.getTransition()).setCellEditor(new DefaultCellEditor(_cbOvergang));
			_cbEndValve = new JComboBox();
			getColumnModel().getColumn(_colIndex.getValveEnd()).setCellEditor(new DefaultCellEditor(_cbEndValve));

			if (_collectorSpecified){
				setComponentList(_cbFlexible, VComponentType.SEMIFLEX_KANAAL, _collector.getBoreOut());
				setComponentList(_cbColValve, VComponentType.VENTIEL_COLLECTOR, _collector.getBoreOut());
				setComponentList(_cbOvergang, VComponentType.OVERGANG,  _collector.getBoreOut());
			}
			setComponentList(_cbEndValve, _valveType, -1);
			
			getSelectionModel().addListSelectionListener(new ListSelectionListener() {				
				@Override
				public void valueChanged(ListSelectionEvent arg0) {
					int row = CollectorTable.this.getSelectedRow();
					if (row != -1 && row < getRowCount() - 1){
						_btRemoveRoom.setEnabled(true);		
						CollectorTrace trace = _collector.getCollectorTraces().get(row);
						_labelInfo.setText(trace.getDescription());
					}
				}
			});
		}
		private void enableButtons(){
			
		}
		private class CollectorModel extends AbstractTableModel {
			@Override
			public int getColumnCount() {
				return _columnNames.length;
			}
			@Override
			public int getRowCount() {
				if (_collector == null) return 1;
				else return _roomCount + 1;//_collector.getCollectorTraces().size() + 1;
			}
			@Override
			public String getColumnName(int col) {
				return _columnNames[col];
			}
			@Override
			public Object getValueAt(int row, int col) {
				if (row < _roomCount)
					return _collector.getCollectorTraces().get(row).getValueAt(col, _colIndex);
				else if (col == 0) return "totaal aantal flexibels";
				else if (col == _colIndex.getCount()) return _collector.getTotalFlexCount();
				else if (col == _colIndex.getFlexible()) return String.valueOf(_collector.getBoreOut()) + " mm";
				else return "";
			}	
			@Override
			public void setValueAt(Object value, int row, int col) {
				_collector.getCollectorTraces().get(row).setValueAt(value, col, _colIndex);
//				if (col == _colIndex.getTransition()) {
//					int bore = _collector.getCollectorTraces().get(row).getOvergang().getBoreOut();
//					System.out
//							.println("CollectorDialog.CollectorTable.CollectorModel.setValueAt(): bore="+bore);
//					setComponentList(_cbEndValve, _valveType, bore);
//				}
				_modelCollector.fireTableDataChanged();
			}
			@Override
		    public boolean isCellEditable(int row, int col) { 
				if (row == _roomCount)  return false;
				else if (col == 0) return false;
		    	else return true;
		    }
		    public Class getColumnClass(int col) { 
		    	if (col == 1  || col == 3) return JComboBox.class;
		    	else return String.class;
		    }
		}
		
		/**
		 * Deze methode overschrijft de prepareRenderer methode van JTable 
		 * De pare rijen worden blauw gekleurd, de selectie groen
		 */
		@Override
		public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
			Component c = super.prepareRenderer(renderer, row, col);
			if (row == _roomCount) {
				c.setFont(c.getFont().deriveFont(Font.BOLD));
				c.setBackground(new Color(210, 210, 210)); 
			}
			else {
				if (row % 2 == 0 && !isRowSelected(row)) c.setBackground(Program.preferences.pareRowColor);
				else if (isRowSelected(row))  c.setBackground(Program.preferences.rowSelectionColor);
				else c.setBackground(getBackground());   		
				if (isCellSelected(row, col)) c.setBackground(Program.preferences.cellSelectionColor);
			}
			return c;
		}
	}
}
