package sim;

import java.awt.*;
import java.awt.event.*;

import sim.util.SimButtonListener;
import sim.util.SimButton;
import sim.lib.wires.Wire;

public class ToolbarListener extends SimButtonListener
{
	private boolean buttonUpOnLastMouseDown;
	private ModuleButton currentActive;
	private AddListener addHandler;
	private WireAddListener wireHandler;
	private EditListener editHandler;
	private ModuleButton editButton;
	
	public ToolbarListener()
	{
		this.editButton = new ModuleButton("sim/images/EditIcon.gif", "Select Components");
		this.currentActive = this.editButton;
		
		this.addHandler = new AddListener();
		this.wireHandler = new WireAddListener();
		this.editHandler = new EditListener();
		
		this.buttonUpOnLastMouseDown = true;
	}
	
	public EditListener getEditHandler()
	{
		return this.editHandler;
	}
	
	
	
	public void removeListeners()
	{
		if(this.currentActive != this.editButton)
			this.switchToEditMode();
		
		this.editHandler.deselect(true);
		
		CentralPanel.ACTIVE_GRID.removeMouseListener(this.editHandler);
		CentralPanel.ACTIVE_GRID.removeMouseMotionListener(this.editHandler);
	}
	
	public void initialiseListeners()
	{
		CentralPanel.ACTIVE_GRID.addMouseListener(this.editHandler);
		CentralPanel.ACTIVE_GRID.addMouseMotionListener(this.editHandler);
		
		SouthPanel.STATUS_BOX.setTitle("Edit mode", false);
	}
	
	public ModuleButton getEditButton()
	{
		return this.editButton;
	}
	
	public ModuleButton getCurrnetActive()
	{
		return this.currentActive;
	}
	
	public void actionPerformed(ActionEvent e)
	{
		ModuleButton source = (ModuleButton)e.getSource();
		
		if(source != this.currentActive)
		{
			if(this.currentActive == this.editButton)
				this.switchToAddMode(source);
			else if(source != this.editButton)
				this.changeStructure(source);
			else
				this.switchToEditMode();
		}
	}
	
	public void changeStructure(ModuleButton source)
	{
		this.currentActive.paintRaised();
		
		CreationModule structure = source.getStructure();
		
		if(structure instanceof Wire)
		{
			if(this.wireHandler.getStructure() != null)
			{
				if(CentralPanel.ACTIVE_GRID.isAncestorOf(this.wireHandler.getPrototype()))
					CentralPanel.ACTIVE_GRID.removeModule(this.wireHandler.getPrototype());
				this.wireHandler.setStructure(structure);
			}
			else
			{
				if(CentralPanel.ACTIVE_GRID.isAncestorOf(this.addHandler.getPrototype()))
					CentralPanel.ACTIVE_GRID.removeModule(this.addHandler.getPrototype());
				CentralPanel.ACTIVE_GRID.removeMouseListener(this.addHandler);
				CentralPanel.ACTIVE_GRID.removeMouseMotionListener(this.addHandler);
				this.addHandler.resetStructure();
				
				this.wireHandler.setStructure(structure);
				CentralPanel.ACTIVE_GRID.addMouseListener(this.wireHandler);
				CentralPanel.ACTIVE_GRID.addMouseMotionListener(this.wireHandler);
			}
		}
		else
		{
			if(this.addHandler.getPrototype() != null)
			{
				if(CentralPanel.ACTIVE_GRID.isAncestorOf(this.addHandler.getPrototype()))
					CentralPanel.ACTIVE_GRID.removeModule(this.addHandler.getPrototype());
				this.addHandler.setStructure(structure);
			}
			else
			{
				if(CentralPanel.ACTIVE_GRID.isAncestorOf(this.wireHandler.getPrototype()))
					CentralPanel.ACTIVE_GRID.removeModule(this.wireHandler.getPrototype());
				CentralPanel.ACTIVE_GRID.removeMouseListener(this.wireHandler);
				CentralPanel.ACTIVE_GRID.removeMouseMotionListener(this.wireHandler);
				this.wireHandler.resetStructure();
				
				this.addHandler.setStructure(structure);
				CentralPanel.ACTIVE_GRID.addMouseListener(this.addHandler);
				CentralPanel.ACTIVE_GRID.addMouseMotionListener(this.addHandler);
			}
		}
		
		this.currentActive = source;
		
		SouthPanel.STATUS_BOX.setTitle("Insert " + structure.getBubbleHelp());
	}
	
