#! /bin/bash -e

#####################################################################
#                                                                   #
#               Compiles Faust programs to ROS packages             #
#               with a GTK interface                                #
#               (c) Grame, 2014                                     #
#                                                                   #
#####################################################################

. faustpath

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

ARCHFILE="jack-gtk-ros.cpp"

path=$(pwd)
CURRENT_DIR=$(pwd)

# Dispatch command arguments
WORKSPACES=''
NEW_NAMES=''
params=("$@")
n=0
for p in $@; do
    n=$(($n+1))

    # install option, get workspace's name
    if [ "$p" = "-install" ]; then
        WORKSPACES="$WORKSPACES ${params[$n]}"
    # o option, get the new application's name
    elif [ "$p" = "-o" ]; then
        NEW_NAMES="$NEW_NAMES ${params[$n]}"
    elif [ "$p" = "--help" ] || [ "$p" = "-h" ] ; then
        HELP=true
    elif [ ${p:0:1} = "-" ]; then
        OPTIONS="$OPTIONS $p ${params[$n]}"
    elif [[ -f "$p" ]] && [ ${p: -4} == ".dsp" ]; then
        FILES="$FILES $p"
    fi
done

# Puts option parameters in tables
NEW_NAMES=($NEW_NAMES)
WORKSPACES=($WORKSPACES)


# Get parameters tables size
NAMES_LENGTH=${#NEW_NAMES[@]}
WS_LENGTH=${#WORKSPACES[@]}

if [ $HELP ]
then
############ BEGIN HELP MESSAGE ############
    echo -e "####################################################################################################
######################################## FAUST2ROS HELP ############################################
####################################################################################################

################################################################################################
                This command allows you to compile a FAUST DSP file into a ROS package,
                        compressed or ready to be used in a workspace.
################################################################################################
USAGE:
faust2rosgtk ~/path/to/mydsp.dsp
Output : mydsp.zip, a compressed package

OPTIONS :
        -install
                faust2rosgtk -install ~/path/to/my/workspace ~/other/path/to/mydsp.dsp
                Output : mydsp.cpp, a C++ file in a package, in a workspace,
                                                        ready to be run
        -o
                faust2rosgtk -o mynewname ~/path/to/mydsp.dsp
                Output : mynewname.zip

For more options and information, type faust -h or faust --help

####################################################################################################
"
############ END HELP MESSAGE ############
else
    # Check if packages exist ; if not, create them
    i=0
    for (( i = 0 ; i < $WS_LENGTH ; i=$i+1 ))
    do
        if [ ! -d ${WORKSPACES[${i}]} ]
        then
            mkdir -p ${WORKSPACES[${i}]}/src
        else
            cd ${WORKSPACES[${i}]}
            if [ ! -d src ]
                then mkdir src
            fi
        fi
        cd ${WORKSPACES[${i}]}/src
            if [ !  CMakeLists.txt ] || [ -w CMakeLists.txt ]
            then
                rm -f CMakeLists.txt
                catkin_init_workspace > /dev/null
            fi
    done

    # if there is only one workspace specified, no need to run a loop
    if [ $WS_LENGTH = 1 ]; then
        WORKSPACE_PATH="${WORKSPACES[$1]}"/src
    fi

    #-------------------------------------------------------------------
    # compile the *.dsp files
    #
    i=0

    for p in $FILES
    do

        # Check .dsp path ; if there is no path, file should be in current directory
        temp=$(basename "$p")
        temp_path=$(dirname ${p})

        if [ ! $temp_path = '.' ]
        then
            p=$temp
            path=$temp_path
        fi

        # Create dsp package depending on options
        if [ "$NEW_NAMES" = "" ]
        then
            f=$(basename "$p")
            name="${f%.dsp}"
        else
            name="${NEW_NAMES[${i}]}"
        fi
        name=$name"_gtk"
        # zip file
        if [ $WS_LENGTH = 0 ]
        then
            cd $CURRENT_DIR
            temp_dir=$(mktemp -d ROS.XXXXXX)
            cd $temp_dir
            mkdir src
            cd src
            catkin_create_pkg $name roscpp std_msgs > /dev/null
            PACKAGE_PATH=$CURRENT_DIR/$temp_dir/src/$name
        else
            # install in workspace
            if [ $WS_LENGTH = 1 ]
            then
                cd $WORKSPACE_PATH
                if [[ -d $WORKSPACE_PATH/$name ]]
                then
                    rm -r $WORKSPACE_PATH/$name
                fi
                catkin_create_pkg $name roscpp std_msgs > /dev/null
                PACKAGE_PATH=$WORKSPACE_PATH/$name
            else
                WORKSPACE_PATH="${WORKSPACES[${i}]}"/src
                cd $WORKSPACE_PATH
                if [ -d $WORKSPACE_PATH/$name ]
                then
                    rm -r $WORKSPACE_PATH/$name
                fi
                catkin_create_pkg $name roscpp std_msgs > /dev/null
                PACKAGE_PATH=$WORKSPACE_PATH/$name
            fi
        fi
        cd $PACKAGE_PATH

# Set CMakeLists.txt to fit to the faust package
############## CMAKELISTS ############################
        echo -e "cmake_minimum_required(VERSION 2.8.3)
project($name)

SET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -O3 -mfpmath=sse -msse -msse2 -msse3 -ffast-math\")

find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK2 REQUIRED gtk+-2.0)
include_directories(\${catkin_INCLUDE_DIRS} \${GTK2_INCLUDE_DIRS})
link_directories(\${GTK2_LIBRARY_DIRS})
catkin_package()
find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
)

