/* $Id: SpoolerQueue.java,v 1.1 2004/01/09 16:55:42 burkhard Exp $
 * Created on 26.09.2003
 *
 */
package de.skyrix.zsp.logic.cache;

import java.util.ArrayList;

import de.skyrix.zsp.logic.DAVItem;

/**Spooler to spool new/edited messages
 * 
 * @author sell
 *
 */
public class SpoolerQueue {
	private ArrayList queue = null;
	private static SpoolerQueue selfInstance = null;

	/**Constructs a SpoolerQueue.
	 *
	 * @see #getInstance() 
	 */
	protected SpoolerQueue() {
		queue = new ArrayList();
	}

	/**Adds a message to the Q to be created on the server.
	 * 
	 * @param message - the message
	 */
	public void createMessage(DAVItem message) {
		queue.add(new ServerJob(message, ServerJob.DO_CREATE));
	}

	/**Adds a message to the Q to be updated on the server.
	 * 
	 * @param message - the message
	 */
	public void updateMessage(DAVItem message) {
		ServerJob job = new ServerJob(message, ServerJob.DO_UPDATE);

		//remove the old job if exists
		queue.remove(job);

		//add the new job
		queue.add(job);
	}

	/**Adds a message to the Q to be deleted on the server.
	 * 
	 * @param message - the message
	 */
	public void deleteMessage(DAVItem message) {
		ServerJob job = new ServerJob(message, ServerJob.DO_DELETE);

		//remove the old job if exists
		queue.remove(job);

		try {
			//new messages mustn't be deleted, we simply don't create them.
			if (!job.getItem().isNew()) {
				queue.add(job);
			}
		}
		catch (Exception e) {
		}
	}

	/**Adds a job directly to the queue.
	 * <p>This is usefull, if a job is removed from the job f.e. by the 
	 * {@link #next() next()} method, but the execution on the server failed.
	 * In that case you have to readd the job to the queue.</p>
	 * 
	 * @param job - the job to add
	 */
	public void addJob(ServerJob job) {
		if (job == null)
			return;

		queue.add(job);
	}

	public boolean hasNext() {
		return (queue.size() > 0);
	}

	public ServerJob next() {
		return (ServerJob) queue.remove(0);
	}

	/**Represents a job queued for execution on the server.
	 * 
	 * @author sell
	 */
	class ServerJob {
		public static final int DO_DELETE = 1;
		public static final int DO_CREATE = 2;
		public static final int DO_UPDATE = 3;

		/**/
		private DAVItem item = null;
		private int operation = 0;

		public ServerJob(DAVItem item, int operation) {
			if (item == null)
				throw new IllegalArgumentException("null is not a valid DAVItem!");
			this.item = item;
			this.operation = operation;
		}

		public boolean equals(Object o) {
			System.out.println("equals called");
			try {
				return item.getID().equals(((ServerJob) o).getItem().getID());
			}
			catch (Exception e) {
			}

			return false;
		}

		public int hashCode() {
			System.out.println("hashcode called");
			try {
				return item.getID().hashCode();
			}
			catch (Exception e) {
			}

			return -1;
		}

		/**
		 * @return
		 */
		public DAVItem getItem() {
			return item;
		}

		/**
		 * @return
		 */
		public int getOperation() {
			return operation;
		}

		public String toString() {
			String ret = "SpoolerJob: ";

			switch (operation) {
				case DO_CREATE :
					ret += "Creating ";
					break;
				case DO_DELETE :
					ret += "Deleting ";
					break;
				case DO_UPDATE :
					ret += "Updateing ";
					break;
			}

			ret += item.getID();

			return ret;
		}
	}

	/**Returns the currently used SpollerQueue instance. 
	 *
	 */
	public static SpoolerQueue getInstance() {
		if (selfInstance == null) {
			selfInstance = new SpoolerQueue();
			CacheManager.getInstance().initSpoolerQueue();
		}

		return selfInstance;
	}
}
