/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void Jpeg2000ReaderPluginFactory::describeInContext( OFX::ImageEffectDescriptor &desc,
						   OFX::EContext context )
{
    OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );
    dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
    dstClip->addSupportedComponent( OFX::ePixelComponentRGB );
    dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
    dstClip->setSupportsTiles( kSupportTiles );

    describeReaderParamsInContext( desc, context );
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void EXRReaderPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,
						OFX::EContext               context )
{
	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGB );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( kSupportTiles );

	describeReaderParamsInContext( desc, context );

	OFX::ChoiceParamDescriptor* outRedIs = desc.defineChoiceParam( kParamOutputRedIs );
	outRedIs->appendOption( "0" );
	outRedIs->appendOption( "1" );
	outRedIs->appendOption( "2" );
	outRedIs->appendOption( "3" );
	outRedIs->setLabel( "Red is" );
	outRedIs->setDefault( 0 );

	OFX::ChoiceParamDescriptor* outGreenIs = desc.defineChoiceParam( kParamOutputGreenIs );
	outGreenIs->appendOption( "0" );
	outGreenIs->appendOption( "1" );
	outGreenIs->appendOption( "2" );
	outGreenIs->appendOption( "3" );
	outGreenIs->setLabel( "Green is" );
	outGreenIs->setDefault( 0 );

	OFX::ChoiceParamDescriptor* outBlueIs = desc.defineChoiceParam( kParamOutputBlueIs );
	outBlueIs->appendOption( "0" );
	outBlueIs->appendOption( "1" );
	outBlueIs->appendOption( "2" );
	outBlueIs->appendOption( "3" );
	outBlueIs->setLabel( "Blue is" );
	outBlueIs->setDefault( 0 );

	OFX::ChoiceParamDescriptor* outAlphaIs = desc.defineChoiceParam( kParamOutputAlphaIs );
	outAlphaIs->appendOption( "0" );
	outAlphaIs->appendOption( "1" );
	outAlphaIs->appendOption( "2" );
	outAlphaIs->appendOption( "3" );
	outAlphaIs->setLabel( "Alpha is" );
	outAlphaIs->setDefault( 0 );
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void AVReaderPluginFactory::describeInContext(OFX::ImageEffectDescriptor& desc, OFX::EContext context)
{
    // Create the mandated output clip
    OFX::ClipDescriptor* dstClip = desc.defineClip(kOfxImageEffectOutputClipName);
    dstClip->addSupportedComponent(OFX::ePixelComponentRGBA);
    dstClip->addSupportedComponent(OFX::ePixelComponentRGB);
    dstClip->addSupportedComponent(OFX::ePixelComponentAlpha);
    dstClip->setSupportsTiles(kSupportTiles);

    describeReaderParamsInContext(desc, context);

    // Groups
    OFX::GroupParamDescriptor* formatGroup = desc.defineGroupParam(kParamFormatGroup);
    OFX::GroupParamDescriptor* videoGroup = desc.defineGroupParam(kParamVideoGroup);
    OFX::GroupParamDescriptor* metaGroup = desc.defineGroupParam(kParamMetaGroup);

    formatGroup->setLabel("Format");
    videoGroup->setLabel("Video");
    metaGroup->setLabel("Metadata");

    formatGroup->setAsTab();
    videoGroup->setAsTab();
    metaGroup->setAsTab();

    /// FORMAT PARAMETERS
    avtranscoder::FormatContext formatContext(AV_OPT_FLAG_DECODING_PARAM);
    avtranscoder::OptionArray formatOptions = formatContext.getOptions();
    common::addOptionsToGroup(desc, formatGroup, formatOptions, common::kPrefixFormat);

    OFX::GroupParamDescriptor* formatDetailedGroup = desc.defineGroupParam(kParamFormatDetailedGroup);
    formatDetailedGroup->setLabel("Detailed");
    formatDetailedGroup->setAsTab();
    formatDetailedGroup->setParent(formatGroup);

    avtranscoder::OptionArrayMap formatDetailedGroupOptions = avtranscoder::getAvailableOptionsPerOutputFormat();
    common::addOptionsToGroup(desc, formatDetailedGroup, formatDetailedGroupOptions, common::kPrefixFormat);

    /// VIDEO PARAMETERS
    AVCodecContext* videoContext = avcodec_alloc_context3(NULL);
    avtranscoder::OptionArray videoOptions;
    avtranscoder::loadOptions(videoOptions, videoContext, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM);
    common::addOptionsToGroup(desc, videoGroup, videoOptions, common::kPrefixVideo);
    av_free(videoContext);

    OFX::BooleanParamDescriptor* useCustomSAR = desc.defineBooleanParam(kParamUseCustomSAR);
    useCustomSAR->setLabel("Override SAR");
    useCustomSAR->setDefault(false);
    useCustomSAR->setHint("Override the file SAR (Storage Aspect Ratio) with a custom SAR value.");
    useCustomSAR->setParent(videoGroup);

    OFX::DoubleParamDescriptor* customSAR = desc.defineDoubleParam(kParamCustomSAR);
    customSAR->setLabel("Custom SAR");
    customSAR->setDefault(1.0);
    customSAR->setDisplayRange(0., 3.);
    customSAR->setRange(0., 10.);
    customSAR->setHint("Choose a custom value to override the file SAR (Storage Aspect Ratio). Maximum value: 10.");
    customSAR->setParent(videoGroup);

    OFX::IntParamDescriptor* streamIndex = desc.defineIntParam(kParamVideoStreamIndex);
    streamIndex->setLabel(kParamVideoStreamIndexLabel);
    streamIndex->setDefault(0);
    streamIndex->setDisplayRange(0., 16.);
    streamIndex->setRange(0., 100.);
    streamIndex->setHint("Choose a custom value to decode the video stream you want. Maximum value: 100.");
    streamIndex->setParent(videoGroup);

    OFX::GroupParamDescriptor* videoDetailedGroup = desc.defineGroupParam(kParamVideoDetailedGroup);
    videoDetailedGroup->setLabel("Detailed");
    videoDetailedGroup->setAsTab();
    videoDetailedGroup->setParent(videoGroup);

    avtranscoder::OptionArrayMap videoDetailedGroupOptions = avtranscoder::getAvailableOptionsPerVideoCodec();
    common::addOptionsToGroup(desc, videoDetailedGroup, videoDetailedGroupOptions, common::kPrefixVideo);

    /// METADATA PARAMETERS
    AVCodecContext* metaDataContext = avcodec_alloc_context3(NULL);
    avtranscoder::OptionArray metaDataOptions;
    avtranscoder::loadOptions(metaDataOptions, metaDataContext, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_METADATA);
    common::addOptionsToGroup(desc, metaGroup, metaDataOptions, common::kPrefixMetaData);
    av_free(metaDataContext);

    OFX::StringParamDescriptor* metaDataWrapper = desc.defineStringParam(kParamMetaDataWrapper);
    metaDataWrapper->setLabel(kParamMetaDataWrapperLabel);
    metaDataWrapper->setEnabled(false);
    metaDataWrapper->setStringType(OFX::eStringTypeMultiLine);
    metaDataWrapper->setParent(metaGroup);

    OFX::StringParamDescriptor* metaDataVideo = desc.defineStringParam(kParamMetaDataVideo);
    metaDataVideo->setLabel(kParamMetaDataVideoLabel);
    metaDataVideo->setEnabled(false);
    metaDataVideo->setStringType(OFX::eStringTypeMultiLine);
    metaDataVideo->setParent(metaGroup);

    OFX::StringParamDescriptor* metaDataAudio = desc.defineStringParam(kParamMetaDataAudio);
    metaDataAudio->setLabel(kParamMetaDataAudioLabel);
    metaDataAudio->setEnabled(false);
    metaDataAudio->setStringType(OFX::eStringTypeMultiLine);
    metaDataAudio->setParent(metaGroup);

    OFX::StringParamDescriptor* metaDataData = desc.defineStringParam(kParamMetaDataData);
    metaDataData->setLabel(kParamMetaDataDataLabel);
    metaDataData->setEnabled(false);
    metaDataData->setStringType(OFX::eStringTypeMultiLine);
    metaDataData->setParent(metaGroup);

    OFX::StringParamDescriptor* metaDataSubtitle = desc.defineStringParam(kParamMetaDataSubtitle);
    metaDataSubtitle->setLabel(kParamMetaDataSubtitleLabel);
    metaDataSubtitle->setEnabled(false);
    metaDataSubtitle->setStringType(OFX::eStringTypeMultiLine);
    metaDataSubtitle->setParent(metaGroup);

    OFX::StringParamDescriptor* metaDataAttachement = desc.defineStringParam(kParamMetaDataAttachement);
    metaDataAttachement->setLabel(kParamMetaDataAttachementLabel);
    metaDataAttachement->setEnabled(false);
    metaDataAttachement->setStringType(OFX::eStringTypeMultiLine);
    metaDataAttachement->setParent(metaGroup);

    OFX::StringParamDescriptor* metaDataUnknown = desc.defineStringParam(kParamMetaDataUnknown);
    metaDataUnknown->setLabel(kParamMetaDataUnknownLabel);
    metaDataUnknown->setEnabled(false);
    metaDataUnknown->setStringType(OFX::eStringTypeMultiLine);
    metaDataUnknown->setParent(metaGroup);

    /// VERBOSE
    OFX::BooleanParamDescriptor* useVerbose = desc.defineBooleanParam(kParamVerbose);
    useVerbose->setLabel("Set to verbose");
    useVerbose->setDefault(false);
    useVerbose->setHint("Set plugin to verbose to get debug informations.");
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void EXRReaderPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,
						OFX::EContext               context )
{
	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGB );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( kSupportTiles );

	describeReaderParamsInContext( desc, context );

	OFX::ChoiceParamDescriptor* outRedIs = desc.defineChoiceParam( kParamOutputRedIs );
	outRedIs->appendOption( "0" );
	outRedIs->appendOption( "1" );
	outRedIs->appendOption( "2" );
	outRedIs->appendOption( "3" );
	outRedIs->setLabel( "Red is" );
	outRedIs->setDefault( 0 );
	outRedIs->setHint(
		"Read-only information to get index of red component in the file.");

	OFX::ChoiceParamDescriptor* outGreenIs = desc.defineChoiceParam( kParamOutputGreenIs );
	outGreenIs->appendOption( "0" );
	outGreenIs->appendOption( "1" );
	outGreenIs->appendOption( "2" );
	outGreenIs->appendOption( "3" );
	outGreenIs->setLabel( "Green is" );
	outGreenIs->setDefault( 0 );
	outGreenIs->setHint(
		"Read-only information to get index of green component in the file.");

	OFX::ChoiceParamDescriptor* outBlueIs = desc.defineChoiceParam( kParamOutputBlueIs );
	outBlueIs->appendOption( "0" );
	outBlueIs->appendOption( "1" );
	outBlueIs->appendOption( "2" );
	outBlueIs->appendOption( "3" );
	outBlueIs->setLabel( "Blue is" );
	outBlueIs->setDefault( 0 );
	outBlueIs->setHint(
		"Read-only information to get index of blue component in the file.");

	OFX::ChoiceParamDescriptor* outAlphaIs = desc.defineChoiceParam( kParamOutputAlphaIs );
	outAlphaIs->appendOption( "0" );
	outAlphaIs->appendOption( "1" );
	outAlphaIs->appendOption( "2" );
	outAlphaIs->appendOption( "3" );
	outAlphaIs->setLabel( "Alpha is" );
	outAlphaIs->setDefault( 0 );
	outAlphaIs->setHint(
		"Read-only information to get index of alpha component in the file.");

	OFX::ChoiceParamDescriptor* outputData = desc.defineChoiceParam( kParamOutputData );
	outputData->appendOption( "display" );
	outputData->appendOption( "data" );
	outputData->setLabel( "Output Data" );
	outputData->setDefault( 0 );

	OFX::ChoiceParamDescriptor* fileBitDepth = desc.defineChoiceParam( kParamFileBitDepth );
	fileBitDepth->setLabel( "File Bit Depth" );
	fileBitDepth->appendOption( kTuttlePluginBitDepth16f );
	fileBitDepth->appendOption( kTuttlePluginBitDepth32 );
	fileBitDepth->appendOption( kTuttlePluginBitDepth32f );
	fileBitDepth->appendOption( kTuttlePluginBitDepthNone );
	fileBitDepth->setDefault( eTuttlePluginFileBitDepthNone );
	fileBitDepth->setHint(
		"Read-only information about the image bit depth stored in the file.\n"
		"Data type is per channel in EXR. So we read the type of the first channel.");

	OFX::ChoiceParamDescriptor* compression = desc.defineChoiceParam( kParamCompression );
	compression->setLabel( "Compression" );
	compression->appendOption( kParamCompressionNone, kParamCompressionHintNone );
	compression->appendOption( kParamCompressionRLE, kParamCompressionHintRLE );
	compression->appendOption( kParamCompressionZIPS, kParamCompressionHintZIPS );
	compression->appendOption( kParamCompressionZIP, kParamCompressionHintZIP );
	compression->appendOption( kParamCompressionPIZ, kParamCompressionHintPIZ );
	compression->appendOption( kParamCompressionPXR24, kParamCompressionHintPXR24 );
	compression->appendOption( kParamCompressionB44, kParamCompressionHintB44 );
	compression->appendOption( kParamCompressionB44A, kParamCompressionHintB44A );
	compression->setDefault( eParamCompression_None );
	compression->setHint(
		"Read-only information about the image compression stored in the file.");
}