#include "CinepakAddon.h"
#include "Cinepak.h"

#include <media2/MediaDefs.h>
#include <media2/MediaConstraint.h>

#include <string.h>
#include <malloc.h>

using namespace B::Media2;

CCinepakAddon::CCinepakAddon(image_id image)
	: BMediaAddon(image)
{
	memset(&mFlavor,0,sizeof(mFlavor));
	
	mFlavor.name=strdup("cinepak.decoder");
	mFlavor.info=strdup("this node decodes encoded cinepak data producing raw-video");
	mFlavor.kinds=0;
	mFlavor.flavor_flags=0;
	mFlavor.internal_id=0;
	mFlavor.possible_count=0;

	BMediaConstraint c(B_FORMATKEY_MEDIA_TYPE,BValue::Int32(B_MEDIA_ENCODED_VIDEO));
	c.And(B_FORMATKEY_WIDTH,BMediaConstraintItem::B_GE,BValue::Int32(1));
	c.And(B_FORMATKEY_HEIGHT,BMediaConstraintItem::B_GE,BValue::Int32(1));

	c.And(B_FORMATKEY_ENCODING,BValue()
								.Overlay(BValue::String("be:avi:cvid")));	

	mFlavor.in_formats=new BMediaConstraint(c);

	c=BMediaConstraint(B_FORMATKEY_MEDIA_TYPE,BValue::Int32(B_MEDIA_RAW_VIDEO));
	c.And(B_FORMATKEY_WIDTH,BMediaConstraintItem::B_GE,BValue::Int32(1));
	c.And(B_FORMATKEY_HEIGHT,BMediaConstraintItem::B_GE,BValue::Int32(1));

	BValue color_spaces;
#if defined(__INTEL__) || defined(__ARMEL__)	/* FIXME: This should probably use <endian.h> for the right define */
	color_spaces.Overlay(BValue::Int32(B_RGB32));
	color_spaces.Overlay(BValue::Int32(B_RGB16));
	color_spaces.Overlay(BValue::Int32(B_RGB15));		
	color_spaces.Overlay(BValue::Int32(B_YCbCr422));
#else
	color_spaces.Overlay(BValue::Int32(B_RGB32_BIG));
	color_spaces.Overlay(BValue::Int32(B_RGB16_BIG));
	color_spaces.Overlay(BValue::Int32(B_RGB15_BIG));		
#endif
					
	c.And(B_FORMATKEY_COLORSPACE,color_spaces);

	mFlavor.out_formats=new BMediaConstraint(c);
}

CCinepakAddon::~CCinepakAddon()
{
	delete mFlavor.out_formats;
	delete mFlavor.in_formats;
	free(mFlavor.info);
	free(mFlavor.name);
}

status_t 
CCinepakAddon::InitCheck(const char **out_failure_text)
{
	static const char *kOkText="everything is just fine.";
	
	*out_failure_text=kOkText;
	
	return B_OK;
}

int32 
CCinepakAddon::CountFlavors()
{
	return 1;
}

status_t 
CCinepakAddon::GetFlavorAt(int32 n, const flavor_info **out_info)
{
	if (n>0)
		return B_ENTRY_NOT_FOUND;
		
	*out_info=&mFlavor;
	
	return B_OK;
}

BMediaNode *
CCinepakAddon::InstantiateNodeFor(const flavor_info *info, status_t *out_error)
{
	if (info!=&mFlavor)
	{
		*out_error=B_BAD_VALUE;
		return NULL;
	}
		
	*out_error=B_OK;
	
	return new B::Private::CinepakDecoder;	
}

BMediaAddon *
make_media_addon (image_id image)
{
	return new CCinepakAddon(image);
}

