#
# Copyright (C) 2007-2008 Arnold Krille
# Copyright (C) 2007-2008 Pieter Palmers
#
# This file is part of FFADO
# FFADO = Free Firewire (pro-)audio drivers for linux
#
# FFADO is based upon FreeBoB.
#
# 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 of the License, or
# (at your option) version 3 of the License.
#
# 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 this program.  If not, see <http://www.gnu.org/licenses/>.
#

import os

Import( 'env' )

libenv = env.Clone()

libenv.MergeFlags( "-I#/ -I#/src" )

ffado_source = env.Split( '\
    devicemanager.cpp \
    ffado.cpp \
    ffadodevice.cpp \
    debugmodule/debugmodule.cpp \
    DeviceStringParser.cpp \
    libieee1394/ARMHandler.cpp \
    libieee1394/configrom.cpp \
    libieee1394/csr1212.c \
    libieee1394/CycleTimerHelper.cpp \
    libieee1394/ieee1394service.cpp \
    libieee1394/IEC61883.cpp \
    libieee1394/IsoHandlerManager.cpp \
    libstreaming/StreamProcessorManager.cpp \
    libstreaming/util/cip.c \
    libstreaming/generic/StreamProcessor.cpp \
    libstreaming/generic/Port.cpp \
    libstreaming/generic/PortManager.cpp \
    libutil/cmd_serialize.cpp \
    libutil/DelayLockedLoop.cpp \
    libutil/IpcRingBuffer.cpp \
    libutil/PacketBuffer.cpp \
    libutil/Configuration.cpp \
    libutil/OptionContainer.cpp \
    libutil/PosixMessageQueue.cpp \
    libutil/PosixSharedMemory.cpp \
    libutil/PosixMutex.cpp \
    libutil/PosixThread.cpp \
    libutil/ringbuffer.c \
    libutil/StreamStatistics.cpp \
    libutil/SystemTimeSource.cpp \
    libutil/TimestampedBuffer.cpp \
    libutil/Watchdog.cpp \
    libcontrol/Element.cpp \
    libcontrol/BasicElements.cpp \
    libcontrol/MatrixMixer.cpp \
    libcontrol/CrossbarRouter.cpp \
    libcontrol/ClockSelect.cpp \
    libcontrol/Nickname.cpp \
')

if env['SERIALIZE_USE_EXPAT']:
    ffado_source.append('libutil/serialize_expat.cpp')
    ffado_source.append('libutil/serialize_expat_xml.cpp')
else:
    ffado_source.append('libutil/serialize_libxml.cpp')

bebob_source = env.Split( '\
    bebob/bebob_avdevice.cpp \
    bebob/bebob_avdevice_subunit.cpp \
    bebob/bebob_avplug.cpp \
    bebob/bebob_dl_bcd.cpp \
    bebob/bebob_dl_codes.cpp \
    bebob/bebob_dl_mgr.cpp \
    bebob/bebob_functionblock.cpp \
    bebob/bebob_mixer.cpp \
    bebob/focusrite/focusrite_generic.cpp \
    bebob/focusrite/focusrite_saffire.cpp \
    bebob/focusrite/focusrite_saffirepro.cpp \
    bebob/focusrite/focusrite_cmd.cpp \
    bebob/terratec/terratec_device.cpp \
    bebob/terratec/terratec_cmd.cpp \
    bebob/edirol/edirol_fa101.cpp \
    bebob/edirol/edirol_fa66.cpp \
    bebob/esi/quatafire610.cpp \
    bebob/mackie/onyxmixer.cpp \
    bebob/yamaha/yamaha_cmd.cpp \
    bebob/yamaha/yamaha_avdevice.cpp \
    bebob/maudio/normal_avdevice.cpp \
    bebob/maudio/special_avdevice.cpp \
    bebob/maudio/special_mixer.cpp \
    bebob/presonus/firebox_avdevice.cpp \
    bebob/presonus/inspire1394_avdevice.cpp \
' )

bebob_pkgdata = env.Split( '\
    bebob/maudio/refdesign.xml \
    bebob/maudio/fw410.xml \
    bebob/maudio/fwap.xml \
' )

genericavc_source =  env.Split( '\
    genericavc/avc_avdevice.cpp \
    genericavc/stanton/scs.cpp \
' )

genericavc_pkgdata = env.Split( '\
' )

fireworks_source =  env.Split( '\
    fireworks/fireworks_device.cpp \
    fireworks/fireworks_control.cpp \
    fireworks/fireworks_firmware.cpp \
    fireworks/efc/efc_avc_cmd.cpp \
    fireworks/efc/efc_cmd.cpp \
    fireworks/efc/efc_cmds_hardware.cpp \
    fireworks/efc/efc_cmds_hardware_ctrl.cpp \
    fireworks/efc/efc_cmds_flash.cpp \
    fireworks/efc/efc_cmds_mixer.cpp \
    fireworks/efc/efc_cmds_monitor.cpp \
    fireworks/efc/efc_cmds_ioconfig.cpp \
    fireworks/fireworks_session_block.cpp \
    fireworks/audiofire/audiofire_device.cpp \
' )

