package framePackage;

import importExportPackage.ExportVentilationFile;
import importExportPackage.ImportVentilationFile;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTabbedPane;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

import componentPackage.VComponent;
import componentPackage.VComponentType;

import dialogPackage.ComponentDialog;
import dialogPackage.HouseDialog;

import assistPackage.Parameters;
import assistPackage.PreferencesV;
import assistPackage.Selectie;
import assistPackage.Zoom;
import basicPackage.Direction;
import basicPackage.House;
import basicPackage.Punt3D;
import basicPackage.Ventilatie;

/**
 * Start van het programma, met de main methode
 * met static eigenschappen en methoden
 * @author Jan Van den Bossche
 *
 */
public class Program extends JFrame{
	private static JFrame _frame;
	private static JMenuBar _menuBar;
	private static MyMenu _fileMenu, _editMenu, _viewMenu, _tracéMenu, _infoMenu;
	private static JMenuItem _miNewFile, _miOpenFile, _miSaveFile, _miSaveAsFile, _miClose;
	private static JRadioButtonMenuItem[] _radioButtonsZoom;
	private static ActionListener _menuListener, _viewListener;
	private static JTabbedPane _tabbedPane;
	private static TabPanel _tracéPanel;
	private static SupplyPanel _supplyPanel;
	private static RoomPanel _roomPanel;
	private static ParamPanel _paramPanel;
	private static DatabasePanel _databasePanel;
	private static JLabel _statusBar;
	private static House _house;
	private static Ventilatie _ventilatie;
	private static HouseDialog _houseDialog;
	private static ComponentDialog _componentDialog;
	private static Zoom _currentZoom;
	private static ImportVentilationFile _import;
	private static ExportVentilationFile _export;
	public static PreferencesV preferences;
	public static Parameters parameters;
	public static float VERHOUDING = 1.66f, X_FACTOR, Y_FACTOR, X_NUL_POSITION;
	public static Dimension PANEL_DIMENSION;
	
	public Program() {
		preferences = new PreferencesV();
		parameters = new Parameters();
		float schuin = (float)Math.sqrt(VERHOUDING * VERHOUDING + 1);
		X_FACTOR = VERHOUDING / (float)Math.sqrt(VERHOUDING * VERHOUDING + 1);
		Y_FACTOR = 1 / schuin;
		_house = new House();
		setPanelDimensions();
		_ventilatie = new Ventilatie();
		_currentZoom = Zoom.Z2;
	
		_import = new ImportVentilationFile();
		_export = new ExportVentilationFile();
		
		_frame = new JFrame();
		_tabbedPane = new JTabbedPane();
		_menuBar = new JMenuBar();
		_fileMenu = new MyMenu("Bestand");
		_editMenu = new MyMenu("Bewerk");
		_viewMenu = new MyMenu("Beeld");
		_tracéMenu = new MyMenu("Tracé");
		_infoMenu = new MyMenu("Info");
		_menuBar.add(_fileMenu);
		_menuBar.add(_editMenu);
		_menuBar.add(_viewMenu);
		_menuBar.add(_tracéMenu);
		_menuBar.add(_infoMenu);
		_frame.setJMenuBar(_menuBar);
		
		_databasePanel = new DatabasePanel();
		_paramPanel = new ParamPanel();
		_tabbedPane.addTab("Parameters", _paramPanel);

		_roomPanel = new RoomPanel();
		_tabbedPane.addTab("Algemeen", _roomPanel);
		
		_tracéPanel = new TabPanel(TabPanel.TRACE, _currentZoom);
		_tabbedPane.addTab("Tracé", _tracéPanel);
		
		_supplyPanel = new SupplyPanel();
		_tabbedPane.addTab("Grid", _supplyPanel);

		_tabbedPane.addTab("Data", _databasePanel);

		_frame.getContentPane().add(_tabbedPane);
		_statusBar = new JLabel("");
		_frame.add(_statusBar, BorderLayout.SOUTH);
		
		_menuListener = new ProgramMenuListener();
		initializeFileMenu();
		initializeTracéMenu();
		initializeViewMenu();
		initializeInfoMenu();
//		_componentDialog = new ComponentDialog(_tracéPanel.getDrawPanel());
//		_lijndDialog = new ComponentDialog();
		_frame.pack();
	}

