#!/usr/bin/env python
from waflib.extras import autowaf as autowaf
from waflib import Options, TaskGen
import waflib.Logs as Logs, waflib.Utils as Utils
import os
import sys
import re
import subprocess
import glob

@TaskGen.extension('.m')
def m_hook(self, node):
    """Alias .m files to be compiled the same as .c files, gcc will do the right thing."""
    return self.create_compiled_task('c', node)

gtk2_ardour_sources = [
        'about.cc',
        'actions.cc',
        'add_route_dialog.cc',
        'ambiguous_file_dialog.cc',
        'analysis_window.cc',
        'ardour_dialog.cc',
        'ardour_http.cc',
        'ardour_message.cc',
        'ardour_ui.cc',
        'ardour_ui2.cc',
        'ardour_ui3.cc',
        'ardour_ui_aaf.cc',
        'ardour_ui_access_web.cc',
        'ardour_ui_dependents.cc',
        'ardour_ui_dialogs.cc',
        'ardour_ui_ed.cc',
        'ardour_ui_engine.cc',
        'ardour_ui_keys.cc',
        'ardour_ui_mixer.cc',
        'ardour_ui_options.cc',
        'ardour_ui_session.cc',
        'ardour_ui_startup.cc',
        'ardour_ui_video.cc',
        'ardour_window.cc',
        'audio_clock.cc',
        'audio_clip_editor.cc',
        'audio_region_editor.cc',
        'audio_region_view.cc',
        'audio_region_operations_box.cc',
        'audio_region_properties_box.cc',
        'audio_trigger_properties_box.cc',
        'audio_streamview.cc',
        'audio_time_axis.cc',
        'automation_controller.cc',
        'automation_line.cc',
        'automation_region_view.cc',
        'automation_streamview.cc',
        'automation_time_axis.cc',
        'axis_view.cc',
        # 'beatbox_gui.cc',
        'bbt_marker_dialog.cc',
        'big_clock_window.cc',
        'big_transport_window.cc',
        'bundle_manager.cc',
        'clock_group.cc',
        'color_theme_manager.cc',
        'configinfo.cc',
        'control_point.cc',
        'control_point_dialog.cc',
        'control_slave_ui.cc',
        'cuebox_ui.cc',
        'cursor_context.cc',
        'curvetest.cc',
        'debug.cc',
        'dsp_stats_ui.cc',
        'dsp_stats_window.cc',
        'duplicate_routes_dialog.cc',
        'edit_note_dialog.cc',
        'editing.cc',
        'editor.cc',
        'editor_actions.cc',
        'editor_audio_import.cc',
        'editor_pt_import.cc',
        'editor_audiotrack.cc',
        'editor_canvas.cc',
        'editor_canvas_events.cc',
        'editor_component.cc',
        'editor_cursors.cc',
        'editor_drag.cc',
        'editor_route_groups.cc',
        'editor_section_box.cc',
        'editor_export_audio.cc',
        'editor_group_tabs.cc',
        'editor_keys.cc',
        'editor_locations.cc',
        'editor_markers.cc',
        'editor_mixer.cc',
        'editor_mouse.cc',
        'editor_ops.cc',
        'editor_regions.cc',
        'editor_routes.cc',
        'editor_rulers.cc',
        'editor_sections.cc',
        'editor_selection.cc',
        'editor_snapshots.cc',
        'editor_sources.cc',
        'editor_summary.cc',
        'editor_tempodisplay.cc',
        'editor_timefx.cc',
        'engine_dialog.cc',
        'enums.cc',
        'export_analysis_graphs.cc',
        'export_channel_selector.cc',
        'export_dialog.cc',
        'export_file_notebook.cc',
        'export_filename_selector.cc',
        'export_format_dialog.cc',
        'export_format_selector.cc',
        'export_preset_selector.cc',
        'export_report.cc',
        'export_timespan_selector.cc',
        'fitted_canvas_widget.cc',
        'fft.cc',
        'fft_graph.cc',
        'fft_result.cc',
        'floating_text_entry.cc',
        'foldback_strip.cc',
        'sfdb_freesound_mootcher.cc',
        'gain_meter.cc',
        'generic_pluginui.cc',
        'ghostregion.cc',
        'global_port_matrix.cc',
        'group_tabs.cc',
        'gui_object.cc',
        'idleometer.cc',
        'input_port_monitor.cc',
        'insert_remove_time_dialog.cc',
        'instrument_selector.cc',
        'interthread_progress_window.cc',
        'io_button.cc',
        'io_plugin_window.cc',
        'io_selector.cc',
        'hit.cc',
        'keyboard.cc',
        'keyeditor.cc',
        'led.cc',
        'level_meter.cc',
        'library_download_dialog.cc',
        'location_ui.cc',
        'loudness_dialog.cc',
        'loudness_settings.cc',
        'lua_script_manager.cc',
        'luadialog.cc',
        'luainstance.cc',
        'luawindow.cc',
        'main.cc',
        'main_clock.cc',
        'marker.cc',
    	'mergeable_line.cc',
        'midi_automation_line.cc',
        'midi_channel_dialog.cc',
        'midi_channel_selector.cc',
        'midi_clip_editor.cc',
        'midi_cut_buffer.cc',
        'midi_export_dialog.cc',
        'midi_list_editor.cc',
        'midi_region_view.cc',
        'midi_region_operations_box.cc',
        'midi_region_properties_box.cc',
        'midi_trigger_properties_box.cc',
        'midi_selection.cc',
        'midi_streamview.cc',
        'midi_time_axis.cc',
        'midi_tracer.cc',
        'midi_velocity_dialog.cc',
        'mini_timeline.cc',
        'missing_file_dialog.cc',
        'missing_filesource_dialog.cc',
        'missing_plugin_dialog.cc',
        'mixer_group_tabs.cc',
        'mixer_strip.cc',
        'mixer_ui.cc',
        'meterbridge.cc',
        'meter_strip.cc',
        'meter_patterns.cc',
        'monitor_section.cc',
        'mono_panner.cc',
        'mono_panner_editor.cc',
        'mouse_cursors.cc',
        'multi_region_properties_box.cc',
        'nag.cc',
        'new_plugin_preset_dialog.cc',
        'new_user_wizard.cc',
        'normalize_dialog.cc',
        'note.cc',
        'note_base.cc',
        'note_player.cc',
        'note_select_dialog.cc',
        'nsm.cc',
        'nsmclient.cc',
        'option_editor.cc',
        'opts.cc',
        'panner2d.cc',
        'panner_editor.cc',
        'panner_interface.cc',
        'panner_ui.cc',
        'patch_change.cc',
        'patch_change_widget.cc',
        'pianokeyboard.cc',
        'piano_key_bindings.cc',
        'piano_roll_header.cc',
        'pingback.cc',
        'playlist_selector.cc',
        'plugin_display.cc',
        'plugin_eq_gui.cc',
        'plugin_manager_ui.cc',
        'plugin_pin_dialog.cc',
        'plugin_presets_ui.cc',
        'plugin_scan_dialog.cc',
        'plugin_setup_dialog.cc',
        'plugin_selector.cc',
        'plugin_ui.cc',
        'plugin_dspload_ui.cc',
        'plugin_dspload_window.cc',
        'plugin_window_proxy.cc',
        'port_group.cc',
        'port_insert_ui.cc',
        'port_matrix.cc',
        'port_matrix_body.cc',
        'port_matrix_column_labels.cc',
        'port_matrix_component.cc',
        'port_matrix_grid.cc',
        'port_matrix_labels.cc',
        'port_matrix_row_labels.cc',
        'processor_box.cc',
        'processor_selection.cc',
        'patch_change_dialog.cc',
        'progress_reporter.cc',
        'pt_import_selector.cc',
        'public_editor.cc',
        'quantize_dialog.cc',
        'rc_option_editor.cc',
        'rec_info_box.cc',
        'recorder_group_tabs.cc',
        'recorder_ui.cc',
        'region_editor.cc',
        'region_fx_line.cc',
        'region_gain_line.cc',
        'region_layering_order_editor.cc',
        'region_list_base.cc',
        'region_peak_cursor.cc',
        'region_selection.cc',
        'region_view.cc',
        'return_ui.cc',
        'rhythm_ferret.cc',
        'route_group_dialog.cc',
        'route_group_menu.cc',
        'route_list_base.cc',
        'route_params_ui.cc',
        'route_processor_selection.cc',
        'route_time_axis.cc',
        'route_ui.cc',
        'ruler_dialog.cc',
        'save_as_dialog.cc',
        'save_template_dialog.cc',
        'search_path_option.cc',
        'screensaver.cc',
        'script_selector.cc',
        'selection.cc',
        'selection_properties_box.cc',
        'selection_memento.cc',
        'send_ui.cc',
        'session_archive_dialog.cc',
        'session_dialog.cc',
        'session_import_dialog.cc',
        'session_metadata_dialog.cc',
        'session_option_editor.cc',
        'sfdb_ui.cc',
        'shuttle_control.cc',
        'simple_export_dialog.cc',
        'slot_properties_box.cc',
        'source_list_base.cc',
        'soundcloud_export_selector.cc',
        'splash.cc',
        'speaker_dialog.cc',
        'startup_fsm.cc',
        'step_editor.cc',
        'step_entry.cc',
        'stereo_panner.cc',
        'stereo_panner_editor.cc',
        'streamview.cc',
        'strip_silence_dialog.cc',
        'stripable_colorpicker.cc',
        'stripable_time_axis.cc',
        'surround_strip.cc',
        'sys_ex.cc',
        'template_dialog.cc',
        'tempo_curve.cc',
        'tempo_dialog.cc',
        'grid_lines.cc',
        'tempo_map_change.cc',
        'time_axis_view.cc',
        'time_axis_view_item.cc',
        'time_fx_dialog.cc',
        'time_info_box.cc',
        'time_selection.cc',
        'timectl_gui.cc',
        'timers.cc',
        'track_record_axis.cc',
        'track_selection.cc',
        'track_view_list.cc',
        'transform_dialog.cc',
        'transport_control.cc',
        'transport_control_ui.cc',
        'transport_masters_dialog.cc',
        'transpose_dialog.cc',
        'trigger_clip_picker.cc',
        'trigger_jump_dialog.cc',
        'trigger_page.cc',
        'trigger_region_list.cc',
        'trigger_route_list.cc',
        'trigger_source_list.cc',
        'trigger_strip.cc',
        'trigger_master.cc',
        'trigger_ui.cc',
        'triggerbox_ui.cc',
        'ui_config.cc',
        'utils.cc',
        'varispeed_dialog.cc',
        'vca_master_strip.cc',
        'verbose_cursor.cc',
        'virtual_keyboard_window.cc',
        'visibility_group.cc',
        'window_manager.cc',
        # video-timeline related sources:
        'video_image_frame.cc',
        'add_video_dialog.cc',
        'editor_videotimeline.cc',
        'vca_time_axis.cc',
        'video_timeline.cc',
        'video_monitor.cc',
        'transcode_ffmpeg.cc',
        'transcode_video_dialog.cc',
        'velocity_ghost_region.cc',
        'video_server_dialog.cc',
        'utils_videotl.cc',
        'export_video_dialog.cc'
]

