package lu.tudor.santec.gecamed.esante.gui.tab;

import java.util.HashSet;
import java.util.Set;

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

import lu.tudor.santec.gecamed.esante.ejb.entity.beans.CdaDocument;

/**
 * @author jens.ferring(at)tudor.lu
 * 
 * @version
 * <br>$Log: CdaListModel.java,v $
 * <br>Revision 1.3  2014-02-04 10:08:35  ferring
 * <br>eSante ID management completed
 * <br>Only those documents will be shown, that are retrieved by the RSQ
 * <br>
 * <br>Revision 1.2  2013-11-25 08:27:36  ferring
 * <br>Root expanding and notifying of JTree fixed
 * <br>
 * <br>Revision 1.1  2013-11-22 14:51:12  ferring
 * <br>Restructured CDA tree and list notification, in order not to use an EntityBean as model.
 * <br>Buttons added to delete the CDA file and remove the incident entry
 * <br>
 */
public class CdaListModel implements ListModel, CdaListener
{
	/* ======================================== */
	// MEMBERS
	/* ======================================== */
	
	private CdaHandler				handler;
	
	private Set<ListDataListener>	listeners	= new HashSet<ListDataListener>();
	
	
	
	/* ======================================== */
	// CONSTRUCTORS
	/* ======================================== */
	
	public CdaListModel (CdaHandler handler)
	{
		this.handler = handler;
		this.handler.addCdaListener(this);
	}
	
	
	
	/* ======================================== */
	// GETTER & SETTER
	/* ======================================== */
	
//	public void fireDocumentChanged (CdaDocument document)
//	{
//		int index = dsp.getDocuments().indexOf(document);
//		if (index >= 0)
//		{
//			dsp.setDocument(index, document);
//			fireModelChanged(ListDataEvent.CONTENTS_CHANGED, index, index);
//			ESanteTab.getESanteTab(dsp.getPatientId()).repaint();
//		}
//	}
	
	
//	public void sortDocuments ()
//	{
//		TreeSet<CdaDocument> sorter = new TreeSet<CdaDocument>(dsp.getDocuments());
//		dsp.setDocuments(sorter);
//	}
	
	
	/* ---------------------------------------- */
	// LIST MODEL METHODS
	/* ---------------------------------------- */

	public int getSize ()
	{
		return handler.getDocumentCount();
	}
	

	public CdaDocument getElementAt (int index)
	{
		return handler.getDocument(index);
	}
	
	
	public void addListDataListener (ListDataListener l)
	{
		listeners.add(l);
	}
	
	
	public void removeListDataListener (ListDataListener l)
	{
		listeners.remove(l);
	}
	
	
	/* ---------------------------------------- */
	// CDA LISTENER METHOD
	/* ---------------------------------------- */
	
	public void documentsChanged (CdaChangeEvent e)
	{
		int eventType;
		
		switch (e.getEventType())
		{
			case CdaChangeEvent.DOCUMENTS_REMOVED:
				eventType = ListDataEvent.INTERVAL_REMOVED;
				break;

			case CdaChangeEvent.DOCUMENTS_ADDED:
				eventType = ListDataEvent.INTERVAL_ADDED;
				break;
			
			case CdaChangeEvent.DOCUMENTS_CHANGED:
				eventType = ListDataEvent.CONTENTS_CHANGED;
				break;
				
			default:
				return;
		}
		
		fireModelChanged(new ListDataEvent(e.getSource(), eventType, 
				e.getStartIndex() == CdaChangeEvent.MAX_SIZE ? 0 : e.getStartIndex(), 
				e.getEndIndex() == CdaChangeEvent.MAX_SIZE ? getSize() : e.getEndIndex()));
	}
	
	
	
	/* ======================================== */
	// HELP METHODS
	/* ======================================== */
	
//	private void fireDocumentsAdded (Collection<CdaDocument> documents)
//	{
//		CdaDocument[] docArray = new CdaDocument[documents.size()];
//		int index = 0;
//		for (CdaDocument doc : documents)
//			docArray[index++] = doc;
//		
//		ListDataEvent e = new CdaListDataEvent(this, ListDataEvent.INTERVAL_ADDED, 0, documents.size(), docArray);
//		fireModelChanged(e);
//	}
//	
//	
//	private void fireDocumentsAdded (int startIndex, int endIndex)
//	{
//		fireModelChanged(ListDataEvent.INTERVAL_ADDED, startIndex, endIndex);
//	}
//	
//	
//	private void fireDocumentsRemoved (int startIndex, int endIndex)
//	{
//		fireModelChanged(ListDataEvent.INTERVAL_REMOVED, startIndex, endIndex);
//	}
	
	
//	private void fireModelChanged (int type, int start, int end)
//	{
//		if (end < 0)
//			end = 0;
//		if (start < 0)
//			start = 0;
//		if (end < start)
//		{
//			int tmp	= end;
//			end		= start;
//			start	= tmp;
//		}
//		
//		if (end >= getSize())
//			return;
//		
//		// TODO: notify the tree model / root as well
//		CdaDocument[] docArray = new CdaDocument[end - start + 1];
//		for (int index = 0; index < docArray.length && (index + start) <= end; index++)
//			docArray[index] = getElementAt(index + start);
//		
//		ListDataEvent e = new CdaListDataEvent(this, 
//				type, start, end, docArray);
//		fireModelChanged (e);
//	}
	
	
	private void fireModelChanged (ListDataEvent e)
	{
		switch (e.getType())
		{
			case ListDataEvent.CONTENTS_CHANGED:
				
				for (ListDataListener l : listeners)
					l.contentsChanged(e);
				break;
			
			case ListDataEvent.INTERVAL_ADDED:
				
				for (ListDataListener l : listeners)
					l.intervalAdded(e);
				break;
			
			case ListDataEvent.INTERVAL_REMOVED:
				
				for (ListDataListener l : listeners)
					l.intervalRemoved(e);
				break;
		}
	}
}
