/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

This library 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "fakesource.h"
#include "iodevicereader.h"
#include "qaudiocdreader.h"

#include "mediagraph.h"
#include "mediaobject.h"


#include <QtCore/QUrl>
#include <QtCore/QDebug>

#include <qnetwork.h>


QT_BEGIN_NAMESPACE

namespace Phonon
{
    namespace DS9
    {
        //description of a connection
        struct GraphConnection
        {
            Filter output;
            int outputOffset;
            Filter input;
            int inputOffset;
        };

        static QList<GraphConnection> getConnections(Filter source)
        {
            QList<GraphConnection> ret;
            int outOffset = 0;
            const QList<OutputPin> outputs = BackendNode::pins(source, PINDIR_OUTPUT);
            for (int i = 0; i < outputs.count(); ++i) {
                InputPin input;
                if (outputs.at(i)->ConnectedTo(input.pparam()) == S_OK) {
                    PIN_INFO info;
                    input->QueryPinInfo(&info);
                    Filter current(info.pFilter);
                    if (current) {
                        //this is a valid connection
                        const int inOffset = BackendNode::pins(current, PINDIR_INPUT).indexOf(input);
                        const GraphConnection connection = {source, outOffset, current, inOffset};
                        ret += connection;
                        ret += getConnections(current); //get subsequent connections
                    }
                }
                outOffset++;
            }
            return ret;
        }
                

/*
        static HRESULT saveToFile(Graph graph, const QString &filepath)
        {
            const WCHAR wszStreamName[] = L"ActiveMovieGraph";
            HRESULT hr;
            ComPointer<IStorage> storage;

            // First, create a document file that will hold the GRF file
            hr = StgCreateDocfile((OLECHAR*)filepath.utf16(),
                STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE |
                STGM_SHARE_EXCLUSIVE,
                0, storage.pparam());

            if (FAILED(hr)) {
                return hr;
            }

            // Next, create a stream to store.
            ComPointer<IStream> stream;
            hr = storage->CreateStream(wszStreamName,
                STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
                0, 0, stream.pparam());

            if (FAILED(hr)) {
                return hr;
            }

            // The IpersistStream::Save method converts a stream into a persistent object.
            ComPointer<IPersistStream> persist(graph, IID_IPersistStream);
            hr = persist->Save(stream, TRUE);
            if (SUCCEEDED(hr)) {
                hr = storage->Commit(STGC_DEFAULT);
            }

            return hr;
        }
*/

        MediaGraph::MediaGraph(MediaObject *mo, short index) :
            m_graph(CLSID_FilterGraph, IID_IGraphBuilder),
            m_fakeSource(new FakeSource()),
            m_hasVideo(false), m_hasAudio(false), m_connectionsDirty(false), 
            m_isStopping(false), m_isSeekable(false), m_result(S_OK),
            m_index(index), m_renderId(0), m_seekId(0),
            m_currentTime(0), m_totalTime(0), m_mediaObject(mo)
        {
            m_mediaControl = ComPointer<IMediaControl>(m_graph, IID_IMediaControl);
            Q_ASSERT(m_mediaControl);
            m_mediaSeeking = ComPointer<IMediaSeeking>(m_graph, IID_IMediaSeeking);
            Q_ASSERT(m_mediaSeeking);

            HRESULT hr = m_graph->AddFilter(m_fakeSource, 0);
            if (m_mediaObject->catchComError(hr)) {
                return;
            }
        }

        MediaGraph::~MediaGraph()
        {
        }

        short MediaGraph::index() const
        {
            return m_index;
        }

        void MediaGraph::grabNode(BackendNode *node)
        {
            grabFilter(node->filter(m_index));
        }

        void MediaGraph::grabFilter(Filter filter)
        {
            if (filter) {
                FILTER_INFO info;
                filter->QueryFilterInfo(&info);
                if (info.pGraph != m_graph) {
                    if (info.pGraph) {
                        m_mediaObject->catchComError(info.pGraph->RemoveFilter(filter));
                    }
                    m_mediaObject->catchComError(m_graph->AddFilter(filter, 0));
                }
                if (info.pGraph) {
                    info.pGraph->Release();
                }
            }
        }

