package sim;

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

import sim.lib.wires.ThinWire;
import sim.lib.wires.FatWire;
import sim.util.BubbleListener;


public class EssentialModulePanel extends ModulePanel implements ItemListener
{
	public static int BUS_SIZE = 8;
	
	private Choice busSize = new Choice();
	private TrackBusUsage[] available;
	private FatWire prototype;
	
	public EssentialModulePanel()
	{
		super();
		
		long currentTime = System.currentTimeMillis();
		
		this.available = new TrackBusUsage[7];
		
		this.available[0] = new TrackBusUsage(currentTime, 2);
		this.available[1] = new TrackBusUsage(currentTime, 3);
		this.available[2] = new TrackBusUsage(currentTime, 5);
		this.available[3] = new TrackBusUsage(currentTime, 8);
		this.available[4] = new TrackBusUsage(currentTime, 10);
		this.available[5] = new TrackBusUsage(currentTime, 13);
		this.available[6] = new TrackBusUsage(currentTime, 16);
		
		this.busSize.add("2");
		this.busSize.add("3");
		this.busSize.add("5");
		this.busSize.add("8");
		this.busSize.add("10");
		this.busSize.add("13");
		this.busSize.add("16");
		this.busSize.add("More...");
		this.busSize.select("8");
		this.busSize.addItemListener(this);
		this.busSize.addMouseListener(new BubbleListener(this.busSize , "Bus size", WestPanel.BUBBLE_WAIT));
	}
	
	public void addNotify()
	{
		super.addNotify();
		
		this.setLayout(new BorderLayout(0, 5));
		
		Panel p = new Panel(new FlowLayout(FlowLayout.CENTER, 0, 0));
		p.add(this.busSize);
		this.add(p, BorderLayout.NORTH);
		
		p = new Panel(new FlowLayout(FlowLayout.CENTER, 0, 0));
		ModuleButton mb = WestPanel.MODE_CONTROL.getEditButton();
		this.initializeListeners(mb);
		p.add(mb);
		mb = new ModuleButton(new ThinWire());
		this.initializeListeners(mb);
		p.add(mb);
		mb = new ModuleButton(new FatWire());
		this.prototype = (FatWire)mb.getStructure();
		this.initializeListeners(mb);
		p.add(mb);
		this.add(p, BorderLayout.CENTER);
	}
	
	public void itemStateChanged(ItemEvent e)
	{
		String selected = (String)e.getItem();
		int index, where;
		
		if(selected.equals("More..."))
		{
			WrapperMenu.PROPERTY_DIALOG.activate(this.prototype);
			
			where = 0;
			
			// check if selected item is in currently available
			try
			{
				for(index = 0; index < this.available.length; index++)
				{
					if(this.available[index].busSize == EssentialModulePanel.BUS_SIZE)
					{
						this.available[index].lastUsed = System.currentTimeMillis();
						this.busSize.select(Integer.toString(EssentialModulePanel.BUS_SIZE));
						where = 1;
					}
				}
			}
			catch(NumberFormatException nfe)
			{
			}
			
			// if not remove least recently used from choice and add new value
			if(where == 0)
			{
				long smallest = this.available[0].lastUsed;
				
				for(index = 1; index < this.available.length; index++)
				{
					if(this.available[index].lastUsed < smallest)
					{
						smallest = this.available[index].lastUsed;
						where = index;
					}
				}
				
				this.busSize.remove(Integer.toString(this.available[where].busSize));
				this.available[where].busSize = EssentialModulePanel.BUS_SIZE;
				this.available[where].lastUsed = System.currentTimeMillis();
				
				where = this.available.length - 1;
				
				try
				{
					for(index = 0; index < where; index++)
					{
						if(Integer.valueOf(this.busSize.getItem(index)).intValue() > EssentialModulePanel.BUS_SIZE)
							where = index;
					}
				
				}
				catch(NumberFormatException nfe)
				{
				}
				
				this.busSize.insert(Integer.toString(EssentialModulePanel.BUS_SIZE), where);
				this.busSize.select(where);
			}
		}
		else
		{
			try
			{
				EssentialModulePanel.BUS_SIZE = Integer.valueOf(selected).intValue();
				
				for(index = 0; index < this.available.length; index++)
				{
					if(this.available[index].busSize == EssentialModulePanel.BUS_SIZE)
						this.available[index].lastUsed = System.currentTimeMillis();
				}
			}
			catch(NumberFormatException nfe)
			{
			}
		}
	}
	
	private class TrackBusUsage
	{
		public long lastUsed;
		public int busSize;
		
		public TrackBusUsage(long time, int size)
		{
			this.lastUsed = time;
			this.busSize = size;
		}
	}
}
