package lu.tudor.santec.gecamed.billing.gui.act;

import java.util.Collection;
import java.util.Date;
import java.util.Vector;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Act;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;


/**
 * <p>This Vector is used to keep Acts sorted by:</p> 
 * <ol>
 * 	<li>date</li>
 * 	<li>time</li>
 * 	<li>code</li>
 * </ol>
 * 
 * @author ferring
 */
public class SortedActVector extends Vector<Act>
{
	/* ======================================== */
	// 		CONSTANTS
	/* ======================================== */
	
	private static final long serialVersionUID = 1L;
	
	
	
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(SortedActVector.class.getName());
	
	
	
	/* ======================================== */
	// 		CONSTRUCTORS
	/* ======================================== */
	
	
	
	public SortedActVector()
	{
		super();
	}
	
	
	public SortedActVector(Collection<? extends Act> c)
	{
		super(c);
	}
	
	
	
	/* ======================================== */
	// 		OVERRIDDEN METHODS
	/* ======================================== */
	
	@Override
	public void add(int index, Act element)
	{
//		this.add(element);
		super.add(index, element);
	}
	
	
	@Override
	public synchronized void addElement(Act obj)
	{
		this.add(obj);
	}
	
	
	@Override
	public synchronized void setElementAt (Act element, int index)
	{
		super.set (index, element);
	}
	
	
	@Override
	public synchronized Act set (int index, Act obj)
	{
		Act old = super.remove(index);
		this.add(obj);
		
		return old;
	}
	
	
	@Override
	public synchronized boolean addAll(int index, Collection<? extends Act> c)
	{
		return addAll(c);
	}
	
	
	@Override
	public synchronized boolean addAll(Collection<? extends Act> c)
	{
		boolean success = true;
		for (Act act : c)
		{
			success = add(act);
		}
		return success;
	}
	
	
	/**
	 * <p>This method replaces the original add method and is called by 
	 * all other inserting or replacing methods.</p>
	 * <p>The acts are ordered by date (, time) and code</p>
	 * 
	 * @param act The act to be added
	 * @return
	 */
	@Override
	public synchronized boolean add (Act act)
	{
		if (act == null)
			return false;
		
		try 
		{
			Act 	referenceAct;
			int 	dateCompared;
			String 	code = act.getCode();
			Date 	date = act.getPerformedDate();
			
			if (date == null)
			{
				/* If there is no date set, set the date of the latest act
				 * of the vector and proceed as usual.
				 */
				act.setPerformedDate(get(size()-1).getPerformedDate());
			}
			
//			if (code != null && code.trim().length() == 0)
//			{
//				// Acts with empty codes will always be appended at the end
//				return super.add(act);
//			}
			
			// go threw the vector until you find the right place to put the act
			int index;
			for (index = 0; index < size(); index++)
			{
				referenceAct 	= get(index);
				dateCompared 	= date.compareTo(referenceAct.getPerformedDate());
				
				if (dateCompared == 0)
				{
					if (code == null || code.trim().length() == 0)
						continue;
					
					// date is equal
					if (referenceAct != null 
							&& code.compareToIgnoreCase(referenceAct.getCode()) < 0)
						// code of act at i is higher than code of act to add
						// => add the vector at i (before the act compared with)
						break;
				}
				else if (dateCompared < 0)
					// date of act at i is higher than date of act to add
					// => add the vector at i (before the act compared with)
					break;
			}
			
			super.add(index, act);
			return true;
		}
		catch (Exception e)
		{
			logger.log(Level.ERROR, e.getMessage(), e);
			return false;
		}
	}
}