        void MediaGraph::switchFilters(Filter oldFilter, Filter newFilter)
        {
            OAFilterState state = syncGetRealState();
            if (state != State_Stopped) {
                ensureStopped(); //to do the transaction
            }


            OutputPin connected;
            {
                InputPin pin = BackendNode::pins(oldFilter, PINDIR_INPUT).first();
                pin->ConnectedTo(connected.pparam());
            }

            m_graph->RemoveFilter(oldFilter);
            m_graph->AddFilter(newFilter, 0);

            if (connected) {
                InputPin pin = BackendNode::pins(newFilter, PINDIR_INPUT).first();
                //let's reestablish the connections
                m_graph->Connect(connected, pin);
            }

            switch(state)
            {
            case State_Running:
                play();
                break;
            case State_Paused:
                pause();
                break;
            default:
                break;
            }

        }

        OAFilterState MediaGraph::syncGetRealState() const
        {
            OAFilterState state;
            m_mediaControl->GetState(INFINITE, &state);
            return state;
        }



        void MediaGraph::ensureSourceDisconnected()
        {
            for (int i = 0; i < m_sinkConnections.count(); ++i) {
                const Filter currentFilter = m_sinkConnections.at(i)->filter(m_index);
                const QList<InputPin> inputs = BackendNode::pins(currentFilter, PINDIR_INPUT);
                const QList<InputPin> outputs = BackendNode::pins(m_fakeSource, PINDIR_OUTPUT);

                for (int i = 0; i < inputs.count(); ++i) {
                    for (int o = 0; o < outputs.count(); o++) {
                        tryDisconnect(outputs.at(o), inputs.at(i));
                    }

                    for (int d = 0; d < m_decoderPins.count(); ++d) {
                        tryDisconnect(m_decoderPins.at(d), inputs.at(i));
                    }
                }
            }
        }

        void MediaGraph::ensureSourceConnectedTo(bool force)
        {
            if (m_connectionsDirty == false && force == false) {
                return;
            }

            m_connectionsDirty = false;
            ensureSourceDisconnected();

            //reconnect the pins
            for (int i = 0; i < m_sinkConnections.count(); ++i) {
                const Filter currentFilter = m_sinkConnections.at(i)->filter(m_index);
                const QList<InputPin> inputs = BackendNode::pins(currentFilter, PINDIR_INPUT);
                for(int i = 0; i < inputs.count(); ++i) {
                    //we ensure the filter belongs to the graph
                    grabFilter(currentFilter);

                    for (int d = 0; d < m_decoderPins.count(); ++d) {
                        //a decoder has only one output
                        if (tryConnect(m_decoderPins.at(d), inputs.at(i))) {
                            break;
                        }
                    }
                }
            }
        }

        QList<Filter> MediaGraph::getAllFilters(Graph graph)
        {
            QList<Filter> ret;
            ComPointer<IEnumFilters> enumFilters;
            graph->EnumFilters(enumFilters.pparam());
            Filter current;
            while( enumFilters && enumFilters->Next(1, current.pparam(), 0) == S_OK) {
                ret += current;
            }
            return ret;
        }

        QList<Filter> MediaGraph::getAllFilters() const
        {
            return getAllFilters(m_graph);
        }


        bool MediaGraph::isSeekable() const
        {
            return m_isSeekable;
        }

        qint64 MediaGraph::absoluteTotalTime() const
        {
            if (m_seekId) {
                return m_totalTime;
            } else {
                qint64 ret = 0;
                if (m_mediaSeeking) {
                    m_mediaSeeking->GetDuration(&ret);
                    ret /= 10000; //convert to milliseconds
                }
                return ret;
            }
        }

        qint64 MediaGraph::absoluteCurrentTime() const
        {
            if (m_seekId) {
                return m_currentTime;
            } else {
                qint64 ret = -1;
                if (m_mediaSeeking) {
                    HRESULT hr = m_mediaSeeking->GetCurrentPosition(&ret);
                    if (FAILED(hr)) {
                        return ret;
                    }
                    ret /= 10000; //convert to milliseconds
                }
                return ret;
            }
        }

        Phonon::MediaSource MediaGraph::mediaSource() const
        {
            return m_mediaSource;
        }

