#! /bin/sh

# $Id$

#######################################################################
# Helpers:

# Split $PATH into words:
oldifs="$IFS"
IFS="   :"
spacepath=`echo $PATH`
IFS="$oldifs"


in_path () {
    # Does $1 exist in $PATH?
    for d in $spacepath; do
        if test -x "$d/$1"; then
            return 0
        fi
    done
    return 1
}


get_path () {
    for d in $spacepath; do
        if test -x "$d/$1"; then
            echo "$d/$1"
            return
        fi
    done
}

#######################################################################
# Defaults

set_defaults () {
    with_equeue_tcl=0
    with_equeue_gtk1=0
    with_equeue_gtk2=0
    with_shell=1
    version="2.1"
    exec_suffix=""
    tcl_defs=""
    tcl_libs=""
#    bindir=`dirname $ocamlc`
}

ocamlc=`get_path ocamlc`
set_defaults

#######################################################################
# Option parsing

help_equeue_tcl="Compile/omit the equeue version for integration into TCL event loops"
help_equeue_gtk1="Compile/omit the equeue version for integration into Glib/gtk1 event loops"
help_equeue_gtk2="Compile/omit the equeue version for integration into Glib/gtk2 event loops"
help_shell="Compile/omit the shell modules"

options="equeue_tcl equeue_gtk1 equeue_gtk2 shell"

print_options () {
	for opt in $options; do
		e="o=\$with_$opt"
		eval "$e"
		uopt=`echo $opt | sed -e 's/_/-/g'`
		if [ $o -gt 0 ]; then
			echo "    -with-$uopt"
		else
			echo "    -without-$uopt"
		fi
	done

	if [ $with_equeue_tcl -gt 0 ]; then
	    echo "    -equeue-tcl-defs \"$tcl_defs\""
	    echo "    -equeue-tcl-libs \"$tcl_libs\""
	fi

}


usage () {
	cat <<_EOF_ >&2
usage: ./configure [ options ]

_EOF_
#	echo "-bindir <dir>:"
#	echo "        Install binaries into this directory"

	for opt in $options; do
		e="help=\$help_$opt"
		eval "$e"
		uopt=`echo $opt | sed -e 's/_/-/g'`
		echo "-with-$uopt:" >&2
		echo "-without-$uopt:" >&2
		echo "        $help" >&2
	done

	echo "-equeue-tcl-defs <opts>:"
	echo "        Set C compiler options to find tcl.h"
	echo
	echo "-equeue-tcl-libs <opts>:"
	echo "        Set C compiler options to link against libtcl"

	cat <<_EOF_ >&2

Defaults are:

_EOF_
	set_defaults
	print_options >&2
	exit 1
}


check_opt () {
	for x in $options; do
		if [ "$x" = "$1" ]; then
			return 0
		fi
	done
	echo "Unknown option: $1" >&2
	exit 1
}


while [ "$#" -gt 0 ]; do
	case "$1" in
		-with-*)
			opt=`echo "$1" | sed -e 's/-with-//' -e 's/-/_/g'`
			check_opt "$opt"
			eval "with_$opt=1"
			shift
			;;
		-without-*)
			opt=`echo "$1" | sed -e 's/-without-//' -e 's/-/_/g'`
			check_opt "$opt"
			eval "with_$opt=0"
			shift
			;;
	        -equeue-tcl-defs)
		        tcl_defs="$tcl_defs $2"
			shift
			shift
			;;
	        -equeue-tcl-libs)
		        tcl_libs="$tcl_libs $2"
			shift
			shift
			;;
#		-bindir)
#		        bindir="$2"
#			shift
#			shift
#			;;
		-version*)
			echo "$version"
			exit 0
			;;
		*)
			usage
	esac
done

######################################################################
# Check ocamlfind

printf "%s" "Checking for ocamlfind... "
if ocamlfind query stdlib >/dev/null 2>/dev/null; then
	echo "found"
