package lu.tudor.santec.gecamed.formeditor.gui.component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.swing.ComboBoxModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import lu.tudor.santec.gecamed.formeditor.gui.model.ComboBoxElement;

public class CBEListModel extends ArrayList<ComboBoxElement<?>> implements ComboBoxModel
{
	private static final long serialVersionUID = 1L;
	
	
	
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	private List<ListDataListener> 	listener = new ArrayList<ListDataListener>();
	
	private ComboBoxElement<?> 		selectedItem;
	
	
	
	/* ======================================== */
	// 		CONSTRUCTOR
	/* ======================================== */
	
	// DEFUALT CONSTRUCTOR
	public CBEListModel ()
	{
	}
	
	public CBEListModel (Collection<ComboBoxElement<?>> elements)
	{
		super(elements);
	}
	
	
	
	/* ======================================== */
	// 		IMPLEMENTED METHODS
	/* ======================================== */
	
	public int getSize()
	{
		return this.size();
	}

	public ComboBoxElement<?> getElementAt(int index)
	{
		return this.get(index);
	}

	public void addListDataListener(ListDataListener l)
	{
		listener.add(l);
	}

	public void removeListDataListener(ListDataListener l)
	{
		listener.remove(l);
	}

	public void setSelectedItem(Object anItem)
	{
		this.selectedItem = (ComboBoxElement<?>) anItem;
	}

	public Object getSelectedItem()
	{
		return this.selectedItem;
	}
	
	
	
	/* ======================================== */
	// 		OVERRIDDEN METHODS
	/* ======================================== */
	
	@Override
	public boolean add(ComboBoxElement<?> e)
	{
		int startIndex = size()-1;
		boolean b = super.add(e);
		if (b)
			fireModelChanged(ListDataEvent.INTERVAL_ADDED, startIndex, this.size()-1);
		return b;
	}
	
	@Override
	public void add(int index, ComboBoxElement<?> element)
	{
		int startIndex = size()-1;
		super.add(index, element);
		fireModelChanged(ListDataEvent.INTERVAL_ADDED, startIndex, this.size()-1);
	}
	
	@Override
	public boolean addAll(Collection<? extends ComboBoxElement<?>> c)
	{
		int startIndex = size()-1;
		boolean b = super.addAll(c);
		if (b)
			fireModelChanged(ListDataEvent.INTERVAL_ADDED, startIndex, this.size()-1);
		return b;
	}
	
	@Override
	public boolean addAll(int index, Collection<? extends ComboBoxElement<?>> c)
	{
		boolean b = super.addAll(index, c);
		if (b)
			fireModelChanged(ListDataEvent.INTERVAL_ADDED, index, this.size()-1);
		return b;
	}
	
	@Override
	public ComboBoxElement<?> set(int index, ComboBoxElement<?> element)
	{
		ComboBoxElement<?> cbe = super.set(index, element);
		fireModelChanged(ListDataEvent.CONTENTS_CHANGED, index, index);
		return cbe;
	}
	
	@Override
	public ComboBoxElement<?> remove(int index)
	{
		ComboBoxElement<?> cbe = super.remove(index);
		fireModelChanged(ListDataEvent.INTERVAL_REMOVED, index, this.size()-1);
		return cbe;
	}
	
	@Override
	public boolean remove(Object o)
	{
		boolean b = super.remove(o);
		if (b)
			fireModelChanged(ListDataEvent.INTERVAL_REMOVED);
		return b;
	}
	
	@Override
	public boolean removeAll(Collection<?> c)
	{
		boolean b = super.removeAll(c);
		if (b)
			fireModelChanged(ListDataEvent.INTERVAL_REMOVED);
		return b;
	}
	
	
	
	/* ======================================== */
	// 		HELP METHODS
	/* ======================================== */
	
	public void fireModelChanged (int type)
	{
		fireModelChanged(type, 0, this.size()-1);
	}
	
	public void fireModelChanged (int type, int startIndex, int endIndex)
	{
		ListDataEvent e = new ListDataEvent(this, type, startIndex, endIndex);
		
		switch (type)
		{
		case ListDataEvent.CONTENTS_CHANGED:
			for (ListDataListener l : listener)
			{
				l.contentsChanged(e);
			}
			break;

		case ListDataEvent.INTERVAL_ADDED:
			for (ListDataListener l : listener)
			{
				l.intervalAdded(e);
			}
			break;
			
		case ListDataEvent.INTERVAL_REMOVED:
			for (ListDataListener l : listener)
			{
				l.intervalRemoved(e);
			}
			break;
		}
	}
}
