package smart_gs.menu.action;

import java.awt.BorderLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
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 java.util.ArrayList;

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


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_RWElement;
import smart_gs.reasoning_web.logical.GS_RWRepository;
import smart_gs.reasoning_web.swingui.ResourceBasketPanel;
import smart_gs.swingui.ResourceBasketsFrame;
import smart_gs.swingui.ResourceList;
import smart_gs.swingui.SetIcon;
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 ResourceBasketPanel resourceBasketPanel;
	private GSResource selectedResource;
	private Point clickedPoint;
	private boolean isBookmarkList = false;
	private JCheckBox save;
	private JCheckBox alwaysOnTop;
	private JScrollPane scrollPane;
	private JPanel mainPanel;
	
	public ResourceListSelectionFrame(ResourceBasket basket) {
		super(basket.getName());
		SetIcon.setIcon(this);
		this.basket = basket;
		this.resourceBasketPanel = new ResourceBasketPanel(this.basket.getResources(),
				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);

	    this.scrollPane = new JScrollPane();
		this.scrollPane.getVerticalScrollBar().setUnitIncrement(25);
		this.scrollPane.setViewportView(this.resourceBasketPanel);
		
    	PointerInfo pointerInfo = MouseInfo.getPointerInfo();
    	Point p = pointerInfo.getLocation();
    	this.setLocation(p.x-WIDTH/2+25,p.y-HEIGHT+33);
	
		this.mainPanel = (JPanel) this.getContentPane();
		this.mainPanel.add(this.scrollPane,BorderLayout.CENTER);
		this.mainPanel.add(this.save);
		this.mainPanel.add(this.alwaysOnTop);
		
		this.arrange();
	}
	
	private void arrange() {
		GroupLayout layout = new GroupLayout(this.mainPanel);
		this.mainPanel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);
		
		layout.setHorizontalGroup(layout.createSequentialGroup()
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.scrollPane)
				.addComponent(this.save)
				.addComponent(this.alwaysOnTop)
			)
		);


		layout.setVerticalGroup(layout.createSequentialGroup()
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.scrollPane))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.save))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.alwaysOnTop)
			)
		);
		this.validate();
		this.pack();
	}
	
	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() {
		this.scrollPane.remove(this.resourceBasketPanel);
		this.resourceBasketPanel = new ResourceBasketPanel(this.basket.getResources(),
				this);
		this.scrollPane.add(this.resourceBasketPanel);
		this.scrollPane.setViewportView(this.resourceBasketPanel);
		
		
		this.arrange();

		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.resourceBasketPanel = new ResourceBasketPanel(this.basket.getResources(),
				this);
	}

	@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();
	}

	public void deleteElement(GS_RWElement element) {
		this.getBasket().removeResource((GSResource)element);
		this.update();
		WorkspaceWindow.setUpdated(true);
	}

}