#pragma once

#include <Evr.h>
extern "C" {
JNIEXPORT jobject JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_init(JNIEnv *, jobject);
JNIEXPORT jint JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_getApiLevel(JNIEnv *, jobject);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_setAudioRenderer(JNIEnv *, jobject,jobject,jobject);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_setNativeVideoWindowHandleLong(JNIEnv *env, jobject obj, jobject nativeP, jlong nativeWindowHwnd);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_setNativeVideoWindowHandlePointer(JNIEnv *env, jobject obj, jobject nativeP, jobject nativeWindowHwndObj);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_setAWTVideoComponent(JNIEnv *env, jobject obj, jobject nativeP, jobject awtComponent);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_buildGraph(JNIEnv *, jobject,jobject,jboolean);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_setVideoCanvasSize(JNIEnv *, jobject,jobject,jint,jint,jint,jint,jboolean);
static jobject createWarnResultJObject(JNIEnv *env, char *msg);
static jobject createWarnPartialRenderResultJObject(JNIEnv *env, char *msg);
JNIEXPORT jobject JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_open(JNIEnv *, jobject,jobject,jstring);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_waitForEvent(JNIEnv *, jobject,jobject);
JNIEXPORT jboolean JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_start(JNIEnv *, jobject,jobject);
JNIEXPORT jboolean JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_stop(JNIEnv *, jobject,jobject);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_close(JNIEnv *, jobject,jobject);
JNIEXPORT jboolean JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_rewind(JNIEnv *, jobject,jobject);
JNIEXPORT jlong JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_getDuration(JNIEnv *, jobject,jobject);
JNIEXPORT jlong JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_getPosition(JNIEnv *, jobject,jobject);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_releaseGraph(JNIEnv *, jobject, jobject);
JNIEXPORT void JNICALL Java_ips_media_jnm_impl_directshow_DSMediaDecodingPlayer_release(JNIEnv *, jobject,jobject);
}

LRESULT CALLBACK CBTProc(int, WPARAM, LPARAM);


class CJStreamReader;
class JVideoRenderer;
class JAudioRenderer;
class DSMediaDecodingPlayer
{
private:
	JavaVM *javaVm;
	jweak objRef;
	jweak imgArrRef;
	jmethodID renderMethodID;
	LONG width;
	LONG height;
	UINT pixelStride;
	jbyte *lineBuffer;

	
IGraphBuilder *pGraph;
IMediaControl *pControl;
IMediaEvent   *pEvent;
IMediaSeeking *pSeek;
//IVMRWindowlessControl9 *pWc;
//IVMRMonitorConfig9 *pMonCfg;

IMFVideoDisplayControl *pWc;
HANDLE hEvent;
CCritSec* cCritSec;
CJStreamReader *strReader;
HWND hwndAWT;
JVideoRenderer *jvr;
JAudioRenderer *jar;
IBasicVideo *iBv;
IBaseFilter *pVmr;
LONGLONG byteLength;
LONGLONG available;
DWORD_PTR dwUserTest;
volatile boolean flushing;
volatile int c;
volatile DWORD renderThreadID;
JNIEnv* renderEnv;
char jRenderThreadName[65];
JavaVMAttachArgs thr_args;
public:
DSMediaDecodingPlayer(JavaVM*,jweak);
jmethodID DSMediaDecodingPlayer::getRenderMethodID();
void DSMediaDecodingPlayer::setRenderMethodID(jmethodID);
void DSMediaDecodingPlayer::getAWTSurface(JNIEnv*,jobject);
void DSMediaDecodingPlayer::setNativeWindowHWND(HWND);
HRESULT tryConnectNativeWindow();
void setAudioRenderer(JAudioRenderer *);
void setVideoCanvas(jint,jint,jint,jint,jboolean);
HRESULT buildGraph(boolean);
HRESULT render(LPCWSTR);
//HRESULT applyInterfaces();
void waitForEvent(JNIEnv *, jobject);
boolean start();
boolean stop();
void releaseGraph();
void close();
HRESULT BeginFlush();
HRESULT EndFlush();
HRESULT length(LONGLONG *,LONGLONG *);
HRESULT read(LONGLONG position,LONG length,BYTE *buf);
HRESULT request(IMediaSample *,LONGLONG,LONG,BYTE *,DWORD_PTR);
void displayChanged();
HRESULT WaitForNext(DWORD,IMediaSample **,DWORD_PTR *);
HRESULT PinBeginFlush();
HRESULT PinEndFlush();
void setVideoSize(GUID,LONG,LONG);
void rendered(BYTE *,long);
boolean rewind();
LONGLONG getDuration();
LONGLONG getPosition();
void release(JNIEnv *);
~DSMediaDecodingPlayer(void);
};
