#!/bin/sh

show_usage() {
cat <<EOT
Usage: ./configure [OPTION]...

This script creates necessary configuration files to build/install.

Main options:
  --prefix=[path]   Base path for build/install.  Default: /usr/local
  --tqtdir=[path]   Directory where TQt is installed.
  --help            This help text.

EOT
}

while [ $# -gt 0 ]; do
	case "$1" in
		--prefix=*)
			PREFIX=`expr "${1}" : "--prefix=\(.*\)"`
			shift
			;;

		--tqtdir=*)
			TQTDIR=`expr "${1}" : "--tqtdir=\(.*\)"`
			shift
			;;

		--debug)
			QC_DEBUG="Y"
			shift
			;;
		--help) show_usage; exit ;;
		*) show_usage; exit ;;
	esac
done

PREFIX=${PREFIX:-/usr/local}

echo "Configuring TQt Cryptographic Architecture (QCA) ..."

if [ "$QC_DEBUG" = "Y" ]; then
echo
echo PREFIX=$PREFIX
echo QTDIR=$QTDIR
echo
fi

printf "Verifying TQt 3.x Multithreaded (MT) build environment ... "

if [ -z "$QTDIR" ]; then
	if [ "$QC_DEBUG" = "Y" ]; then
		echo \$TQTDIR not set... trying to find TQt manually
	fi
	for p in /usr/lib/tqt /usr/share/tqt /usr/share/tqt3 /usr/local/lib/tqt /usr/local/share/tqt /usr/lib/tqt3 /usr/local/lib/tqt3 /usr/lib/qt /usr/share/qt /usr/share/qt3 /usr/local/lib/qt /usr/local/share/qt /usr/lib/qt3 /usr/local/lib/qt3 /usr/lib64/tqt /usr/local/lib64/tqt /usr/lib64/tqt3 /usr/local/lib64/tqt3 /usr/lib64/qt /usr/local/lib64/qt /usr/lib64/qt3 /usr/local/lib64/qt3 /usr/X11R6/share/qt /usr/qt/3 ; do
		if [ -d "$p/mkspecs" ]; then
			QTDIR=$p
			break;
		fi;
	done
	if [ -z "$QTDIR" ]; then
		echo fail
		echo
		echo Unable to find TQt 'mkspecs'. Please set TQTDIR
		echo manually. Perhaps you need to install TQt 3
		echo development utilities. You may download them
		echo from the the repos of your distribution or from
		echo https://mirror.git.trinitydesktop.org/gitea/TDE/tqt3/.
		echo
		exit 1;
	fi
fi

if [ ! -x "$QTDIR/bin/tqmake" ]; then
	if [ "$QC_DEBUG" = "Y" ]; then
		echo Warning: tqmake not in \$QTDIR/bin/tqmake
		echo trying to find it in \$PATH
	fi
	qm=`type -p tqmake`
	if [ -x "$qm" ]; then
		if [ "$QC_DEBUG" = "Y" ]; then
			echo tqmake found in $qm
		fi
	else
		echo fail
		echo
		echo Sorry, you seem to have a very unusual setup,
		echo or I missdetected \$QTDIR=$QTDIR
		echo
		echo Please set \$QTDIR manually and make sure that
		echo \$QTDIR/bin/tqmake exists.
		echo
		exit 1;
	fi
else
	qm=$QTDIR/bin/tqmake
fi