        void MediaGraph::play()
        {
            ensureSourceConnectedTo();
            m_mediaObject->workerThread()->addStateChangeRequest(m_graph, State_Running, m_decoders);
        }

        void MediaGraph::pause()
        {
            ensureSourceConnectedTo();
            m_mediaObject->workerThread()->addStateChangeRequest(m_graph, State_Paused, m_decoders);
        }

        HRESULT MediaGraph::renderResult() const
        {
            return m_result;
        }

        bool MediaGraph::isStopping() const
        {
            return m_isStopping;
        }

        Graph MediaGraph::graph() const
        {
            return m_graph;
        }

        void MediaGraph::stop()
        {
            if (!isLoading()) {
                ensureStopped();
                absoluteSeek(0); //resets the clock
			} else {
				m_mediaObject->workerThread()->abortCurrentRender(m_renderId);
     			m_renderId = 0; //cancels current loading
			}
            m_mediaObject->workerThread()->addStateChangeRequest(m_graph, State_Stopped);
        }

        void MediaGraph::ensureStopped()
        {
            m_isStopping = true;
            //special case here because we want stopped to be synchronous
            m_graph->Abort();
            m_mediaControl->Stop(); 
            OAFilterState dummy;
            //this will wait until the change is effective
            m_mediaControl->GetState(INFINITE, &dummy);
            m_isStopping = false;
        }

        bool MediaGraph::isLoading() const
        {
            return m_renderId != 0;
        }

        void MediaGraph::absoluteSeek(qint64 time)
        {
            //this just sends a request
            if (m_seekId == 0) {
                m_currentTime = absoluteCurrentTime();
                m_totalTime = absoluteTotalTime();
            }
            m_seekId = m_mediaObject->workerThread()->addSeekRequest(m_graph, time);
        }

        HRESULT MediaGraph::removeFilter(const Filter& filter)
        {
            FILTER_INFO info;
            filter->QueryFilterInfo(&info);
#ifdef GRAPH_DEBUG
            qDebug() << "removeFilter" << QString((const QChar *)info.achName);
#endif
            if (info.pGraph) {
                info.pGraph->Release();
                if (info.pGraph == m_graph)
                    return m_graph->RemoveFilter(filter);
            }

            //already removed
            return S_OK;
        }

        HRESULT MediaGraph::cleanup()
        {
            stop();

            ensureSourceDisconnected();

            QList<Filter> list = m_decoders;
            if (m_demux) {
                list << m_demux;
            }
            if (m_realSource) {
                list << m_realSource;
            }
            list << m_decoders;

            for (int i = 0; i < m_decoders.count(); ++i) {
                list += getFilterChain(m_demux, m_decoders.at(i));
            }

            for (int i = 0; i < list.count(); ++i) {
                removeFilter(list.at(i));
            }

            //Let's reinitialize the internal lists
            m_decoderPins.clear();
            m_decoders.clear();
            m_demux = Filter();
            m_realSource = Filter();
            m_mediaSource = Phonon::MediaSource();

            absoluteSeek(0); //resets the clock

            return S_OK;
        }


        bool MediaGraph::disconnectNodes(BackendNode *source, BackendNode *sink)
        {
            const Filter sinkFilter = sink->filter(m_index);
            const QList<InputPin> inputs = BackendNode::pins(sinkFilter, PINDIR_INPUT);

            QList<OutputPin> outputs;
            if (source == m_mediaObject) {
                outputs = BackendNode::pins(m_fakeSource, PINDIR_OUTPUT);
                outputs += m_decoderPins;
            } else {
                outputs = BackendNode::pins(source->filter(m_index), PINDIR_OUTPUT);
            }


            for (int i = 0; i < inputs.count(); ++i) {
                for (int o = 0; o < outputs.count(); ++o) {
                    tryDisconnect(outputs.at(o), inputs.at(i));
                }
            }

            if (m_sinkConnections.removeOne(sink)) {
                m_connectionsDirty = true;
            }
            return true;
        }

