package ui.view;

import java.awt.BorderLayout;

import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import classes.AbstractCpsObject;

import javax.swing.JLabel;

import java.awt.Font;

import javax.swing.ButtonGroup;
import javax.swing.JTextField;
import javax.swing.JRadioButton;
import javax.swing.JButton;

import ui.controller.Control;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.awt.event.ActionEvent;

/**
 * This Class represents a popup to seatch for Objects on the Canvas.
 * 
 * @author Gruppe14
 */
public class SearchPopUp extends JDialog {

	private static final long serialVersionUID = 1L;
	private final JPanel contentPanel = new JPanel();
	private JTextField replaceTextField;
	private JTextField findTextField;
	private Control controller;
	private MyCanvas canvas;
	private JRadioButton rdbtnForward;
	private JRadioButton rdbtnBackward;
	private JRadioButton rdbtnAll;
	private JRadioButton rdbtnSingle;
	private int idx;

	/**
	 * Constructor.
	 * @param contr Controller
	 * @param can Canvas
	 */
	SearchPopUp(Control contr, MyCanvas can) {
		super((java.awt.Frame) null, true);
		idx = -1;
		setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL);
		this.setTitle("Search for Objects");
		setBounds(100, 100, 238, 360);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(null);

		this.controller = contr;
		this.canvas = can;

		JLabel lblFind = new JLabel("Find:");
		lblFind.setFont(new Font("Tahoma", Font.PLAIN, 13));
		lblFind.setBounds(10, 11, 46, 19);
		contentPanel.add(lblFind);

		JLabel lblReplace = new JLabel("Replace:");
		lblReplace.setFont(new Font("Tahoma", Font.PLAIN, 13));
		lblReplace.setBounds(10, 41, 56, 14);
		contentPanel.add(lblReplace);

		// ReplaceTest
		replaceTextField = new JTextField();
		replaceTextField.setBounds(76, 39, 101, 20);
		contentPanel.add(replaceTextField);
		replaceTextField.setColumns(10);

		// FindText
		findTextField = new JTextField();
		findTextField.setBounds(76, 11, 101, 20);
		contentPanel.add(findTextField);
		findTextField.setColumns(10);

