// Path: public-java/io/iamcontent-usb/src/main/java/com/iamcontent/io/usb/UsbDevicePredicates.java
// public static boolean vendorAndProductIdsMatch(short vendorId, short productId, UsbDevice device) {
// 	return vendorAndProductIdsMatch(vendorId, productId, device.getUsbDeviceDescriptor());
// }
// 
// Path: public-java/devices/iamcontent-pololu-servo-controllers/src/main/java/com/iamcontent/device/controller/pololu/maestro/MaestroCardType.java
// public enum MaestroCardType {
// 	
// 	MICRO_MAESTRO_6(6),
// 	MINI_MAESTRO_12(12),
// 	MINI_MAESTRO_18(18),
// 	MINI_MAESTRO_24(24);
// 	
// 	private final int channelCount;
// 
// 	private MaestroCardType(int channelCount) {
// 		this.channelCount = channelCount;
// 	}
// 
// 	public int channelCount() {
// 		return channelCount;
// 	}
// }
// 
// Path: public-java/io/iamcontent-usb/src/main/java/com/iamcontent/io/usb/UsbRuntimeException.java
// public class UsbRuntimeException extends RuntimeException {
// 	public UsbRuntimeException(String message) {
// 		super(message);
// 	}
// 
// 	public UsbRuntimeException(Throwable cause) {
// 		super(cause);
// 	}
// 	
// 	private static final long serialVersionUID = 1L;
// }


import static com.iamcontent.device.controller.pololu.maestro.MaestroCardType.MICRO_MAESTRO_6;
import static com.iamcontent.device.controller.pololu.maestro.MaestroCardType.MINI_MAESTRO_12;
import static com.iamcontent.device.controller.pololu.maestro.MaestroCardType.MINI_MAESTRO_18;
import static com.iamcontent.device.controller.pololu.maestro.MaestroCardType.MINI_MAESTRO_24;
import static com.iamcontent.io.usb.UsbDevicePredicates.vendorAndProductIdsMatch;
import java.util.Optional;
import java.util.stream.Stream;
import javax.usb.UsbDevice;
import com.iamcontent.device.controller.pololu.maestro.MaestroCardType;
import com.iamcontent.io.usb.UsbRuntimeException;

/**
  IAmContent Public Libraries.
  Copyright (C) 2015-2021 Greg Elderfield
  @author Greg Elderfield, support@jarchitect.co.uk
 
  This program is free software; you can redistribute it and/or modify it under the terms of the
  GNU General Public License as published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.

  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., 
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package com.iamcontent.device.controller.pololu.maestro.usb;





/**
 * The USB characteristics of the different types of Pololu Maestro cards.
 * 
 * The id values used by this protocol were obtained from Pololu's Native USB SDK,
 * downloaded from www.pololu.com.
 * 
 * @author Greg Elderfield
 */
public enum UsbMaestroCardType {
	
	USB_MICRO_MAESTRO_6(MICRO_MAESTRO_6, 0x0089),
	USB_MINI_MAESTRO_12(MINI_MAESTRO_12, 0x008A),
	USB_MINI_MAESTRO_18(MINI_MAESTRO_18, 0x008B),
	USB_MINI_MAESTRO_24(MINI_MAESTRO_24, 0x008C);
	
	public static final short VENDOR_ID = 0x1ffb;
	
	private final MaestroCardType type;
	private final short productId;

	private UsbMaestroCardType(MaestroCardType type, int productId) {
		this.type = type;
		this.productId = (short)productId;
	}

	public MaestroCardType getType() {
		return type;
	}

	public short getProductId() {
		return productId;
	}

	public static UsbMaestroCardType cardTypeForUsbDeviceOrThrow(UsbDevice device) {
		return cardTypeForUsbDevice(device).orElseThrow(() -> new UsbRuntimeException("USB Device is not a Usb Maestro Card"));
	}

	public static boolean isAMaestroCard(UsbDevice device) {
		return cardTypeForUsbDevice(device).isPresent();
	}
	