	private static void initializeFileMenu(){
		_fileMenu.addMenuItem(_miNewFile = new JMenuItem(), 
				"&Nieuw dossier", "control N", _menuListener); //$NON-NLS-1$ //$NON-NLS-2$
		_fileMenu.addMenuItem(_miOpenFile = new JMenuItem(), 
				"&Open dossier", "control 0", _menuListener); //$NON-NLS-1$ //$NON-NLS-2$
		_fileMenu.addMenuItem(_miSaveFile = new JMenuItem(), 
				"Op&slaan dossier", "control S", _menuListener); //$NON-NLS-1$ //$NON-NLS-2$
//		_fileMenu.addMenuItem(_miSaveAsFile = new JMenuItem(), 
//				"&Nieuw dossier", "control N", _menuListener); //$NON-NLS-1$ //$NON-NLS-2$
		
	}
	private static void initializeTracéMenu(){
		final JMenuItem componentMenuItem = new JMenuItem("Voeg component toe");
		final JMenuItem roosterMenuItem = new JMenuItem("Voeg rooster toe");
		final JMenuItem lijnMenuItem = new JMenuItem("Voeg lijn toe");
		final JMenuItem houseMenuItem = new JMenuItem("Gegevens voor het huis");
		final JMenuItem deleteMenuItem = new JMenuItem("Verwijder selectie");
		_tracéMenu.add(componentMenuItem);
		_tracéMenu.add(roosterMenuItem);
		_tracéMenu.add(lijnMenuItem);
		_tracéMenu.add(houseMenuItem);
		_tracéMenu.add(deleteMenuItem);
		componentMenuItem.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				_componentDialog = new ComponentDialog(_tracéPanel.getDrawPanel(), VComponentType.GENERIC);
				_componentDialog.setVisible(true);
//				System.out.println("Program.addBuis(): "+_tabbedPane.getSelectedComponent().getClass().getSimpleName());
				_tracéPanel.drawDrawPanel();
			}
		});
		roosterMenuItem.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				_componentDialog = new ComponentDialog(_tracéPanel.getDrawPanel(), VComponentType.ROOSTER);
				_componentDialog.setVisible(true);
				_tracéPanel.drawDrawPanel();
			}
		});
		lijnMenuItem.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent arg0) {
				_componentDialog = new ComponentDialog(_tracéPanel.getDrawPanel(), VComponentType.LIJN);
				_componentDialog.setVisible(true);
				_tracéPanel.drawDrawPanel();
			}
		});
		houseMenuItem.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (_houseDialog == null) _houseDialog = new HouseDialog();
				_houseDialog.setVisible(true);
				_tracéPanel.drawDrawPanel();
			}
		});
		deleteMenuItem.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent arg0) {
				Selectie selectie = _tracéPanel.getDrawPanel().getSelecties().get(0);
				if (selectie.getType() == Selectie.COMPONENT) _ventilatie.removeComponent(selectie.getComponent());
				else if (selectie.getType() == selectie.LIJN) _house.removeLijn(selectie.getLijn());
				else return;
				_tracéPanel.getDrawPanel().clearSelecties();
				_tracéPanel.drawDrawPanel();
			}
		});
		JMenuItem testMenuItem = new JMenuItem("test");
		_tracéMenu.add(testMenuItem);
		testMenuItem.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				String factor =JOptionPane.showInputDialog("Wijzig de isometrische factor (1.66)");
				VERHOUDING = Float.parseFloat(factor);
				float schuin = (float)Math.sqrt(VERHOUDING * VERHOUDING + 1);
				X_FACTOR = VERHOUDING / (float)Math.sqrt(VERHOUDING * VERHOUDING + 1);
				Y_FACTOR = 1 / schuin;
