#!/bin/sh

. scripts/configure.sh || exit 1

check_cflags()
{
	check_cc_flag -std=gnu99 -pipe -Wall -Wshadow -Wcast-align -Wpointer-arith \
		-Wwrite-strings -Wundef -Wmissing-prototypes -Wredundant-decls \
		-Wextra -Wno-sign-compare -Wformat-security

	for i in -Wdeclaration-after-statement \
		-Wold-style-definition \
		-Wno-pointer-sign \
		-Werror-implicit-function-declaration \
		-Wno-unused-parameter
	do
		check_cc_flag $i
	done
	return 0
}

check_compat()
{
	COMPAT_LIBS=
	case `uname -s` in
	SunOS)
		# connect() etc.
		try_link -lsocket && COMPAT_LIBS="$COMPAT_LIBS -lsocket"

		# gethostbyname()
		try_link -lnsl && COMPAT_LIBS="$COMPAT_LIBS -lnsl"

		# nanosleep()
		if try_link -lrt
		then
			COMPAT_LIBS="$COMPAT_LIBS -lrt"
		elif try_link -lposix4
		then
			COMPAT_LIBS="$COMPAT_LIBS -lposix4"
		fi
		;;
	CYGWIN*)
		CONFIG_CYGWIN=y
		makefile_vars CONFIG_CYGWIN
	esac
	makefile_vars COMPAT_LIBS
}

rtsched_code="
#include <pthread.h>

int main(int argc, char *argv[])
{
	pthread_attr_t attr;
	struct sched_param param;

	pthread_attr_init(&attr);
	pthread_attr_setschedpolicy(&attr, SCHED_RR);
	param.sched_priority = sched_get_priority_max(SCHED_RR);
	pthread_attr_setschedparam(&attr, &param);
	return 0;
}
"

check_rtsched()
{
	msg_checking "for realtime scheduling"
	if try_compile_link "$rtsched_code" $PTHREAD_CFLAGS $PTHREAD_LIBS
	then
		msg_result yes
		EXTRA_CFLAGS="$EXTRA_CFLAGS -DREALTIME_SCHEDULING"
	else
		msg_result no
	fi
	return 0
}

ncurses_code="
#if defined(__sun__) || defined(__CYGWIN__)
#include <termios.h>
#include <ncurses.h>
#else
#include <curses.h>
#endif

int main(void)
{
	initscr();
	endwin();
	return 0;
}
"

check_ncurses()
{
	if check_library NCURSES "" -lncursesw
	then
		widechars=y
	elif check_library NCURSES "" -lncurses || check_library NCURSES "" -lcurses
	then
		widechars=n
		msg_error "Your ncurses does not support wide characters!"
		msg_error "Install ncursesw if you need wide character support,"
		msg_error "you can ignore this warning otherwise."
	fi
	test -z "$widechars" && return 1

	msg_checking "for working ncurses setup"
	for flag in "" "-I/usr/include/ncurses" "-I/usr/include/ncursesw"
	do
		if try_compile_link "$ncurses_code" $flag $NCURSES_LIBS
		then
			NCURSES_CFLAGS="$NCURSES_CFLAGS $flag"
			msg_result yes
			working_curses=y
			break
		fi
	done
	if test -z "$working_curses"
	then
		msg_result no
		return 1
	fi

	check_function "resizeterm" $NCURSES_CFLAGS $NCURSES_LIBS
	HAVE_RESIZETERM=`test $? -ne 0 ; echo $?`

	check_function "use_default_colors" $NCURSES_CFLAGS $NCURSES_LIBS
	HAVE_USE_DEFAULT_COLORS=`test $? -ne 0 ; echo $?`

	return 0
}

check_discid()
{
	HAVE_DISCID=n
	pkg_config DISCID "libdiscid" "" "-ldiscid" && HAVE_DISCID=y
	return $?
}

check_mpc()
{
	MPC_SV8=0
	if check_header mpc/mpcdec.h
	then
		MPC_SV8=1
	else
		check_header mpcdec/mpcdec.h || return $?
	fi
	check_library MPC "" "-lmpcdec -lm"
	return $?
}

check_cddb()
{
	pkg_config CDDB "libcddb" "" "-lcddb" && HAVE_CDDB=y
	return $?
}