def enoify (major, minor):
    # Code names based on
    # https://en.wikipedia.org/wiki/Brian_Eno_discography
    #
    # sort Studio albums + Collaborative albums + Compilation albums by Month/Year.
    # (no Singles, no EPs, no Video Albums, no Production)
    if major == 3:
        return "\\n\\\"E-No\\\""
    elif major == 4:
        if minor == 0:
            return "\\n\\\"No Pussyfooting\\\""
        elif minor == 1:
            return "\\n\\\"Here Come the Warm Jets\\\""
        elif minor == 2:
            return "\\n\\\"Taking Tiger Mountain\\\""
        elif minor == 3:
            return "\\n\\\"Lady June's Linguistic Leprosy\\\""
        elif minor == 4:
            return "\\n\\\"Discreet Music\\\""
        elif minor == 5:
            return "\\n\\\"Another Green World\\\""
        elif minor == 6:
            return "\\n\\\"Evening Star\\\""
        elif minor == 7:
            return "\\n\\\"Cluster and Eno\\\""
    elif major == 5:
        if minor == 0:
            return "\\n\\\"Before and After Science\\\""
        elif minor == 1:
            return "\\n\\\"After the Heat\\\""
        elif minor == 2:
            return "\\n\\\"Music for Airports\\\""
        elif minor == 3:
            return "\\n\\\"Music for Films\\\""
        elif minor == 4:
            return "\\n\\\"In a Land of Clear Colours\\\""
        elif minor == 5:
            return "\\n\\\"The Plateaux of Mirror\\\""
        elif minor == 6:
            return "\\n\\\"Possible Musics\\\"" # 1980 Collaborative
        elif minor == 7:
            return "\\n\\\"My Life in the Bush of Ghosts\\\"" # 1981
        elif minor == 8:
            return "\\n\\\"Music for Airplay\\\"" # 1981 Compilation
        elif minor == 9:
            return "\\n\\\"On Land\\\"" # 1982
        elif minor == 10:
            return "\\n\\\"Atmospheres and Soundtracks\\\"" # 1983
        elif minor == 11:
            return "\\n\\\"More Music for Films\\\"" # 1983
        elif minor == 12:
            return "\\n\\\"Working Backwards\\\"" # 1984 Compilation
    elif major == 6:
        if minor == 0:
            return "\\n\\\"The Pearl\\\"" # 1984 Collaborative
        elif minor == 1:
            return "\\n\\\"Begegnungen\\\"" # 1984 Compilation
        elif minor == 2:
            return "\\n\\\"Thursday Afternoon\\\"" # 1985
        elif minor == 3:
            return "\\n\\\"Hybrid\\\"" # 1985 Collaborative
        elif minor == 4 or minor == 5: # (there was on 6.4 release)
            return "\\n\\\"Old Land\\\"" # 1985 Compilation
        elif minor == 6 or minor == 7: # still on the desert island
            return "\\n\\\"Desert Island Selection\\\"" # 1986 Compilation
        else:
            return "\\n\\\"After Bach\\\"" # the odd one out
    elif major == 7:
        if minor == 0:
            return "\\n\\\"More Blank Than Frank\\\"" # 1986 Compilation
        if minor == 1:
            return "\\n\\\"Music for Films III\\\"" # 1988 Collaborative
        if minor == 2:
            return "\\n\\\"Wrong Way Up\\\"" # 1990 Collaborative
        if minor == 3:
            return "\\n\\\"Nerve Net\\\"" # 1992
        if minor == 4:
            return "\\n\\\"The Shutov Assembly\\\"" # 1992
        if minor == 5:
            return "\\n\\\"Neroli\\\"" # 1993
    elif major == 8:
        if minor == 0:
            return "\\n\\\"Spinner\\\"" # 1995
        if minor == 1:
            return "\\n\\\"The Drop\\\"" # 1997
        if minor == 2:
            return "\\n\\\"Tracks and Traces\\\"" # 1997
        if minor == 3:
            return "\\n\\\"Music for White Cube\\\"" # 1997
        if minor == 4:
            return "\\n\\\"Music for the Marble Palace\\\"" # 1998
        if minor == 5:
            return "\\n\\\"I Dormienti\\\"" # 1999
        if minor == 6:
            return "\\n\\\"Kite Stories\\\"" # 1999
        if minor >= 7:
            return "\\n\\\"Sonora Portraits\\\"" # 1999 Compilation
    elif major == 9:
        if minor == 0:
            return "\\n\\\"Music for Civic Recovery Centre\\\"" # 2000
        if minor == 1:
            return "\\n\\\"Music for Onmyo-Ji\\\"" # 2000 Collaborative
        if minor == 2:
            return "\\n\\\"Compact Forest Proposal\\\"" # 2001
        if minor == 3:
            return "\\n\\\"Drawn from Life\\\"" # 2001 Collaborative
    return "\\\"\\\""

