#!/bin/bash

#####################################################################
#
#				Compiles Faust programs to Audio Unit
#				(c) Grame 2013
#
#####################################################################
. usage.sh

CXXFLAGS+=" $MYGCCFLAGS"  # So that additional CXXFLAGS can be used

PATH=$PATH:/usr/local/bin
DST=`pwd`

#-------------------------------------------------------------------------------
# Search where Faust is installed. Store '.../share/faust/' in $FLIB
# and '.../include/(faust)' in $FINC

FLIB=""; FINC="";
FPATH="$FAUST_INSTALL /usr/local /usr /opt /opt/local"; # <- where to search
for f in $FPATH; do
	if [ -e $f/share/faust ]; then
		FLIB=$f/share/faust;
	fi
	if [ -e $f/include/faust ]; then
		FINC=$f/include/;
	fi
done

if [ -z $ARCHPATH ]; then
	ARCHPATH=$FLIB
fi

if [ -z "$FLIB" -o -z "$FINC" ]; then
	echo "ERROR : $0 cannot find Faust directories (normally /usr/local/include/faust and /usr/local/share/faust)";
	exit 1;
fi

#-------------------------------------------------------------------------------
#PHASE 1 : collects files and options from the command line

DEBUG=0
INSTALLAU=0
MANUFACTURER="Grame"

for p in $@; do

	if [ $p = "-help" ] || [ $p = "-h" ]; then
		usage faust2au "[options] [Faust options] <file.dsp>"
		platform MacOS
		echo "Compiles Faust programs to Audio Unit"
		option
		options -httpd -osc
		option -install
		option -debug "print all the build steps and keep intermediate build folder"
		option "Faust options"
		exit
	fi

	if [ "$p" = -omp ]; then
		if [[ $CXX == "icpc" ]]; then
			OMP="-openmp"
		else
			OMP="-fopenmp"
		fi
	fi

	if [ "$p" = "-debug" ]; then
		DEBUG=1
	elif [ "$p" = "-icc" ]; then
		ignore=" "
	elif [ $p = "-osc" ]; then
		OSCDEFS="DEFINES += OSCCTRL"
		OSCLIBS="-lOSCFaust"
	elif [ "$p" = "-httpd" ]; then
		HTTPDEFS="DEFINES += HTTPCTRL"
		HTTPLIBS="-lHTTPDFaust -lmicrohttpd"
	elif [ $p = "-manufacturer" ]; then
		$MANUFACTURER=$p
	elif [ $p = "-install" ]; then
		INSTALLAU=1
	elif [ ${p:0:1} = "-" ]; then
		OPTIONS="$OPTIONS $p"
	elif [[ -f "$p" ]] && [ ${p: -4} == ".dsp" ]; then
		FILES="$FILES $p"
	else
		OPTIONS="$OPTIONS $p"
	fi
done

if [ $DEBUG -eq 1 ]; then
	PRINTDEV=/dev/tty
else
	PRINTDEV=/dev/null
fi

#-------------------------------------------------------------------------------

#PHASE 2 : compile the *.dsp files