fireworks_pkgdata =  env.Split( '\
' )

oxford_source =  env.Split( '\
    oxford/oxford_device.cpp \
    libstreaming/amdtp-oxford/AmdtpOxfordReceiveStreamProcessor.cpp \
' )

oxford_pkgdata = env.Split( '\
' )

motu_source = env.Split( '\
    motu/motu_avdevice.cpp \
    motu/motu_controls.cpp \
    motu/motu_mark3_controls.cpp \
    motu/motu_mixerdefs.cpp \
    motu/motu_mark3_mixerdefs.cpp \
    motu/motu_mixer.cpp \
    libstreaming/motu/MotuPort.cpp \
    libstreaming/motu/MotuPortInfo.cpp \
    libstreaming/motu/MotuReceiveStreamProcessor.cpp \
    libstreaming/motu/MotuTransmitStreamProcessor.cpp \
' )

dice_source = env.Split( '\
    dice/dice_avdevice.cpp \
    dice/dice_firmware_loader.cpp \
    dice/dice_eap.cpp \
    dice/focusrite/focusrite_eap.cpp \
    dice/focusrite/saffire_pro40.cpp \
    dice/focusrite/saffire_pro26.cpp \
    dice/focusrite/saffire_pro24.cpp \
    dice/focusrite/saffire_pro14.cpp \
    dice/focusrite/saffire_56.cpp \
    dice/maudio/profire_2626.cpp \
    dice/presonus/firestudio_tube.cpp \
    dice/presonus/firestudio_project.cpp \
    dice/presonus/firestudio_mobile.cpp \
' )

bounce_source = env.Split( '\
    bounce/bounce_avdevice.cpp \
    bounce/bounce_slave_avdevice.cpp \
' )

metric_halo_source = env.Split( '\
    metrichalo/mh_avdevice.cpp \
' )

rme_source = env.Split( '\
    rme/rme_shm.cpp \
    rme/rme_avdevice.cpp \
    rme/rme_avdevice_settings.cpp \
    rme/fireface_flash.cpp \
    rme/fireface_hw.cpp \
    rme/fireface_settings_ctrls.cpp \
    libstreaming/rme/RmePort.cpp \
    libstreaming/rme/RmePortInfo.cpp \
    libstreaming/rme/RmeReceiveStreamProcessor.cpp \
    libstreaming/rme/RmeTransmitStreamProcessor.cpp \
' )

digidesign_source = env.Split( '\
    digidesign/digidesign_avdevice.cpp \
    libstreaming/digidesign/DigidesignPort.cpp \
    libstreaming/digidesign/DigidesignPortInfo.cpp \
    libstreaming/digidesign/DigidesignReceiveStreamProcessor.cpp \
    libstreaming/digidesign/DigidesignTransmitStreamProcessor.cpp \
' )

amdtp_source = env.Split( '\
    libstreaming/amdtp/AmdtpPort.cpp \
    libstreaming/amdtp/AmdtpPortInfo.cpp \
    libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp \
    libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp \
' )

libavc_source = env.Split( '\
    libavc/streamformat/avc_extended_stream_format.cpp \
    libavc/musicsubunit/avc_descriptor_music.cpp \
    libavc/musicsubunit/avc_musicsubunit.cpp \
    libavc/audiosubunit/avc_audiosubunit.cpp \
    libavc/audiosubunit/avc_descriptor_audio.cpp \
    libavc/audiosubunit/avc_function_block.cpp \
    libavc/descriptors/avc_descriptor_cmd.cpp \
    libavc/descriptors/avc_descriptor.cpp \
    libavc/general/avc_extended_subunit_info.cpp \
    libavc/general/avc_unit_info.cpp \
    libavc/general/avc_generic.cpp \
    libavc/general/avc_subunit_info.cpp \
    libavc/general/avc_connect.cpp \
    libavc/general/avc_signal_format.cpp \
    libavc/general/avc_extended_cmd_generic.cpp \
    libavc/general/avc_extended_plug_info.cpp \
    libavc/general/avc_plug_info.cpp \
    libavc/general/avc_unit.cpp \
    libavc/general/avc_subunit.cpp \
    libavc/general/avc_plug.cpp \
    libavc/general/avc_vendor_dependent_cmd.cpp \
    libavc/avc_definitions.cpp \
    libavc/ccm/avc_signal_source.cpp \
' )

