#!/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 platform as PLATFORM
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',
        'application_bar.cc',
        'ardour_color_dialog.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_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_text_entry.cc',
        'automation_time_axis.cc',
        'axis_view.cc',
        # 'beatbox_gui.cc',
        'bbt_marker_dialog.cc',
        'big_clock_window.cc',
        'big_transport_window.cc',
        'boundary.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',
        'cue_editor.cc',
        'curvetest.cc',
        'debug.cc',
        'dsp_stats_ui.cc',
        'dsp_stats_window.cc',
        'duplicate_routes_dialog.cc',
        'edit_note_dialog.cc',
        'editing.cc',
        'editing_context.cc',
        'editor.cc',
        'editor_actions.cc',
        'editor_automation_line.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',
        'ghost_event.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_cut_buffer.cc',
        'midi_export_dialog.cc',
        'midi_list_editor.cc',
        'midi_region_view.cc',
        'midi_trigger_properties_box.cc',
        'midi_selection.cc',
        'midi_streamview.cc',
        'midi_time_axis.cc',
        'midi_tracer.cc',
        'midi_util.cc',
        'midi_velocity_dialog.cc',
        'midi_view.cc',
        'midi_view_background.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',
        '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',
        'pianoroll.cc',
        'pianoroll_automation_line.cc',
        'pianoroll_background.cc',
        'pianoroll_velocity.cc',
        'pianoroll_midi_view.cc',
        'pianoroll_window.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',
	'prh.cc',
	'prh_base.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_editor_window.cc',
        'region_fx_line.cc',
        'region_fx_properties_box.cc',
        'region_gain_line.cc',
        'region_layering_order_editor.cc',
        'region_list_base.cc',
        'region_peak_cursor.cc',
        'region_selection.cc',
        'region_ui_settings.cc',
        'region_view.cc',
        'return_ui.cc',
        'rhythm_ferret.cc',
        'route_comment_editor.cc',
        'route_group_dialog.cc',
        'route_group_menu.cc',
        'route_list_base.cc',
        'route_params_ui.cc',
        'route_properties_box.cc',
        'route_processor_selection.cc',
        'route_time_axis.cc',
        'route_ui.cc',
        'rta_manager.cc',
        'rta_window.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_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_export_dialog.cc',
        'strip_import_dialog.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',
	'view_background.cc',
        'transcode_ffmpeg.cc',
        'transcode_video_dialog.cc',
        'velocity_display.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')

    conf.check(header_name='unistd.h', define_name='HAVE_UNISTD_H',mandatory=False)

    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' ]
        obj.use    += [ 'libytk', 'libytkmm' ]
        obj.uselib += ' GLIBMM GIOMM PANGOMM PANGOFT2 LIBPNG'

        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' ]
            obj.use += [ 'libsuil' ]
        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' or bld.env['build_target'] == 'msvc':
                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' or bld.env['build_target'] == 'msvc':
        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',
                     'libytk',
                     'libytkmm',
                     ]

    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    = bld.env['compiler_flags_dict']['execstack']
    obj.uselib       = 'UUID FLAC FONTCONFIG GTHREAD OGG PANGOMM CURL DL CANVAS FFTW3F LO TAGLIB XML LILV RUBBERBAND AUBIO LRDF ARCHIVE VAMPSDK VAMPHOSTSDK GLIBMM GIOMM PANGOFT2 LIBPNG'

    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' or bld.env['build_target'] == 'msvc':
        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' or bld.env['build_target'] == 'msvc':
        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' and bld.env['build_target'] != 'msvc':
        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' or bld.env['build_target'] == 'msvc':
            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']
    }

    if bld.env['build_target'] == 'mingw' and sys.platform == "win32":
        wrapper_subst_dict.update({
            'LD_LIBRARY_PATH': 'PATH'
        })
    else:
        wrapper_subst_dict.update({
            'LD_LIBRARY_PATH': 'LD_LIBRARY_PATH'
        })

    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 = {
                'VERYSMALL' : '7',
                'SMALLER' : '9',
                'SMALL' : '10',
                'NORMAL' : '11',
                'BIG' : '13',
                'BIGGER' : '17',
                'LARGE' : '18',
                'LARGER' : '28',
                'HUGER' : '36',
                'MASSIVE' : '60',
        }
        font_names = {
                'MONOSPACE' : 'ArdourMono',
                'CLOCKFONT' : 'ArdourMono',
                }
    else: # Linux/X11 & Windows fonts
        basefont = '' # unspecified - use system defaults
        font_sizes = {
                'VERYSMALL' : '8',
                '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 bld.env['DEBUG']:
        menus_argv += [ '-DVAPOR' ]

    if not bld.env['DEBUG']:
        menus_argv += [ '-DNDEBUG' ]

    # 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
    #
    #
    # ***** NOTE: THE CANONICAL LIST OF FILES PROCESSED FOR BINDINGS IS INSIDE ../tools/fmt-bindings
    #
    # If you add or delete some ,bindings files, be sure to edit fmt_bindings too, or better yet,
    # hack fmt-bindings and this wscript file so that the list is defined here and passed in.
    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', 'regionfx_box.bindings', 'automation.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' or bld.env['build_target'] == 'msvc':
        # 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_func(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)
    appdata_i18n_mo(bld)

def i18n_pot_func(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_func(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_func(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 in ('i18n_pot', 'i18n'):
        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)
