# vim: filetype=python expandtab sw=4 tabstop=4

import sys
import glob

Import("commonEnvironment", "commandOptions", "util" )
Import("configure")

commandOptions.Add('buildImageOpcodes',
    'Set to 0 to avoid building image opcodes',
    '1')
commandOptions.Add('useOSC',
    'Set to 1 if you want OSC support',
    '0')
if util.platform != 'win32':
    commandOptions.Add('useUDP',
        'Set to 0 if you do not want UDP support',
        '1')
else:
    commandOptions.Add('useUDP',
        'Set to 1 if you want UDP support',
        '0')
commandOptions.Add('buildFluidOpcodes',
    'Set to 1 to build the Fluid Opcodes',
    '0')
commandOptions.Add('buildDSSI',
    "Build DSSI/LADSPA host opcodes",
    '0')
commandOptions.Add('buildLoris',
    'Set to 1 to build the Loris Python extension and opcodes',
    '0')

commandOptions.Update(commonEnvironment)

util.fixEnvForOLPC(commonEnvironment)

pluginEnvironment = commonEnvironment.Clone()

buildOLPC = (commonEnvironment['buildOLPC'] != '0')

if util.platform == 'darwin':
    pluginEnvironment.Append(LINKFLAGS = Split('''
        -framework CoreMidi -framework CoreFoundation -framework CoreAudio
    '''))
    # pluginEnvironment.Append(LINKFLAGS = ['-dynamiclib'])
    pluginEnvironment['SHLIBSUFFIX'] = '.dylib'
    pluginEnvironment.Prepend(CXXFLAGS = "-fno-rtti")

stdsrcs = Split( '''
                    bbcut.c         biquad.c
    butter.c        clfilt.c        cross2.c
    dam.c           dcblockr.c      filter.c
    flanger.c       follow.c        fout.c
    freeverb.c      ftconv.c        ftgen.c
    gab/gab.c       gab/vectorial.c grain.c
    locsig.c        lowpassr.c      metro.c
    midiops2.c      midiops3.c      newfils.c
    nlfilt.c        oscbnk.c        pluck.c
    repluck.c       reverbsc.c      seqtime.c
    sndloop.c       sndwarp.c       space.c
                    syncgrain.c     ugens7.c
    ugens9.c        ugensa.c        uggab.c
    ugmoss.c                        ugsc.c
    wave-terrain.c  stdopcod.c
        ''')
if not buildOLPC:
    stdsrcs.append(Split('ambicode.c spat3d.c ugnorman.c') )

util.makePlugin(pluginEnvironment, 'stdopcod', stdsrcs)

if util.platform != 'win32' and not buildOLPC:
    util.makePlugin(pluginEnvironment, 'control', 'control.c')

util.makePlugin(pluginEnvironment, 'eqfil', 'eqfil.c')
util.makePlugin(pluginEnvironment, 'pvsbuffer', 'pvsbuffer.c')
util.makePlugin(pluginEnvironment, 'scoreline', 'scoreline.c')

if not buildOLPC:
  util.makePlugin(pluginEnvironment, 'ftest', 'ftest.c')

util.makePlugin(pluginEnvironment, 'mixer', 'mixer.cpp')
util.makePlugin(pluginEnvironment, 'modal4',
    ['modal4.c', 'physutil.c'])
util.makePlugin(pluginEnvironment, 'physmod', Split('''
    physmod.c physutil.c mandolin.c singwave.c
    fm4op.c moog1.c shaker.c bowedbar.c
'''))
util.makePlugin(pluginEnvironment, 'pitch',
    ['pitch.c', 'pitch0.c', 'spectra.c'])
util.makePlugin(pluginEnvironment, 'scansyn',
    ['scansyn.c', 'scansynx.c'])

sfontEnvironment = pluginEnvironment.Clone()
if util.compilerGNU():
    sfontEnvironment.Append(CCFLAGS = ['-fno-strict-aliasing'])
if sys.byteorder == 'big':
    sfontEnvironment.Append(CCFLAGS = ['-DWORDS_BIGENDIAN'])
util.makePlugin(sfontEnvironment, 'sfont', ['sfont.c'])

if not buildOLPC:
  util.makePlugin(pluginEnvironment, 'babo', ['babo.c'])

util.makePlugin(pluginEnvironment, 'barmodel', ['bilbar.c'])
util.makePlugin(pluginEnvironment, 'compress', ['compress.c'])
util.makePlugin(pluginEnvironment, 'grain4', ['grain4.c'])

if not buildOLPC:
  util.makePlugin(pluginEnvironment, 'hrtferX', ['hrtferX.c'])