        bool MediaGraph::tryDisconnect(const OutputPin &out, const InputPin &in)
        {
            bool ret = false;

            OutputPin output;
            if (SUCCEEDED(in->ConnectedTo(output.pparam()))) {

                if (output == out) {
                    //we need a simple disconnection
                    ret = SUCCEEDED(out->Disconnect()) && SUCCEEDED(in->Disconnect());
                } else {
                    InputPin in2;
                    if (SUCCEEDED(out->ConnectedTo(in2.pparam()))) {
                        PIN_INFO info;
                        in2->QueryPinInfo(&info);
                        Filter tee(info.pFilter);
                        CLSID clsid;
                        tee->GetClassID(&clsid);
                        if (clsid == CLSID_InfTee) {
                            //we have to remove all intermediate filters between the tee and the sink
                            PIN_INFO info;
                            in->QueryPinInfo(&info);
                            Filter sink(info.pFilter);
                            QList<Filter> list = getFilterChain(tee, sink);
                            out->QueryPinInfo(&info);
                            Filter source(info.pFilter);

                            if (list.isEmpty()) {
                                output->QueryPinInfo(&info);
                                if (Filter(info.pFilter) == tee) {
                                    ret = SUCCEEDED(output->Disconnect()) && SUCCEEDED(in->Disconnect());
                                }
                            } else {
                                ret = true;
                                for (int i = 0; i < list.count(); ++i) {
                                    ret = ret && SUCCEEDED(removeFilter(list.at(i)));
                                }
                            }

                            //Let's try to see if the Tee filter is still useful
                            if (ret) {
                                int connections = 0;
                                const QList<OutputPin> outputs = BackendNode::pins(tee, PINDIR_OUTPUT);
                                for(int i = 0; i < outputs.count(); ++i) {
                                    InputPin p;
                                    if ( SUCCEEDED(outputs.at(i)->ConnectedTo(p.pparam()))) {
                                        connections++;
                                    }
                                }
                                if (connections == 0) {
                                    //this avoids a crash if the filter is destroyed
                                    //by the subsequent call to removeFilter
                                    output = OutputPin();
                                    removeFilter(tee); //there is no more output for the tee, we remove it
                                }
                            }
                        }
                    }
                }
            }
            return ret;
        }

        bool MediaGraph::tryConnect(const OutputPin &out, const InputPin &newIn)
        {


            ///The management of the creation of the Tees is done here (this is the only place where we call IPin::Connect
            InputPin inPin;
            if (SUCCEEDED(out->ConnectedTo(inPin.pparam()))) {

                //the fake source has another mechanism for the connection
                if (BackendNode::pins(m_fakeSource, PINDIR_OUTPUT).contains(out)) {
                    return false;
                }

                //the output pin is already connected
                PIN_INFO info;
                inPin->QueryPinInfo(&info);
                Filter filter(info.pFilter); //this will ensure the interface is "Release"d
                CLSID clsid;
                filter->GetClassID(&clsid);
                if (clsid == CLSID_InfTee) {
                    //there is already a Tee (namely 'filter') in use
                    const QList<OutputPin> outputs = BackendNode::pins(filter, PINDIR_OUTPUT);
                    for(int i = 0; i < outputs.count(); ++i) {
                        const OutputPin &pin = outputs.at(i);
                        if (HRESULT(VFW_E_NOT_CONNECTED) == pin->ConnectedTo(inPin.pparam())) {
                            return SUCCEEDED(pin->Connect(newIn, 0));
                        }
                    }
                    //we shoud never go here
                    return false;
                } else {
                    QAMMediaType type;
                    out->ConnectionMediaType(&type);

                    //first we disconnect the current connection (and we save the current media type)
                    if (!tryDisconnect(out, inPin)) {
                        return false;
                    }

                    //..then we try to connect the new node
                    if (SUCCEEDED(out->Connect(newIn, 0))) {

                        //we have to insert the Tee
                        if (!tryDisconnect(out, newIn)) {
                            return false;
                        }

                        Filter filter(CLSID_InfTee, IID_IBaseFilter);
                        if (!filter) {
                            //rollback
                            m_graph->Connect(out, inPin);
                            return false;
                        }

                        if (FAILED(m_graph->AddFilter(filter, 0))) {
                            return false;
                        }


                        InputPin teeIn = BackendNode::pins(filter, PINDIR_INPUT).first(); //a Tee has always one input
                        HRESULT hr = out->Connect(teeIn, &type);
                        if (FAILED(hr)) {
                            hr = m_graph->Connect(out, teeIn);
                        }
                        if (FAILED(hr)) {
                            m_graph->Connect(out, inPin);
                            return false;
                        }

                        OutputPin teeOut = BackendNode::pins(filter, PINDIR_OUTPUT).last(); //the last is always the one that's not connected

                        //we simply reconnect the pins as they
                        hr = m_graph->Connect(teeOut, inPin);
                        if (FAILED(hr)) {
                            m_graph->Connect(out, inPin);
                            return false;
                        }

                        teeOut = BackendNode::pins(filter, PINDIR_OUTPUT).last(); //the last is always the one that's not connected
                        if (FAILED(m_graph->Connect(teeOut, newIn))) {
                            m_graph->Connect(out, inPin);
                            return false;
                        }

                        return true;
                    } else {
                        //we simply reconnect the pins as they
                        m_graph->Connect(out, inPin);
                        return false;
                    }
                }

            } else {
                return SUCCEEDED(m_graph->Connect(out, newIn));
            }
        }

