/**
 * \brief Get a list of interface association Descriptors from the device
 */
std::list<USBDescriptorPtr>	Device::interfaceAssociationDescriptors(
					bool videoonly) throw(USBError) {
	std::list<USBDescriptorPtr>	iadescriptors;

	// see whether there is any additional data that could contain
	// an interface association descriptor
	ConfigurationPtr	config = activeConfig();
	if (config->extra().size() == 0) {
		debug(LOG_DEBUG, DEBUG_LOG, 0, "no data for descriptors");
		return iadescriptors;
	}

	// try to parse additional descriptors
	DescriptorFactory	f(*this);
	std::vector<USBDescriptorPtr>	list = f.descriptors(config->extra());
	debug(LOG_DEBUG, DEBUG_LOG, 0, "found %d additional descriptors",
		list.size());

	// no check whether they are InterfaceAssociationDescriptors
	std::vector<USBDescriptorPtr>::const_iterator	i;
	for (i = list.begin(); i != list.end(); i++) {
		USBDescriptorPtr	dp = *i;
		if (isPtr<InterfaceAssociationDescriptor>(dp)) {
			InterfaceAssociationDescriptor	*iad
				= getPtr<InterfaceAssociationDescriptor>(dp);
			bool	isvideo = iad->isVideoInterfaceCollection();
			debug(LOG_DEBUG, DEBUG_LOG, 0, "isvideo = %s",
				(isvideo) ? "YES" : "NO");
			if ((!videoonly) || (isvideo)) {
				iadescriptors.push_back(dp);
			}
		}
	}

	// return all the interface association descriptors we have found
	return iadescriptors;
}
/**
 * \brief Construct a camera from a USB Device
 *
 * The constructor undertakes an extensive analysis of the descriptors
 * to find the video control and video streaming interfaces of the video
 * function of the device. It also makes sure no kernel driver is attached
 * to the device. It does not, however, claim any of the interfaces, this
 * is done when the device is really used.
 * \param _device	an USB device to open as a UVC camera
 * \param force		force opening as camera even if the
 *			interface associaten descriptor does not
 *			declare itself as a video interface association
 *                      descriptor (handles the TIS camera)
 * XXX apparently the force parameter is never used, so the question should be
 *     asked whether we can remove it.
 */
UVCCamera::UVCCamera(Device& _device, bool /* force */) throw(USBError)
	: device(_device) {
	debug(LOG_DEBUG, DEBUG_LOG, 0, "create a UVC camera object");

	// make sure the camera is open, this most probably will not have
	// any effect
	device.open();

	// scan the active configuration for one that has an Interface
	// association descriptor
	ConfigurationPtr config = device.activeConfig();
	if (config->extra().size() == 0) {
		debug(LOG_ERR, DEBUG_LOG, 0, "no extra descriptors");
		throw USBError("no InterfaceAssociationDescriptor");
	}

	// get the list of interface association descriptors
	std::list<USBDescriptorPtr>	iadlist
		= device.interfaceAssociationDescriptors(true);
	if (0 == iadlist.size()) {
		throw USBError("no Video Interface Association found");
	}
	iadptr = *iadlist.begin();
	debug(LOG_DEBUG, DEBUG_LOG, 0, "Video Interface Association found");

	// get the control interface, and the list of interface descriptors
	// for the control interface, and claim it
	uint8_t	ci = controlInterfaceNumber();
	videocontrol = (*config)[ci];
	debug(LOG_DEBUG, DEBUG_LOG, 0, "Control interface number: %d", ci);
	videocontrol->detachKernelDriver();

	// we also need to know all the video control descriptors appended
	// to this InterfaceDescriptor. The VideoControlDescriptorFactory
	// does that.
	debug(LOG_DEBUG, DEBUG_LOG, 0, "parse the video control descriptors");
	InterfaceDescriptorPtr	controlinterface = (*videocontrol)[0];
	VideoControlDescriptorFactory	vcdf(device);
	videocontroldescriptors = vcdf.descriptors(controlinterface->extra());
	std::cout << videocontroldescriptors[0];
	
	// now claim get the various interface descriptors, i.e. the
	// alternate settings for an interface
	int	interfacecount = iad().bInterfaceCount();
	debug(LOG_DEBUG, DEBUG_LOG, 0, "interfaces in association: %d",
		interfacecount);

	// now parse the video streaming interfaces
	debug(LOG_DEBUG, DEBUG_LOG, 0, "parse streaming interface descriptors");
	VideoStreamingDescriptorFactory	vsf(device);
	for (int vsif = controlInterfaceNumber() + 1;
		vsif < controlInterfaceNumber() + iad().bInterfaceCount();
		vsif++) {
		debug(LOG_DEBUG, DEBUG_LOG, 0,
			"analyzing video streaming interface %d", vsif);
		InterfacePtr	interface = (*config)[vsif];
		// only alternate setting 0 contains the formats
		InterfaceDescriptorPtr	id = (*interface)[0];
		std::string	extra = id->extra();
		debug(LOG_DEBUG, DEBUG_LOG, 0, "extra descriptors: %d bytes",
			extra.size());
		USBDescriptorPtr	vsd = vsf.descriptor(extra);
		debug(LOG_DEBUG, DEBUG_LOG, 0, "parse complete");
		videostreaming.push_back(vsd);
	}
	debug(LOG_DEBUG, DEBUG_LOG, 0, "UVCCamera constructed");
}