package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;

import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.PacketCaptureController;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.SimulationController;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.PacketCollector;
import de.tu_darmstadt.tk.SmartHomeNetworkSim.view.util.Utility;

import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;



/**
 * PopUp for managing the Collectors/PacketSniffers
 *
 * @author Andreas T. Meyer-Berg
 */
public class EditCollectorsPopUp extends JDialog implements Observer {
	/**
	 * serial
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * Controller for manipulating the simulation and adding algorithms
	 */
	private Controller controller;
	
	/**
	 * Simulation controller for access to the algorithms
	 */
	private SimulationController sim;
	
	/**
	 * Packet captureController
	 */
	private PacketCaptureController captureController;
	
	/**
	 * Jlist for listing the PacketListener
	 */
	private JList<String> list;
	
	/**
	 * Scroll Pane for scrolling in the Algorithm list
	 */
	private JScrollPane scrollPanelList;
	
	/**
	 * Mutex, to disable listeners on update
	 */
	private boolean mutex = true;
	/**
	 * Reference to this
	 */
	private EditCollectorsPopUp that = this;
	
	/**
	 * Creates and shows a new EditAlgorithmPopUp
	 * @param controller controller
	 * @param parent parent container the location should be set relative to
	 */
	public EditCollectorsPopUp(Controller controller, Container parent) {
		this.controller = controller;
		sim = this.controller.getSimulationController();
		captureController = sim.getPacketCaptureController();
		captureController.addObserver(this);
		this.setSize(400, 400);
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		setTitle("Manage PacketCollectors/PacketSniffers");
		this.setIconImage(Utility.loadFile("images/smartHome_icon.png"));
		getContentPane().setLayout(null);
		
		list = null;

		JButton btnImportAlgorithm = new JButton("Create Collector");
		btnImportAlgorithm.setToolTipText("Create a new PacketCollector which will collect packets");
		btnImportAlgorithm.setBounds(220, 130, 160, 25);
		getContentPane().add(btnImportAlgorithm);
		btnImportAlgorithm.addActionListener(a->{
			if(mutex)
				return;
			EditPacketSniffer popUp = new EditPacketSniffer(controller, that, new PacketCollector(), false); 
			popUp.setEnabled(true);
			popUp.setVisible(true);
		});
		
		JButton btnRemoveSelected = new JButton("Remove Selected");
		btnRemoveSelected.setToolTipText("Remove the selected PacketCollector, it will no longer collect packets");
		btnRemoveSelected.setBounds(220, 160, 160, 25);
		getContentPane().add(btnRemoveSelected);
		btnRemoveSelected.addActionListener(a->{
			if(mutex)
				return;
			/**
			 * Selected Index
			 */
			int index = list.getSelectedIndex();
			if(index<0||index>=captureController.getPacketCollectors().size())
				return;
			/**
			 * PacketCollector which should be removed
			 */
			PacketCollector p = null;
			Iterator<PacketCollector> it = captureController.getPacketCollectors().iterator();
			for(int i = 0; i<index&&it.hasNext();i++){
				it.next();
			}
			if(it.hasNext()){
				p=it.next();
				captureController.removePacketCollector(p);
			}
		});
		
		JButton btnEditSelected = new JButton("Edit Selected");
		btnEditSelected.setToolTipText("Edit the selected PacketCollector");
		btnEditSelected.setBounds(220, 190, 160, 25);
		btnEditSelected.addActionListener(a->{
			if(mutex)
				return;
			/**
			 * Selected Index
			 */
			int index = list.getSelectedIndex();
			if(index<0||index>=captureController.getPacketCollectors().size())
				return;
			/**
			 * PacketCollector which should be edited
			 */
			PacketCollector p = null;
			Iterator<PacketCollector> it = captureController.getPacketCollectors().iterator();
			for(int i = 0; i<index&&it.hasNext();i++){
				it.next();
			}
			if(it.hasNext()){
				p=it.next();
				EditPacketSniffer popUp =new EditPacketSniffer(controller, that, p,true);
				popUp.setEnabled(true);
				popUp.setVisible(true);
			}
			
		});
		getContentPane().add(btnEditSelected);
		
		scrollPanelList = new JScrollPane();
		scrollPanelList.setBounds(0, 0, 205, 375);
		getContentPane().add(scrollPanelList);
		
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				captureController.removeObserver(that);
			}
		});
		update(null,null);
		this.setResizable(false);
		this.setLocationRelativeTo(parent);
		this.setEnabled(true);
		this.setVisible(true);
	}

	@Override
	public void update(Observable o, Object arg) {
		mutex = true;
		/**
		 * Update List
		 */
		/**
		 * Names of the collectors
		 */
		String[] collectorNames = new String[captureController.getPacketCollectors().size()];
		if(captureController.getPacketCollectors().size()!=0){
		Iterator<PacketCollector> it = captureController.getPacketCollectors().iterator();
			for(int i=0;i<captureController.getPacketCollectors().size();i++){
				if(it.hasNext()){
					PacketCollector p = it.next();
					if(p.getPacketAlgorithm()==null){
						collectorNames[i] = "Null";
					}else{
						collectorNames[i] = p.getPacketAlgorithm().getClass().getSimpleName();
					}
				}else{
					collectorNames[i] = "Invalid Size";
				}
			}
		}
		/**
		 * New list
		 */
		JList<String> newList = new JList<String>(collectorNames);
		newList.setToolTipText("List of all currently active PacketCollectos/PacketSniffers.");
		newList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		int pos = scrollPanelList.getVerticalScrollBar().getValue();

		if(list!=null){
			scrollPanelList.remove(list);
			newList.setSelectedIndex(list.getSelectedIndex());		
		}
		scrollPanelList.setViewportView(newList);
		scrollPanelList.getVerticalScrollBar().setValue(pos);
		list = newList;
		
		this.repaint();
		mutex = false;
		
	}
}