        bool MediaGraph::connectNodes(BackendNode *source, BackendNode *sink)
        {
            bool ret = false;
            const QList<InputPin> inputs = BackendNode::pins(sink->filter(m_index), PINDIR_INPUT);
            QList<OutputPin> outputs = BackendNode::pins(source == m_mediaObject ? m_fakeSource : source->filter(m_index), PINDIR_OUTPUT);
            
            if (source == m_mediaObject) {
                grabFilter(m_fakeSource);
            }

#ifdef GRAPH_DEBUG
            qDebug() << Q_FUNC_INFO << source << sink << this;
#endif

            for (int o = 0; o < outputs.count(); o++) {
                InputPin p;
                for (int i = 0; i < inputs.count(); i++) {
                    const InputPin &inPin = inputs.at(i);
                    if (tryConnect(outputs.at(o), inPin)) {
                        //tell the sink node that it just got a new input
                        sink->connected(source, inPin);
                        ret = true;
                        if (source == m_mediaObject) {
                            m_connectionsDirty = true;
                            m_sinkConnections += sink;
#ifdef GRAPH_DEBUG
                            qDebug() << "found a sink connection" << sink << m_sinkConnections.count();
#endif
                        }
                        break;
                    }
                }
            }

            return ret;
        }


        HRESULT MediaGraph::loadSource(const Phonon::MediaSource &source)
        {
            m_hasVideo = false;
            m_hasAudio = false;
            m_isSeekable = false;


            //cleanup of the previous filters
            m_result = cleanup();
            if (FAILED(m_result)) {
                return m_result;
            }

            m_mediaSource = source;

            switch (source.type())
            {
            case Phonon::MediaSource::Disc:
                if (source.discType() == Phonon::Dvd) {
                    m_result = E_NOTIMPL;
                    /*m_realSource = Filter(CLSID_DVDNavigator, IID_IBaseFilter);
                    if (m_realSource) {
                        return REGDB_E_CLASSNOTREG;
                    }

                    m_result = m_graph->AddFilter(m_realSource, L"DVD Navigator");*/


 #ifndef QT_NO_PHONON_MEDIACONTROLLER
               } else if (source.discType() == Phonon::Cd) {
                    m_realSource = Filter(new QAudioCDPlayer);

#endif //QT_NO_PHONON_MEDIACONTROLLER
                } else {
                    m_result = E_NOTIMPL;
                }
                if (FAILED(m_result)) {
                    return m_result;
                }
                m_renderId = m_mediaObject->workerThread()->addFilterToRender(m_realSource);
                return m_result;
            case Phonon::MediaSource::Invalid:
                return m_result;
            case Phonon::MediaSource::Url:
            case Phonon::MediaSource::LocalFile:
                {
                    QString url;
                    if (source.type() == Phonon::MediaSource::LocalFile) {
                        url = source.fileName();
                    } else {
                        url = source.url().toString();
                    }
                    m_renderId = m_mediaObject->workerThread()->addUrlToRender(url);
                }
                break;
#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
            case Phonon::MediaSource::Stream:
                {
                    m_realSource = Filter(new IODeviceReader(source, this));
                    m_renderId = m_mediaObject->workerThread()->addFilterToRender(m_realSource);
                }
                break;
#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
            default:
                m_result = E_FAIL;
            }

            return m_result;
        }