check_cdio()
{
	pkg_config CDIO "libcdio_cdda" "" "-lcdio_cdio -lcdio -lm"
	return $?
}

check_flac()
{
	if pkg_config FLAC "flac" "" "-lFLAC -lm"
	then
		# Make sure the FLAC_CFLAGS value is sane, strip trailing '/FLAC'.
		FLAC_CFLAGS=`echo $FLAC_CFLAGS | sed "s/FLAC$//"`
		return 0
	fi
	check_library FLAC "" "-lFLAC -lvorbisfile -lm"
	return $?
}

check_mad()
{
	pkg_config MAD "mad" "" "-lmad -lm"
	return $?
}

check_cue()
{
	pkg_config CUE "libcue >= 1.3"
	return $?
}


mikmod_code="
#include <mikmod.h>
int main() {
	MikMod_RegisterAllDrivers();
	return 0;
}
"
check_mikmod()
{
	# mikmod is linked against pthread
	app_config MIKMOD libmikmod-config || \
		check_library MIKMOD "$PTHREAD_CFLAGS" "-lmikmod $PTHREAD_LIBS" || \
		return 1
	try_compile_link "$mikmod_code" $MIKMOD_CFLAGS $MIKMOD_LIBS
	return $?
}

check_modplug()
{
	pkg_config MODPLUG "libmodplug" "-I/usr/include/libmodplug" "-lmodplug -lstdc++ -lm" || return $?
	MODPLUG_API_8=0
	if check_function "ModPlug_GetModuleType" $MODPLUG_CFLAGS $MODPLUG_LIBS
	then
		MODPLUG_API_8=1
	fi
	return 0
}

check_vorbis()
{
	if test "$CONFIG_TREMOR" = y
	then
		pkg_config VORBIS "vorbisidec" "" "-lvorbisidec -lm"
		return $?
	else
		pkg_config VORBIS "vorbisfile" "" "-lvorbisfile -lvorbis -lm -logg"
		return $?
	fi
}

check_wavpack()
{
	pkg_config WAVPACK "wavpack" "" "-lwavpack"
	return $?
}

check_pulse()
{
	pkg_config PULSE "libpulse >= 0.9.19"
	return $?
}

check_alsa()
{
	# the alsa.pc file should be always available
	pkg_config ALSA "alsa >= 1.0.11"
	return $?
}

check_ao()
{
	pkg_config AO "ao" "" "-lao"
	return $?
}

arts_code="
#include <artsc.h>
int main() {
	return arts_init();
}
"
check_arts()
{
	app_config ARTS artsc-config || return 1
	try_compile_link "$arts_code" $ARTS_CFLAGS $ARTS_LIBS
	return $?
}

check_oss()
{
	case `uname -s` in
		Linux|*FreeBSD)
			;;
		*BSD)
			check_library OSS "" "-lossaudio"
			return $?
			;;
		*)
			# unknown
			;;
	esac

	OSS_CFLAGS=""
	OSS_LIBS=""
	msg_checking "for header <sys/soundcard.h>"
	if test -f /usr/include/sys/soundcard.h
	then
		msg_result "yes"
		makefile_vars OSS_CFLAGS OSS_LIBS
		return 0
	else
		msg_result "no"
	fi
	return 1
}

check_sun()
{
	msg_checking "for header <sys/audioio.h>"
	if test -f /usr/include/sys/audioio.h
	then
		msg_result "yes"
		return 0
	else
		msg_result "no"
		return 1
	fi
}

check_waveout()
{
	case `uname -s` in
	CYGWIN*)
		check_library WAVEOUT "" "-lwinmm"
		return $?
	esac
	return 1
}

check_roar()
{
	pkg_config ROAR "libroar >= 0.4.5"
	return $?
}

check_mp4()
{
	USE_MPEG4IP=1
	if check_header mp4v2/mp4v2.h
	then
		USE_MPEG4IP=0
	else
		check_header mp4.h || return $?
	fi
	check_header neaacdec.h &&
	check_library MP4 "" "-lmp4v2 -lfaad -lm"
	return $?
}

check_aac()
{
	check_header neaacdec.h &&
	check_library AAC "" "-lfaad -lm"
	return $?
}