	public void switchToAddMode(ModuleButton source)
	{
		this.currentActive.paintRaised();
		
		this.editHandler.deselect(true);
		CentralPanel.ACTIVE_GRID.removeMouseListener(this.editHandler);
		CentralPanel.ACTIVE_GRID.removeMouseMotionListener(this.editHandler);
		
		CreationModule structure = source.getStructure();
		
		if(structure instanceof Wire)
		{
			this.wireHandler.setStructure(structure);
			CentralPanel.ACTIVE_GRID.addMouseListener(this.wireHandler);
			CentralPanel.ACTIVE_GRID.addMouseMotionListener(this.wireHandler);
		}
		else
		{
			this.addHandler.setStructure(structure);
			CentralPanel.ACTIVE_GRID.addMouseListener(this.addHandler);
			CentralPanel.ACTIVE_GRID.addMouseMotionListener(this.addHandler);
		}
		
		this.currentActive = source;
		
		SouthPanel.STATUS_BOX.setTitle("Insert " + structure.getBubbleHelp());
	}

	public void switchToEditMode()
	{
		this.editButton.paintInset();
		this.currentActive.paintRaised();
		
		if(this.addHandler.getPrototype() != null)
		{
			if(CentralPanel.ACTIVE_GRID.isAncestorOf(this.addHandler.getPrototype()))
				CentralPanel.ACTIVE_GRID.removeModule(this.addHandler.getPrototype());
			
			CentralPanel.ACTIVE_GRID.removeMouseListener(this.addHandler);
			CentralPanel.ACTIVE_GRID.removeMouseMotionListener(this.addHandler);
			this.addHandler.resetStructure();
		}
		else
		{
			if(CentralPanel.ACTIVE_GRID.isAncestorOf(this.wireHandler.getPrototype()))
				CentralPanel.ACTIVE_GRID.removeModule(this.wireHandler.getPrototype());
			
			CentralPanel.ACTIVE_GRID.removeMouseListener(this.wireHandler);
			CentralPanel.ACTIVE_GRID.removeMouseMotionListener(this.wireHandler);
			this.wireHandler.resetStructure();
		}
		
		this.currentActive = this.editButton;
		
		CentralPanel.ACTIVE_GRID.addMouseListener(this.editHandler);
		CentralPanel.ACTIVE_GRID.addMouseMotionListener(this.editHandler);
		
		SouthPanel.STATUS_BOX.setTitle("Edit mode");
	}
	
	public void activate(SimButton ib)
	{
		ib.processActionEvent();
		ib.setArmed(false);
	}
	
	public void arm(SimButton ib)
	{
		ib.setArmed(true);
	}
	
	public void disarm(SimButton ib)
	{
		ib.setArmed(false);
	}
	
	public void mousePressed(MouseEvent event)
	{
		SimButton ib = (SimButton)event.getSource();
		if(ib.isEnabled())
			if(ib.isRaised())
			{
				ib.paintInset();
				this.buttonUpOnLastMouseDown = ib.isRaised();
				this.arm(ib);
			}
	}
	
	public void mouseClicked(MouseEvent event)
	{
		SimButton ib = (SimButton)event.getSource();
		if(ib.isEnabled() && ib.isArmed())
			this.activate(ib);
	}
	
	public void mouseReleased(MouseEvent event)
	{
		SimButton ib = (SimButton)event.getSource();
		Point pt = event.getPoint();
		
		if(ib.contains(pt.x, pt.y))
			this.mouseClicked(event);
	}
	
	public void mouseDragged(MouseEvent event)
	{
		SimButton ib = (SimButton)event.getSource();
		if(ib.isEnabled() && ib.isArmed())
		{
			Point loc = event.getPoint();
			
			if(ib.contains(loc.x,loc.y))
			{
				if(this.buttonUpOnLastMouseDown)
				{
					if( ! ib.isRaised()) 
						ib.paintRaised();
				}
				else
					if(ib.isRaised())
						ib.paintInset();
			}
			else
			{
				if(this.buttonUpOnLastMouseDown)
					{
					if(ib.isRaised())
						ib.paintInset();
				}
				else
					if( ! ib.isRaised())
						ib.paintRaised();
			}
		}
	}
}