        void MediaGraph::finishSeeking(quint16 workId, qint64 time)
        {
            if (m_seekId == workId) {
                m_currentTime = time;
                m_mediaObject->seekingFinished(this);
                m_seekId = 0;
            } else {
                //it's a queue seek command
                //we're still seeking
            }
        }

        void MediaGraph::finishLoading(quint16 workId, HRESULT hr, Graph graph)
        {
            if (m_renderId == workId) {
                m_renderId = 0;

				//let's determine if the graph is seekable
				{
					ComPointer<IMediaSeeking> mediaSeeking(graph, IID_IMediaSeeking);
					DWORD caps = AM_SEEKING_CanSeekAbsolute;
                    m_isSeekable = mediaSeeking && SUCCEEDED(mediaSeeking->CheckCapabilities(&caps));
				}

                m_result = reallyFinishLoading(hr, graph);
                m_mediaObject->loadingFinished(this);
            }
        }


        HRESULT MediaGraph::reallyFinishLoading(HRESULT hr, const Graph &graph)
        {
            if (FAILED(hr)) {
                return hr;
            }

            const Graph oldGraph = m_graph;
            m_graph = graph;

            //we keep the source and all the way down to the decoders
            QList<Filter> removedFilters;

			const QList<Filter> allFilters = getAllFilters(graph);
            for (int i = 0; i < allFilters.count(); ++i) {
                const Filter &filter = allFilters.at(i);
                if (isSourceFilter(filter)) {
                    m_realSource = filter; //save the source filter
                    if (!m_demux ) {
                        m_demux = filter; //in the WMV case, the demuxer is the source filter itself
                    }
                } else if (isDemuxerFilter(filter)) {
                    m_demux = filter;
                } else if (isDecoderFilter(filter)) {
                    m_decoders += filter;
                    m_decoderPins += BackendNode::pins(filter, PINDIR_OUTPUT).first();
                }  else {
                    removedFilters += filter;
                }
            }

            for (int i = 0; i < m_decoders.count(); ++i) {
                QList<Filter> chain = getFilterChain(m_demux, m_decoders.at(i));
                for (int i = 0; i < chain.count(); ++i) {
                    //we keep those filters
                    removedFilters.removeOne(chain.at(i));
                }
            }

            for (int i = 0; i < removedFilters.count(); ++i) {
                graph->RemoveFilter(removedFilters.at(i));
            }

            m_mediaObject->workerThread()->replaceGraphForEventManagement(graph, oldGraph);

            //let's transfer the nodes from the current graph to the new one
            QList<GraphConnection> connections; //we store the connections that need to be restored

            // First get all the sink nodes (nodes with no input connected)
            for (int i = 0; i < m_sinkConnections.count(); ++i) {
                Filter currentFilter = m_sinkConnections.at(i)->filter(m_index);
                connections += getConnections(currentFilter);
                grabFilter(currentFilter);
            }

            //we need to do something smart to detect if the streams are unencoded
            if (m_demux) {
                const QList<OutputPin> outputs = BackendNode::pins(m_demux, PINDIR_OUTPUT);
                for (int i = 0; i < outputs.count(); ++i) {
                    const OutputPin &out = outputs.at(i);
                    InputPin pin;
                    if (out->ConnectedTo(pin.pparam()) == HRESULT(VFW_E_NOT_CONNECTED)) {
                        m_decoderPins += out; //unconnected outputs can be decoded outputs
                    }
                }
            }

            ensureSourceConnectedTo(true);

            //let's reestablish the connections
            for (int i = 0; i < connections.count(); ++i) {
                const GraphConnection &connection = connections.at(i);
                //check if we shoud transfer the sink node

                grabFilter(connection.input);
                grabFilter(connection.output);

                const OutputPin output = BackendNode::pins(connection.output, PINDIR_OUTPUT).at(connection.outputOffset);
                const InputPin input   = BackendNode::pins(connection.input, PINDIR_INPUT).at(connection.inputOffset);
                HRESULT hr = output->Connect(input, 0);
                Q_UNUSED(hr);
                Q_ASSERT( SUCCEEDED(hr));
            }

            //Finally, let's update the interfaces
            m_mediaControl = ComPointer<IMediaControl>(graph, IID_IMediaControl);
            m_mediaSeeking = ComPointer<IMediaSeeking>(graph, IID_IMediaSeeking);
            return hr;
        }