source = ffado_source
pkgdata = []
if env['ENABLE_BEBOB']:
    env['ENABLE_GENERICAVC'] = True
    libenv.MergeFlags( "-DENABLE_BEBOB" )
    source += bebob_source
    pkgdata += bebob_pkgdata
if env['ENABLE_FIREWORKS']:
    env['ENABLE_GENERICAVC'] = True
    libenv.MergeFlags( "-DENABLE_FIREWORKS" )
    source += fireworks_source
    pkgdata += fireworks_pkgdata
if env['ENABLE_OXFORD']:
    env['ENABLE_GENERICAVC'] = True
    libenv.MergeFlags( "-DENABLE_OXFORD" )
    source += oxford_source
    pkgdata += oxford_pkgdata
if env['ENABLE_MOTU']:
    libenv.MergeFlags( "-DENABLE_MOTU" )
    source += motu_source
if env['ENABLE_DICE']:
    env['ENABLE_GENERICAVC'] = True
    libenv.MergeFlags( "-DENABLE_DICE" )
    source += dice_source
if env['ENABLE_METRIC_HALO']:
    libenv.MergeFlags( "-DENABLE_METRIC_HALO" )
    source += metric_halo_source
if env['ENABLE_RME']:
    libenv.MergeFlags( "-DENABLE_RME" )
    source += rme_source
if env['ENABLE_DIGIDESIGN']:
    libenv.MergeFlags( "-DENABLE_DIGIDESIGN" )
    source += digidesign_source
if env['ENABLE_BOUNCE']:
    env['ENABLE_GENERICAVC'] = True
    libenv.MergeFlags( "-DENABLE_BOUNCE" )
    source += bounce_source

if env['ENABLE_GENERICAVC']:
    libenv.MergeFlags( "-DENABLE_GENERICAVC" )
    source += libavc_source
    source += amdtp_source
    source += genericavc_source
    pkgdata += genericavc_pkgdata

if not env.GetOption( "clean" ):
    libenv.MergeFlags( "-lrt -lpthread" )
    libenv.MergeFlags( env['LIBRAW1394_FLAGS'].decode() )
    libenv.MergeFlags( env['LIBIEC61883_FLAGS'].decode() )
    libenv.MergeFlags( env['LIBCONFIG_FLAGS'].decode() )
    if not env['SERIALIZE_USE_EXPAT']:
        if 'LIBXML30_FLAGS' in env :
            libenv.MergeFlags( env['LIBXML30_FLAGS'].decode() )
        if not('LIBXML30_FLAGS' in env) :
            libenv.MergeFlags( env['LIBXML26_FLAGS'].decode() )
    else:
        libenv.PrependUnique( LIBS=["expat"] )
        libenv.MergeFlags( "-DSERIALIZE_USE_EXPAT" )
    if env['REQUIRE_LIBAVC']:
        libenv.MergeFlags( env['LIBAVC1394_FLAGS'].decode() )

libname_versioned = "libffado.so.%s" % libenv['VERSION']
libname_versioned_short = "libffado.so.%s" % libenv['VERSION'].split('.')[0]

libenv.MergeFlags( "-Wl,-soname=%s" % libname_versioned_short )
ffadolib = libenv.SharedLibrary( "ffado", source )

#libenv.Install( "$libdir", ffadolib )
installer = libenv.InstallAs ( "$libdir/%s" % libname_versioned , ffadolib )

# if stripping would be something for us
#libenv.AddPostAction(installer, [['strip', env['STRIPFLAGS'], t[0].path]])

# make the required links
libenv.NoCache( '$libdir/%s' % libname_versioned )
libenv.AddPostAction(installer, [['rm', '-f', '$libdir/libffado.so', '$libdir/%s' % libname_versioned_short],
                                 ['cd', '$libdir',
                                 '&&','ln', '-s', libname_versioned_short, 'libffado.so',
                                 '&&','ln', '-s', installer[0].name, libname_versioned_short,
                                 ]
                                ])

if libenv['BUILD_STATIC_LIB']:
    ffadolib_static = libenv.StaticLibrary( "ffado", source )

#
# Install the pkgdata to $sharedir
#
for data in pkgdata:
    libenv.Install( "$sharedir", data )

#
# For the debugging apps
#
env2 = libenv.Clone()
env2.PrependUnique( LIBPATH=env['build_base']+"src" )
env2.PrependUnique( LIBS="ffado" )

apps = { \
    "test-debugmodule" : "debugmodule/test_debugmodule.cpp", \
    "test-dll" : "libutil/test-dll.cpp", \
    "test-unittests-util" : "libutil/unittests.cpp", \
    "test-cyclecalc" : "libieee1394/test-cyclecalc.cpp", \
}

installapps = []

for app in apps.keys():
    env2.Program( target=app, source = env.Split( apps[app] ) )
    if app.find( "test" ) == -1:
        env2.Install( "$bindir", app )
