/*
 * Copyright 2006 Phidgets Inc.  All rights reserved.
 */

package com.phidgets;

import com.phidgets.event.*;

import java.util.Iterator;
import java.util.LinkedList;

public class Manager
{
	static {
		System.loadLibrary("phidget21");
	}

	public Manager() {
	}

	public native void nativeFree() throws PhidgetException;
	public native void nativeInitialize() throws PhidgetException;

	public final void start() throws PhidgetException {
		enableEvents(true);
		nativeInitialize();
	}

	public final void close() throws PhidgetException {
		enableEvents(false);
		nativeFree();
	}

	private void enableEvents(boolean b)
	{
		enableManagerAttachEvents(b && attachListeners.size() > 0);
		enableManagerDetachEvents(b && detachListeners.size() > 0);
	}

	/**
	 * Halts event dispatch while there are no listeners or the
	 * device is closed.  Should not affect Listeners.
	 */

	private LinkedList attachListeners = new LinkedList();
	private long nativeAttachHandler = 0;
	public final void addAttachListener(AttachListener l) {
		synchronized (attachListeners) {
			attachListeners.add(l);
			enableManagerAttachEvents(true);
		}
	}
	public final void removeAttachListener(AttachListener l) {
		synchronized (attachListeners) {
			attachListeners.remove(l);
			enableManagerAttachEvents(attachListeners.size() > 0);
		}
	}
	private void fireAttach(AttachEvent e) {
		synchronized (attachListeners) {
			for (Iterator it = attachListeners.iterator();
			  it.hasNext(); )
				((AttachListener)it.next()).attached(e);
		}
	}
	private native void enableManagerAttachEvents(boolean b);

	private LinkedList detachListeners = new LinkedList();
	private long nativeDetachHandler = 0;
	public final void addDetachListener(DetachListener l) {
		synchronized (detachListeners) {
			detachListeners.add(l);
			enableManagerDetachEvents(true);
		}
	}
	public final void removeDetachListener(DetachListener l) {
		synchronized (detachListeners) {
			detachListeners.remove(l);
			enableManagerDetachEvents(detachListeners.size() > 0);
		}
	}
	private void fireDetach(DetachEvent e) {
		synchronized (detachListeners) {
			for (Iterator it = detachListeners.iterator();
			  it.hasNext(); )
			((DetachListener)it.next()).detached(e);
		}
	}
	private native void enableManagerDetachEvents(boolean b);

	public void finalize() {
		try
		{
			nativeFree();
		} catch (Exception e) {
			;
		}
	}
}
