#!/bin/bash


#---- Configuration ------------------------------------------------------------

# absolute path to folders containing RSTT libraries
LIBDIR="$PWD/../lib"


#---- Explanation of some common compiling parameters --------------------------

# -D<arch>
# Defines a symbol for the preprocessor which may adjust some code for different
# operating systems.

# -m<32|64>
# Tells the compiler whether we're on a 32 or 64-bit system.

# -O<1-3>
# Optimize the code, which makes compilation take longer but improves runtime
# performance and filesize. Level 3 (-O3) is the maximum, but newer version of
# gcc don't recommend above level 2 (-O2), and RSTT seems to throw some
# compilation errors when level 2 is used.

# -I
# Include directories for various headers.

# -L
# Location of the libraries (*.so or *.dylib) that we load with "-l" commands.

# -Wl
# Defines some parameters for the linker.

# -Wl,-rpath,<path>
# Tells the linker to search the <path> for linked libraries at runtime. In this
# shell script, we are pointing to the absolute path of the directory containing
# the RSTT library files ($LIBDIR); however, we could also specify relative
# paths by using "$$ORIGIN" on Linux or "@executable_path" on MacOS to mean
# "the directory containing the application executable". For example,
# -Wl,-rpath,'$$ORIGIN/../lib'


#---- C++ compile --------------------------------------------------------------

compile_cc() {

    # MacOS
    if [ "$(uname -s)" == "Darwin" ]; then

        g++ -Ddarwin -m64 -O1 -I../GeoTessCPP/include -I../SLBM/include -o cc_example.o -c cc_example.cc
        g++ -Ddarwin -m64 -O1 -Wl,-rpath,"$LIBDIR" -o cc_example cc_example.o -lm -lstdc++ -L"$LIBDIR" -lgeotesscpp -lslbm

    else  #linux

        g++ -Dlinux -m64 -O1 -I../GeoTessCPP/include -I../SLBM/include -o cc_example.o -c cc_example.cc
        g++ -Dlinux -m64 -O1 -Wl,-rpath,"$LIBDIR" -o cc_example cc_example.o -lm -lstdc++ -L"$LIBDIR" -lgeotesscpp -lslbm

    fi

    # clean up
    rm cc_example.o

}


#---- C compile ----------------------------------------------------------------

compile_c() {

    # MacOS
    if [ "$(uname -s)" == "Darwin" ]; then

        gcc -Ddarwin -m64 -O1 -I../GeoTessCPP/include -I../SLBM_C_shell/include -o c_example.o -c c_example.c
        gcc -Ddarwin -m64 -O1 -Wl,-rpath,"$LIBDIR" -o c_example c_example.o -lm -lstdc++ -L"$LIBDIR" -lgeotesscpp -lslbm -lslbmCshell

    else  # linux

        gcc -Dlinux -m64 -O1 -I../GeoTessCPP/include -I../SLBM/include -I../SLBM_C_shell/include -o c_example.o -c c_example.c
        gcc -Dlinux -m64 -O1 -Wl,-rpath,"$LIBDIR" -o c_example c_example.o -lm -lstdc++ -L"$LIBDIR" -lgeotesscpp -lslbm -lslbmCshell

    fi

    # clean up
    rm c_example.o

}


#---- Fortran compile ----------------------------------------------------------

compile_fortran() {

    # MacOS
    if [ "$(uname -s)" == "Darwin" ]; then

        gfortran -Ddarwin -m64 -O1 -fno-underscoring -I../GeoTessCPP/include -I../SLBM/include -I../SLBM_Fort_shell/include -o fortran_example.o -c fortran_example.f90
        gfortran -Ddarwin -m64 -O1 -fno-underscoring -Wl,-rpath,"$LIBDIR" -o fortran_example fortran_example.o -lm -lstdc++ -L"$LIBDIR" -lgeotesscpp -lslbm -lslbmFshell

    else #linux

        gfortran -Dlinux -m64 -O1 -fno-underscoring -I../GeoTessCPP/include -I../SLBM/include -I../SLBM_Fort_shell/include -o fortran_example.o -c fortran_example.f90
        gfortran -Dlinux -m64 -O1 -fno-underscoring -Wl,-rpath,"$LIBDIR" -o fortran_example fortran_example.o -lm -lstdc++ -L"$LIBDIR" -lgeotesscpp -lslbm -lslbmFshell

    fi

    # clean up
    rm fortran_example.o constants.mod

}


#---- Java compile -------------------------------------------------------------

compile_java() {

    # compile java code
    javac -cp "$LIBDIR/slbmjni.jar" java_example.java

}


#---- run code -----------------------------------------------------------------

run_cc() {
    ./cc_example
}

run_c() {
    ./c_example
}

run_fortran() {
    ./fortran_example
}

run_java() {
    java -Djava.library.path="$LIBDIR" -cp .:"$LIBDIR/slbmjni.jar" java_example
}


#---- main ---------------------------------------------------------------------

# if no arguments are given
if [ $# -eq 0 ]; then

    # show usage example
    echo "Usage: $0 [ all | cc | c | fortran | java ]"
    exit

fi

# if arguments are given, loop through them
while [ $# -gt 0 ]; do

    # turn off case matching of `case` statements
    shopt -s nocasematch

    # check the current argument 
    case "${1}" in

        cc|c++)
            compile_cc && run_cc
            ;;

        c)
            compile_c && run_c
            ;;

        fortran)
            compile_fortran && run_fortran
            ;;

        java)
            compile_java && run_java
            ;;

        all)
            compile_cc      && run_cc
            compile_c       && run_c
            compile_fortran && run_fortran
            compile_java    && run_java
            ;;

        *)
            echo "Usage: $0 [ all | cc | c | fortran | java ]"
            exit
            ;;

    esac

    # remove the current argument from the stack and move onto the next one
    shift

done