gen_files() {
cat >$1/modules.cpp <<EOT

EOT
cat >$1/modules_new.cpp <<EOT

EOT
cat >$1/conf.cpp <<EOT
#include<stdio.h>
#include<stdlib.h>
#include<tqstring.h>
#include<tqdict.h>
#include<tqptrlist.h>
#include<tqfileinfo.h>
#include<tqfile.h>
#include<tqdir.h>
#include<tqstringlist.h>

class Conf;

class ConfObj
{
public:
	ConfObj(Conf *c);
	virtual ~ConfObj();

	virtual TQString name() const=0;
	virtual TQString shortname() const=0;
	virtual bool exec()=0;

	Conf *conf;
	bool required;
	bool disabled;
};

typedef TQPtrList<ConfObj> ConfObjList;
typedef TQPtrListIterator<ConfObj> ConfObjListIt;

class Conf
{
public:
	Conf() : vars(17)
	{
		list.setAutoDelete(true);
		vars.setAutoDelete(true);

		vars.insert("QMAKE_INCDIR_X11", new TQString(X11_INC));
		vars.insert("QMAKE_LIBDIR_X11", new TQString(X11_LIBDIR));
		vars.insert("QMAKE_LIBS_X11",   new TQString(X11_LIB));
		vars.insert("QMAKE_CC",         new TQString(CC));
	}

	~Conf()
	{
	}

	void added(ConfObj *o)
	{
		list.append(o);
	}

	TQString getenv(const TQString &var)
	{
		char *p = ::getenv(var.latin1());
		if(!p)
			return TQString::null;
		return TQString(p);
	}

	bool exec()
	{
		ConfObjListIt it(list);
		for(ConfObj *o; (o = it.current()); ++it) {
			// if this was a disabled-by-default option, check if it was enabled
			if(o->disabled) {
				TQString v = TQString("QC_ENABLE_") + o->shortname();
				if(getenv(v) != "Y")
					continue;
			}
			// and the opposite?
			else {
				TQString v = TQString("QC_DISABLE_") + o->shortname();
				if(getenv(v) == "Y")
					continue;
			}

			printf("Checking for %s ...", o->name().latin1());
			fflush(stdout);
			bool ok = o->exec();
			if(ok)
				printf(" yes\n");
			else
				printf(" no\n");
			if(!ok && o->required) {
				printf("\nError: need %s!\n", o->name().latin1());
				return false;
			}
		}
		return true;
	}

	const TQString & qvar(const TQString &s)
	{
		TQString *p = vars.find(s);
		if(p)
			return *p;
		else
			return blank;
	}

	TQString expandIncludes(const TQString &inc)
	{
		return TQString("-I") + inc;
	}

	TQString expandLibs(const TQString &lib)
	{
		return TQString("-L") + lib;
	}

	int doCommand(const TQString &s)
	{
		//printf("[%s]\n", s.latin1());
		int r = system((s + " 1>/dev/null 2>/dev/null").latin1());
		//printf("returned: %d\n", r);
		return r;
	}

	bool doCompileAndLink(const TQString &filedata, const TQString &flags, int *retcode=0)
	{
		TQDir dir(".");
		TQString fname = "atest.c";
		TQString out = "atest";
		TQFile f(fname);
		TQCString cs = filedata.latin1();
		if(!f.open(IO_WriteOnly | IO_Truncate))
			return false;
		f.writeBlock(cs.data(), cs.length());
		f.close();

		TQString str = qvar("QMAKE_CC") + ' ' + fname + " -o " + out + ' ' + flags;
		int r = doCommand(str);
		if(r == 0 && retcode)
			*retcode = doCommand(TQString("./") + out);
		dir.remove(fname);
		dir.remove(out);
		if(r != 0)
			return false;
		return true;
	}

	bool checkHeader(const TQString &path, const TQString &h)
	{
		TQFileInfo fi(path + '/' + h);
		if(fi.exists())
			return true;
		return false;
	}

	bool findHeader(const TQString &h, const TQStringList &ext, TQString *inc)
	{
		if(checkHeader("/usr/include", h)) {
			*inc = "";
			return true;
		}
		TQStringList dirs;
		dirs += "/usr/local/include";
		dirs += ext;
		for(TQStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
			if(checkHeader(*it, h)) {
				*inc = *it;
				return true;
			}
		}
		return false;
	}

	bool checkLibrary(const TQString &path, const TQString &name)
	{
		TQString str =
			"int main()\n"
			"{\n"
			"    return 0;\n"
			"}\n";

		TQString extra;
		if(!path.isEmpty())
			extra += TQString("-L") + path + ' ';
		extra += TQString("-l") + name;
		if(!doCompileAndLink(str, extra))
			return false;
		return true;
	}

	bool findLibrary(const TQString &name, TQString *lib)
	{
		if(checkLibrary("", name)) {
			*lib = "";
			return true;
		}
		if(checkLibrary("/usr/local/lib", name)) {
			*lib = "/usr/local/lib";
			return true;
		}
		if(checkLibrary("/usr/local/lib64", name)) {
			*lib = "/usr/local/lib64";
			return true;
		}
		return false;
	}

	void addDefine(const TQString &str)
	{
		if(DEFINES.isEmpty())
			DEFINES = str;
		else
			DEFINES += TQString(" ") + str;
	}

	void addLib(const TQString &str)
	{
		if(LIBS.isEmpty())
			LIBS = str;
		else
			LIBS += TQString(" ") + str;
	}

	void addIncludePath(const TQString &str)
	{
		if(INCLUDEPATH.isEmpty())
			INCLUDEPATH = str;
		else
			INCLUDEPATH += TQString(" ") + str;
	}

	void addExtra(const TQString &str)
	{
		extra += str + '\n';
	}

	TQString DEFINES;
	TQString INCLUDEPATH;
	TQString LIBS;
	TQString extra;

private:
	ConfObjList list;
	TQDict<TQString> vars;
	TQString blank;
};

ConfObj::ConfObj(Conf *c)
{
	conf = c;
	conf->added(this);
	required = false;
	disabled = false;
}

ConfObj::~ConfObj()
{
}

#include"modules.cpp"

//----------------------------------------------------------------------------
// main
//----------------------------------------------------------------------------
int main()
{
	Conf *conf = new Conf;
	ConfObj *o;
	o = 0;
#include"modules_new.cpp"

	printf("ok\n");
	bool success = false;
	if(conf->exec()) {
		TQFile f("conf.pri");
		if(!f.open(IO_WriteOnly | IO_Truncate)) {
			printf("Error writing %s\n", f.name().latin1());
			return 1;
		}

		TQString str;
		str += "# qconf\n";
    str += "QT_PATH_PLUGINS = " + TQString(tqInstallPathPlugins()) + '\n';
		if(!conf->DEFINES.isEmpty())
			str += "DEFINES += " + conf->DEFINES + '\n';
		if(!conf->INCLUDEPATH.isEmpty())
			str += "INCLUDEPATH += " + conf->INCLUDEPATH + '\n';
		if(!conf->LIBS.isEmpty())
			str += "LIBS += " + conf->LIBS + '\n';
		if(!conf->extra.isEmpty())
			str += conf->extra;
		str += '\n';

		char *p = getenv("BINDIR");
		if(p) {
			str += TQString("target.path = ") + p + '\n';
			str += "INSTALLS += target\n";
		}

		TQCString cs = str.latin1();
		f.writeBlock(cs.data(), cs.length());
		f.close();
		success = true;
	}
	delete conf;

	if(success)
		return 0;
	else
		return 1;
}

EOT
cat >$1/conf.pro <<EOT
TEMPLATE = app
CONFIG += qt x11 thread console
TARGET = conf
INCLUDEPATH += '/usr/include/tqt'

DEFINES += X11_INC='"\$\$QMAKE_INCDIR_X11"'
DEFINES += X11_LIBDIR='"\$\$QMAKE_LIBDIR_X11"'
DEFINES += X11_LIB='"\$\$QMAKE_LIBS_X11"'
DEFINES += CC='"\$\$QMAKE_CC"'

SOURCES += conf.cpp

EOT
}

