package smart_gs.swingui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
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.Preference;
import smart_gs.logical.ResourceBasket;
import smart_gs.logical.SpreadTree;
import smart_gs.menu.action.ResourceListSelectionFrame;
import smart_gs.reasoning_web.logical.GS_RWRepository;

public class ResourceBasketsFrame extends JFrame 
	implements ListSelectionListener, MouseListener, ChangeListener {

	private static ResourceBasketsFrame singleton = new ResourceBasketsFrame();

	private GSResource resource;
	private ResourceList list;
	private Point clickedPoint;
	private ResourceBasket selectedBasket;
	private List<ResourceListSelectionFrame> selectionFrames;
	private JTextArea statusBar;

	private JCheckBox alwaysOnTop;

	public ResourceBasketsFrame() {
		super("Resource Baskets");
		JPanel panel = (JPanel) this.getContentPane();
		this.synchronizeWithRWRepository();
		this.setSize(new Dimension(300,300));
		this.setMaximumSize(new Dimension(300,1000));
		int size = this.list.getLength();
		list.addListSelectionListener(this);
		list.addMouseListener(this);
		list.setVisibleRowCount(20);
		JScrollPane sPane = new JScrollPane(list);
	    panel.add(sPane);
		JTextField textField = new JTextField("Resource Basket " + (size + 1));
		panel.add(textField);
		JButton createButton = new JButton("New Basket");
		createButton.addActionListener(new CreateResourceBasket(this, textField));
		panel.add(createButton);
		
		this.statusBar = new JTextArea("");
		this.statusBar.setLineWrap(true);
		this.statusBar.setEditable(false);
		this.statusBar.setBackground(this.getBackground());
		this.statusBar.setFont(new Font(null, Font.BOLD, 11));
		panel.add(this.statusBar);
		
	    this.alwaysOnTop = new JCheckBox("Always on top", true);
	    this.setAlwaysOnTop(this.alwaysOnTop.isSelected());
	    this.alwaysOnTop.addChangeListener(this);
	    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(createButton)
				.addComponent(textField)
				.addComponent(this.statusBar)
				.addComponent(this.alwaysOnTop)
			)
		);
	
	
		layout.setVerticalGroup(layout.createSequentialGroup()
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(sPane))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(createButton))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(textField))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.statusBar))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
					.addComponent(this.alwaysOnTop)
			)
		);
		this.selectionFrames = new ArrayList<ResourceListSelectionFrame>();
	}

	public void synchronizeWithRWRepository() {
		List<GSResource> baskets = GS_RWRepository.getInstance().getResourceBaskets();
		if (baskets == null) {
			baskets = new ArrayList<GSResource>();
		}
		if (this.list == null) {
			this.list = new ResourceList(baskets);
		} else {
			this.list.setResources(baskets);
		}
		this.repaint();
	}
	public static ResourceBasketsFrame getInstance() {
		return singleton;
	}
	
	public void createAndAddResourceListSelectionFrame(ResourceBasket basket) {
		ResourceListSelectionFrame sFrame = new ResourceListSelectionFrame(basket);
		singleton.selectionFrames.add(sFrame);
		sFrame.showResourceSelectionFrame();
	}
	
	public boolean opened(ResourceBasket basket) {
		for (int i = 0; i < this.selectionFrames.size(); i++) {
			if (this.selectionFrames.get(i).getBasket().equals(basket)) {
				return true;
			}
		}
		return false;
	}
	public ResourceListSelectionFrame getSelectionFrame(ResourceBasket basket) {
		for (int i = 0; i < this.selectionFrames.size(); i++) {
			if (this.selectionFrames.get(i).getBasket().equals(basket)) {
				return this.selectionFrames.get(i);
			}
		}
		this.selectionFrames.add(new ResourceListSelectionFrame(basket));
		return this.selectionFrames.get(this.selectionFrames.size()-1);
	}

	
	@Override
	public void valueChanged(ListSelectionEvent arg0) {
		this.selectedBasket = ((ResourceBasket) list.getSelectedValue());
	}

	public void showResourceBasketFrame() {
		this.synchronizeWithRWRepository();
		this.setVisible(true);
		this.setAlwaysOnTop(true);
	}
	
	class CreateResourceBasket implements ActionListener {
		
		ResourceBasketsFrame frame;
		JTextField textField;
		
		CreateResourceBasket(ResourceBasketsFrame frame, JTextField textField) {
			this.frame = frame;
			this.textField = textField;
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			ArrayList<GSResource> resources = new ArrayList<GSResource>();
			ResourceBasket basket = new ResourceBasket(resources, this.textField.getText());
			basket.setToBeSaved(new Boolean(Preference.getInstance().getResourceBasketSaveOption()));
			if (frame.resource != null) {
				basket.addResource(frame.resource);
			}
			GS_RWRepository.getInstance().addResourceBasket(basket);
			this.textField.setText("Resource Basket " + (GS_RWRepository.getInstance().getResourceBaskets().size() + 1));
			((DefaultListModel)this.frame.list.getModel()).addElement((GSResource)basket);
			this.frame.synchronizeWithRWRepository();
			this.frame.repaint();
		}
	}

	public void setResource(GSResource resource) {
		this.resource = resource;
		this.statusBar.setText("Add: " + resource.toString());
		this.repaint();
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		if (this.selectedBasket != null) {
			if (this.resource != null) {
				this.selectedBasket.addResource(this.resource);
				this.resource = null;
				this.statusBar.setText("");
				ResourceListSelectionFrame frame = this.getSelectionFrame(this.selectedBasket);
				frame.setBasket(this.selectedBasket);
				this.repaint();
			} else {
				this.clickedPoint = arg0.getPoint();
				ResourceBasketSelectionPopupMenu menu = new ResourceBasketSelectionPopupMenu(this);
				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 ResourceBasketSelectionPopupMenu extends JPopupMenu {
		ResourceBasketSelectionPopupMenu(ResourceBasketsFrame frame) {
			if (resource == null) { 
				JMenuItem openItem = new JMenuItem("Open");
				openItem.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						if (singleton.opened(singleton.selectedBasket)) {
							singleton.getSelectionFrame(singleton.selectedBasket).showResourceSelectionFrame();
						} else {
							singleton.createAndAddResourceListSelectionFrame(singleton.selectedBasket);
						}
					}});
				JMenuItem deleteItem = new JMenuItem("Delete");
				deleteItem.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						GS_RWRepository.getInstance().getResourceBaskets().remove(singleton.selectedBasket);
						singleton.synchronizeWithRWRepository();
					}});
				JMenuItem changeNameItem = new JMenuItem("Change Name");
				changeNameItem.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent arg0) {
						String oldName = singleton.selectedBasket.getName();
						String newName = JOptionPane.showInputDialog("New Name", oldName);
						if (newName == null) {
							newName = oldName;
						} else if (newName.equals("")) {
							newName = "UNTITLED";
						}
						singleton.selectedBasket.setName(newName);
					}
				});
				this.add(openItem);
				this.add(deleteItem);
				this.add(changeNameItem);
			} else {
				selectedBasket.addResource(resource);
				resource = null;
			}
		}
	}
	public static void renew() {
		singleton.dispose();
		singleton = new ResourceBasketsFrame();
	}
	@Override
	public void stateChanged(ChangeEvent arg0) {
		this.setAlwaysOnTop(this.alwaysOnTop.isSelected());
	}
}
