package de.tu_darmstadt.tk.SmartHomeNetworkSim.view;

import java.awt.FlowLayout;
import java.util.LinkedList;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import javax.swing.JOptionPane;

import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.SettingsController;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.menuBar.MenuBarInsertAnomalies;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.menuBar.MenuBarNetworkExamples;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.AboutPopUp;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.ConnectionCreationDialog;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.EditAlgorithmsPopUp;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.EditCollectorsPopUp;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.LinkCreationDialog;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.NetworkTreeWindow;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.SettingsPopUp;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.SimulationConfigurator;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups.SmartDeviceCreationPopUp;

/**
 * MenuBar for the MainFrame, which contains the different items like options
 *
 * @author Andreas T. Meyer-Berg
 */
public class MenuBar extends JMenuBar {

	/**
	 * Controller to manipulate the model
	 */
	private Controller controller;
	
	/**
	 * Settings Controller
	 */
	private SettingsController config;

	/**
	 * JMenu for the Simulation
	 */
	private JMenu mnSimulation;

	/**
	 * JMenu for Creation of Devices etc.
	 */
	private JMenu mnCreate;

	/**
	 * JMenu for Editing of Devices, Options etc.
	 */
	private JMenu mnEdit;

	/**
	 * JMenu for managing different views
	 */
	private JMenu mnView;

	/**
	 * JMenu for managing different algorithms
	 */
	private JMenu mnAlgorithms;

	/**
	 * JMenu for help with the program
	 */
	private JMenu mnHelp;
	
	/**
	 * JMenu for examples
	 */
	private JMenu mnExamples;
	
	/**
	 * JMenu for Examample Anomalies
	 */
	private JMenu mnInsertAnomaly;

	/**
	 * Serial Version
	 */
	private static final long serialVersionUID = 4293499386792032777L;

	/**
	 * Initialize the Menu Bar, add all the items and add the different actions
	 * 
	 * @param controller
	 *            Controller
	 */
	public MenuBar(Controller controller) {
		this.controller = controller;
		this.config = controller.getSettingsController();

		
		this.setLayout(new FlowLayout(FlowLayout.LEADING));

		
		initializeSimulationMenu();
		this.add(mnSimulation);
		initializeCreateMenu();
		this.add(mnCreate);
		initializeEditMenu();
		this.add(mnEdit);
		initializeViewMenu();
		this.add(mnView);
		initializeAlgorithmMenu();
		this.add(mnAlgorithms);
		initializeHelpMenu();
		this.add(mnHelp);
	}

	/**
	 * Initializes the Simulation Menu
	 */
	private void initializeSimulationMenu() {
		mnSimulation = new JMenu("Simulation");
		JMenuItem mntmConfigureSim = new JMenuItem("Configure Sim");
		mntmConfigureSim.addActionListener(a -> {
			SimulationConfigurator sim = new SimulationConfigurator(controller);
			sim.setLocationRelativeTo(this.getParent());
			sim.setVisible(true);
		});
		mnSimulation.add(mntmConfigureSim);
	}

