/* 
 *	Copyright (C) 2003-2005 Gabest
 *	http://www.gabest.org
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#pragma once

class CPlayerWindow : public CWnd
{
public:
	CPlayerWindow() {}

protected:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	DECLARE_MESSAGE_MAP()
};

typedef enum {DirectShow = 0, RealMedia, QuickTime, ShockWave} engine_t;

[uuid("B110CDE5-6331-4118-8AAF-A870D6F7E2E4")]
interface IGraphEngine : public IUnknown
{
	STDMETHOD_(engine_t, GetEngine) () = 0;
};

namespace DSObjects
{

enum 
{
	EC_BG_AUDIO_CHANGED = EC_USER+1,
	EC_BG_ERROR
};

class CBaseGraph
	: public CUnknown
	, public IGraphBuilder
	, public IMediaControl
	, public IMediaEventEx
	, public IMediaSeeking
	, public IVideoWindow
	, public IBasicVideo
	, public IBasicAudio
	, public IAMOpenProgress
	, public IGraphEngine
{
	OAHWND m_hNotifyWnd;
	long m_lNotifyMsg;
	LONG_PTR m_lNotifyInstData;

	typedef struct {long m_lEventCode; LONG_PTR m_lParam1, m_lParam2;} GMSG;
	CList<GMSG> m_msgqueue;

protected:
	void ClearMessageQueue();

public:
	CBaseGraph();
	virtual ~CBaseGraph();

    DECLARE_IUNKNOWN;
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv);

	void NotifyEvent(long lEventCode, LONG_PTR lParam1 = 0, LONG_PTR lParam2 = 0);

protected:
    // IDispatch
	STDMETHODIMP GetTypeInfoCount(UINT* pctinfo);
	STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo);
	STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId);
	STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr);

	// IFilterGraph
    STDMETHODIMP AddFilter(IBaseFilter* pFilter, LPCWSTR pName);
	STDMETHODIMP RemoveFilter(IBaseFilter* pFilter);
	STDMETHODIMP EnumFilters(IEnumFilters** ppEnum);
	STDMETHODIMP FindFilterByName(LPCWSTR pName, IBaseFilter** ppFilter);
	STDMETHODIMP ConnectDirect(IPin* ppinOut, IPin* ppinIn, const AM_MEDIA_TYPE* pmt);
    STDMETHODIMP Reconnect(IPin* ppin);
	STDMETHODIMP Disconnect(IPin* ppin);
    STDMETHODIMP SetDefaultSyncSource();

	// IGraphBuilder
	STDMETHODIMP Connect(IPin* ppinOut, IPin* ppinIn);
    STDMETHODIMP Render(IPin* ppinOut);
    STDMETHODIMP RenderFile(LPCWSTR lpcwstrFile, LPCWSTR lpcwstrPlayList);
	STDMETHODIMP AddSourceFilter(LPCWSTR lpcwstrFileName, LPCWSTR lpcwstrFilterName, IBaseFilter** ppFilter);
    STDMETHODIMP SetLogFile(DWORD_PTR hFile);
    STDMETHODIMP Abort();
    STDMETHODIMP ShouldOperationContinue();

	// IMediaControl
    STDMETHODIMP Run();
    STDMETHODIMP Pause();
    STDMETHODIMP Stop();
	STDMETHODIMP GetState(LONG msTimeout, OAFilterState* pfs);
    STDMETHODIMP RenderFile(BSTR strFilename);
    STDMETHODIMP AddSourceFilter(BSTR strFilename, IDispatch** ppUnk);
    STDMETHODIMP get_FilterCollection(IDispatch** ppUnk);
    STDMETHODIMP get_RegFilterCollection(IDispatch** ppUnk);
    STDMETHODIMP StopWhenReady();

	// IMediaEvent
    STDMETHODIMP GetEventHandle(OAEVENT* hEvent);
	STDMETHODIMP GetEvent(long* lEventCode, LONG_PTR* lParam1, LONG_PTR* lParam2, long msTimeout);
    STDMETHODIMP WaitForCompletion(long msTimeout, long* pEvCode);
	STDMETHODIMP CancelDefaultHandling(long lEvCode);
	STDMETHODIMP RestoreDefaultHandling(long lEvCode);
	STDMETHODIMP FreeEventParams(long lEvCode, LONG_PTR lParam1, LONG_PTR lParam2);

	// IMediaEventEx
    STDMETHODIMP SetNotifyWindow(OAHWND hwnd, long lMsg, LONG_PTR lInstanceData);
    STDMETHODIMP SetNotifyFlags(long lNoNotifyFlags);
	STDMETHODIMP GetNotifyFlags(long* lplNoNotifyFlags);

	// IMediaSeeking
	STDMETHODIMP GetCapabilities(DWORD* pCapabilities);
	STDMETHODIMP CheckCapabilities(DWORD* pCapabilities);
	STDMETHODIMP IsFormatSupported(const GUID* pFormat);
	STDMETHODIMP QueryPreferredFormat(GUID* pFormat);
	STDMETHODIMP GetTimeFormat(GUID* pFormat);
	STDMETHODIMP IsUsingTimeFormat(const GUID* pFormat);
	STDMETHODIMP SetTimeFormat(const GUID* pFormat);
	STDMETHODIMP GetDuration(LONGLONG* pDuration);
	STDMETHODIMP GetStopPosition(LONGLONG* pStop);
	STDMETHODIMP GetCurrentPosition(LONGLONG* pCurrent);
	STDMETHODIMP ConvertTimeFormat(LONGLONG* pTarget, const GUID* pTargetFormat, LONGLONG Source, const GUID* pSourceFormat);
	STDMETHODIMP SetPositions(LONGLONG* pCurrent, DWORD dwCurrentFlags, LONGLONG* pStop, DWORD dwStopFlags);
	STDMETHODIMP GetPositions(LONGLONG* pCurrent, LONGLONG* pStop);
	STDMETHODIMP GetAvailable(LONGLONG* pEarliest, LONGLONG* pLatest);
	STDMETHODIMP SetRate(double dRate);
	STDMETHODIMP GetRate(double* pdRate);
	STDMETHODIMP GetPreroll(LONGLONG* pllPreroll);

	// IVideoWindow
    STDMETHODIMP put_Caption(BSTR strCaption);    
    STDMETHODIMP get_Caption(BSTR* strCaption);
	STDMETHODIMP put_WindowStyle(long WindowStyle);
	STDMETHODIMP get_WindowStyle(long* WindowStyle);
	STDMETHODIMP put_WindowStyleEx(long WindowStyleEx);
	STDMETHODIMP get_WindowStyleEx(long* WindowStyleEx);
	STDMETHODIMP put_AutoShow(long AutoShow);
	STDMETHODIMP get_AutoShow(long* AutoShow);
	STDMETHODIMP put_WindowState(long WindowState);
	STDMETHODIMP get_WindowState(long* WindowState);
	STDMETHODIMP put_BackgroundPalette(long BackgroundPalette);
	STDMETHODIMP get_BackgroundPalette(long* pBackgroundPalette);
	STDMETHODIMP put_Visible(long Visible);
	STDMETHODIMP get_Visible(long* pVisible);
	STDMETHODIMP put_Left(long Left);
	STDMETHODIMP get_Left(long* pLeft);
	STDMETHODIMP put_Width(long Width);
	STDMETHODIMP get_Width(long* pWidth);
	STDMETHODIMP put_Top(long Top);
	STDMETHODIMP get_Top(long* pTop);
	STDMETHODIMP put_Height(long Height);
	STDMETHODIMP get_Height(long* pHeight);
	STDMETHODIMP put_Owner(OAHWND Owner);
	STDMETHODIMP get_Owner(OAHWND* Owner);
	STDMETHODIMP put_MessageDrain(OAHWND Drain);
	STDMETHODIMP get_MessageDrain(OAHWND* Drain);
	STDMETHODIMP get_BorderColor(long* Color);
	STDMETHODIMP put_BorderColor(long Color);
	STDMETHODIMP get_FullScreenMode(long* FullScreenMode);
	STDMETHODIMP put_FullScreenMode(long FullScreenMode);
    STDMETHODIMP SetWindowForeground(long Focus);
    STDMETHODIMP NotifyOwnerMessage(OAHWND hwnd, long uMsg, LONG_PTR wParam, LONG_PTR lParam);
    STDMETHODIMP SetWindowPosition(long Left, long Top, long Width, long Height);
	STDMETHODIMP GetWindowPosition(long* pLeft, long* pTop, long* pWidth, long* pHeight);
	STDMETHODIMP GetMinIdealImageSize(long* pWidth, long* pHeight);
	STDMETHODIMP GetMaxIdealImageSize(long* pWidth, long* pHeight);
	STDMETHODIMP GetRestorePosition(long* pLeft, long* pTop, long* pWidth, long* pHeight);
	STDMETHODIMP HideCursor(long HideCursor);
	STDMETHODIMP IsCursorHidden(long* CursorHidden);

	// IBasicVideo
    STDMETHODIMP get_AvgTimePerFrame(REFTIME* pAvgTimePerFrame);
    STDMETHODIMP get_BitRate(long* pBitRate);
    STDMETHODIMP get_BitErrorRate(long* pBitErrorRate);
    STDMETHODIMP get_VideoWidth(long* pVideoWidth);
    STDMETHODIMP get_VideoHeight(long* pVideoHeight);
    STDMETHODIMP put_SourceLeft(long SourceLeft);
    STDMETHODIMP get_SourceLeft(long* pSourceLeft);
    STDMETHODIMP put_SourceWidth(long SourceWidth);
    STDMETHODIMP get_SourceWidth(long* pSourceWidth);
    STDMETHODIMP put_SourceTop(long SourceTop);
    STDMETHODIMP get_SourceTop(long* pSourceTop);
    STDMETHODIMP put_SourceHeight(long SourceHeight);
    STDMETHODIMP get_SourceHeight(long* pSourceHeight);
    STDMETHODIMP put_DestinationLeft(long DestinationLeft);
    STDMETHODIMP get_DestinationLeft(long* pDestinationLeft);
    STDMETHODIMP put_DestinationWidth(long DestinationWidth);
    STDMETHODIMP get_DestinationWidth(long* pDestinationWidth);
    STDMETHODIMP put_DestinationTop(long DestinationTop);
    STDMETHODIMP get_DestinationTop(long* pDestinationTop);
    STDMETHODIMP put_DestinationHeight(long DestinationHeight);
    STDMETHODIMP get_DestinationHeight(long* pDestinationHeight);
    STDMETHODIMP SetSourcePosition(long Left, long Top, long Width, long Height);
    STDMETHODIMP GetSourcePosition(long* pLeft, long* pTop, long* pWidth, long* pHeight);
    STDMETHODIMP SetDefaultSourcePosition();
    STDMETHODIMP SetDestinationPosition(long Left, long Top, long Width, long Height);
    STDMETHODIMP GetDestinationPosition(long* pLeft, long* pTop, long* pWidth, long* pHeight);
    STDMETHODIMP SetDefaultDestinationPosition();
    STDMETHODIMP GetVideoSize(long* pWidth, long* pHeight);
    STDMETHODIMP GetVideoPaletteEntries(long StartIndex, long Entries, long* pRetrieved, long* pPalette);
    STDMETHODIMP GetCurrentImage(long* pBufferSize, long* pDIBImage);
    STDMETHODIMP IsUsingDefaultSource();
    STDMETHODIMP IsUsingDefaultDestination();

	// IBasicAudio
    STDMETHODIMP put_Volume(long lVolume);
    STDMETHODIMP get_Volume(long* plVolume);
    STDMETHODIMP put_Balance(long lBalance);
    STDMETHODIMP get_Balance(long* plBalance);

	// IAMOpenProgress
	STDMETHODIMP QueryProgress(LONGLONG* pllTotal, LONGLONG* pllCurrent);
	STDMETHODIMP AbortOperation();

	// IGraphEngine
	STDMETHODIMP_(engine_t) GetEngine();
};

}
using namespace DSObjects;