def options(opt):
    pass

def configure(conf):
    conf.load('misc')  # make 'command-output' available

    # TODO: Insert a sanity check for on OS X to ensure CoreAudio is present

    autowaf.check_pkg(conf, 'fftw3f', uselib_store='FFTW3F',
                      mandatory=True)
    autowaf.check_pkg(conf, 'flac', uselib_store='FLAC',
                      atleast_version='1.2.1')
    autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD',
                      atleast_version='2.10.1')
    autowaf.check_pkg(conf, 'ogg', uselib_store='OGG', atleast_version='1.1.2')
    autowaf.check_pkg(conf, 'x11', uselib_store='X11', atleast_version='1.1', mandatory=False)
    autowaf.check_pkg(conf, 'pangoft2', uselib_store='PANGOFT2', atleast_version='1.36.8', mandatory=False)
    autowaf.check_pkg(conf, 'fontconfig', uselib_store='FONTCONFIG')

    if not conf.is_defined('YTK'):
        autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK', atleast_version='2.18')
        autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM', atleast_version='2.18', mandatory=True)

    if conf.env.CC_NAME == 'gcc' and Options.options.strict:
        conf.define('GLIB_DISABLE_DEPRECATION_WARNINGS', 1)
        for var in ['CFLAGS', 'CXXFLAGS']:
            for lib in ['GTK', 'GTKMM']:
                for d in conf.env['INCLUDES_' + lib]:
                    conf.env.append_value(var, ['-isystem', d])

    if sys.platform == 'darwin':
        if conf.env['build_target'] in ['bigsur', 'monterey']:
            # we cannot execute test code when x-compiling ARM on Intel,
            # besides, NSWindowWillStartLiveResizeNotification is definitely available
            conf.define('HAVE_COCOA_LIVE_RESIZING', 1)
        else:
            conf.check(
                    msg              ='Checking for Cocoa live resizing constants',
                    fragment         = '#include <AppKit/NSWindow.h>\n int main(void) { (void) NSWindowWillStartLiveResizeNotification; return 0; }\n',
                    define_name      = 'HAVE_COCOA_LIVE_RESIZING',
                    uselib_store     = 'COCOA_LIVE_RESIZING',
                    compiler         = 'cc',
                    compile_filename = 'test.m',
                    execute          = True,
                    mandatory        = False)

    conf.write_config_header('gtk2ardour-config.h', remove=False)

    bak = conf.env['define_key']
    conf.define('VERSIONSTRING', conf.env['VERSION'])
    conf.define('CODENAME', enoify(int(conf.env['MAJOR']), int(conf.env['MINOR'])))
    conf.env['define_key'] = ['VERSIONSTRING', 'CODENAME' ]
    conf.write_config_header('gtk2ardour-version.h')
    conf.env['define_key'] = bak