export PREFIX
export QTDIR
rm -rf .qconftemp
(
	mkdir .qconftemp
	gen_files .qconftemp
	cd .qconftemp
	$qm conf.pro >/dev/null
	QTDIR=$QTDIR make clean >/dev/null 2>&1
	QTDIR=$QTDIR make >../conf.log 2>&1
)

if [ "$?" != "0" ]; then
	rm -rf .qconftemp
	echo fail
	echo
	echo "There was an error compiling 'conf'.  Be sure you have a proper"
	echo "TQt 3.x Multithreaded (MT) build environment set up."
	if [ ! -f "$QTDIR/lib/libtqt-mt.so.3" ]; then
		if [ ! -f "$QTDIR/lib64/libtqt-mt.so.3" ]; then
			echo
			echo "One possible reason is that you don't have"
			echo "libtqt-mt.so.3 installed in $QTDIR/lib/"
			echo "or $QTDIR/lib64/."
		fi
	fi
	echo
	exit 1;
fi

.qconftemp/conf
ret="$?"
if [ "$ret" = "1" ]; then
	rm -rf .qconftemp
	echo
	exit 1;
else
	if [ "$ret" != "0" ]; then
		rm -rf .qconftemp
		echo fail
		echo
		echo Unexpected error launching 'conf'
		echo
		exit 1;
	fi
fi
rm -rf .qconftemp

if [ -x "./qcextra" ]; then
	./qcextra
fi
# run tqmake
$qm qca.pro
if [ "$?" != "0" ]; then
	echo
	exit 1;
fi
cat >Makefile.tmp <<EOT
export QTDIR = $QTDIR
EOT
cat Makefile >> Makefile.tmp
rm -f Makefile
cp -f Makefile.tmp Makefile
rm -f Makefile.tmp

echo
echo Good, your configure finished.  Now run \'make\'.
echo