util.makePlugin(pluginEnvironment, 'loscilx', ['loscilx.c'])
util.makePlugin(pluginEnvironment, 'minmax', ['minmax.c'])
util.makePlugin(pluginEnvironment, 'cs_pan2', ['pan2.c'])
util.makePlugin(pluginEnvironment, 'phisem', ['phisem.c'])
util.makePlugin(pluginEnvironment, 'pvoc', Split('''
    dsputil.c pvadd.c pvinterp.c pvocext.c
    pvread.c ugens8.c vpvoc.c pvoc.c
'''))
util.makePlugin(pluginEnvironment, 'cs_pvs_ops', Split('''
    ifd.c partials.c psynth.c pvsbasic.c
    pvscent.c pvsdemix.c pvs_ops.c pvsband.c
'''))
util.makePlugin(pluginEnvironment, 'stackops', ['stackops.c'])

if not buildOLPC:
  util.makePlugin(pluginEnvironment, 'vbap',
           ['vbap.c', 'vbap_eight.c', 'vbap_four.c',
            'vbap_sixteen.c', 'vbap_zak.c'])

util.makePlugin(pluginEnvironment, 'vaops', ['vaops.c'])
util.makePlugin(pluginEnvironment, 'harmon', ['harmon.c'])
util.makePlugin(pluginEnvironment, 'ampmidid', ['ampmidid.cpp'])
util.makePlugin(pluginEnvironment, 'cs_date', ['date.c'])
util.makePlugin(pluginEnvironment, 'system_call', ['system_call.c'])
util.makePlugin(pluginEnvironment, 'ptrack', ['pitchtrack.c'])
util.makePlugin(pluginEnvironment, 'mutexops', ['mutexops.cpp'])
util.makePlugin(pluginEnvironment, 'partikkel', ['partikkel.c'])
util.makePlugin(pluginEnvironment, 'shape', ['shape.c'])

if buildOLPC :
    oggEnvironment = pluginEnvironment.Clone()
    oggEnvironment.Append(LIBS=['vorbisfile', 'vorbis', 'ogg'])
    util.makePlugin(oggEnvironment, 'ogg', ['ogg.c'])
    util.makePlugin(oggEnvironment, 'oggplay', ['oggplay.c'])

util.makePlugin(pluginEnvironment, 'vosim', ['Vosim.c'])

util.makePlugin(pluginEnvironment, 'gabnew', Split('''
    gab/tabmorph.c  gab/hvs.c
    gab/sliderTable.c
    gab/newgabopc.c
'''))
util.makePlugin(pluginEnvironment, 'hrtfnew', 'hrtfopcodes.c')

if not buildOLPC:
    jackFound = configure.CheckLibWithHeader("jack", "jack/jack.h",
        language = "C", autoadd=False)
    if jackFound:
        jackEnv = pluginEnvironment.Clone()
        jackEnv.Append(LIBS = 'jack')
        util.makePlugin(jackEnv, 'jackTransport', 'jackTransport.c')

if commonEnvironment['buildImageOpcodes'] == '1':
    if not configure.CheckHeader("png.h", language="C"):
        util.fatal("You specified buildImageOpcodes but libpng was not found")
    if not configure.CheckHeader("zlib.h", language = "C"):
        util.fatal("You specified buildImageOpcodes but zlib was not found")
    util.confDecision('Building image opcodes')
    imgEnvironment = pluginEnvironment.Clone()
    imgEnvironment.Append(LIBS= Split(''' png z '''))
    util.makePlugin(imgEnvironment, 'image', ['imageOpcodes.c'])
else:
    util.confDecision('Not building image opcodes')


# OSC opcodes
if commonEnvironment['useOSC'] == '1':
    if not configure.CheckLibWithHeader("lo", "lo/lo.h", language = "C"):
        util.fatal("You specified useOSC but OSC was not found.")
    util.confDecision("Building OSC plugin.")
    oscEnvironment = pluginEnvironment.Clone()
    oscEnvironment.Append(LIBS = ['lo', 'pthread'])
    if util.platform == 'win32':
        if util.compilerGNU():
            oscEnvironment.Append(SHLINKFLAGS = ['-Wl,--enable-stdcall-fixup'])
    util.makePlugin(oscEnvironment, 'osc', ['OSC.c'])
else:
    util.confDecision("Not building OSC plugin.")

# UDP opcodes

if commonEnvironment['useUDP'] != '0':
    util.confDecision("Building UDP plugins.")
    udpEnvironment = pluginEnvironment.Clone()
    udpEnvironment.Append(LIBS = ['pthread'])
    util.makePlugin(udpEnvironment, 'udprecv', ['sockrecv.c'])
    util.makePlugin(udpEnvironment, 'udpsend', ['socksend.c'])
else:
    util.confDecision("Not building UDP plugins.")