        //utility functions
        //retrieves the filters between source and sink
        QList<Filter> MediaGraph::getFilterChain(const Filter &source, const Filter &sink)
        {
            QList<Filter> ret;
            Filter current = sink;
            while (current && BackendNode::pins(current, PINDIR_INPUT).count() == 1 && current != source) {
                if (current != source)
                    ret += current;
                InputPin pin = BackendNode::pins(current, PINDIR_INPUT).first();
                current = Filter();
                OutputPin output;
                if (pin->ConnectedTo(output.pparam()) == S_OK) {
                    PIN_INFO info;
                    if (SUCCEEDED(output->QueryPinInfo(&info)) && info.pFilter) {
                        current = Filter(info.pFilter); //this will take care of releasing the interface pFilter
                    }
                }
            }
            if (current != source) {
                //the soruce and sink don't seem to be connected
                ret.clear();
            }
            return ret;
        }

        bool MediaGraph::isDecoderFilter(const Filter &filter)
        {
            if (filter == 0) {
                return false;
            }
#ifdef GRAPH_DEBUG
            {
                FILTER_INFO info;
                filter->QueryFilterInfo(&info);
                qDebug() << Q_FUNC_INFO << QString((const QChar *)info.achName);
                if (info.pGraph) {
                    info.pGraph->Release();
                }
            }
#endif


            QList<InputPin> inputs = BackendNode::pins(filter, PINDIR_INPUT);
            QList<OutputPin> outputs = BackendNode::pins(filter, PINDIR_OUTPUT);

            //TODO: find a better way to detect if a node is a decoder
            if (inputs.count() == 0 || outputs.count() ==0) {
                return false;
            }

            //the input pin must be encoded data
            QAMMediaType type;
            HRESULT hr = inputs.first()->ConnectionMediaType(&type);
            if (FAILED(hr)) {
                return false;
            }


            //...and the output must be decoded
            QAMMediaType type2;
            hr = outputs.first()->ConnectionMediaType(&type2);
            if (FAILED(hr)) {
                return false;
            }

            if (type2.majortype != MEDIATYPE_Video &&
                type2.majortype != MEDIATYPE_Audio) {
                    return false;
            }

            if (type2.majortype == MEDIATYPE_Video) {
                m_hasVideo = true;
            } else {
                m_hasAudio = true;
            }

#ifdef GRAPH_DEBUG
            {
                FILTER_INFO info;
                filter->QueryFilterInfo(&info);
                qDebug() << "found a decoder filter" << QString((const QChar *)info.achName);
                if (info.pGraph) {
                    info.pGraph->Release();
                }
            }
#endif

            return true;
        }

        bool MediaGraph::isSourceFilter(const Filter &filter) const
        {
#ifdef GRAPH_DEBUG
            {
                FILTER_INFO info;
                filter->QueryFilterInfo(&info);
                qDebug() << Q_FUNC_INFO << QString((const QChar *)info.achName);
                if (info.pGraph) {
                    info.pGraph->Release();
                }
            }
#endif
            //a source filter is one that has no input
            return BackendNode::pins(filter, PINDIR_INPUT).isEmpty();
        }