for f in $FILES; do

	# could use FILES for handling multiple dap files, while other AU args like manufacturer and subtype should be handled in a way

	# Get the number of inputs of the Faust code:
	LINPUTS=$(faust -uim "$f" | grep FAUST_INPUTS)
	NINPUTS=${LINPUTS//[^0-9]/}
	# echo "Number of Faust module inputs = $NINPUTS"

	if [ $NINPUTS -gt 0 ]; then
		echo "Generating an AU Effect plugin..."
		ARCHFILE="au-effect.cpp"
		AUTYPE=aufx
		FAUSTAU_CLASS=FaustAUEffect
		COMPTYPE=kAudioUnitType_Effect
	else
		echo "Generating an AU Instrument plugin..."
		ARCHFILE="au-instrument.cpp"
		AUTYPE=aumu
		FAUSTAU_CLASS=FaustAUInstrument
		COMPTYPE=kAudioUnitType_MusicDevice
	fi

	export ARCHFILE
	export AUTYPE
	export FAUSTAU_CLASS
	export COMPTYPE

	AU_DIR=$HOME/Library/Audio/Plug-Ins/Components
	TEMP_DIR=`dirname $f`/faustAUtmp.`basename $f`

	if [ -d $TEMP_DIR ]; then
		rm -r $TEMP_DIR
	fi
	mkdir $TEMP_DIR
	cp -r $ARCHPATH/AU/* $TEMP_DIR
	cp $f $TEMP_DIR
	cp *.dsp $TEMP_DIR >& $PRINTDEV
	cp *.lib $TEMP_DIR >& $PRINTDEV

	cd $TEMP_DIR
	mkdir Source >& $PRINTDEV

	FULL_FILE_NAME=$f

	FILE_NAME=$(BASENAME "$FULL_FILE_NAME")
	EXTENSION="${FILE_NAME##*.}"
	FILE_NAME="${FILE_NAME%.*}"

	cp $ARCHPATH/$ARCHFILE au-arch-temp.cpp
	perl -pi -e 's/FaustAU_CustomViewFactory/'FaustAU_"$FILE_NAME"CustomViewFactory'/g' au-arch-temp.cpp
	perl -pi -e 's/FaustAU_CustomViewFactory/'FaustAU_"$FILE_NAME"CustomViewFactory'/g' FaustAUCustomView.plist

	faust $OPTIONS -a au-arch-temp.cpp $f -o Source/au-output.cpp || exit 1

	rm au-arch-temp.cpp

	faust $OPTIONS -xml $f > $PRINTDEV
	mv $f.xml Source/au-output.xml

	if [ ! -f Source/au-output.cpp ]; then
		echo FAUST could not generate cpp file
		cd ..
		rm -r $TEMP_DIR
		exit 1
	fi

	NAME=$MANUFACTURER:' '"$FILE_NAME"
	SUB_TYPE=$(echo ${FILE_NAME:0:4} | tr [[:upper:]] [[:lower:]])
	MANF=${MANUFACTURER:0:4}

	perl -pi -e 's/_NAME_/'"$NAME"'/g' Info.plist
	perl -pi -e 's/_DESC_/'"$NAME"'/g' Info.plist
	perl -pi -e 's/_STYP_/'"$SUB_TYPE"'/g'	Info.plist
	perl -pi -e 's/_MANF_/'"$MANF"'/g' Info.plist
	perl -pi -e 's/_BUNDLE_ID_/'"$FILE_NAME"'/g' Info.plist
	perl -pi -e 's/_TYPE_/'"$AUTYPE"'/g' Info.plist

	perl -pi -e 's/_BUNDLE_NAME_/'"$FILE_NAME"'/g' English.lproj/InfoPlist.strings
	perl -pi -e 's/_BUNDLE_INFO_/'"$NAME"'/g' English.lproj/InfoPlist.strings

	perl -pi -e 's/_NAME_/'"$NAME"'/g' Source/AUSource/FaustAU.r
	perl -pi -e 's/_DESC_/'"$NAME"'/g' Source/AUSource/FaustAU.r
	perl -pi -e 's/_COMPTYPE_/'"$COMPTYPE"'/g' Source/AUSource/FaustAU.r

	perl -pi -e 's/_FaustAUClass_/'"$FAUSTAU_CLASS"'/g' Source/AUSource/FaustAU.h

	perl -pi -e 's/_STYP_/'"$SUB_TYPE"'/g' Source/AUSource/FaustAUVersion.h
	perl -pi -e 's/_MANF_/'"$MANF"'/g' Source/AUSource/FaustAUVersion.h

	perl -pi -e 's/_FILENAME_/'"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomView.m

	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomView.h
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomView.m
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomViewFactory.h
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_CustomViewFactory.m
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Bargraph.h
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Bargraph.m
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Button.h
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Button.m
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Knob.h
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Knob.m
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Slider.h
	perl -pi -e 's/FaustAU_/'FaustAU_"$FILE_NAME"'/g' Source/CocoaUI/FaustAU_Slider.m

	perl -pi -e 's/FaustAU_CustomView.h/'FaustAU_"$FILE_NAME"CustomView.h'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_CustomView.m/'FaustAU_"$FILE_NAME"CustomView.m'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_CustomViewFactory.h/'FaustAU_"$FILE_NAME"CustomViewFactory.h'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_CustomViewFactory.m/'FaustAU_"$FILE_NAME"CustomViewFactory.m'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_Knob.h/'FaustAU_"$FILE_NAME"Knob.h'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_Knob.m/'FaustAU_"$FILE_NAME"Knob.m'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_Button.h/'FaustAU_"$FILE_NAME"Button.h'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_Button.m/'FaustAU_"$FILE_NAME"Button.m'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_Slider.h/'FaustAU_"$FILE_NAME"Slider.h'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_Slider.m/'FaustAU_"$FILE_NAME"Slider.m'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_Bargraph.h/'FaustAU_"$FILE_NAME"Bargraph.h'/g' FaustAU.xcodeproj/project.pbxproj
	perl -pi -e 's/FaustAU_Bargraph.m/'FaustAU_"$FILE_NAME"Bargraph.m'/g' FaustAU.xcodeproj/project.pbxproj


	mv Source/CocoaUI/FaustAU_CustomView.h Source/CocoaUI/FaustAU_"$FILE_NAME"CustomView.h
	mv Source/CocoaUI/FaustAU_CustomView.m Source/CocoaUI/FaustAU_"$FILE_NAME"CustomView.m
	mv Source/CocoaUI/FaustAU_CustomViewFactory.h Source/CocoaUI/FaustAU_"$FILE_NAME"CustomViewFactory.h
	mv Source/CocoaUI/FaustAU_CustomViewFactory.m Source/CocoaUI/FaustAU_"$FILE_NAME"CustomViewFactory.m
	mv Source/CocoaUI/FaustAU_Bargraph.h Source/CocoaUI/FaustAU_"$FILE_NAME"Bargraph.h
	mv Source/CocoaUI/FaustAU_Bargraph.m Source/CocoaUI/FaustAU_"$FILE_NAME"Bargraph.m
	mv Source/CocoaUI/FaustAU_Button.h Source/CocoaUI/FaustAU_"$FILE_NAME"Button.h
	mv Source/CocoaUI/FaustAU_Button.m Source/CocoaUI/FaustAU_"$FILE_NAME"Button.m
	mv Source/CocoaUI/FaustAU_Knob.h Source/CocoaUI/FaustAU_"$FILE_NAME"Knob.h
	mv Source/CocoaUI/FaustAU_Knob.m Source/CocoaUI/FaustAU_"$FILE_NAME"Knob.m
	mv Source/CocoaUI/FaustAU_Slider.h Source/CocoaUI/FaustAU_"$FILE_NAME"Slider.h
	mv Source/CocoaUI/FaustAU_Slider.m Source/CocoaUI/FaustAU_"$FILE_NAME"Slider.m

	xcodebuild ARCHS="x86_64" HEADER_SEARCH_PATHS=$FINC CONFIGURATION_BUILD_DIR=$HOME/Library/Audio/Plug-Ins/Components > $PRINTDEV > ./build_errors.log || exit 1

	if [ ! -d $AU_DIR/FaustAU.component/ ]; then
		echo Unable to generate Audio Unit
		cd ..
		if [ $DEBUG -eq 0 ]; then
			rm -r $TEMP_DIR
		fi
		exit 1
	fi

	if [ -d $AU_DIR/"$FILE_NAME".component/ ]; then
		if [ $DEBUG -eq 0 ]; then
			rm -r  $AU_DIR/"$FILE_NAME".component/
		fi
	fi

	mv $AU_DIR/FaustAU.component $AU_DIR/"$FILE_NAME".component

	if [ -d $AU_DIR/FaustAUCustomView.bundle/ ]; then
		rm -r  $AU_DIR/FaustAUCustomView.bundle/
	fi

	cd ..
	if [ $DEBUG -eq 0 ]; then
		rm -r $TEMP_DIR
	fi

	echo "'$NAME'" Audio Unit generated and installed successfully

	if [ $DEBUG -eq 1 ]; then
		echo "See $TEMP_DIR for build products"
	fi

	if [ $INSTALLAU -eq 0 ]; then
		mv $AU_DIR/"$FILE_NAME".component .
		echo ./"$FILE_NAME".component";"
	else
		echo $AU_DIR/"$FILE_NAME".component";"
	fi
done