check_ffmpeg()
{
	HAVE_FFMPEG_AVCODEC_H=y
	pkg_config FFMPEG "libavformat" || return $?
	if check_header "libavcodec/avcodec.h" $FFMPEG_CFLAGS
	then
		HAVE_FFMPEG_AVCODEC_H=n
	else
		check_header "ffmpeg/avcodec.h" $FFMPEG_CFLAGS || return $?
	fi
	# ffmpeg api changes so frequently that it is best to compile the module
	libs="$LDDLFLAGS $FFMPEG_LIBS"
	cflags="$SOFLAGS $FFMPEG_CFLAGS"
	if test "$HAVE_FFMPEG_AVCODEC_H" = y
	then
		cflags="$cflags -DHAVE_FFMPEG_AVCODEC_H"
	fi
	topdir=`dirname "$0"`
	ffmpeg_code=`cat "$topdir"/ffmpeg.c | sed 's/\\\n//g'`
	msg_checking "for successful build of ffmpeg.c"
	if try_compile_link "$ffmpeg_code" $cflags $libs
	then
		msg_result yes
		return 0
	fi
	msg_result no
	return 1
}

check_string_function()
{
	msg_checking "for function $1"
	string_function_code="
#include <string.h>
int main() {
	return $1;
}
"
	if try_compile_link "$string_function_code"
	then
		msg_result yes
		return 0
	fi
	msg_result no
	return 1
}


# defaults
prefix=/usr/local
DEBUG=1
HAVE_CDDB=n
CONFIG_TREMOR=n
CONFIG_MIKMOD=n
USE_FALLBACK_IP=n
HAVE_BYTESWAP_H=n
HAVE_STRDUP=n
HAVE_STRNDUP=n
# unset CONFIG_* variables: if check succeeds 'y', otherwise 'n'

USAGE="
Options:
  prefix          Installation prefix    [$prefix]
  bindir          User executables       [\$prefix/bin]
  datadir         Read-only data         [\$prefix/share]
  libdir          Libraries              [\$prefix/lib]
  mandir          Man pages              [\$datadir/man]
  exampledir      Examples               [\$datadir/doc/cmus/examples]
  DEBUG           Debugging level (0-2)  [$DEBUG]

Optional Features: y/n
  CONFIG_CDDB     	libcddb CDDA identification                     [auto]
  CONFIG_CDIO     	libcdio CDDA input                              [auto]
  CONFIG_DISCID   	libdiscid CDDA identification                   [auto]
  CONFIG_FLAC     	Free Lossless Audio Codec (.flac, .fla)         [auto]
  CONFIG_MAD      	MPEG Audio Decoder (.mp3, .mp2, streams)        [auto]
  CONFIG_MODPLUG  	libmodplug (.mod, .x3m, ...)                    [auto]
  CONFIG_MIKMOD   	libmikmod (.mod, .x3m, ...)                     [n]
  CONFIG_MPC      	libmpcdec (Musepack .mpc, .mpp, .mp+)           [auto]
  CONFIG_VORBIS   	Ogg/Vorbis (.ogg, application/ogg, audio/x-ogg) [auto]
  CONFIG_TREMOR   	Use Tremor as Ogg/Vorbis input plugin           [n]
  CONFIG_WAV      	WAV                                             [y]
  CONFIG_WAVPACK  	WavPack (.wv, audio/x-wavpack)                  [auto]
  CONFIG_MP4      	MPEG-4 AAC (.mp4, .m4a, .m4b)                   [auto]
  CONFIG_AAC      	AAC (.aac, audio/aac, audio/aacp)               [auto]
  CONFIG_FFMPEG   	FFMPEG (.shn, .wma)                             [auto]
  CONFIG_CUE    	CUE sheets (.cue)                               [auto]
  CONFIG_ROAR           native RoarAudio output                         [auto]
  CONFIG_PULSE    	native PulseAudio output                        [auto]
  CONFIG_ALSA     	ALSA                                            [auto]
  CONFIG_AO       	Libao cross-platform audio library              [auto]
  CONFIG_ARTS     	ARTS                                            [auto]
  CONFIG_OSS      	Open Sound System                               [auto]
  CONFIG_SUN      	Sun Audio                                       [auto]
  CONFIG_WAVEOUT  	Windows Wave Out                                [auto]
  USE_FALLBACK_IP	Use a specific IP for every unrecognized	[n]
                        input format. Currently set to FFMPEG.