else
	echo "not found"
	echo "Sorry, installation is not possible without ocamlfind (findlib)!"
	echo "Make sure that ocamlfind is in your PATH, or download findlib"
	echo "from www.ocaml-programming.de"
	exit 1
fi

######################################################################
# Check multi-threading style

echo "Checking multi-threading support: "
mt_byte=""
mt_native=""
mt_native_p=""

stdlib=`ocamlc -where`

printf "%s" "  for bytecode applications: "
if [ -f "$stdlib/vmthreads/threads.cma" ]; then
    # Note: We prefer -vmthread for compilation even if systhreads are
    # available. This does not cause any problems, because the type of
    # mt is selected in the final link step of the executable, and not
    # important for the creation of libraries.
    mt_byte="-vmthread"
elif [ -f "$stdlib/threads/threads.cma" ]; then
    mt_byte="-thread"
else
    echo "Internal error: This library is incompatible with your version"
    echo "of O'Caml, as my assumptions about stdlib layout do not hold."
    exit 1
fi
echo "$mt_byte"

printf "%s" "  for native code applications: "
if [ -f "$stdlib/threads/threads.cmxa" ]; then
    mt_native="-thread"
    mt_native_p="yes"
fi

if [ -n "$mt_native" ]; then
    echo "$mt_native"
else
    echo "not available"
fi

######################################################################
# Check equeue-tcl-defs and -libs

if [ $with_equeue_tcl -gt 0 ]; then
    printf "%s" "Checking switches for tcl.h... "

    tcl_defs_1=""
    for d in $tcl_defs; do
	tcl_defs_1="$tcl_defs_1 -ccopt '$d'"
    done

    rm -rf tmp
    mkdir -p tmp

    cat <<EOF >tmp/t.c
#include "tcl.h"

main () {
}
EOF

    if ( cd tmp; ocamlc $tcl_defs_1 -c t.c >/dev/null 2>/dev/null ) then
	echo "ok"
    else
	echo "not ok"
	echo
	echo "Please check -equeue-tcl-defs!"
	exit 1
    fi

    printf "%s" "Checking switches to link libtcl... "

    cat <<EOF >tmp/t.c
#include <stdlib.h>
#include <stdio.h>
#include "tcl.h"
 
do_something () {
    void (*x)(int);
    x = Tcl_Exit;
    exit(0);
}
EOF

    cat <<EOF >tmp/t.ml
exit 0
EOF

    if ( cd tmp
	 ocamlc $tcl_defs_1 -c t.c >/dev/null 2>/dev/null &&
	 ocamlc -c t.ml >/dev/null 2>/dev/null &&
	 ocamlc -o t -custom t.o t.cmo -cclib "$tcl_libs"
       ) 
    then
	if tmp/t; then
	    echo "ok"
	else
	    echo "not ok (check ldd output of tmp/t)"
	    echo
	    echo "Please check -equeue-tcl-libs!"
	    exit 1
	fi
    else
	echo "not ok"
	echo
	echo "Please check -equeue-tcl-libs!"
	exit 1
    fi

fi

######################################################################
# Check lablgtk

if [ $with_equeue_gtk1 -gt 0 ]; then
    printf "%s" "Checking for lablgtk... "
    if ocamlfind query lablgtk >/dev/null 2>/dev/null; then
	echo "found"
    else
	echo "not found"
	with_equeue_gtk1=0
    fi
fi

######################################################################
# Check lablgtk2

if [ $with_equeue_gtk2 -gt 0 ]; then
    printf "%s" "Checking for lablgtk2... "
    if ocamlfind query lablgtk2 >/dev/null 2>/dev/null; then
	echo "found"
    else
	echo "not found"
	with_equeue_gtk2=0
    fi
fi

if [ $with_equeue_gtk2 -gt 0 ]; then
    printf "%s" "Checking whether lablgtk2 has GMain.Io.remove... "
    mkdir -p tmp
    cat <<EOF >tmp/gtk.ml
