/*
 * Quantis Library for Java
 *
 * Copyright (c) 2004-2010 id Quantique SA, Carouge/Geneva, Switzerland
 * All rights reserved.
 *
 * ----------------------------------------------------------------------------
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY.
 *
 * ----------------------------------------------------------------------------
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */
package com.idquantique.quantis;

/**
 * The quantis java library can be used to access Quantis Module.
 * This library is OS independent and has been tested with Windows and
 * Linux.
 */
public class Quantis {

    // Load the Library containing the native code implementation
    // NOTE: You might need to configure your environment so the loadLibrary
    // method can find the native code library.
    static {
        System.loadLibrary("Quantis");
    }

    /**
     *
     */
    public enum QuantisDeviceType {

        /** Quantis PCI or PCI-Express */
        QUANTIS_DEVICE_PCI(1),
        
        /** Quantis USB */
        QUANTIS_DEVICE_USB(2);

        private int deviceType;

        QuantisDeviceType(int deviceType) {
            this.deviceType = deviceType;
        }

        public int getType() {
            return deviceType;
        }
    }

    private QuantisDeviceType deviceType;
    private int deviceNumber;

    /**
     *
     * @param deviceType
     * @param deviceNumber
     */
    public Quantis(QuantisDeviceType deviceType, int deviceNumber) {
        this.deviceType = deviceType;
        this.deviceNumber = deviceNumber;
    }

    /**
     *
     * @throws QuantisException
     */
    public void QuantisBoardReset() throws QuantisException {
        QuantisBoardReset(deviceType.getType(), deviceNumber);
    }

    /**
     *
     * @param deviceType
     * @return
     */
    public static int Count(QuantisDeviceType deviceType) {
        return QuantisCount(deviceType.getType());
    }

    /**
     *
     * @return
     * @throws QuantisException
     */
    public int GetBoardVersion() throws QuantisException {
        return QuantisGetBoardVersion(deviceType.getType(), deviceNumber);
    }

    /**
     *
     * @return
     * @throws QuantisException
     */
    public float GetDriverVersion() throws QuantisException {
        return QuantisGetDriverVersion(deviceType.getType());
    }

    /**
     *
     * @return
     */
    public static float GetLibVersion() {
        return QuantisGetLibVersion();
    }

    /**
     *
     * @return
     * @throws QuantisException
     */
    public int GetModulesCount() throws QuantisException {
        return QuantisGetModulesCount(deviceType.getType(), deviceNumber);
    }

    /**
     *
     * @return
     * @throws QuantisException
     */
    public int GetModulesDataRate() throws QuantisException {
        return QuantisGetModulesDataRate(deviceType.getType(), deviceNumber);
    }

    /**
     *
     * @return
     * @throws QuantisException
     */
    public int GetModulesMask() throws QuantisException {
        return QuantisGetModulesMask(deviceType.getType(), deviceNumber);
    }

    /**
     *
     * @return
     * @throws QuantisException
     */
    public int GetModulesPower() throws QuantisException {
        return QuantisGetModulesPower(deviceType.getType(), deviceNumber);
    }

    /**
     *
     * @return
     * @throws QuantisException
     */
    public int GetModulesStatus() throws QuantisException {
        return QuantisGetModulesStatus(deviceType.getType(), deviceNumber);
    }

    /**
     *
     * @return
     */
    public String GetSerialNumber() {
        return QuantisGetSerialNumber(deviceType.getType(), deviceNumber);
    }

    /**
     *
     * @param modulesMask
     * @throws QuantisException
     */
    public void ModulesDisable(int modulesMask) throws QuantisException {
        QuantisModulesDisable(deviceType.getType(), deviceNumber, modulesMask);
    }

    /**
     *
     * @param modulesMask
     * @throws QuantisException
     */
    public void ModulesEnable(int modulesMask) throws QuantisException {
        QuantisModulesEnable(deviceType.getType(), deviceNumber, modulesMask);
    }

    /**
     *
     * @param modulesMask
     * @throws QuantisException
     */
    public void ModulesReset(int modulesMask) throws QuantisException {
        QuantisModulesReset(deviceType.getType(), deviceNumber, modulesMask);
    }

    /**
     *
     * @param size
     * @return
     * @throws QuantisException
     */
    public byte[] Read(int size) throws QuantisException {
        return QuantisRead(deviceType.getType(), deviceNumber, size);
    }

    public double ReadDouble() throws QuantisException {
        return QuantisReadDouble01(deviceType.getType(), deviceNumber);
    }

    public double ReadDouble(double min, double max) throws QuantisException {
        return QuantisReadScaledDouble(deviceType.getType(), deviceNumber, min, max);
    }

    public float ReadFloat() throws QuantisException {
        return QuantisReadFloat01(deviceType.getType(), deviceNumber);
    }

    public float ReadFloat(float min, float max) throws QuantisException {
        return QuantisReadScaledFloat(deviceType.getType(), deviceNumber, min, max);

    }

    public int ReadInt() throws QuantisException {
        return QuantisReadInt(deviceType.getType(), deviceNumber);
    }

    public int ReadInt(int min, int max) throws QuantisException {
        return QuantisReadScaledInt(deviceType.getType(), deviceNumber, min, max);
    }

    public short ReadShort() throws QuantisException {
        return QuantisReadShort(deviceType.getType(), deviceNumber);
    }

    public short ReadShort(short min, short max) throws QuantisException {
        return QuantisReadScaledShort(deviceType.getType(), deviceNumber, min, max);
    }

    // -------------------- Native methods declaration --------------------
    private static native void QuantisBoardReset(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native int QuantisCount(int deviceType);

    private static native int QuantisGetBoardVersion(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native float QuantisGetDriverVersion(int deviceType)
            throws QuantisException;

    private static native float QuantisGetLibVersion();

    private static native int QuantisGetModulesCount(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native int QuantisGetModulesDataRate(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native int QuantisGetModulesMask(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native int QuantisGetModulesPower(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native int QuantisGetModulesStatus(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native String QuantisGetSerialNumber(int deviceType,
            int deviceNumber);

    private static native void QuantisModulesDisable(int deviceType,
            int deviceNumber,
            int modulesMask)
            throws QuantisException;

    private static native void QuantisModulesEnable(int deviceType,
            int deviceNumber,
            int modulesMask)
            throws QuantisException;

    private static native void QuantisModulesReset(int deviceType,
            int deviceNumber,
            int modulesMask)
            throws QuantisException;

    private static native byte[] QuantisRead(int deviceType,
            int deviceNumber,
            int size)
            throws QuantisException;

    private static native double QuantisReadDouble01(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native float QuantisReadFloat01(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native int QuantisReadInt(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native short QuantisReadShort(int deviceType,
            int deviceNumber)
            throws QuantisException;

    private static native double QuantisReadScaledDouble(int deviceType,
            int deviceNumber,
            double min,
            double max)
            throws QuantisException;

    private static native float QuantisReadScaledFloat(int deviceType,
            int deviceNumber,
            float min,
            float max)
            throws QuantisException;

    private static native int QuantisReadScaledInt(int deviceType,
            int deviceNumber,
            int min,
            int max)
            throws QuantisException;

    private static native short QuantisReadScaledShort(int deviceType,
            int deviceNumber,
            short min,
            short max)
            throws QuantisException;
}
