/*  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 "mediaobject.h"

#include "mmf_medianode.h"

QT_BEGIN_NAMESPACE

using namespace Phonon;
using namespace Phonon::MMF;

/*! \class MMF::MediaNode
  \internal
*/

MMF::MediaNode::MediaNode(QObject *parent)
    :   QObject(parent)
    ,   m_mediaObject(qobject_cast<MediaObject *>(this))
    ,   m_input(0)
{

}

MMF::MediaNode::~MediaNode()
{
    // Phonon framework ensures nodes are disconnected before being destroyed.
    Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO,
        "Media node not disconnected before destruction");
}

bool MMF::MediaNode::connectOutput(MediaNode *output)
{
    Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer");

    bool connected = false;

    // Check that this connection will not result in a graph which
    // containing more than one MediaObject
    const bool mediaObjectMisMatch =
            m_mediaObject
        &&  output->m_mediaObject
        &&  m_mediaObject != output->m_mediaObject;

    const bool canConnect =
            !output->isMediaObject()
        &&  !output->m_input
        &&  !m_outputs.contains(output);

    if (canConnect && !mediaObjectMisMatch) {
        output->m_input = this;
        m_outputs += output;
        updateMediaObject();
        connected = true;
    }

    return connected;
}

bool MMF::MediaNode::disconnectOutput(MediaNode *output)
{
    Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer");

    bool disconnected = false;

    if (m_outputs.contains(output) && this == output->m_input) {
        output->m_input = 0;
        const bool removed = m_outputs.removeOne(output);
        Q_ASSERT_X(removed, Q_FUNC_INFO, "Output removal failed");

        Q_ASSERT_X(!m_outputs.contains(output), Q_FUNC_INFO,
            "Output list contains duplicate entries");

        // Perform traversal across each of the two graphs separately
        updateMediaObject();
        output->updateMediaObject();

        disconnected = true;
    }

    return disconnected;
}

bool MMF::MediaNode::isMediaObject() const
{
    return (qobject_cast<const MediaObject *>(this) != 0);
}

void MMF::MediaNode::updateMediaObject()
{
    QList<MediaNode *> nodes;
    MediaObject *mediaObject = 0;

    // Traverse the graph, collecting a list of nodes, and locating
    // the MediaObject node, if present
    visit(nodes, mediaObject);

    MediaNode *node = 0;
    foreach(node, nodes)
        node->setMediaObject(mediaObject);
}

void MMF::MediaNode::setMediaObject(MediaObject *mediaObject)
{
    if(!isMediaObject() && m_mediaObject != mediaObject) {
        if (!mediaObject)
            disconnectMediaObject(m_mediaObject);
        else {
            Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO, "MediaObject already set");
            connectMediaObject(mediaObject);
        }
        m_mediaObject = mediaObject;
    }
}

void MMF::MediaNode::visit(QList<MediaNode *>& visited, MediaObject*& mediaObject)
{
    if (isMediaObject()) {
        // There can never be more than one MediaObject per graph, due to the
        // mediaObjectMisMatch test in connectOutput().
        Q_ASSERT_X(!mediaObject, Q_FUNC_INFO, "MediaObject already found");
        mediaObject = static_cast<MediaObject *>(this);
    }

    visited += this;

    if (m_input && !visited.contains(m_input))
        m_input->visit(visited, mediaObject);

    MediaNode *output = 0;
    foreach (output, m_outputs)
        if (!visited.contains(output))
            output->visit(visited, mediaObject);
}

QT_END_NAMESPACE