let _ = GMain.Io.remove;;
EOF

    if ocamlfind ocamlc -package lablgtk2 -c tmp/gtk.ml >/dev/null 2>/dev/null; then
	echo "yes"
    else
	echo "no"
	echo "Your version of lablgtk2 is too old!"
	with_equeue_gtk2=0
    fi
fi

if [ $with_equeue_gtk2 -gt 0 ]; then
    printf "%s" "Checking whether lablgtk2's GMain.Io.add_watch is broken... "
    mkdir -p tmp
    cat <<'EOF' >tmp/gtk.ml
GMain.Main.init();;
let ch = GMain.Io.channel_of_descr (Unix.stdout) in
let w = GMain.Io.add_watch 
          ~cond:`OUT ~callback:(fun () -> true) ch in
(* add_watch is broken when it just returns Val_unit, and ok when it
 * returns a positive int
 *)
if (Obj.magic w : int) > 0 then
  exit 0
else
  exit 1
EOF
    if ocamlfind ocamlc -package unix,lablgtk2 -linkpkg -o tmp/gtk tmp/gtk.ml  && tmp/gtk; then #>/dev/null 2>/dev/null
	echo "no"
    else
	echo "yes"
	echo "You should apply the patch-ab-ml_glib.c to lablgtk2 to fix this!"
	with_equeue_gtk2=0
    fi
fi


######################################################################
# Check cygwin

printf "%s" "Checking for cygwin... "
u=`uname`
case "$u" in
	CYGWIN*)
		echo "found"
		exec_suffix=".exe"
		;;
	*)
		echo "not found"
		;;
esac

######################################################################
# Summary

echo
echo "Effective options:"
print_options
echo

pkglist_build="equeue"
pkglist_install="equeue"

if [ "$with_equeue_tcl" -gt 0 ]
then pkglist_build="$pkglist_build equeue-tcl"
     pkglist_install="$pkglist_install equeue-tcl"; fi

if [ "$with_equeue_gtk1" -gt 0 ]
then pkglist_build="$pkglist_build equeue-gtk"
     pkglist_install="$pkglist_install equeue-gtk"
     rm -f src/equeue-gtk1
     ln -s equeue-gtk src/equeue-gtk1
fi

if [ "$with_equeue_gtk2" -gt 0 ]
then pkglist_build="$pkglist_build equeue-gtk2"
     pkglist_install="$pkglist_install equeue-gtk2"
     for f in Makefile uq_gtk.ml uq_gtk.mli; do
	 rm -f src/equeue-gtk2/$f
	 ln -s ../equeue-gtk/$f src/equeue-gtk2
     done
fi

if [ "$with_shell" -gt 0 ]
then pkglist_build="$pkglist_build shell"
     pkglist_install="$pkglist_install shell"; fi

######################################################################
# Write META

for pkg in $pkglist_install; do
	if [ -f src/$pkg/META.in ]; then
	    echo "Writing src/$pkg/META"
	    sed -e "s/@VERSION@/$version/g" \
		src/$pkg/META.in >src/$pkg/META
	fi
done

######################################################################
# Write Makefile.conf

echo "Writing Makefile.conf"
cat <<_EOF_ >Makefile.conf
VERSION = $version
PKGLIST_BUILD = $pkglist_build
PKGLIST_INSTALL = $pkglist_install
EXEC_SUFFIX = $exec_suffix
MT_BYTE = $mt_byte
MT_NATIVE = $mt_native
MT_NATIVE_P = $mt_native_p
EQUEUE_TCL_DEFS = $tcl_defs_1
EQUEUE_TCL_LIBS = $tcl_libs
_EOF_

######################################################################
# Finish

echo
echo "You can now compile equeue by invoking"
echo "   make all"
echo "for the bytecode compiler, and optionally by invoking"
echo "   make opt"
echo "for the native-code compiler (if supported on your architecture)."
echo "Finally, a"
echo "   make install"
echo "will install the package."
