/*  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 "audionode.h"
#include "audiograph.h"
#include "audioconnection.h"
#include "medianode.h"

QT_BEGIN_NAMESPACE

namespace Phonon
{
namespace QT7
{

AudioNode::AudioNode(int maxInputBusses, int maxOutputBusses)
{
    m_auNode = 0;
    m_audioUnit = 0;
    m_audioGraph = 0;
    m_maxInputBusses = maxInputBusses;
    m_maxOutputBusses = maxOutputBusses;
    m_lastConnectionIn = 0;
}

AudioNode::~AudioNode()
{
    setGraph(0);
}

void AudioNode::setGraph(AudioGraph *audioGraph)
{
    if (m_audioGraph == audioGraph)
        return;

    DEBUG_AUDIO_GRAPH("AudioNode" << int(this) << "is setting graph:" << int(audioGraph))    
    if (m_auNode){
        AUGraphRemoveNode(m_audioGraph->audioGraphRef(), m_auNode);
        m_auNode = 0;
    }
    
    m_audioUnit = 0;
    m_lastConnectionIn = 0;
    m_audioGraph = audioGraph;
}

void AudioNode::createAndConnectAUNodes()
{
    if (m_auNode)
        return;

    ComponentDescription description = getAudioNodeDescription();
    DEBUG_AUDIO_GRAPH("AudioNode" << int(this) << "creates AUNode" 
        << QString(!FindNextComponent(0, &description) ? "ERROR: COMPONENT NOT FOUND!" : "OK!"))

    OSStatus err = noErr;

    // The proper function to call here is AUGraphAddNode() but the type has
    // changed between 10.5 and 10.6. it's still OK to call this function, but
    // if we want to use the proper thing we need to move over to
    // AudioComponentDescription everywhere, which is very similar to the
    // ComponentDescription, but a different size.  however,
    // AudioComponentDescription only exists on 10.6+. More fun than we need to
    // deal with at the moment, so we'll take the "deprecated" warning instead.
    err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode);
        
    BACKEND_ASSERT2(err != kAUGraphErr_OutputNodeErr, "A MediaObject can only be connected to one audio output device.", FATAL_ERROR)
    BACKEND_ASSERT2(err == noErr, "Could not create new AUNode.", FATAL_ERROR)
}

AUNode AudioNode::getInputAUNode()
{
    return m_auNode;
}

AUNode AudioNode::getOutputAUNode()
{
    return m_auNode;
}

void AudioNode::createAudioUnits()
{
    if (m_audioUnit)
        return;

    DEBUG_AUDIO_GRAPH("AudioNode" << int(this) << "creates AudioUnit")
    OSStatus err = AUGraphGetNodeInfo(m_audioGraph->audioGraphRef(), m_auNode, 0, 0, 0, &m_audioUnit);
    BACKEND_ASSERT2(err == noErr, "Could not get audio unit from audio node.", FATAL_ERROR)
    initializeAudioUnit();
}

ComponentDescription AudioNode::getAudioNodeDescription() const
{
    // Override if needed.
    ComponentDescription cd;
    Q_UNUSED(cd);
    return cd;
}

bool AudioNode::setStreamHelp(AudioConnection *c, int bus, OSType scope, bool fromSource)
{
    if (fromSource){
	    OSStatus err = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, scope,
	        bus, &c->m_sourceStreamDescription, sizeof(AudioStreamBasicDescription));
        if (err != noErr){
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << " - failed setting stream format")
            return false;
        }
	    AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_AudioChannelLayout, scope,
	    bus, c->m_sourceChannelLayout, c->m_sourceChannelLayoutSize);
    } else {
	    OSStatus err = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, scope,
	        bus, &c->m_sinkStreamDescription, sizeof(AudioStreamBasicDescription));
        if (err != noErr){
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << " - failed setting stream format")
            return false;
        }
	    AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_AudioChannelLayout, scope,
	    bus, c->m_sinkChannelLayout, c->m_sourceChannelLayoutSize);
    }
    return true;
}

bool AudioNode::setStreamSpecification(AudioConnection *connection, ConnectionSide side)
{
    if (side == Source){
        // This object am source of connection:
        if (connection->m_hasSourceSpecification){
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "sets stream specification out"
                << connection->m_sourceOutputBus << "from connection source")
            return setStreamHelp(connection, connection->m_sourceOutputBus, kAudioUnitScope_Output, true);
        } else {
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "did not set stream specification out")
        }
    } else {
        if (connection->m_hasSinkSpecification){
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "sets stream specification"
                << connection->m_sinkInputBus << "from connection sink")
            return setStreamHelp(connection, connection->m_sinkInputBus, kAudioUnitScope_Input, false);
        } else if (connection->m_hasSourceSpecification){
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "sets stream specification"
            << connection->m_sinkInputBus << "from connection source")
            return setStreamHelp(connection, connection->m_sinkInputBus, kAudioUnitScope_Input, true);
        } else {
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "did not set stream specification in")
        }
    }
    return true;
}

bool AudioNode::fillInStreamSpecification(AudioConnection *connection, ConnectionSide side)
{
    if (side == Source){
        // As default, use the last description to describe the source:
        if (m_lastConnectionIn->m_hasSinkSpecification){
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "is source, and fills in stream spec using last connection sink.")
            connection->m_sourceStreamDescription = m_lastConnectionIn->m_sinkStreamDescription;
            connection->m_sourceChannelLayout = (AudioChannelLayout *) malloc(m_lastConnectionIn->m_sinkChannelLayoutSize);
            memcpy(connection->m_sourceChannelLayout, m_lastConnectionIn->m_sinkChannelLayout, m_lastConnectionIn->m_sinkChannelLayoutSize);
            connection->m_sourceChannelLayoutSize = m_lastConnectionIn->m_sinkChannelLayoutSize;
            connection->m_hasSourceSpecification = true;
        } else if (m_lastConnectionIn->m_hasSourceSpecification){
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "is source, and fills in stream spec using last connection source.")
            connection->m_sourceStreamDescription = m_lastConnectionIn->m_sourceStreamDescription;
            connection->m_sourceChannelLayout = (AudioChannelLayout *) malloc(m_lastConnectionIn->m_sourceChannelLayoutSize);
            memcpy(connection->m_sourceChannelLayout, m_lastConnectionIn->m_sourceChannelLayout, m_lastConnectionIn->m_sourceChannelLayoutSize);
            connection->m_sourceChannelLayoutSize = m_lastConnectionIn->m_sourceChannelLayoutSize;
            connection->m_hasSourceSpecification = true;
        } else {
            DEBUG_AUDIO_STREAM("AudioNode" << int(this) << " __WARNING__: could not get stream specification...")
        }
    } else {
        DEBUG_AUDIO_STREAM("AudioNode" << int(this) << "is sink, skips filling in stream.")
        if (!connection->isSinkOnly())
            m_lastConnectionIn = connection;
    }
    return true;
}

/**
    Let timeProperty be one of e.g
    {kAudioUnitProperty_Latency, kAudioUnitProperty_TailTime,
    kAudioOutputUnitProperty_StartTime, kAudioUnitProperty_CurrentPlayTime}
*/
Float64 AudioNode::getTimeInSamples(int timeProperty)
{
    if (!m_audioUnit)
        return 0;

    AudioTimeStamp timeStamp;
    UInt32 size = sizeof(timeStamp);
    memset(&timeStamp, 0, sizeof(timeStamp));
	OSStatus err = AudioUnitGetProperty(m_audioUnit,
        timeProperty, kAudioUnitScope_Global,
        0, &timeStamp, &size);
    if (err != noErr)
        return 0;
    return timeStamp.mSampleTime;
}

void AudioNode::notify(const MediaNodeEvent *event)
{
    switch(event->type()){
    case MediaNodeEvent::AudioGraphAboutToBeDeleted:
        setGraph(0);
        break;
    case MediaNodeEvent::NewAudioGraph:
        setGraph(static_cast<AudioGraph *>(event->data()));
        break;
    default:
        break;
    }

    mediaNodeEvent(event);
}

void AudioNode::mediaNodeEvent(const MediaNodeEvent */*event*/)
{
    // Override if needed
}

void AudioNode::initializeAudioUnit()
{
    // Override if needed.
}

}} //namespace Phonon::QT7

QT_END_NAMESPACE