		JLabel lblNewLabel = new JLabel("Direction");
		lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 13));
		lblNewLabel.setBounds(10, 90, 82, 14);
		contentPanel.add(lblNewLabel);

		rdbtnForward = new JRadioButton("Forward");
		rdbtnForward.setFont(new Font("Tahoma", Font.PLAIN, 13));
		rdbtnForward.setBounds(10, 111, 109, 23);
		contentPanel.add(rdbtnForward);
		rdbtnForward.setSelected(true);

		rdbtnBackward = new JRadioButton("Backward");
		rdbtnBackward.setFont(new Font("Tahoma", Font.PLAIN, 13));
		rdbtnBackward.setBounds(10, 137, 109, 23);
		contentPanel.add(rdbtnBackward);

		JLabel lblScope = new JLabel("Scope");
		lblScope.setFont(new Font("Tahoma", Font.BOLD, 13));
		lblScope.setBounds(122, 90, 46, 14);
		contentPanel.add(lblScope);

		rdbtnAll = new JRadioButton("All");
		rdbtnAll.setFont(new Font("Tahoma", Font.PLAIN, 13));
		rdbtnAll.setBounds(121, 112, 109, 23);
		contentPanel.add(rdbtnAll);
		rdbtnAll.setSelected(true);

		rdbtnSingle = new JRadioButton("Single");
		rdbtnSingle.setFont(new Font("Tahoma", Font.PLAIN, 13));
		rdbtnSingle.setBounds(121, 138, 109, 23);
		contentPanel.add(rdbtnSingle);

		// FindButton
		JButton btnFind = new JButton("Find");
		btnFind.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (rdbtnAll.isSelected()) {
					for (AbstractCpsObject cps : controller.getModel().getObjectsOnCanvas()) {

						if (cps.getName().equals(findTextField.getText())
								&& !controller.getModel().getSelectedCpsObjects().contains(cps)) {
							controller.getModel().getSelectedCpsObjects().add(cps);
						}

					}

				}
				if (rdbtnSingle.isSelected()) {
					controller.getModel().getSelectedCpsObjects().clear();

					if (!controller.getModel().getObjectsOnCanvas().isEmpty() && !findTextField.getText().isEmpty()) {

						if (rdbtnForward.isSelected()) {
							if ((idx = getNext(++idx)) != -1)
								controller.getModel().getSelectedCpsObjects().add(getObj(idx));
						} else if (rdbtnBackward.isSelected()) {
							if ((idx = getPrev(--idx)) != -1)
								controller.getModel().getSelectedCpsObjects().add(getObj(idx));
						}
					}

				}

				canvas.repaint();
			}
		});
		btnFind.setFont(new Font("Tahoma", Font.PLAIN, 13));
		btnFind.setBounds(10, 186, 89, 23);
		contentPanel.add(btnFind);

		// ReplaceButton
		JButton btnReplace = new JButton("Replace");
		btnReplace.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				if (controller.getModel().getSelectedCpsObjects().size() == 1 && controller.getModel()
						.getSelectedCpsObjects().get(0).getName().equals(findTextField.getText()))
					controller.getModel().getSelectedCpsObjects().get(0).setName(replaceTextField.getText());
				canvas.repaint();
			}
		});
		btnReplace.setFont(new Font("Tahoma", Font.PLAIN, 13));
		btnReplace.setBounds(110, 187, 89, 23);
		contentPanel.add(btnReplace);

		// ReplaceAllButton
		JButton btnReplaceAll = new JButton("Replace All");
		btnReplaceAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				canvas.tempCps = null;
				canvas.tempSelected = new ArrayList<>();
				controller.getModel().getSelectedCpsObjects().clear();

				for (AbstractCpsObject cps : controller.getModel().getObjectsOnCanvas()) {
					if (cps.getName().equals(findTextField.getText())
							&& !controller.getModel().getSelectedCpsObjects().contains(cps))
						selectObj(cps);
				}

				for (AbstractCpsObject cps : controller.getModel().getSelectedCpsObjects()) {
					renameObj(cps, replaceTextField.getText());
				}

				canvas.repaint();
			}
		});
		btnReplaceAll.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnReplaceAll.setBounds(110, 218, 89, 23);
		contentPanel.add(btnReplaceAll);

		// CloseButton
		JButton btnClose = new JButton("Close");
		btnClose.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				dispose();
			}
		});
		btnClose.setFont(new Font("Tahoma", Font.PLAIN, 13));
		btnClose.setBounds(110, 287, 89, 23);
		contentPanel.add(btnClose);

		ButtonGroup directionbtns = new ButtonGroup();
		ButtonGroup scopebtns = new ButtonGroup();

		directionbtns.add(rdbtnBackward);
		directionbtns.add(rdbtnForward);
		scopebtns.add(rdbtnSingle);
		scopebtns.add(rdbtnAll);

	}

	/**
	 * add the searched Objects to the Selected Objects.
	 * @param obj The Object
	 */
	public void selectObj(AbstractCpsObject obj) {
		controller.getModel().getSelectedCpsObjects().add(obj);
	}

	/**
	 * Rename an Object.
	 * 
	 * @param obj the Object
 	 * @param name the new name
	 */
	public void renameObj(AbstractCpsObject obj, String name) {
		obj.setName(name);
	}

	/**
	 * get the Object with the specific ID.
	 * 
	 * @param idx the ID
	 * @return the Object with that ID
	 */
	public AbstractCpsObject getObj(int idx) {
		return controller.getModel().getObjectsOnCanvas().get(idx);
	}

	/**
	 * Get the next Object ID.
	 * 
	 * @param idx the Index
	 * @return the next Index
	 */
	public int getNext(int idx) {
		for (int i = idx; i < controller.getModel().getObjectsOnCanvas().size(); i++) {
			if (getObj(i).getName().equals(findTextField.getText())
					&& !controller.getModel().getSelectedCpsObjects().contains(getObj(i)))
				return i;
		}
		for (int i = 0; i < idx; i++) {
			if (getObj(i).getName().equals(findTextField.getText())
					&& !controller.getModel().getSelectedCpsObjects().contains(getObj(i)))
				return i;
		}
		return -1;
	}

	/**
	 * Get the previous Index.
	 * 
	 * @param idx the Index
	 * @return the previousIndex
	 */
	public int getPrev(int idx) {
		for (int i = idx; i >= 0; i--) {
			if (getObj(i).getName().equals(findTextField.getText())
					&& !controller.getModel().getSelectedCpsObjects().contains(getObj(i)))
				return i;
		}
		for (int i = controller.getModel().getObjectsOnCanvas().size() - 1; i > idx; i--) {
			if (getObj(i).getName().equals(findTextField.getText())
					&& !controller.getModel().getSelectedCpsObjects().contains(getObj(i)))
				return i;
		}
		return -1;
	}
}