Also many standard variables like CC, LD, CFLAGS, LDFLAGS are recognized.
Cross compiling is supported via CROSS=target-prefix-
    optionally set HOSTCC=this-machine-gcc, HOSTLD, HOST_CFLAGS, HOST_LDFLAGS."

parse_command_line "$@"

case $DEBUG in
[0-2])
	;;
*)
	die "DEBUG must be 0-2"
	;;
esac

var_default bindir "${prefix}/bin"
var_default datadir "${prefix}/share"
var_default libdir "${prefix}/lib"
var_default mandir "${datadir}/man"
var_default exampledir "${datadir}/doc/cmus/examples"

check check_cc
check check_host_cc
check check_cflags
check check_cc_depgen
check check_endianness
check check_compat
check check_dl
check check_pthread
check check_rtsched
check check_ncurses
check check_iconv
check_header byteswap.h && HAVE_BYTESWAP_H=y
check_string_function "strdup" && HAVE_STRDUP=y
check_string_function "strndup" && HAVE_STRNDUP=y

check check_cddb    CONFIG_CDDB
check check_cdio    CONFIG_CDIO
check check_flac    CONFIG_FLAC
check check_mad     CONFIG_MAD
check check_mikmod  CONFIG_MIKMOD
check check_modplug CONFIG_MODPLUG
check check_mpc     CONFIG_MPC
check check_vorbis  CONFIG_VORBIS
check check_wavpack CONFIG_WAVPACK
check check_mp4     CONFIG_MP4
check check_aac     CONFIG_AAC
check check_ffmpeg  CONFIG_FFMPEG
check check_cue     CONFIG_CUE
# nothing to check, just validate the variable values
check true          CONFIG_TREMOR
check true          CONFIG_WAV
check check_pulse   CONFIG_PULSE
check check_alsa    CONFIG_ALSA
check check_ao      CONFIG_AO
check check_arts    CONFIG_ARTS
check check_oss     CONFIG_OSS
check check_sun     CONFIG_SUN
check check_waveout CONFIG_WAVEOUT
check check_roar    CONFIG_ROAR

# discid is only needed if at least one cdda plugin is active
test -z "$CONFIG_DISCID" && CONFIG_DISCID=a
if test "$CONFIG_DISCID" = a
then
	test "$CONFIG_CDIO" = n && CONFIG_DISCID=n
fi
check check_discid  CONFIG_DISCID

test "$WORDS_BIGENDIAN" = y && CFLAGS="${CFLAGS} -DWORDS_BIGENDIAN"
test "$HAVE_DISCID" = y && CFLAGS="${CFLAGS} -DHAVE_DISCID"

DATADIR="$datadir"
LIBDIR="$libdir"

config_header config/cdio.h HAVE_CDDB
config_header config/datadir.h DATADIR
config_header config/libdir.h LIBDIR
config_header config/debug.h DEBUG
config_header config/tremor.h CONFIG_TREMOR
config_header config/modplug.h MODPLUG_API_8
config_header config/mpc.h MPC_SV8
config_header config/mp4.h USE_MPEG4IP
config_header config/curses.h HAVE_RESIZETERM HAVE_USE_DEFAULT_COLORS
config_header config/ffmpeg.h HAVE_FFMPEG_AVCODEC_H USE_FALLBACK_IP
config_header config/utils.h HAVE_BYTESWAP_H
config_header config/iconv.h HAVE_ICONV
config_header config/xmalloc.h HAVE_STRDUP HAVE_STRNDUP
config_header config/cue.h CONFIG_CUE

CFLAGS="${CFLAGS} -DHAVE_CONFIG"

makefile_vars bindir datadir libdir mandir exampledir
makefile_vars CONFIG_CDIO CONFIG_FLAC CONFIG_MAD CONFIG_MIKMOD CONFIG_MODPLUG CONFIG_MPC CONFIG_VORBIS CONFIG_WAVPACK CONFIG_WAV CONFIG_MP4 CONFIG_AAC CONFIG_FFMPEG CONFIG_CUE
makefile_vars CONFIG_ROAR CONFIG_PULSE CONFIG_ALSA CONFIG_AO CONFIG_ARTS CONFIG_OSS CONFIG_SUN CONFIG_WAVEOUT

generate_config_mk