if commonEnvironment['buildFluidOpcodes']!='0':
    if not configure.CheckHeader("fluidsynth.h", language = "C"):
        util.fatal("You specified buildFluidOpcodes but fluidsynth was not found")
    util.confDecision("Building fluid opcodes.")
    fluidEnvironment = pluginEnvironment.Clone()
    fluidEnvironment.Append(LIBS        = ['fluidsynth'])
    if util.platform == 'win32':
        fluidEnvironment.Append(CPPFLAGS    = ['-DFLUIDSYNTH_NOT_A_DLL'])
        fluidEnvironment.Append(LIBS        = ['winmm', 'dsound'])
    elif util.platform == 'linux' or util.platform == 'darwin':
        fluidEnvironment.Append(LIBS        = ['pthread'])
    util.makePlugin(fluidEnvironment, 'fluidOpcodes',
                    ['fluidOpcodes/fluidOpcodes.c'])
else:
    util.confDecision("Not building fluid opcodes.")

# DSSI host
if commonEnvironment['buildDSSI'] == '1':
    if not configure.CheckHeader("ladspa.h", language = "C"):
        util.fatal("You specified buildDSSI but LADSPA was not found")
    if not configure.CheckLibWithHeader('asound',
     'alsa/asoundlib.h', language="C"):
        util.fatal("You specified buildDSSI but ALSA was not found")
    util.confDecision("Building DSSI plugin host opcodes.")
    dssiEnvironment = pluginEnvironment.Clone()
    dssiEnvironment.Append(LIBS = ['dl'])
    dssiSrc = ['dssi4cs/src/load.c', 'dssi4cs/src/dssi4cs.c']
    util.makePlugin(dssiEnvironment, 'dssi4cs', dssiSrc)
else:
    util.confDecision("Not building DSSI plugin host opcodes.")

# Loris opcodes

if commonEnvironment['buildLoris'] == '1':
    if not configure.CheckHeader("Opcodes/Loris/src/loris.h"):
        util.fatal("You specified buildLoris but Loris was not found")
    if not configure.CheckHeader("fftw3.h"):
        util.fatal("You specified buildLoris but fftw3.h was not found")
    util.confDecision("Building Loris Python extension and Csound opcodes.")
    # For Loris, we build only the loris Python extension module and
    # the Csound opcodes (modified for Csound 5).
    # It is assumed that you have copied all contents of the Loris
    # distribution into the csound5/Opcodes/Loris directory, e.g.
    # csound5/Opcodes/Loris/src/*, etc.
    lorisEnvironment = pluginEnvironment.Clone()
    lorisEnvironment.Append(CCFLAGS = '-DHAVE_FFTW3_H')
    if commonEnvironment['buildRelease'] == '0':
        lorisEnvironment.Append(CCFLAGS = '-DDEBUG_LORISGENS')
    if util.platform == 'win32':
        lorisEnvironment.Append(CCFLAGS = '-D_MSC_VER')
    if util.compilerGNU():
        lorisEnvironment.Prepend(LIBS = ['stdc++'])
        lorisEnvironment.Append(CCFLAGS = Split(
        '-Wno-comment -Wno-unknown-pragmas -Wno-sign-compare'))
    lorisEnvironment.Append(CPPPATH = Split(
        'Loris Loris/src'))
    lorisSources = glob.glob('Loris/src/*.[Cc]')
    if 'Loris/src/lorisgens.C' in lorisSources:
        lorisSources.remove('Loris/src/lorisgens.C')
    lorisLibrarySources = []
    for i in lorisSources:
        lorisLibrarySources += lorisEnvironment.SharedObject(i)
    lorisLibrary = lorisEnvironment.StaticLibrary(
        'lorisbase', lorisLibrarySources)
    lorisEnvironment.Prepend(LIBS = [lorisLibrary, 'fftw3'])
    # The following file has been patched for Csound 5
    # and you should update it from Csound 5 CVS.
    lorisOpcodes = util.makePlugin(
        lorisEnvironment, 'loris', ['Loris/lorisgens5.C'])
    lorisPythonEnvironment = lorisEnvironment.Clone()
    util.fixCFlagsForSwig(lorisPythonEnvironment)
    util.fixEnvForPython(lorisPythonEnvironment, configure)
    lorisPythonEnvironment.Append(SWIGPATH  = ['#./', '#./Opcodes/Loris/src'])
    lorisPythonEnvironment.Prepend(SWIGFLAGS = Split('''
        -module loris -c++ -includeall -verbose -outdir . -python
        -DHAVE_FFTW3_H
    '''))
    lorisPythonWrapper = lorisPythonEnvironment.SharedObject(
        'Loris/scripting/loris.i')
    lorisPythonEnvironment['SHLIBPREFIX'] = ''
    lorisPythonModule = util.makePythonModule(
        lorisPythonEnvironment, 'loris', lorisPythonWrapper)
else:
    util.confDecision("Not building Loris Python extension and Csound opcodes.")