#include "StdAfx.h"
//#include <InitGuid.h>
#include <streams.h>
#include <jni.h>
#include <dshow.h>
#include <D3d9.h>
#include <Vmr9.h>
#include <Dvdmedia.h>
#include <Evr.h>
#include "JVideoRenderer.h"
#include "DSMediaDecodingPlayer.h"

// BLA TEST

JVideoRenderer::JVideoRenderer(LPUNKNOWN pUnk,HRESULT *phr,DSMediaDecodingPlayer *inMdp) :
CBaseVideoRenderer(CLSID_JVideoRenderer,NAME("JVideoRenderer"), pUnk,phr)
{
	mdp=inMdp;
}

HRESULT JVideoRenderer::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr, DSMediaDecodingPlayer *inMdp, JVideoRenderer **ppJvr)
{
	if (ppJvr == NULL)
	{
		return E_POINTER;
	}
	
	JVideoRenderer *pJvr = new (std::nothrow) JVideoRenderer(pUnk,phr, inMdp);
	if (pJvr == NULL)
	{
		return E_OUTOFMEMORY;
	}
	*ppJvr = pJvr;
	pJvr->AddRef();
	return S_OK;
}

void JVideoRenderer::setMdp(DSMediaDecodingPlayer *inMdp){
	mdp=inMdp;
}

HRESULT __stdcall JVideoRenderer::QueryInterface(REFIID refIid, void **ppObj){
	if (refIid == IID_IUnknown){
		*ppObj = this;
		AddRef();
		return S_OK;
	}
	else if (refIid == CLSID_JVideoRenderer){
		*ppObj = this;
		AddRef();
		return S_OK;
	}
	else{
		return CBaseVideoRenderer::QueryInterface(refIid, ppObj);

	}
}

// CheckMediaType
//
// Check if the pin can support this specific proposed type and format
//
HRESULT JVideoRenderer::CheckMediaType(const CMediaType *mediaType)
{
	HRESULT hr=S_FALSE;
	//const GUID *formatType=mediaType->FormatType();
	//printf("Major format: %s\n",GuidNames[mediaType->majortype]);
	//printf("Sub format: %s\n",GuidNames[mediaType->subtype]);

	// Accept only RGB formats for now
	// TODO should depend on renderer mode, RGB only is only required for Swing/JavaFX painting 
	// 
	if(mediaType->majortype == MEDIATYPE_Video){
		
		if(mediaType->subtype == MEDIASUBTYPE_RGB24){
			//printf("RGB 24\n");
			hr=S_OK;
		}
		else 
		if(mediaType->subtype == MEDIASUBTYPE_ARGB32){
			hr=S_OK;
		}
		else
		if (mediaType->subtype == MEDIASUBTYPE_RGB32){
			mediaType->formattype;
			hr = S_OK;
		}
		else{
			//printf("Unsupported video format: %s\n",GuidNames[mediaType->subtype]);
		}
	}else if(mediaType->majortype == MEDIATYPE_Audio){
		if(mediaType->subtype == MEDIASUBTYPE_PCM){
			//printf("Audio PCM\n");
		}
		//printf("Other audio format\n");
	}
	else if (mediaType->majortype == MEDIATYPE_Stream){
		//printf("Unsupported stream format: %s\n", GuidNames[mediaType->subtype]);
	}
	else{
		
		//printf("Unsupported (major) format: %s\n", GuidNames[mediaType->majortype]);
	}
	//fflush(stdout);
	return hr;

}

HRESULT JVideoRenderer::SetMediaType(const CMediaType *pmt)   {

	// "For RGB DIBs, the image orientation is indicated by the biHeight member of the BITMAPINFOHEADER structure.If biHeight is positive, the image is bottom - up.If biHeight is negative, the image is top - down."

	const GUID *fmtType=pmt->FormatType();
	//printf("Format type : %s\n",GuidNames[*fmtType]);

	if(*fmtType==FORMAT_VideoInfo2){
		
		VIDEOINFOHEADER2* vi = (VIDEOINFOHEADER2*) pmt->pbFormat;
		if (vi->bmiHeader.biCompression != BI_RGB){
			fprintf(stderr, "biCompression != BI_RGB");
			fflush(stderr);
		}
		LONG w=vi->bmiHeader.biWidth;
		LONG h=vi->bmiHeader.biHeight;
		DWORD parX=vi->dwPictAspectRatioX;
		DWORD parY=vi->dwPictAspectRatioY;
		// How is picture aspect related to pixel aspect ratio?
		// same semantics as with GStreamer?
		//TODO  (I have no test video)

		//printf("PAR %d x %d\n",parX,parY);
		//printf("%ld x %ld\n",w,h);

		VIDEOINFOHEADER2* vic=(VIDEOINFOHEADER2*)malloc(sizeof(VIDEOINFOHEADER2));
		memcpy(vic,vi,sizeof(VIDEOINFOHEADER2));
		//printf("Height: %ld\n", h);
		mdp->setVideoSize(pmt->subtype,w,h);
	}else if(*fmtType==FORMAT_VideoInfo){
		VIDEOINFOHEADER* vi = (VIDEOINFOHEADER*) pmt->pbFormat;
		if (vi->bmiHeader.biCompression != BI_RGB){
			fprintf(stderr, "biCompression != BI_RGB");
			fflush(stderr);
		}
		LONG w=vi->bmiHeader.biWidth;
		LONG h=vi->bmiHeader.biHeight;
		//printf("%ld x %ld\n",w,h);
		VIDEOINFOHEADER *vic=(VIDEOINFOHEADER*)malloc(sizeof(VIDEOINFOHEADER));
		memcpy(vic,vi,sizeof(VIDEOINFOHEADER));
		//printf("Height: %ld\n", h);
		mdp->setVideoSize(pmt->subtype,w,h);
	}
	else{
		fprintf(stderr,"Unsupported video format.\n");
		fflush(stderr);
	}
	
	
	return S_OK;
}   

HRESULT JVideoRenderer::DoRenderSample(IMediaSample *pMediaSample){
	//printf("doRenderSample\n");
	//fflush(stdout);
	long dataLength=pMediaSample->GetActualDataLength();

	BYTE *pBuf;
	HRESULT hr=pMediaSample->GetPointer(&pBuf);
	AM_MEDIA_TYPE *mType=NULL;
	//if(hr==0){
	pMediaSample->GetMediaType(&mType);

	mdp->rendered(pBuf,dataLength);
	return S_OK;
}

JVideoRenderer::~JVideoRenderer(void)
{

}