        bool MediaGraph::isDemuxerFilter(const Filter &filter) const
        {
            QList<InputPin> inputs = BackendNode::pins(filter, PINDIR_INPUT);
            QList<OutputPin> outputs = BackendNode::pins(filter, PINDIR_OUTPUT);

#ifdef GRAPH_DEBUG
            {
                FILTER_INFO info;
                filter->QueryFilterInfo(&info);
                qDebug() << Q_FUNC_INFO << QString((const QChar *)info.achName);
                if (info.pGraph) {
                    info.pGraph->Release();
                }
            }
#endif

            if (inputs.count() != 1 || outputs.count() == 0) {
                return false; //a demuxer has only one input
            }

            QAMMediaType type;
            HRESULT hr = inputs.first()->ConnectionMediaType(&type);
            if (FAILED(hr)) {
                return false;
            }

            if (type.majortype != MEDIATYPE_Stream) {
                return false;
            }

            for (int i = 0; i < outputs.count(); ++i) {
                QAMMediaType type;
                //for now we support only video and audio
                hr = outputs.at(i)->ConnectionMediaType(&type);
                if (SUCCEEDED(hr) && 
                    type.majortype != MEDIATYPE_Video && type.majortype != MEDIATYPE_Audio) {
                        return false;
                }
            }
#ifdef GRAPH_DEBUG
            {
                FILTER_INFO info;
                filter->QueryFilterInfo(&info);
                qDebug() << "found a demuxer filter" << QString((const QChar *)info.achName);
                if (info.pGraph) {
                    info.pGraph->Release();
                }
            }
#endif
            return true;
        }

        QMultiMap<QString, QString> MediaGraph::metadata() const
        {
            QMultiMap<QString, QString> ret;
            ComPointer<IAMMediaContent> mediaContent(m_demux, IID_IAMMediaContent);
            if (mediaContent) {
                //let's get the meta data
                BSTR str;
                HRESULT hr = mediaContent->get_AuthorName(&str);
                if (SUCCEEDED(hr)) {
                    ret.insert(QLatin1String("ARTIST"), QString::fromWCharArray(str));
                    SysFreeString(str);
                }
                hr = mediaContent->get_Title(&str);
                if (SUCCEEDED(hr)) {
                    ret.insert(QLatin1String("TITLE"), QString::fromWCharArray(str));
                    SysFreeString(str);
                }
                hr = mediaContent->get_Description(&str);
                if (SUCCEEDED(hr)) {
                    ret.insert(QLatin1String("DESCRIPTION"), QString::fromWCharArray(str));
                    SysFreeString(str);
                }
                hr = mediaContent->get_Copyright(&str);
                if (SUCCEEDED(hr)) {
                    ret.insert(QLatin1String("COPYRIGHT"), QString::fromWCharArray(str));
                    SysFreeString(str);
                }
                hr = mediaContent->get_MoreInfoText(&str);
                if (SUCCEEDED(hr)) {
                    ret.insert(QLatin1String("MOREINFO"), QString::fromWCharArray(str));
                    SysFreeString(str);
                }
            }
            return ret;
        }

        Filter MediaGraph::realSource() const
        {
            return m_realSource;
        }

#ifndef QT_NO_PHONON_MEDIACONTROLLER
        void MediaGraph::setStopPosition(qint64 time)
        {
            qint64 current = 0,
                stop = 0;
            m_mediaSeeking->GetPositions(&current, &stop);

            const bool shouldSeek = current == stop;

            if (time == -1) {
                HRESULT hr = m_mediaSeeking->GetDuration(&time);
                if (FAILED(hr)) {
                    return;
                }
            } else {
                time *= 10000;
            }

            if (time == stop) {
                //the stop position is already at the right place
                return;
            }

            if (shouldSeek) {
                m_mediaSeeking->SetPositions(&current, AM_SEEKING_AbsolutePositioning, 
                    &time, AM_SEEKING_AbsolutePositioning);
            } else {
                m_mediaSeeking->SetPositions(0, AM_SEEKING_NoPositioning, 
                    &time, AM_SEEKING_AbsolutePositioning);
            }
        }

        qint64 MediaGraph::stopPosition() const
        {
            qint64 ret;
            m_mediaSeeking->GetStopPosition(&ret);
            return ret / 10000;

        }

        QList<qint64> MediaGraph::titles() const
        {
            //for now we only manage that for the audio cd
            ComPointer<ITitleInterface> titleIFace(m_realSource, IID_ITitleInterface);
            if (titleIFace) {
                return titleIFace->titles();
            } else {
                // the default value: only one title that starts at position 0
                return QList<qint64>() << 0;
            }
        }
#endif //QT_NO_PHONON_MEDIACONTROLLER



    }
}

QT_END_NAMESPACE
