#ifndef LIBWIN32_FILLPLUGINS_H
#define LIBWIN32_FILLPLUGINS_H

#include <infotypes.h>
#include <default.h>
#include <fourcc.h>

static const char none_about[] =
    "No help available for this codec.";

static void add_divx(std::vector<CodecInfo>& ci)
{
    static const char divx_about[] =
	"Very popular MPEG-4 video codec, based on "
	"Microsoft MPEG-4 implementation. Advanced "
	"compression technologies allow it to "
	"compress 640x480x25 video with a perfect "
	"quality into 100-150 kbytes/s ( 3-4 times "
	"less than MPEG-2 ), by the cost of increased "
	"requirements for playback.<br>"
	"Web site: <a href=\"http://divx.ctw.cc\">http://divx.ctw.cc</a>";
    static const GUID wmv1_clsid =
    {
	0x4facbba1, 0xffd8, 0x4cd7,
	{0x82, 0x28, 0x61, 0xe2, 0xf6, 0x5c, 0xb1, 0xae}
    };
    static const GUID wmv2_clsid =
    {
	0x521fb373, 0x7654, 0x49f2,
	{0xbd, 0xb1, 0x0c, 0x6e, 0x66, 0x60, 0x71, 0x4f}
    };
#ifndef GUIDS_H
    static const GUID CLSID_DivxDecompressorCF =
    {
	0x82CCd3E0, 0xF71A, 0x11D0,
	{ 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}
    };
#endif
    static const int wmv1_codecs[] = { fccWMV1, fccwmv1, 0 };
    /* it may be able to decode wmv1, too */
    static const int wmv2_codecs[] = { fccWMV2, fccwmv2, 0 };
    /* divx is able to decode large variety of formats */
    static const int div3_codecsd[] = { fccDIV3, fccdiv3, fccDIV4, fccdiv4,
    				       fccDIV5, fccdiv5, fccDIV6, fccdiv6,
                                       fccMP41, fccMP43, fccmp43,
    				       fccAP41, fccap41, fccAP42, fccap42,
				       0 };
    static const int div3_codecs[] = { fccDIV3, fccdiv3, 0 };
    static const int div4_codecs[] = { fccDIV4, fccdiv4, 0 };
    // using different codec - divxcfvk.ax when available
    static const int div5_codecs[] = { fccDIV5, fccdiv5, fccDIV6, fccdiv6, 0 };
    static const int div6_codecs[] = { fccDIV6, fccdiv6, 0 };

// FIFO order is important - if this will ever change - few things
// would have to be repaired

    std::vector<AttributeInfo> vs;
    std::vector<AttributeInfo> ds;
    vs.push_back("BitRate");
    vs.push_back("Crispness");
    vs.push_back("KeyFrames");
    ds.push_back(AttributeInfo("Quality", "Quality/CPU balance ( 0 fastest )", AttributeInfo::Integer, 0, 4));

    std::vector<AttributeInfo> ds1;
    ds1.push_back(AttributeInfo("Quality", "Quality/CPU balance ( 0 fastest )", AttributeInfo::Integer, 0, 4));
    ds1.push_back(AttributeInfo("Saturation", "Saturation", AttributeInfo::Integer, 0, 100));
    ds1.push_back(AttributeInfo("Hue", "Hue", AttributeInfo::Integer, 0, 100));
    ds1.push_back(AttributeInfo("Brightness", "Brightness", AttributeInfo::Integer, 0, 100));
    ds1.push_back(AttributeInfo("Contrast", "Contrast", AttributeInfo::Integer, 0, 100));

    // DS player
    ci.push_back(CodecInfo(div5_codecs, "DivX ;-) low-motion VKI DirectShow",
			   "divxcvki.ax",
			   divx_about, CodecInfo::DShow_Dec,
			   CodecInfo::Video, CodecInfo::Decode,
			   &CLSID_DivxDecompressorCF, vs, ds1));
    // DS player
    ci.push_back(CodecInfo(div3_codecsd, "DivX ;-) low-motion DirectShow",
			   "divx_c32.ax",
			   divx_about, CodecInfo::DShow_Dec,
			   CodecInfo::Video, CodecInfo::Decode,
			   &CLSID_DivxDecompressorCF, vs, ds1));
    // for encoding
    ci.push_back(CodecInfo(div6_codecs, "DivX ;-) fast-motion VKI", "divxcfvk.dll",
			   divx_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both, 0, vs, ds));
    // for encoding
    ci.push_back(CodecInfo(div5_codecs,	"DivX ;-) low-motion VKI", "divxcvki.dll",
			   divx_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both, 0, vs, ds));
    // for encoding
    ci.push_back(CodecInfo(div4_codecs, "DivX ;-) fast-motion", "divxc32f.dll",
			   divx_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both, 0, vs, ds));
    // for encoding
    ci.push_back(CodecInfo(div3_codecs,	"DivX ;-) low-motion", "divxc32.dll",
			   divx_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both, 0, vs, ds));

    ci.push_back(CodecInfo(wmv1_codecs, "Windows Media Video 7 DirectShow",
			   "wmvds32.ax",
			   none_about, CodecInfo::DShow_Dec,
			   CodecInfo::Video, CodecInfo::Decode,
			   &wmv1_clsid, vs, ds1));
#if 1
    // crash with SIGFPE
    ci.push_back(CodecInfo(wmv2_codecs, "Windows Media Video 8 DirectShow Beta",
			   "wmv8ds32.ax",
			   none_about, CodecInfo::DShow_Dec,
			   CodecInfo::Video, CodecInfo::Decode,
			   &wmv2_clsid, vs, ds1));
#else
    // doesn't work at all
    ci.push_back(CodecInfo(wmv2_codecs,	"Windows Media Video 8 DirectShow Beta",
			   "wmv8dmod.dll",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));
#endif
}