add_executable(\${PROJECT_NAME} src/\${PROJECT_NAME}.cpp)

target_link_libraries(\${PROJECT_NAME} \${GTK2_LIBRARIES} jack \${catkin_LIBRARIES})" > CMakeLists.txt
############# END CMAKELISTS #########################

        # Double compilation
        cd src
        faust -i -a ros-callbacks.cpp -o "$PACKAGE_PATH/src/$name.cpp" $path/$p || exit
        $CXX $name.cpp -o $name
        faust -i -a $ARCHFILE $OPTIONS "$path/$p" -o "$PACKAGE_PATH/src/$name.cpp" $path/$p    > /dev/null || exit
        ./$name        # adds the callbacks declaration to the generated c++ file
        rm $name

        # zip file
        if [ $WS_LENGTH = 0 ]
        then
            cd $CURRENT_DIR/$temp_dir/src/$name
############ BEGIN README ############
            echo -e "                        README : Using Faust with ROS
                Grame, Centre National de Creation Musicale
                ###########################################

This file was automatically generated with faust2ros or faust2rosgtk

To run your new application :
        1) unzip this package into a ROS workspace.
        2) source this workspace :
                a) go in your workspace's root
                b) type 'source devel/setup.bash'
        3) run with 'rosrun myapp myapp'

For more information, check the documentation :
https://sourceforge.net/p/faudiostream/code/ci/master/tree/documentation" > README.txt
############ END README ############
            cd $CURRENT_DIR/$temp_dir/src
            zip -r $name.zip $name > /dev/null
            cd $CURRENT_DIR
            cp $temp_dir/src/$name.zip $CURRENT_DIR
            rm -r $temp_dir
            OUTPUT="$OUTPUT $name.zip;"
            # package installation
        else
            cd ${WORKSPACES[${i}]}
############ BEGIN README ############
            echo -e "                        README : Using Faust with ROS
                Grame, Centre National de Creation Musicale
                ###########################################

This file was automatically generated with faust2ros or faust2rosgtk

To run your new application :
        1) source this workspace :
                a) go in your workspace's root
                b) type 'source devel/setup.bash'
        3) run with 'rosrun myapp myapp'

For more information, check the documentation :
https://sourceforge.net/p/faudiostream/code/ci/master/tree/documentation" > README.txt
############ END README ############
            catkin_make > /dev/null || exit
            OUTPUT="$OUTPUT $name.cpp;"
        fi
        i=$((i+1))
    done
    echo $OUTPUT
fi