def build(bld):
    I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']

    # Tool to dump lua-bindings (of gtk2ardour + libs)
    if re.search ("linux", sys.platform) != None and bld.env['LUABINDINGDOC']:
        obj = bld (features = 'cxx c cxxprogram')
        obj.install_path = None
        obj.source    = list(gtk2_ardour_sources)
        obj.target    = 'luadoc'
        obj.includes  = ['.', '../libs', '../libs/vst3']
        obj.use       = [
                'libpbd',
                'libardour',
                'libardour_cp',
                'libtemporal',
                'libmidipp',
                'libgtkmm2ext',
                'libcanvas',
                'libwaveview',
                'libwidgets',
                'libptformat',
                ]
        obj.defines = [
                'NOMAIN',
                'PACKAGE="' + I18N_PACKAGE + '"',
                'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
                'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
                'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
                ]
        obj.linkflags = ''
        obj.uselib       = 'UUID FLAC FONTCONFIG GTHREAD GTK OGG PANGOMM CURL DL CANVAS FFTW3F LO TAGLIB XML LILV RUBBERBAND AUBIO LRDF ARCHIVE VAMPSDK VAMPHOSTSDK'
        obj.source += [ 'luadoc.cc', 'bundle_env_linux.cc' ]
        obj.use += [ 'X11' ]
        if bld.is_defined('YTK'):
            obj.use    += [ 'libytk', 'libytkmm' ]
            obj.uselib += ' GLIBMM GIOMM PANGOMM PANGOFT2 LIBPNG'
        else:
            obj.uselib += ' GTKMM'

        if False and bld.is_defined('USE_EXTERNAL_LIBS'):
            obj.uselib += ' LIBAAF'
        else:
            obj.use.extend (['libaaf'])

        if bld.is_defined('HAVE_USB'):
            obj.uselib += ' USB'
        if bld.is_defined('HAVE_SUIL'):
            obj.source += [ 'lv2_plugin_ui.cc' ]
            if bld.is_defined('YTK'):
                obj.use += [ 'libsuil' ]
            else:
                obj.uselib += ' SUIL'
        if bld.is_defined('LXVST_SUPPORT'):
            obj.source += [ 'vst_plugin_ui.cc' ]
            obj.source += [ 'linux_vst_gui_support.cc', 'lxvst_plugin_ui.cc' ]
            obj.defines += [ 'LXVST_SUPPORT' ]

        if bld.is_defined('VST3_SUPPORT'):
            obj.source += [ 'vst3_plugin_ui.cc' ]
            if sys.platform == 'darwin':
                obj.source += [ 'vst3_nsview_plugin_ui.mm' ]
            elif bld.env['build_target'] == 'mingw':
                obj.source += [ 'vst3_hwnd_plugin_ui.cc' ]
            else:
                obj.source += [ 'vst3_x11_plugin_ui.cc' ]

