/* File: EditPermissionsPane.java
 * Author: Jason Gookins
 * Description: Allows an admin to alter the permissions of a network or view.
 */

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;

public class EditPermissionsPane extends JPanel implements ActionListener
{
	/************************
	 ** Instance Variables **
	 ************************/

	private Belief belief;
	private JRadioButton networksRadioButton, viewsRadioButton, publicRadioButton, privateRadioButton;
	private DefaultListModel networkList, viewList;
	private JList networkListDisplay, viewListDisplay;
	private JButton selectButton, removeButton, okayButton, cancelButton;
	private JLabel targetNameLabel, currentAccessLabel, futureAccessLabel;
	private String type;



	/**********************
	 ** Main Constructor **
	 **********************/

	public EditPermissionsPane(Belief belief)
	{
		this.belief = belief;

		setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();

		JLabel editPermissionsLabel = new JLabel("Edit Permissions", JLabel.CENTER);
		editPermissionsLabel.setFont(new Font("SansSerif", Font.PLAIN, 20));
		editPermissionsLabel.setPreferredSize(new Dimension(200, 60));
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 2;
		c.gridheight = 1;
		c.fill = GridBagConstraints.BOTH;
		add(editPermissionsLabel, c);

		ButtonGroup objectGroup = new ButtonGroup();

		networksRadioButton = new JRadioButton("Networks");
		networksRadioButton.setSelected(true);
		networksRadioButton.addActionListener(this);
		c.gridy = 1;
		c.gridwidth = 1;
		c.insets = new Insets(5, 5, 5, 5);
		c.fill = GridBagConstraints.NONE;
		objectGroup.add(networksRadioButton);
		add(networksRadioButton, c);

		viewsRadioButton = new JRadioButton("Views");
		viewsRadioButton.addActionListener(this);
		c.gridx = 1;
		objectGroup.add(viewsRadioButton);
		add(viewsRadioButton, c);

		JPanel networksPanel = new JPanel(new GridBagLayout());
		networksPanel.setPreferredSize(new Dimension(170, 125));
		networksPanel.setMinimumSize(new Dimension(170, 125));
		GridBagConstraints d = new GridBagConstraints();

		JPanel networkListPanel = new JPanel(new GridBagLayout());

		networkList = new DefaultListModel();
		networkListDisplay = new JList(networkList);
		networkListDisplay.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		d.weightx = 1.0;
		d.weighty = 1.0;
		d.fill = GridBagConstraints.BOTH;
		networkListPanel.add(networkListDisplay, d);

		JScrollPane networkListScrollPane = new JScrollPane(networkListPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		networksPanel.add(networkListScrollPane, d);

		c.gridx = 0;
		c.gridy = 2;
		add(networksPanel, c);

		JPanel viewsPanel = new JPanel(new GridBagLayout());
		viewsPanel.setPreferredSize(new Dimension(170, 125));
		viewsPanel.setMinimumSize(new Dimension(170, 125));

		JPanel viewListPanel = new JPanel(new GridBagLayout());

		viewList = new DefaultListModel();
		viewListDisplay = new JList(viewList);
		viewListDisplay.setEnabled(false);
		viewListDisplay.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		viewListPanel.add(viewListDisplay, d);

		JScrollPane viewListScrollPane = new JScrollPane(networkListPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		viewsPanel.add(viewListScrollPane, d);

		c.gridx = 1;
		add(viewsPanel, c);

		selectButton = new JButton("v  v  v");
		selectButton.setMargin(new Insets(0, 0, 0, 0));
		selectButton.setPreferredSize(new Dimension(75, 30));
		selectButton.setMinimumSize(new Dimension(75, 30));
		selectButton.addActionListener(this);
		c.gridx = 0;
		c.gridy = 3;
		c.insets = new Insets(5, 0, 5, 5);
		c.anchor = GridBagConstraints.EAST;
		add(selectButton, c);

		removeButton = new JButton("^  ^  ^");
		removeButton.setEnabled(false);
		removeButton.setMargin(new Insets(0, 0, 0, 0));
		removeButton.setPreferredSize(new Dimension(75, 30));
		removeButton.setMinimumSize(new Dimension(75, 30));
		removeButton.addActionListener(this);
		c.gridx = 1;
		c.insets = new Insets(5, 5, 5, 0);
		c.anchor = GridBagConstraints.WEST;
		add(removeButton, c);

		JPanel targetPanel = new JPanel(new GridBagLayout());

		JLabel targetLabel = new JLabel("Target:", JLabel.RIGHT);
		targetLabel.setPreferredSize(new Dimension(75, 20));
		targetLabel.setMinimumSize(new Dimension(75, 20));
		d.weightx = 0.0;
		d.weighty = 0.0;
		d.fill = GridBagConstraints.NONE;
		d.insets = new Insets(5, 0, 5, 5);
		d.anchor = GridBagConstraints.EAST;
		targetPanel.add(targetLabel, d);

		JLabel currentlyLabel = new JLabel("Currently:", JLabel.RIGHT);
		currentlyLabel.setPreferredSize(new Dimension(75, 20));
		currentlyLabel.setMinimumSize(new Dimension(75, 20));
		d.gridy = 1;
		targetPanel.add(currentlyLabel, d);

		JLabel willBeLabel = new JLabel("Will Be:", JLabel.RIGHT);
		willBeLabel.setPreferredSize(new Dimension(75, 20));
		willBeLabel.setMinimumSize(new Dimension(75, 20));
		d.gridy = 2;
		targetPanel.add(willBeLabel, d);

		targetNameLabel = new JLabel();
		targetNameLabel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.BLACK), BorderFactory.createEmptyBorder(0, 3, 0, 3)));
		targetNameLabel.setBackground(Color.WHITE);
		targetNameLabel.setPreferredSize(new Dimension(200, 20));
		targetNameLabel.setMinimumSize(new Dimension(200, 20));
		d.gridx = 1;
		d.gridy = 0;
		d.insets = new Insets(5, 5, 5, 0);
		d.anchor = GridBagConstraints.WEST;
		targetPanel.add(targetNameLabel, d);