static void add_angel(std::vector<CodecInfo>& ci)
{
    // crashing anyway - using divx instead of this
    const int apxx_codecs[] = { fccAP41, fccap41, fccAP42, fccap42, 0 };

    ci.push_back(CodecInfo(apxx_codecs, "AngelPotion MPEG-4", "apmpg4v1.dll",
			   none_about, CodecInfo::Win32));
}

static void add_ati(std::vector<CodecInfo>& ci)
{
    const int vcr1_codecs[] = { fccVCR1, 0 };
    const int vcr2_codecs[] = { fccVCR2, 0 };

    ci.push_back(CodecInfo(vcr1_codecs, "ATI VCR-1", "ativcr1.dll",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));

    ci.push_back(CodecInfo(vcr2_codecs, "ATI VCR-2", "ativcr2.dll",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));
}

static void add_asus(std::vector<CodecInfo>& ci)
{
    const int asv1_codecs[] = { fccASV1, 0 };
    const int asv2_codecs[] = { fccASV2, 0 };

    ci.push_back(CodecInfo(asv1_codecs, "ASUS V1 - crash", "asusasvd.dll",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));

    ci.push_back(CodecInfo(asv2_codecs, "ASUS V2", "asusasv2.dll",
			   none_about, CodecInfo::Win32,
                           CodecInfo::Video, CodecInfo::Decode));
}

static void add_dvsd(std::vector<CodecInfo>& ci)
{
    static const char dvsd_about[] = "Sony Digital Video (DV)";
    static const int dvsd_codecs[] = { fccdvsd,	0 };
    static const GUID dvsd_clsid =
    {
	0xB1B77C00, 0xC3E4, 0x11CF,
	{0xAF, 0x79, 0x00, 0xAA, 0x00, 0xB6, 0x7A, 0x42}
    };
    ci.push_back(CodecInfo(dvsd_codecs,	"DVSD",	"qdv.dll",
			   dvsd_about, CodecInfo::DShow_Dec,
			   CodecInfo::Video, CodecInfo::Decode,
			   &dvsd_clsid));
    //  not a true Win32 library
    //ci.push_back(CodecInfo(dvsd_codecs,
    //    				"DVSD",	"qdv.dll",
    //    				dvsd_about, CodecInfo::Win32,
    //    				CodecInfo::Video, CodecInfo::Both));
}

