package smart_gs.menu.action;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.MenuElement;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import smart_gs.debugprint.Debugprint;
import smart_gs.logical.GSResource;
import smart_gs.logical.ResourceBasket;
import smart_gs.logical.Markup;
import smart_gs.logical.TextSegment;
import smart_gs.logical.URIObject;
import smart_gs.reasoning_web.logical.GS_RWRepository;
import smart_gs.swingui.ResourceBasketsFrame;
import smart_gs.swingui.ResourceList;
import smart_gs.swingui.WorkspaceWindow;

@SuppressWarnings("serial")
public class ResourceListSelectionFrame extends JFrame
	implements ListSelectionListener, MouseListener, WindowListener, ChangeListener{

	private ResourceList list;
	private String name;
	private ResourceBasket basket;
	private GSResource selectedResource;
	private Point clickedPoint;
	private boolean isBookmarkList = false;
	private JCheckBox save;
	private JCheckBox alwaysOnTop;
	
	public ResourceListSelectionFrame(ResourceBasket basket) {
		super(basket.getName());
		this.basket = basket;
		this.list = new ResourceList(basket.getResources());
		this.list.addMouseListener(this);
		this.setName(basket.getName());
		this.list.setVisibleRowCount(10);
		JScrollPane sPane = new JScrollPane(list);
		this.setBounds(350,200,300,300);
	    this.list.addListSelectionListener((ListSelectionListener)this);
	    this.addWindowListener(this);
	    this.save = new JCheckBox("Save this list", basket.toBeSaved());
	    this.save.addChangeListener(this);
	    this.alwaysOnTop = new JCheckBox("Always on top", true);
	    this.alwaysOnTop.addChangeListener(this);
		JPanel panel = (JPanel) this.getContentPane();
		panel.add(sPane);
		panel.add(this.save);
		panel.add(this.alwaysOnTop);
		
		GroupLayout layout = new GroupLayout(panel);
		panel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);
		
		layout.setHorizontalGroup(layout.createSequentialGroup()
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(sPane)
				.addComponent(this.save)
				.addComponent(this.alwaysOnTop)
			)
		);


		layout.setVerticalGroup(layout.createSequentialGroup()
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(sPane))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.save))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.alwaysOnTop)
			)
		);

	}
	
	public ResourceListSelectionFrame(ResourceBasket resourceBasket,
			boolean isBookmarkList) {
		this(resourceBasket);
		this.remove(this.save);
		this.isBookmarkList = isBookmarkList;
	}

	public void showResourceSelectionFrame() {
	    this.setVisible(true);
	    this.setAlwaysOnTop(this.alwaysOnTop.isSelected());
	}
	public void update() {
		DefaultListModel model = new DefaultListModel();			
		for (int i = 0; i < this.basket.getResources().size(); i++) {
			model.addElement(this.basket.getResources().get(i));
		}
		this.list.setModel(model);
		this.repaint();
		this.showResourceSelectionFrame();
	}

	@Override
	public void valueChanged(ListSelectionEvent e) {
			this.selectedResource = (GSResource)list.getSelectedValue();
	}

	
	public String getName() {
		return this.name;
	}
	
	@Override
	public void mouseClicked(MouseEvent arg0) {
		this.clickedPoint = arg0.getPoint();
		GSResourceListSelectionPopupMenu menu = new GSResourceListSelectionPopupMenu(this.selectedResource, this.isBookmarkList);
		menu.show(this.list,this.clickedPoint.x,this.clickedPoint.y);		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	class GSResourceListSelectionPopupMenu extends JPopupMenu {
		
		public GSResourceListSelectionPopupMenu(GSResource resource, boolean isBookmarkList) {
			if (resource == null) {
				return;
			}
			if (!resource.getTypeString().equals(URIObject.TEXT_SEGMENT)){
				JMenuItem jumpItem = new JMenuItem("Jump");
				jumpItem.addActionListener(new ResourceJumpActionListener(resource));
				this.add(jumpItem);
			} else {
				TextSegment segment = (TextSegment)resource;
				if (segment.getDocument().isIDAT()) {
					JMenuItem jumpItem = new JMenuItem("Jump");
					jumpItem.addActionListener(new ResourceJumpActionListener(resource));
					this.add(jumpItem);
				}
			}
			JMenuItem openItem = new JMenuItem("Open");
			openItem.addActionListener(new ResourceOpenActionListener(resource));
			JMenuItem deleteItem = new JMenuItem("Delete from List");
			deleteItem.addActionListener(new ResourceDeleteActionListener(resource, list, basket));
			this.add(openItem);
			if (!isBookmarkList) {
				this.add(deleteItem);
			}
		}
	}

	class ResourceJumpActionListener implements ActionListener {

		private GSResource resource;

		ResourceJumpActionListener(GSResource resource) {
			super();
			this.resource = resource;
		}
		
		@Override
		public void actionPerformed(ActionEvent arg0) {
			((Markup)this.resource).jump();
		}

	}
	
	class ResourceOpenActionListener implements ActionListener {

		private GSResource resource;

		ResourceOpenActionListener(GSResource resource) {
			super();
			this.resource = resource;
		}

		@Override
		public void actionPerformed(ActionEvent arg0) {
			((Markup)this.resource).openNewWindow();
		}
	}

	class ResourceDeleteActionListener implements ActionListener {

		private GSResource resource;
		private ResourceList list;
		private ResourceBasket basket;

		ResourceDeleteActionListener(GSResource resource, ResourceList list, ResourceBasket basket) {
			super();
			this.resource = resource;
			this.list = list;
			this.basket = basket;
		}

		@Override
		public void actionPerformed(ActionEvent arg0) {
			this.list.removeResource(this.resource);
			this.basket.removeResource(this.resource);
		}
	}

	public ResourceBasket getBasket() {
		return this.basket;
	}

	public void setBasket(ResourceBasket basket) {
		this.basket = basket;
		this.list.setResources(basket.getResources());
	}

	@Override
	public void windowActivated(WindowEvent arg0) {
	}

	@Override
	public void windowClosed(WindowEvent arg0) {
	}

	@Override
	public void windowClosing(WindowEvent arg0) {
		if (this.isBookmarkList) {
			return;
		}
		if (!this.save.isSelected()) {
			this.deleteFromRopository();
		}
	}

	private void deleteFromRopository() {
		ResourceBasket basket = this.getBasket();
		GS_RWRepository.getInstance().getResourceBaskets().remove(basket);
		ResourceBasketsFrame.getInstance().synchronizeWithRWRepository();
	}

	@Override
	public void windowDeactivated(WindowEvent arg0) {
	}

	@Override
	public void windowDeiconified(WindowEvent arg0) {
	}

	@Override
	public void windowIconified(WindowEvent arg0) {
	}

	@Override
	public void windowOpened(WindowEvent arg0) {
	}

	@Override
	public void stateChanged(ChangeEvent e) {
		if (e.getSource().equals(this.save)) {
			this.basket.setToBeSaved(this.save.isSelected());
			WorkspaceWindow.setUpdated(true);
		} else if (e.getSource().equals(this.alwaysOnTop)) {
			this.setAlwaysOnTop(this.alwaysOnTop.isSelected());
		}
	}

	public boolean getSaveOption() {
		return this.save.isSelected();
	}

}