	public static Optional<UsbMaestroCardType> cardTypeForUsbDevice(UsbDevice device) {

// Path: public-java/io/iamcontent-usb/src/main/java/com/iamcontent/io/usb/UsbDevicePredicates.java
// public static boolean vendorAndProductIdsMatch(short vendorId, short productId, UsbDevice device) {
// 	return vendorAndProductIdsMatch(vendorId, productId, device.getUsbDeviceDescriptor());
// }
// 
// Path: public-java/devices/iamcontent-pololu-servo-controllers/src/main/java/com/iamcontent/device/controller/pololu/maestro/MaestroCardType.java
// public enum MaestroCardType {
// 	
// 	MICRO_MAESTRO_6(6),
// 	MINI_MAESTRO_12(12),
// 	MINI_MAESTRO_18(18),
// 	MINI_MAESTRO_24(24);
// 	
// 	private final int channelCount;
// 
// 	private MaestroCardType(int channelCount) {
// 		this.channelCount = channelCount;
// 	}
// 
// 	public int channelCount() {
// 		return channelCount;
// 	}
// }
// 
// Path: public-java/io/iamcontent-usb/src/main/java/com/iamcontent/io/usb/UsbRuntimeException.java
// public class UsbRuntimeException extends RuntimeException {
// 	public UsbRuntimeException(String message) {
// 		super(message);
// 	}
// 
// 	public UsbRuntimeException(Throwable cause) {
// 		super(cause);
// 	}
// 	
// 	private static final long serialVersionUID = 1L;
// }


// Path: public-java/devices/iamcontent-pololu-servo-controllers/src/main/java/com/iamcontent/device/controller/pololu/maestro/usb/UsbMaestroCardType.java
import static com.iamcontent.device.controller.pololu.maestro.MaestroCardType.MICRO_MAESTRO_6;
import static com.iamcontent.device.controller.pololu.maestro.MaestroCardType.MINI_MAESTRO_12;
import static com.iamcontent.device.controller.pololu.maestro.MaestroCardType.MINI_MAESTRO_18;
import static com.iamcontent.device.controller.pololu.maestro.MaestroCardType.MINI_MAESTRO_24;
import static com.iamcontent.io.usb.UsbDevicePredicates.vendorAndProductIdsMatch;
import java.util.Optional;
import java.util.stream.Stream;
import javax.usb.UsbDevice;
import com.iamcontent.device.controller.pololu.maestro.MaestroCardType;
import com.iamcontent.io.usb.UsbRuntimeException;

/**
  IAmContent Public Libraries.
  Copyright (C) 2015-2021 Greg Elderfield
  @author Greg Elderfield, support@jarchitect.co.uk
 
  This program is free software; you can redistribute it and/or modify it under the terms of the
  GNU General Public License as published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.

  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., 
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package com.iamcontent.device.controller.pololu.maestro.usb;





/**
 * The USB characteristics of the different types of Pololu Maestro cards.
 * 
 * The id values used by this protocol were obtained from Pololu's Native USB SDK,
 * downloaded from www.pololu.com.
 * 
 * @author Greg Elderfield
 */
public enum UsbMaestroCardType {
	
	USB_MICRO_MAESTRO_6(MICRO_MAESTRO_6, 0x0089),
	USB_MINI_MAESTRO_12(MINI_MAESTRO_12, 0x008A),
	USB_MINI_MAESTRO_18(MINI_MAESTRO_18, 0x008B),
	USB_MINI_MAESTRO_24(MINI_MAESTRO_24, 0x008C);
	
	public static final short VENDOR_ID = 0x1ffb;
	
	private final MaestroCardType type;
	private final short productId;

	private UsbMaestroCardType(MaestroCardType type, int productId) {
		this.type = type;
		this.productId = (short)productId;
	}

	public MaestroCardType getType() {
		return type;
	}

	public short getProductId() {
		return productId;
	}

	public static UsbMaestroCardType cardTypeForUsbDeviceOrThrow(UsbDevice device) {
		return cardTypeForUsbDevice(device).orElseThrow(() -> new UsbRuntimeException("USB Device is not a Usb Maestro Card"));
	}

	public static boolean isAMaestroCard(UsbDevice device) {
		return cardTypeForUsbDevice(device).isPresent();
	}
	
	public static Optional<UsbMaestroCardType> cardTypeForUsbDevice(UsbDevice device) {

		return Stream.of(values()).filter(c -> vendorAndProductIdsMatch(VENDOR_ID, c.getProductId(), device)).findFirst();
