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

package com.phidgets;

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

import com.phidgets.event.*;

public final class InterfaceKitPhidget extends Phidget
{
	public InterfaceKitPhidget() throws PhidgetException {
		super(create());
	}

	private static native long create() throws PhidgetException;

	public native int getOutputCount() throws PhidgetException;
	public native int getInputCount() throws PhidgetException;
	public native int getSensorCount() throws PhidgetException;
	public native boolean getInputState(int index) throws PhidgetException;
	public native boolean getOutputState(int index)
	  throws PhidgetException;
	public native int getSensorValue(int index) throws PhidgetException;
	public native int getSensorRawValue(int index) throws PhidgetException;
	public native int getSensorChangeTrigger(int index)
	  throws PhidgetException;

	public native void setOutputState(int index, boolean newVal)
	  throws PhidgetException;
	public native void setSensorChangeTrigger(int index, int newVal)
	  throws PhidgetException;

	protected final void enableDeviceSpecificEvents(boolean b) {
		enableInputChangeEvents(b && inputChangeListeners.size() > 0);
		enableOutputChangeEvents(b && outputChangeListeners.size() > 0);
		enableSensorChangeEvents(b && sensorChangeListeners.size() > 0);
	}

	private LinkedList inputChangeListeners = new LinkedList();
	private long nativeInputChangeHandler = 0;
	public final void addInputChangeListener(InputChangeListener l) {
		synchronized (inputChangeListeners) {
			inputChangeListeners.add(l);
			enableInputChangeEvents(true);
		}
	}
	public final void removeInputChangeListener(InputChangeListener l) {
		synchronized (inputChangeListeners) {
			inputChangeListeners.remove(l);
			enableInputChangeEvents(inputChangeListeners.size() >
			  0);
		}
	}
	private void fireInputChange(InputChangeEvent e) {
		synchronized (inputChangeListeners) {
			for (Iterator it = inputChangeListeners.iterator();
			  it.hasNext(); )
				((InputChangeListener)it.next()).inputChanged(
				  e);
		}
	}
	private native void enableInputChangeEvents(boolean b);

	private LinkedList outputChangeListeners = new LinkedList();
	private long nativeOutputChangeHandler = 0;
	public final void addOutputChangeListener(OutputChangeListener l) {
		synchronized (outputChangeListeners) {
			outputChangeListeners.add(l);
			enableOutputChangeEvents(true);
		}
	}
	public final void removeOutputChangeListener(OutputChangeListener l) {
		synchronized (outputChangeListeners) {
			outputChangeListeners.remove(l);
			enableOutputChangeEvents(outputChangeListeners.size()
			  > 0);
		}
	}
	private void fireOutputChange(OutputChangeEvent e) {
		synchronized (outputChangeListeners) {
			for (Iterator it = outputChangeListeners.iterator();
			  it.hasNext(); )
				((OutputChangeListener)it.next())
				  .outputChanged(e);
		}
	}
	private native void enableOutputChangeEvents(boolean b);

	private LinkedList sensorChangeListeners = new LinkedList();
	private long nativeSensorChangeHandler = 0;
	public final void addSensorChangeListener(SensorChangeListener l) {
		synchronized (sensorChangeListeners) {
			sensorChangeListeners.add(l);
			enableSensorChangeEvents(true);
		}
	}
	public final void removeSensorChangeListener(SensorChangeListener l) {
		synchronized (sensorChangeListeners) {
			sensorChangeListeners.remove(l);
			enableSensorChangeEvents(sensorChangeListeners.size()
			  > 0);
		}
	}
	private void fireSensorChange(SensorChangeEvent e) {
		synchronized (sensorChangeListeners) {
			for (Iterator it = sensorChangeListeners.iterator();
			  it.hasNext(); )
				((SensorChangeListener)it.next())
				  .sensorChanged(e);
		}
	}
	private native void enableSensorChangeEvents(boolean b);
}
