//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#ifndef _TEST_GRAPH_H
#define _TEST_GRAPH_H

#include <streams.h>
#include "TestInterfaces.h"
#include "DummySink.h"
#include "DummySource.h"

enum ConnectionValidation {
	Supported,
	Unsupported,
	Unknown
};

enum ConnectionOrder
{
	InputFirst,
	OutputFirst,
	EitherFirst
};

class CTestGraph;

typedef IPin* PPIN;

class CTestGraph
{
public:

	// GUIDs of the test source, sink and filter under test. Factory method for the verifier to be used.
	CTestGraph(GUID sourcGUID, GUID filterGUID, GUID sinkGUID, GUID verifierGuid);

	// An xml file specifying the GUIDs and verifier (if any).
	CTestGraph(const TCHAR* xmlfile);

	// Blah.
	virtual ~CTestGraph();

	// Returns a pointer to the filter under test. Addrefs returned filter. Creates if not already created.
	virtual IBaseFilter* GetFilter();

	// Returns a pointer to the source test filter. Addrefs returned filter. Creates if not already created.
	virtual IBaseFilter* GetSourceFilter();

	// Returns a pointer to the sink test test. Addrefs returned filter. Creates if not already created.
	virtual IBaseFilter* GetSinkFilter();

	// Returns a pointer to the test source interface. Addrefs returned interface. Creates if not already created.
	virtual ITestSource* GetTestSource();

	// Returns a pointer to the test sink interface. Addrefs returned interface. Creates if not already created.
	virtual ITestSink* GetTestSink();

	// Adds all filters to the graph.
	virtual HRESULT AddFiltersToGraph();

	// Get the underlying control for the graph
	virtual IMediaControl* GetMediaControlGraph(); 

	// Get the underlying IMediaEvent for the graph
	virtual IMediaEvent* GetMediaEventGraph(); 

	// Get the underlying filter graph builder
	virtual IGraphBuilder* GetFilterGraphBuilder(); 

	// Create all filters needed for test graph and adds them to the graph.
	virtual HRESULT CreateFilters();

	// Enumerate and acquire all pins on the filters.
	virtual HRESULT AcquirePins();

	// Disconnects connected filters and releases all resources.
	virtual HRESULT Release();

	// Connects all output pins on source filter to corresponding input pins on filter under test.
	virtual HRESULT ConnectSource();

	// Disconnects all connected output pins on source filter from corresponding input pins on filter under test.
	virtual HRESULT DisconnectSource();

	// Connects all output pins on filter under test to corresponding input pins on sink filter.
	virtual HRESULT ConnectSink();

	// Disconnects all connected output pins on filter under test from corresponding input pins on sink filter.
	virtual HRESULT DisconnectSink();

	// Connects corresponding pins from source to filter under test first and then from filter under test to sink.
	virtual HRESULT ConnectGraph(ConnectionOrder connorder = InputFirst);

	// Disconnects corresponding pins from filter under test to sink first and then from source to filter under test.
	virtual HRESULT DisconnectGraph();

	// The following methods allow the generic tests to perform more specific tests.

	// Create specific filter needed for this test graph
	virtual HRESULT CreateFilter(const GUID clsid, REFIID riid, void** ppInterface) = 0;

	// Create specific verifier needed for this test graph
	//This is not pure virtual like CreateFilter, because you only need to implement this if your test is using a Verifier
	virtual HRESULT CreateVerifier(const GUID clsid, IVerifier** ppVerifier);

	// Number of input pins on filter under test.
	virtual int GetNumFilterInputPins();

	// Number of output pins on filter under test.
	virtual int GetNumFilterOutputPins();
	
	// This allows the graph to specify if it can be connected from either direction 
	virtual ConnectionOrder GetConnectionOrder();

	// Is called right after filter to be tested is added to graph and before it is connected
	virtual HRESULT  InitializeFilter ();

	// What dummy sink to use for Media Combination test
	virtual CDummySink* GetMediaCombTestSink(HRESULT *phr, int nPins); 

	// What source to use for Media Combination test
	virtual CDummySource* GetMediaCombTestSource(HRESULT *phr, int nPins); 

	// Helper for the tests to determine what needs to be tested. This has to be overridden by the derived test graphs
	virtual MediaTypeCombination* GetMediaTypeCombination(int enumerator, bool &bValidConnection);
	virtual int GetNumMediaTypeCombinations();
	virtual ConnectionValidation ValidateMediaTypeCombination(AM_MEDIA_TYPE** ppSourceMediaType, AM_MEDIA_TYPE** ppSinkMediaType);

	// Helper for the tests to determine valid streaming modes and source of data
	virtual int GetNumStreamingModes();
	virtual bool GetStreamingMode(int enumerator, StreamingMode& mode, int& nUnits, StreamingFlags& flags, TCHAR **datasource);
	
protected:
	HRESULT GetPinArray(IBaseFilter* pFilter, IPin*** pppPins, int *pNumPins, PIN_DIRECTION pinDir);
	void ReleaseFilters();
	void ReleasePins();
	IBaseFilter *m_pFilter;
	IBaseFilter *m_pSourceFilter;
	IBaseFilter *m_pSinkFilter;
	IPin **m_ppFilterOutputPinArray;
	int m_nFilterOutputPins;

private:
	IGraphBuilder *m_pGraph;
	ITestSource *m_pTestSource;
	ITestSink *m_pTestSink;
	IVerifier *m_pVerifier;

	IPin **m_ppSourceOutputPinArray;
	int m_nSourceOutputPins;

	IPin **m_ppSinkInputPinArray;
	int m_nSinkInputPins;

	IPin **m_ppFilterInputPinArray;
	int m_nFilterInputPins;

	GUID m_guidSource;
	GUID m_guidSink;
	GUID m_guidFilter;
	GUID m_guidVerifier;
};
#endif // _TEST_GRAPH_H