//				_house = new House();
				setPanelDimensions();
				_tracéPanel.drawDrawPanel();
			}
		});
		_tracéMenu.addMenuListener(new MenuListener() {		
			@Override
			public void menuSelected(MenuEvent arg0) {
				boolean selectComp = false;
				boolean select = false;
				if (_tracéPanel.getDrawPanel().getSelecties().size() > 0){
					select = true;
					Selectie selectie = _tracéPanel.getDrawPanel().getSelecties().get(0);
					if (selectie.getType() == Selectie.COMPONENT || selectie.getType() == Selectie.LIJN) selectComp = true;
				}
				componentMenuItem.setEnabled(!selectComp && select);
				roosterMenuItem.setEnabled(!selectComp && select);
				lijnMenuItem.setEnabled(!selectComp && select);
				deleteMenuItem.setEnabled(selectComp);
			}			
			@Override
			public void menuDeselected(MenuEvent arg0) {}
			@Override
			public void menuCanceled(MenuEvent arg0) {}
		});
	}
	private void initializeViewMenu(){
		final Zoom[] lijstZoom = Zoom.values();
		ButtonGroup groepZoom = new ButtonGroup();
		_radioButtonsZoom = new JRadioButtonMenuItem[lijstZoom.length];
		for (int i = 0; i < lijstZoom.length; i++) {
			final Zoom zoom = lijstZoom[i];
			_radioButtonsZoom[i] = new JRadioButtonMenuItem(zoom.toString());
			_radioButtonsZoom[i].setMnemonic(lijstZoom[i].getMnemonic());
			if (lijstZoom[i] == _currentZoom)			
				_radioButtonsZoom[i].setSelected(true);
			_radioButtonsZoom[i].addActionListener(new ActionListener() {				
				@Override
				public void actionPerformed(ActionEvent e) {
					_currentZoom = zoom;
					_tracéPanel.drawDrawPanel();
//					if (currentZoom == Zoom.Z10) _zoomIn.setEnabled(false);
//					else  _zoomIn.setEnabled(true);
//					if (currentZoom == Zoom.Z1)  _zoomOut.setEnabled(false);
//					else  _zoomOut.setEnabled(true);
				}
			});
			groepZoom.add(_radioButtonsZoom[i]);
			_viewMenu.add(_radioButtonsZoom[i]);
		}	
	}
	private void initializeInfoMenu(){
		JMenuItem traceInfoMenu = new JMenuItem("Info voor de tekening");
		_infoMenu.add(traceInfoMenu);
		traceInfoMenu.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent arg0) {
				JOptionPane.showMessageDialog(Program.this, "SELECTEREN\n" +
						"Klik op een hoekpunt van het huis, of op een eindpunt van een component:\n" +
						"zo wordt een punt geselecteerd. \n" +
						"In het menu 'Tracé' kan je dan kiezen voor een lijn, component of rooster.\n\n" +
						"Als je op het middenpunt van een element aanklikt, wordt het element geselecteerd.\n" +
						"Je kan dan het element via het menu 'Tracé' verwijderen.\n" +
						"Je kan 2 punten selecteren door 'shift' ingedrukt te houden voor een tweede punt.\n" +
						"Je kan dan via het menu 'Tracé' een lijn of component tussen de 2 punten tekenen.\n\n" +
						"HUIS\n" +
						"In het menu 'Tracé' vind je ook 'Gegevens voor het huis'.\n" +
						"Hier kan je de breedte, diepte en hoogte in meter (met kommagetal) ingeven. \n" +
						"De breedte (links-rechts) loopt van het midden schuin naar boven rechts, \n" +
						"de diepte (voor-achter) loopt van het midden schuin naar links.\n" +
						"Voor de hoogte, kan je verschillende waarden, gescheiden door een spatie, ingeven, \n" +
						"Die zullen dan de verschillende verdiepingen voorstellen. \n" +
						"Het eerste getal mag ook negatief zijn (= kelder). \n\n" +
						"PERSPECTIEF \n" +
						"Via 'Tracé, Test' kan je een andere waarde dan 1.66 ingeven.\n" +
						"Deze waarde is de verhouding tussen x en y op de lijnen links-rechts voor-achter. \n" +
						"Bij wijze van test kan je dan bv. 3 ingeven.\n\n" +
						"BEELD\n" +
						"In het menu beeld' kan je in of uitzoomen, de percentages slaan op de verhouding tot.\n" +
						"de ware grootte (ongeveer).\n" , 
						"Info over het tekenen van de ventilatie",JOptionPane.PLAIN_MESSAGE); 
			}
		});
	}
	private static class ProgramMenuListener implements ActionListener {
		public void actionPerformed(ActionEvent e) { 
			if (e.getSource() == _miNewFile){
				
			}
			else if (e.getSource() == _miSaveFile){
//				if (_xml.exportFrame(_listFrames, false)) setSaveOk(true);
				_export.exportVentilation(_ventilatie, true);
			}
			else if (e.getSource() == _miOpenFile){
				_ventilatie = _import.importVentilation();
				_roomPanel.updateRoomTable(_ventilatie);
			}
		}
	}

	public void updateScrollPane() {
		_tracéPanel.updateScrollPane();	
	}

	public static JFrame getFrame(){
		return _frame;
	}
	public static House getHouse(){
		return _house;
	}
	public static Ventilatie getVentilatie(){		
		return _ventilatie;
	}
	public static VComponent[] getComponentDatabase(){
		return _databasePanel.getData();
	}
	public static ComponentDialog getComponentDialog(){
		if (_componentDialog == null) _componentDialog = new ComponentDialog(_tracéPanel.getDrawPanel(), VComponentType.GENERIC);
		return _componentDialog;
	}
	public static void setPanelDimensions(){
//		PANEL_DIMENSION = _house.getIsometricPanelDimension();
		X_NUL_POSITION = _house.getXNulPosition();
		PANEL_DIMENSION = getIsometricPanelDimension();
	}
	/**
	 * Geeft hoogte en breedte van het panel waarin de ventilatie getekend wordt in isometrisch perspectief
	 * @return
	 */
	public static Dimension getIsometricPanelDimension(){
		Dimension dim = new Dimension();
		dim.width = (int)(((parameters.getPanelWidth() + parameters.getPanelDept()) * Program.X_FACTOR * 
				Program.preferences.FACTOR_PIXEL_METER) + Program.preferences.MARGE * 2);
		dim.height = (int)((((parameters.getPanelWidth() + parameters.getPanelDept()) * 
				Program.Y_FACTOR + parameters.getPanelHeight()) * 
				Program.preferences.FACTOR_PIXEL_METER) + Program.preferences.MARGE * 2);
		return dim;
	}

	public static Zoom getCurrentZoom(){
		return _currentZoom;
	}

	public static void main(String[] args) {
		Program program = new Program();
		Program.getFrame().setTitle("Ventilatie");
		Program.getFrame().setExtendedState(JFrame.MAXIMIZED_BOTH);
		Program.getFrame().setMinimumSize(new Dimension(300,300));
		Program.getFrame().setVisible(true);
	}

}