static void add_opendivx(std::vector<CodecInfo>& ci)
{
    // crash - do not use with Windows DLL
    // External func COMCTL32.dll:17
    // Called unk_GetCursorPos
    // avi: line 4: 15263 (SIGSEGV) (core dumped) aviplay avi

    static const char opendix_about[] = "OpenDivX MPEG-4";
    static const int opendix_codecs[] = { fccDIVX, fccdivx, fccDIV1, fccdiv1, fccMP4S, fccmp4s, 0x4, 0 };
    ci.push_back(CodecInfo(opendix_codecs, "DIVX", "divx.dll",
			   opendix_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));
}

static void add_indeo(std::vector<CodecInfo>& ci)
{
    static const char ivxx_about[] =
	"A set of wavelet video codecs, developed "
	"by Intel and currently owned by Ligos corp. "
	"Indeo Video 5.0 with turned on \"QuickCompress\" "
	"option is a good choice for real-time video "
	"capture - it is faster than DivX ;-) and compresses "
	"data better than Motion JPEG.<br>"
	"Home page:<a href=\"http://www.ligos.com/indeo\"> http://www.ligos.com/indeo</a>";
#ifndef GUIDS_H
    static const GUID CLSID_IV50_Decoder =
    {
	0x30355649, 0x0000, 0x0010,
	{0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
    };
#endif
    static const int iv50_codecs[] = { fccIV50, fcciv50, 0 };
    static const int iv41_codecs[] = { fccIV41, fcciv41, 0 };
    static const int iv32_codecs[] = { fccIV32, fcciv32, 0 };
    static const int iv31_codecs[] = { fccIV31, fcciv31, 0 };
    std::vector<AttributeInfo> vs;
    std::vector<AttributeInfo> ds;

    ds.push_back(AttributeInfo("Saturation", "Saturation", AttributeInfo::Integer, -100, 100));
    ds.push_back(AttributeInfo("Brightness", "Brightness", AttributeInfo::Integer, -100, 100));
    ds.push_back(AttributeInfo("Contrast", "Contrast", AttributeInfo::Integer, -100, 100));
    ci.push_back(CodecInfo(iv50_codecs, "Indeo Video 5.0 DirectShow", "ir50_32.dll",
			   ivxx_about, CodecInfo::DShow_Dec,
			   CodecInfo::Video, CodecInfo::Decode,
			   &CLSID_IV50_Decoder, vs, ds));
    vs.push_back("QuickCompress");
    ci.push_back(CodecInfo(iv50_codecs, "Indeo Video 5.0", "ir50_32.dll",
			   ivxx_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both, 0, vs));
    ci.push_back(CodecInfo(iv41_codecs,	"Indeo Video 4.1", "ir41_32.dll",
			   ivxx_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both, 0, vs));
    ci.push_back(CodecInfo(iv32_codecs, "Indeo Video 3.2", "ir32_32.dll",
			   ivxx_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both));
    ci.push_back(CodecInfo(iv31_codecs, "Indeo Video 3.1", "ir32_32.dll",
			   ivxx_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));
}

static void add_morgan(std::vector<CodecInfo>& ci)
{
    static const char mjpg_about[] =
	"Very fast Motion JPEG video codec, by Morgan "
	"Multimedia company. Recommended for "
	"video capture on slow machines or in high "
	"resolutions. Shareware. Current version "
	"is time-limited and will stop working after "
	"Mar. 1, 2001. Registration costs $25. Visit "
	"their web site for details.<br>"
	"Web site: <a href=\"http://www.morgan-multimedia.com\">http://www.morgan-multimedia.com</a>";
    static const GUID CLSID_MorganMjpeg =
    {
	0x6988b440, 0x8352, 0x11d3,
	{0x9b, 0xda, 0xca, 0x86, 0x73, 0x7c, 0x71, 0x68}
    };
    static const int mjpg_codecs[] = { fccMJPG, fccmjpg, 0 };

    static const char* mjpeg_modes[] =
    {
	"Fast integer",	"Integer", "Float", 0
    };

    std::vector<AttributeInfo> vs;

    vs.push_back(AttributeInfo("Mode", "Calculation precision mode", (const char**)mjpeg_modes));
    vs.push_back(AttributeInfo("LicenseKey", "License key", AttributeInfo::String));
    vs.push_back(AttributeInfo("UserName", "User name", AttributeInfo::String));
//    ci.push_back(CodecInfo(mjpg_codecs, "Motion JPEG DirectShow Decoder", 	"m3jpegdec.ax",mjpg_about, CodecInfo::DShow_Dec, &CLSID_MorganMjpeg, vs));
    ci.push_back(CodecInfo(mjpg_codecs, "Motion JPEG", "m3jpeg32.dll",
			   mjpg_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both,
			   0, vs));
}

static void add_huffyuv(std::vector<CodecInfo>& ci)
{
    static const char huffyuv_about[] =
	"Web site: <a href=\"http://TO BE ADDED\"></a>";
    static const int huffyuv_codecs[] = { fccHFYU, 0 };
    static const char* huffyuv_modes[] =
    {
	"Predict left (fastest)",
	"Predict gradient",
	"Predict median (best)",
	0
    };

    std::vector<AttributeInfo> vs;

    //vs.push_back(AttributeInfo("Mode", "Calculation precision mode", (const char**)mjpeg_modes));
    //ci.push_back(CodecInfo(mjpg_codecs, "Motion JPEG DirectShow Decoder", 	"m3jpegdec.ax",mjpg_about, CodecInfo::DShow_Dec, &CLSID_MorganMjpeg, vs));

    ci.push_back(CodecInfo(huffyuv_codecs, "Huffyuv", "huffyuv.dll",
			   huffyuv_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Both));
}

static void add_audio(std::vector<CodecInfo>& ci)
{
    static const int adpcm_codecs[] = { 2, 0 };
    ci.push_back(CodecInfo(adpcm_codecs, "MS ADPCM", "msadp32.acm",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Audio, CodecInfo::Decode));
/*
    static const int imaadpcm_codecs[] = { 0x11, 0 };
    ci.push_back(CodecInfo(imaadpcm_codecs, "IMA ADPCM", "imaadp32.acm",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Audio, CodecInfo::Decode));
*/
    static const GUID CLSID_Voxware =
    {
	0x73f7a062, 0x8829, 0x11d1,
	{ 0xb5, 0x50, 0x00, 0x60, 0x97, 0x24, 0x2d, 0x8d }
    };
    static const int voxware_codecs[]={ 0x75, 0};
    ci.push_back(CodecInfo(voxware_codecs, "Voxware Metasound", "voxmsdec.ax",
			   none_about, CodecInfo::DShow_Dec,
			   CodecInfo::Audio, CodecInfo::Decode,
			   &CLSID_Voxware));

    static const GUID CLSID_Acelp =
    {
	0x4009f700, 0xaeba, 0x11d1,
	{ 0x83, 0x44, 0x00, 0xc0, 0x4f, 0xb9, 0x2e, 0xb7 }
    };
    static const int acelp_codecs[]={ 0x130, 0 };
    ci.push_back(CodecInfo(acelp_codecs, "ACELP.net", "acelpdec.ax",
			   none_about, CodecInfo::DShow_Dec,
			   CodecInfo::Audio, CodecInfo::Decode,
			   &CLSID_Acelp));

    static const int wma_codecs[] = { 0x160, 0x161, 0 };
    ci.push_back(CodecInfo(wma_codecs, "Windows Media Audio", "divxa32.acm",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Audio, CodecInfo::Decode));

    static const int imc_codecs[] = { 0x401, 0 };
    ci.push_back(CodecInfo(imc_codecs, "Intel Music Coder", "imc32.acm",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Audio, CodecInfo::Decode));

#if 0
    // works now - but I'm suspecting it cause complete deadlock
    // of kernel from time to time - it might be the internall
    // fault of tihs codec - anyway later I'll try to make this optional
    static const int mpeg_codecs[] = { 0x55, 0 };
    ci.push_back(CodecInfo(mpeg_codecs, "MPEG Layer-3", "l3codecx.acm",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Audio, CodecInfo::Decode));
#endif
#if 0
    // this works but only as a last resource - it has quite poor quality
    static const int mpeg_codecs[] = { 0x55, 0 };
    ci.push_back(CodecInfo(mpeg_codecs, "MPEG Layer-3", "divxa32.acm",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Audio, CodecInfo::Decode));
#endif

}


static void libwin32_FillPlugins(std::vector<CodecInfo>& ci)
{
    // disabled when crashing
    // add_angel(ci); - using divx instead
    add_divx(ci);
    add_ati(ci);
    add_asus(ci);
    // add_opendivx(ci);
    add_dvsd(ci);
    add_indeo(ci);
    add_morgan(ci);
    add_huffyuv(ci);

    add_audio(ci);
    //0x5f3647a1, 0x8829, 0x11d1, 0xb5, 0x50, 0x00, 0x60, 0x97, 0x24, 0x2d, 0x8d};
    //0x46e32b01, 0x8829, 0x11d1, 0xb5, 0x50, 0x00, 0x60, 0x97, 0x24, 0x2d, 0x8d};
    //0x73f7a063, 0x8829, 0x11d1, 0xb5, 0x50, 0x00, 0x60, 0x97, 0x24, 0x2d, 0x8d};

    //const int zero[]={ 0 };
    static const char mpg4_about[] =
	"Old beta version of Microsoft MPEG-4 "
	"video codec, incompatible with DivX ;-).";
    static const int mpg4_codecs[]=
    {
	fccMP42, fccmp42, fccmp43,
        fccMPG4, fccmpg4, fccDIV2, fccdiv2, 0
    };
    ci.push_back(CodecInfo(mpg4_codecs, "Microsoft MPEG-4", "mpg4c32.dll",
			   mpg4_about, CodecInfo::Win32));

    static const char cvid_about[] =
	"Very old video codec, usually "
	"available as a part of Windows.";
    static const int cvid_codecs[] = { fcccvid, 0 };
    ci.push_back(CodecInfo(cvid_codecs, "Cinepak Video", "iccvid.dll",
			   cvid_about, CodecInfo::Win32));

    static const int i263_codecs[] = { fcci263,	fccI263, 0 };
    ci.push_back(CodecInfo(i263_codecs,	"I263", "i263_32.drv",
			   none_about, CodecInfo::Win32));

    static const int mwv1_codecs[] = { fccMWV1, 0 };
    ci.push_back(CodecInfo(mwv1_codecs,	"Motion Wavelets", "icmw_32.dll",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));

    static const int mszh_codecs[] = { fccMSZH, 0 };
    ci.push_back(CodecInfo(mszh_codecs,	"AVImszh", "avimszh.dll",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));

    static const int zlib_codecs[] = { fccZLIB, 0 };
    ci.push_back(CodecInfo(zlib_codecs,	"AVIzlib", "avizlib.dll",
			   none_about, CodecInfo::Win32,
			   CodecInfo::Video, CodecInfo::Decode));

#if 0
    /*
     * crash with:  External func COMCTL32.dll:17 (SIGILL)
     */
    static const GUID CLSID_Tm20 =
    {
        0x4cb63e61, 0xc611, 0x11D0,
	{ 0x83, 0xaa, 0x00, 0x00, 0x92, 0x90, 0x01, 0x84 }
    };
    static const int tm20_codecs[] = { fccTM20, 0 };
    ci.push_back(CodecInfo(tm20_codecs,	"TrueMotion 2.0", "tm20dec.ax",
			   none_about, CodecInfo::DShow_Dec,
			   CodecInfo::Video, CodecInfo::Decode,
			   &CLSID_Tm20));
#endif
    static const int cram_codecs[] = { fccCRAM, fcccram, fccMSVC, 0 };
    ci.push_back(CodecInfo(cram_codecs,	"Microsoft Video 1", "msvidc32.dll",
			   none_about, CodecInfo::Win32));
}

#endif