		currentAccessLabel = new JLabel();
		currentAccessLabel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.BLACK), BorderFactory.createEmptyBorder(0, 3, 0, 3)));
		currentAccessLabel.setBackground(Color.WHITE);
		currentAccessLabel.setPreferredSize(new Dimension(200, 20));
		currentAccessLabel.setMinimumSize(new Dimension(200, 20));
		d.gridy = 1;
		targetPanel.add(currentAccessLabel, d);

		futureAccessLabel = new JLabel();
		futureAccessLabel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.BLACK), BorderFactory.createEmptyBorder(0, 3, 0, 3)));
		futureAccessLabel.setBackground(Color.WHITE);
		futureAccessLabel.setPreferredSize(new Dimension(200, 20));
		futureAccessLabel.setMinimumSize(new Dimension(200, 20));
		d.gridy = 2;
		targetPanel.add(futureAccessLabel, d);

		c.gridx = 0;
		c.gridy = 4;
		c.gridwidth = 2;
		c.insets = new Insets(5, 5, 5, 5);
		c.anchor = GridBagConstraints.CENTER;
		add(targetPanel, c);

		okayButton = new JButton("Okay");
		okayButton.setEnabled(false);
		okayButton.setPreferredSize(new Dimension(75, 30));
		okayButton.setMinimumSize(new Dimension(75, 30));
		okayButton.addActionListener(this);
		c.gridy = 5;
		c.gridwidth = 1;
		c.insets = new Insets(10, 0, 0, 5);
		c.fill = GridBagConstraints.NONE;
		c.anchor = GridBagConstraints.EAST;
		add(okayButton, c);

		cancelButton = new JButton("Cancel");
		cancelButton.setPreferredSize(new Dimension(75, 30));
		cancelButton.setMinimumSize(new Dimension(75, 30));
		cancelButton.addActionListener(this);
		c.gridx = 1;
		c.insets = new Insets(10, 5, 0, 0);
		c.anchor = GridBagConstraints.WEST;
		add(cancelButton, c);
	}



	/*******************
	 ** Action Events **
	 *******************/

	public void actionPerformed(ActionEvent evt)
	{
		if (evt.getSource().equals(networksRadioButton))
		{
			networkListDisplay.setEnabled(true);
			viewListDisplay.setEnabled(false);
		}
		else if (evt.getSource().equals(viewsRadioButton))
		{
			networkListDisplay.setEnabled(false);
			viewListDisplay.setEnabled(true);
		}
		else if (evt.getSource().equals(selectButton))
		{
			selectItem();
		}
		else if (evt.getSource().equals(removeButton))
		{
			removeItem();
		}
		else if (evt.getSource().equals(okayButton))
		{
			editPermissions();
		}
		else if (evt.getSource().equals(cancelButton))
		{
			returnToAdminChoicePane();
		}
	}



	/**********************
	 ** Instance Methods **
	 **********************/

	public void initialize()
	{
		try
		{
			Class.forName("org.sqlite.JDBC");
			Connection conn = DriverManager.getConnection("jdbc:sqlite:belief.db");
			Statement statement = conn.createStatement();
			ResultSet rs = statement.executeQuery("SELECT name FROM networks");
			ArrayList<String> networks = new ArrayList<String>();
			ArrayList<String> views = new ArrayList<String>();

			while (rs.next())
			{
				networks.add(rs.getString("name"));
			}

			Collections.sort(networks);
			networkList = new DefaultListModel();

			for (int i = 0; i < networks.size(); i++)
			{
				networkList.addElement(networks.get(i));
			}

			rs = statement.executeQuery("SELECT name FROM views");

			while (rs.next())
			{
				views.add(rs.getString("name"));
			}

			rs.close();
			conn.close();

			Collections.sort(views);
			viewList = new DefaultListModel();

			for (int i = 0; i < views.size(); i++)
			{
				viewList.addElement(views.get(i));
			}

			networksRadioButton.setSelected(true);
			networkListDisplay.setEnabled(true);
			networkListDisplay.setModel(networkList);
			viewListDisplay.setEnabled(false);
			viewListDisplay.setModel(viewList);
			selectButton.setEnabled(true);
			removeButton.setEnabled(false);
			targetNameLabel.setText(null);
			currentAccessLabel.setText(null);
			futureAccessLabel.setText(null);
			okayButton.setEnabled(false);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	private void selectItem()
	{
		try
		{
			String item = null;
			Class.forName("org.sqlite.JDBC");
			Connection conn = DriverManager.getConnection("jdbc:sqlite:belief.db");
			Statement statement = conn.createStatement();
			ResultSet rs;

			if (networksRadioButton.isSelected() && networkListDisplay.getSelectedIndex() > -1)
			{
				type = "networks";
				item = (String)networkListDisplay.getSelectedValue();
				networkList.remove(networkList.indexOf(item));
				rs = statement.executeQuery("SELECT access_level FROM networks WHERE name = '" + item + "'");
				currentAccessLabel.setText(rs.getString("access_level"));

				if (currentAccessLabel.getText().equals("public"))
				{
					futureAccessLabel.setText("private");
				}
				else
				{
					futureAccessLabel.setText("public");
				}

				rs.close();
				conn.close();

				networksRadioButton.setEnabled(false);
				viewsRadioButton.setEnabled(false);
				networkListDisplay.setEnabled(false);
				viewListDisplay.setEnabled(false);
				selectButton.setEnabled(false);
				removeButton.setEnabled(true);
				targetNameLabel.setText(item);
				okayButton.setEnabled(true);
			}
			else if (viewsRadioButton.isSelected() && networkListDisplay.getSelectedIndex() > -1)
			{
				type = "views";
				item = (String)viewListDisplay.getSelectedValue();
				viewList.remove(viewList.indexOf(item));
				rs = statement.executeQuery("SELECT access_level FROM views WHERE name = '" + item + "'");
				currentAccessLabel.setText(rs.getString("access_level"));

				if (currentAccessLabel.getText().equals("public"))
				{
					futureAccessLabel.setText("private");
				}
				else
				{
					futureAccessLabel.setText("public");
				}

				rs.close();
				conn.close();

				networksRadioButton.setEnabled(false);
				viewsRadioButton.setEnabled(false);
				networkListDisplay.setEnabled(false);
				viewListDisplay.setEnabled(false);
				selectButton.setEnabled(false);
				removeButton.setEnabled(true);
				targetNameLabel.setText(item);
				okayButton.setEnabled(true);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	private void removeItem()
	{
		String item = targetNameLabel.getText();
		ArrayList<String> items = new ArrayList<String>();

		if (networksRadioButton.isSelected())
		{
			for (int i = 0; i < networkList.size(); i++)
			{
				items.add((String)networkList.get(i));
			}
			items.add(item);

			Collections.sort(items);
			networkList = new DefaultListModel();

			for (int i = 0; i < items.size(); i++)
			{
				networkList.addElement(items.get(i));
			}

			networkListDisplay.setModel(networkList);
			networkListDisplay.setEnabled(true);
		}
		else
		{
			for (int i = 0; i < viewList.size(); i++)
			{
				items.add((String)viewList.get(i));
			}
			items.add(item);

			Collections.sort(items);
			viewList = new DefaultListModel();

			for (int i = 0; i < items.size(); i++)
			{
				viewList.addElement(items.get(i));
			}

			viewListDisplay.setModel(viewList);
			viewListDisplay.setEnabled(true);
		}

		networksRadioButton.setEnabled(true);
		viewsRadioButton.setEnabled(true);
		selectButton.setEnabled(true);
		removeButton.setEnabled(false);
		targetNameLabel.setText(null);
		currentAccessLabel.setText(null);
		futureAccessLabel.setText(null);
		okayButton.setEnabled(false);
	}

	private void editPermissions()
	{
		try
		{
			Class.forName("org.sqlite.JDBC");
			Connection conn = DriverManager.getConnection("jdbc:sqlite:belief.db");
			Statement stat = conn.createStatement();

			stat.execute("UPDATE " + type + " SET access_level = '" + futureAccessLabel.getText() + "' WHERE name = '" + targetNameLabel.getText() + "'");

			conn.close();

			EditPermissionsDialog editPermissionsDialog = new EditPermissionsDialog("Belief", new JOptionPane("Permissions edited successfully.", JOptionPane.INFORMATION_MESSAGE));
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	private void returnToAdminChoicePane()
	{
		CardLayout mainLayout = (CardLayout)belief.getContentPane().getLayout();

		mainLayout.show(belief.getContentPane(), "adminChoicePane");
	}



	/**********************
	 ** Internal Classes **
	 **********************/

	private class EditPermissionsDialog extends InternalModalDialog
	{
		public EditPermissionsDialog(String title, JOptionPane pane)
		{
			super(title, belief, pane);
		}

		public void cleanUpAfterClosing()
		{
			returnToAdminChoicePane();
		}
	}
}