#    # Tool to test libcanvas
#    if re.search ("linux", sys.platform) != None and bld.env['CANVASTESTUI']:
#        obj = bld (features = 'cxx c cxxprogram')
#        obj.install_path = None
#        obj.source    = list(gtk2_ardour_sources)
#        obj.source    = [ 'ardour_button.cc', 'ui_config.cc', 'tooltips.cc' ]
#        obj.target    = 'canvas_test'
#        obj.includes  = ['.', '../libs']
#        obj.use       = [
#                'libpbd',
#                'libardour',
#                'libardour_cp',
#                'libtemporal',
#                'libmidipp',
#                'libgtkmm2ext',
#                'libcanvas',
#                'libptformat',
#                ]
#        obj.defines = [
#                'NOMAIN',
#                'PACKAGE="' + I18N_PACKAGE + '"',
#                'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
#                'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
#                'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
#                ]
#        obj.linkflags = ''
#        obj.uselib    = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL GTKMM CANVAS FFTW3F LO TAGLIB XML '
#        # obj.source += [ 'canvas_test.cc', ]
#        obj.source += [ 'toolbar_test.cc', 'enums.cc']

    # executable version of the GTK GUI
    if bld.env['build_target'] == 'mingw':
        obj = bld (features = 'cxx c cxxprogram winres')
    else:
        obj = bld (features = 'cxx c cxxprogram')

    # operate on copy to avoid adding sources twice
    obj.source    = list(gtk2_ardour_sources)
    obj.target    = 'ardour-' + bld.env['VERSION']
    obj.includes  = ['.']

    if bld.is_defined('WINDOWS_VST_SUPPORT'):
        obj.includes += [ '../libs/fst' ]

    # at this point, "obj" refers to either the normal native executable
    # OR the shared library built for use with wine on linux.

    obj.use      = [ 'libpbd',
                     'libardour',
                     'libardour_cp',
                     'libtemporal',
                     'libmidipp',
                     'libgtkmm2ext',
                     'libcanvas',
                     'libwaveview',
                     'libwidgets',
                     'libptformat',
                     ]

    obj.defines = [
        'PACKAGE="' + I18N_PACKAGE + '"',
        'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
        'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
        'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"',
        ]
    obj.install_path = bld.env['DLLDIR']
    obj.linkflags    = ''
    obj.uselib       = 'UUID FLAC FONTCONFIG GTHREAD OGG PANGOMM CURL DL CANVAS FFTW3F LO TAGLIB XML LILV RUBBERBAND AUBIO LRDF ARCHIVE VAMPSDK VAMPHOSTSDK'

    if bld.is_defined('YTK'):
        obj.use    += [ 'libytk', 'libytkmm' ]
        obj.uselib += ' GLIBMM GIOMM PANGOFT2 LIBPNG'
    else:
        obj.uselib += ' GTKMM GTK'

    if False and bld.is_defined('USE_EXTERNAL_LIBS'):
        obj.uselib += ' LIBAAF'
    else:
        obj.use.extend (['libaaf'])

    if bld.is_defined('HAVE_USB'):
        obj.uselib += ' USB'
    if sys.platform == 'darwin':
        obj.uselib += ' AUDIOUNITS OSX '
        obj.use    += ' libappleutility'
        obj.source += [ 'cocoacarbon.mm', 'bundle_env_cocoa.cc' ]
    elif bld.env['build_target'] == 'mingw':
        obj.source += [ 'bundle_env_mingw.cc' ]
        obj.source += [ 'windows_icon.rc' ]
    else:
        obj.source += [ 'bundle_env_linux.cc' ]
        obj.use += [ 'X11' ]

    obj.includes += ['../libs']
    obj.includes += ['../libs/vst3']

    if bld.env['build_target'] == 'mingw':
        obj.linkflags += ' -mwindows'
        obj.use += [ 'PANGOFT2' ]

    if bld.is_defined('HAVE_SUIL'):
        obj.source += [ 'lv2_plugin_ui.cc' ]
        obj.use += [ 'SUIL' ]

    if bld.is_defined('HAVE_FFTW35F') and bld.env['build_target'] != 'mingw':
        bld.env['LIB_FFTW3F'] += ['fftw3f_threads']

    if bld.is_defined('NEED_INTL'):
        obj.linkflags += ' -lintl'

    if bld.is_defined('WINDOWS_VST_SUPPORT'):
        obj.source += [ 'windows_vst_plugin_ui.cc' ]
        obj.defines += [ 'WINDOWS_VST_SUPPORT' ]

    if bld.is_defined('LXVST_SUPPORT'):
        obj.source += [ 'linux_vst_gui_support.cc', 'lxvst_plugin_ui.cc' ]
        obj.defines += [ 'LXVST_SUPPORT' ]

    if bld.is_defined('MACVST_SUPPORT'):
        obj.source += [ 'mac_vst_plugin_ui.mm' ]
        obj.defines += [ 'MACVST_SUPPORT' ]

    if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT') or bld.is_defined ('MACVST_SUPPORT'):
        obj.source += [ 'vst_plugin_ui.cc' ]

    if bld.is_defined('PHONE_HOME'):
        obj.defines += [ 'PHONE_HOME' ]

    if bld.is_defined('HAVE_COREAUDIO'):
        TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cc']
        obj.use += ' libappleutility '

    if bld.is_defined('AUDIOUNIT_SUPPORT'):
        obj.source += [ 'au_pluginui.mm' ]

    if bld.is_defined('VST3_SUPPORT'):
        obj.source += [ 'vst3_plugin_ui.cc' ]
        if sys.platform == 'darwin':
            obj.source += [ 'vst3_nsview_plugin_ui.mm' ]
        elif bld.env['build_target'] == 'mingw':
            obj.source += [ 'vst3_hwnd_plugin_ui.cc' ]
        else:
            obj.source += [ 'vst3_x11_plugin_ui.cc' ]

    # Wrappers

    wrapper_subst_dict = {
            'INSTALL_PREFIX' : bld.env['PREFIX'],
            'LIBDIR'         : os.path.normpath(bld.env['DLLDIR']),
            'DATADIR'        : os.path.normpath(bld.env['DATADIR']),
            'CONFDIR'        : os.path.normpath(bld.env['CONFDIR']),
            'LIBS'           : 'build/libs',
            'VERSION'        : bld.env['VERSION'],
            'EXECUTABLE'     : 'build/gtk2_ardour/ardour-' + bld.env['VERSION']
    }

    def set_subst_dict(obj, dict):
        for i in dict:
            setattr(obj, i, dict[i])

    obj              = bld(features = 'subst')
    obj.source       = 'ardev_common.sh.in'
    obj.target       = 'ardev_common_waf.sh'
    obj.chmod        = Utils.O755
    obj.dict         = wrapper_subst_dict
    set_subst_dict(obj, wrapper_subst_dict)

    obj              = bld(features = 'subst')
    obj.source       = 'ardour.sh.in'
    obj.target       = 'ardour' + bld.env['MAJOR']
    obj.chmod        = Utils.O755
    obj.dict         = wrapper_subst_dict
    obj.install_path = bld.env['BINDIR']
    set_subst_dict(obj, wrapper_subst_dict)

    # Font configuration

    font_subst_dict = {}
    font_sizes      = {}

    # Set up font sizes
    if sys.platform == 'darwin':
        basefont = ""
        font_sizes = {
                'SMALLER' : '9',
                'SMALL' : '10',
                'NORMAL' : '11',
                'BIG' : '13',
                'BIGGER' : '17',
                'LARGE' : '18',
                'LARGER' : '28',
                'HUGER' : '36',
                'MASSIVE' : '60',
        }
        if bld.env['build_target'] in ['panther', 'tiger', 'leopard'] or (Options.options.ppc and bld.env['build_target'] == 'snowleopard'):
            # CTFontManagerRegisterFontsForURL for ArdourMono is 10.6 or newer
            # "Lucida Grande" is not mono-spaced, but works for most cases, except big-clock-window
            font_names = {
                    'MONOSPACE' : 'Monaco',
                    'CLOCKFONT' : 'Lucida Grande',
                    }
        else:
            font_names = {
                    'MONOSPACE' : 'Monaco',
                    'CLOCKFONT' : 'ArdourMono',
                    }
    else: # Linux/X11 & Windows fonts
        basefont = '' # unspecified - use system defaults
        font_sizes = {
                'SMALLER' : '6',
                'SMALL' : '7',
                'NORMAL' : '8',
                'BIG' : '11',
                'BIGGER' : '13.5',
                'LARGE' : '14.5',
                'LARGER' : '19',
                'HUGER' : '27',
                'MASSIVE' : '48',
        }
        font_names = {
                'MONOSPACE' : 'ArdourMono',
                'CLOCKFONT' : 'ArdourMono',
        }

    # Set up font substitution dictionary
    # @FONT_XXXX@
    for style in ['', 'BOLD', 'ITALIC']:
        for sizename,points in iter(font_sizes.items()):
            if (len (style)):
                key = "_".join (['FONT',style,sizename])
                fontstyle = " ".join ([basefont,style.lower(),points])
            else:
                key = "_".join (['FONT',sizename])
                fontstyle = " ".join ([basefont,points])

            font_subst_dict[key] = fontstyle

    # @FONT_SIZE_XXXX@
    for sizename,points in iter(font_sizes.items()):
        key = "_".join (['FONT_SIZE',sizename])
        font_subst_dict[key] = points

    # various font names, eg @BOLD_MONOSPACE@
    for font_sym,text in iter(font_names.items()):
        key = font_sym
        font_subst_dict[key] = text

    font_subst_dict['FONTFAMILY'] = ''
    # RC file

    obj              = bld(features = 'subst')
    obj.source       = [ 'clearlooks.rc.in' ]
    obj.target       = 'clearlooks.rc'
    obj.install_path = bld.env['CONFDIR']
    set_subst_dict(obj, font_subst_dict)

    font_subst_dict['FONTFAMILY'] = 'ArdourSans'

    obj              = bld(features = 'subst')
    obj.source       = [ 'clearlooks.rc.in' ]
    obj.target       = 'clearlooks.ardoursans.rc'
    obj.install_path = bld.env['CONFDIR']
    set_subst_dict(obj, font_subst_dict)

    obj              = bld(features = 'subst')
    obj.source       = [ 'default_ui_config.in' ]
    obj.target       = 'default_ui_config'
    obj.install_path = bld.env['CONFDIR']
    set_subst_dict(obj, font_subst_dict)

    # Menus
    menus_argv = []
    if sys.platform == 'darwin':
        menus_argv = [ '-E', '-P', '-D__APPLE__', '-' ]
    else:
        menus_argv = [ '-E', '-P' ]

    if bld.is_defined('MIXBUS'):
        menus_argv += [ '-DMIXBUS' ]

    if bld.is_defined('PTFORMAT'):
        menus_argv += [ '-DPTFORMAT' ]

    if bld.is_defined('MIXBUS') or Options.options.debug:
        menus_argv += [ '-DVAPOR' ]

    # always build all versions of the menu definitions
    # so that we can try them out with different program builds.

    obj = bld(features = 'command-output')
    obj.command = 'cpp'
    obj.command_is_external = True
    obj.no_inputs = True
    obj.argv = menus_argv
    obj.dep_vars = ['PTFORMAT', 'MIXBUS', 'WINDOWS', 'debug']
    if bld.is_defined('LIVETRAX'):
        obj.stdin = 'livetrax.menus.in'
    else:
        obj.stdin = 'ardour.menus.in'
    obj.stdout = 'ardour.menus'        
    bld.install_files (bld.env['CONFDIR'], 'ardour.menus')

    # Freedesktop
    freedesktop_subst_dict = {
                    'ARDOUR_EXEC' : bld.env['lwrcase_dirname'],
                    'ARDOUR_ICON' : bld.env['lwrcase_dirname'],
                    'VERSION': bld.env['VERSION'],
                    'DATE': bld.env['DATE'],
    }

    if bld.env['FREEDESKTOP']:
        obj              = bld(features = 'subst')
        obj.source       = 'ardour.desktop.in'
        obj.target       = bld.env['lwrcase_dirname'] + '.desktop'
        obj.chmod        = Utils.O644
        obj.dict         = freedesktop_subst_dict
        set_subst_dict(obj, freedesktop_subst_dict)
        bld.install_files (os.path.join (bld.env['PREFIX'], 'share/applications'), obj.target)

        obj              = bld(features = 'subst')
        obj.source       = 'ardour-mime-info.xml'
        obj.target       = 'ardour.xml'
        obj.chmod        = Utils.O644
        bld.install_files (os.path.join (bld.env['PREFIX'], 'share/mime/packages'), obj.target)

        # build appdata with translations
        appdata_i18n_mo(bld)
        appdata_i18n_xmlin(bld)
        obj              = bld(features = 'subst')
        obj.source       = 'ardour.appdata.xml.in'
        obj.target       = bld.env['lwrcase_dirname'] + '.appdata.xml'
        obj.chmod        = Utils.O644
        obj.dict         = freedesktop_subst_dict
        set_subst_dict(obj, freedesktop_subst_dict)
        bld.install_files (os.path.join (bld.env['PREFIX'], 'share/appdata'), obj.target)

        # install desktop icon files
        icon_file_name = bld.env['lwrcase_dirname'] + '.png'
        bld.install_as('${PREFIX}/share/icons/hicolor/16x16/apps/' + icon_file_name, 'resources/Ardour-icon_16px.png')
        bld.install_as('${PREFIX}/share/icons/hicolor/22x22/apps/'+ icon_file_name, 'resources/Ardour-icon_22px.png')
        bld.install_as('${PREFIX}/share/icons/hicolor/32x32/apps/'+ icon_file_name, 'resources/Ardour-icon_32px.png')
        bld.install_as('${PREFIX}/share/icons/hicolor/48x48/apps/'+ icon_file_name, 'resources/Ardour-icon_48px.png')
        bld.install_as('${PREFIX}/share/icons/hicolor/256x256/apps/'+ icon_file_name, 'resources/Ardour-icon_256px.png')
        bld.install_as('${PREFIX}/share/icons/hicolor/512x512/apps/'+ icon_file_name, 'resources/Ardour-icon_512px.png')

    # Keybindings

    # NATIVE ARDOUR BINDING FILES
    # explicitly state the use of perl here so that it works on windows too
    #
    a_rule = 'perl %s/tools/fmt-bindings --platform="%s" --winkey="%s" --accelmap 1 ${SRC[0].abspath()} >${TGT}' % (bld.top_dir, sys.platform, bld.env['WINDOWS_KEY'] )
    for b in [ 'ardour' ] :
        obj = bld(
            target = b + '.keys',
            source = [ b + '.keys.in', 'mixer.bindings', 'processor_box.bindings', 'step_editing.bindings', 'monitor.bindings', 'trigger.bindings' ],
            rule = a_rule
            )
        obj.install_path = bld.env['CONFDIR']

    # Icons/Images
    bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/*.png'))
    bld.install_files(bld.env['DATADIR'], 'ArdourMono.ttf')
    bld.install_files(bld.env['DATADIR'], 'ArdourSans.ttf')

    # Application/Product specific resources (icon, splash)
    pgmname = bld.env['PROGRAM_NAME']
    bld.install_files(os.path.join(bld.env['DATADIR'], 'resources'), bld.path.ant_glob('resources/' + pgmname + '*'))

    if bld.env['build_target'] == 'mingw':
        # These icons need to overwrite the files already installed in the icons
        # directory above. Do this in the external packaging scripts for now.
        #bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/cursor_square/*.png'))
        bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), 'icons/cursor_square/hotspots')

    # Default UI configuration
    bld.install_files(bld.env['CONFDIR'], 'default_ui_config')
    # Color Themes. Find each color file for this program only
    # and install
    bld.install_files (os.path.join(bld.env['DATADIR'], 'themes'), bld.path.ant_glob ('themes/*-' + pgmname.lower() + '.colors'))

    # Default export stuff
    bld.install_files(os.path.join(bld.env['CONFDIR'], 'export'), bld.path.ant_glob('export/*.format'))

    # i18n
    if bld.is_defined('ENABLE_NLS'):
        mo_files = bld.path.ant_glob('po/*.mo')
        for mo in mo_files:
            lang = os.path.basename(mo.srcpath()).replace('.mo', '')
            bld.install_as (os.path.join(os.path.normpath(bld.env['LOCALEDIR']), lang, 'LC_MESSAGES', I18N_PACKAGE + '.mo'),
                            mo)

def i18n(bld):
    I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
    autowaf.build_i18n(bld, '.', 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
                       'Paul Davis')
    appdata_i18n_pot(bld)
    appdata_i18n_po(bld)

def i18n_pot(bld):
    I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
    autowaf.build_i18n_pot(bld, '.', 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
                           'Paul Davis')
    appdata_i18n_pot(bld)

def i18n_po(bld):
    I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
    autowaf.build_i18n_po(bld, '.', 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
                          'Paul Davis')
    appdata_i18n_po(bld)

def i18n_mo(bld):
    I18N_PACKAGE = 'gtk2_ardour' + bld.env['MAJOR']
    autowaf.build_i18n_mo(bld, '.', 'gtk2_ardour', I18N_PACKAGE, gtk2_ardour_sources,
                          'Paul Davis')

def appdata_i18n_pot(bld):
    potfile = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata',
            'ardour.appdata.pot')
    if bld.cmd == 'i18n_pot':
        Logs.info('Generating pot file from Ardour appdata')
        itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
        adsource = os.path.join(bld.top_dir, 'gtk2_ardour',
                'ardour.appdata.xml.in.in')
        Logs.info('Updating ' + potfile)
        try:
            subprocess.call(('itstool', '-i', itsfile, '-o', potfile, adsource))
        except:
            print ('Error processing appdata pot file - ignored')
    elif bld.cmd == 'clean' and os.path.exists(potfile):
        Logs.info('Removing Ardour appdata pot file')
        os.remove(potfile)

def appdata_i18n_po(bld):
    autowaf.build_i18n_po(bld, bld.top_dir, os.path.join(
        'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')

def appdata_i18n_mo(bld):
    autowaf.build_i18n_mo(bld, bld.top_dir, os.path.join(
        'gtk2_ardour', 'appdata'), 'ardour.appdata', 'dummy', 'dummy')

def appdata_i18n_xmlin(bld):
    adxmlinfile = os.path.join(bld.top_dir, 'gtk2_ardour',
            'ardour.appdata.xml.in')
    if bld.cmd == 'build':
        itsfile = os.path.join(bld.top_dir, 'tools', 'as-metainfo.its')
        adxmlininfile = os.path.join(bld.top_dir, 'gtk2_ardour',
                'ardour.appdata.xml.in.in')
        mo_glob = os.path.join(bld.top_dir, 'gtk2_ardour', 'appdata', 'po', '*.mo')
        mo_files = glob.glob(mo_glob)
        Logs.info('Generating ' + adxmlinfile)
        subprocess.call(['itstool', '-i', itsfile, '-o', adxmlinfile,
            '-j', adxmlininfile] + mo_files)
    elif bld.cmd == 'clean' and os.path.exists(adxmlinfile):
        Logs.info('Removing ' + adxmlinfile)
        os.remove(adxmlinfile)