	/**
	 * Initialize the creation menu
	 */
	private void initializeCreateMenu() {
		mnCreate = new JMenu("Create");

		// Create device option
		JMenuItem mntmCreateDevice = new JMenuItem("Create SmartDevice");

		mntmCreateDevice.addActionListener(e -> {
			SmartDevice newDevice = new SmartDevice();
			/**
			 * Device radius,
			 */
			int rad = config.getDeviceVisualizationRadius();
			int x = (int)Math.round(Math.random()*(config.getWidth()-2*rad))+rad;
			int y = (int)Math.round(Math.random()*(config.getHeight()-2*rad))+rad;
			int z = (int)Math.round(Math.random()*(config.getDepth()-2*rad))+rad;
			controller.getNetworkController().moveSmartDevice(newDevice, x, y, z);

			SmartDeviceCreationPopUp popUp = new SmartDeviceCreationPopUp(newDevice, false, controller);
			popUp.setLocationRelativeTo(this.getParent());
			popUp.setEnabled(true);
			popUp.setVisible(true);
		});
		mnCreate.add(mntmCreateDevice);

		// Create Link option
		JMenuItem mntmCreateLink = new JMenuItem("Create Link of all visible Devices");
		mntmCreateLink.addActionListener(e -> {
			new LinkCreationDialog(controller.getNetworkController().getVisibleSmartDevices(), controller,
					this.getParent());

		});
		mnCreate.add(mntmCreateLink);
		
		// Create Link of selected option
		JMenuItem mntmCreateLinkOfSelected = new JMenuItem("Create Link of all selected Devices");
		mntmCreateLinkOfSelected.addActionListener(e -> {
			LinkedList<SmartDevice> devices = controller.getSettingsController().getConfigurationManager().getSelectionModel().selectedDevices;
			if(!devices.isEmpty())
				new LinkCreationDialog(devices, controller, this.getParent());

		});
		mnCreate.add(mntmCreateLinkOfSelected);
		
		// Create Connection option
		JMenuItem mntmCreateConnection = new JMenuItem("Create Connection of all visible Devices");
		mntmCreateConnection.addActionListener(e -> {
			new ConnectionCreationDialog(controller.getNetworkController().getVisibleSmartDevices(), controller,
					this.getParent());
			});
		mnCreate.add(mntmCreateConnection);
		
		// Create Connection option
		JMenuItem mntmCreateConnectionOfSelected = new JMenuItem("Create Connection of all selected Devices");
		mntmCreateConnectionOfSelected.addActionListener(e -> {
			LinkedList<SmartDevice> devices = controller.getSettingsController().getConfigurationManager().getSelectionModel().selectedDevices;
			if(!devices.isEmpty())
				new ConnectionCreationDialog(devices, controller,
					this.getParent());
			});
		mnCreate.add(mntmCreateConnectionOfSelected);
		
		// Create example network option
		mnExamples = new MenuBarNetworkExamples(controller);
		mnCreate.add(mnExamples);
		
		// Create Anomaly Example
		mnInsertAnomaly = new MenuBarInsertAnomalies(controller);
		mnCreate.add(mnInsertAnomaly);
		
		
	}

	/**
	 * Initializes the Edit Menu
	 */
	private void initializeEditMenu() {
		mnEdit = new JMenu("Edit");

		JMenuItem mntmDeleteModel = new JMenuItem("Delete Network");
		mntmDeleteModel.addActionListener(a -> {
			int dialogResult = JOptionPane.showConfirmDialog(this.getParent(),
					"Do you really want do delete all Devices, Ports, Links & Connections?");
			if (dialogResult == JOptionPane.YES_OPTION) {
				controller.getNetworkController().deleteNetworkModel();
			}
		});
		mnEdit.add(mntmDeleteModel);

		JMenuItem mntmOption = new JMenuItem("Settings");
		mntmOption.addActionListener(a -> {
			SettingsPopUp settings = new SettingsPopUp(controller);
			settings.setLocationRelativeTo(this.getParent());
			settings.setVisible(true);
		});
		mnEdit.add(mntmOption);
	}

	/**
	 * Initializes the View Menu
	 */
	private void initializeViewMenu() {
		mnView = new JMenu("View");

		JMenuItem mntmTreeView = new JMenuItem("Tree View");
		mntmTreeView.addActionListener(a -> {
			NetworkTreeWindow net = new NetworkTreeWindow(controller, this.getParent());
			net.setVisible(true);
		});
		mnView.add(mntmTreeView);

		JMenuItem mntmOption = new JMenuItem("View Settings");
		mntmOption.addActionListener(a -> {
			SettingsPopUp settings = new SettingsPopUp(controller);
			settings.setLocationRelativeTo(this.getParent());
			settings.setVisible(true);
		});
		mnView.add(mntmOption);
	}

	/**
	 * Initializes the Algorithm Menu
	 */
	private void initializeAlgorithmMenu() {
		mnAlgorithms = new JMenu("Algorithms");

		JMenuItem mntmManageAlgos = new JMenuItem("Manage Algorithms");
		mntmManageAlgos.addActionListener(a -> {
			new EditAlgorithmsPopUp(controller, this.getParent());
		});
		mnAlgorithms.add(mntmManageAlgos);

		JMenuItem mntmManageCollectors = new JMenuItem("Manage Collectors & PacketSniffers");
		mntmManageCollectors.setToolTipText("Allows managing of the Packet Collectors and Packet Sniffer");
		mntmManageCollectors.addActionListener(a -> {
			new EditCollectorsPopUp(controller, this.getParent());
		});
		mnAlgorithms.add(mntmManageCollectors);
	}

	/**
	 * Initializes the Help Menu
	 */
	private void initializeHelpMenu() {
		mnHelp = new JMenu("Help");
		JMenuItem mntmAbout = new JMenuItem("About");
		mntmAbout.addActionListener(a -> {
			AboutPopUp about = new AboutPopUp();
			about.setLocationRelativeTo(this.getParent());
			about.setVisible(true);
		});
		mnHelp.add(mntmAbout);
	}
}
