/*
Copyright (C) 2004-2008  Justin Karneges

This file is free software; unlimited permission is given to copy and/or
distribute it, with or without modifications, as long as this notice is
preserved.
*/

#ifndef QC_CONF4_H
#define QC_CONF4_H

#include <QtCore>

class Conf;

enum VersionMode { VersionMin, VersionExact, VersionMax, VersionAny };

// ConfObj
//
// Subclass ConfObj to create a new configuration module.
class ConfObj
{
public:
	Conf *conf;
	bool required;
	bool disabled;
	bool success;

	ConfObj(Conf *c);
	virtual ~ConfObj();

	// long or descriptive name of what is being checked/performed
	// example: "KDE >= 3.3"
	virtual QString name() const = 0;

	// short name
	// example: "kde"
	virtual QString shortname() const = 0;

	// string to display during check
	// default: "Checking for [name] ..."
	virtual QString checkString() const;

	// string to display after check
	// default: "yes" or "no", based on result of exec()
	virtual QString resultString() const;

	// this is where the checking code goes
	virtual bool exec() = 0;
};

// Conf
//
// Interact with this class from your ConfObj to perform detection
// operations and to output configuration parameters.
class Conf
{
public:
	bool debug_enabled;
	QString qmake_path;
	QString qmakespec;
	QString maketool;

	QString DEFINES;
	QStringList INCLUDEPATH;
	QStringList LIBS;
	QString extra;

	QList<ConfObj*> list;
	QMap<QString,QString> vars;

	Conf();
	~Conf();

	QString getenv(const QString &var);
	QString qvar(const QString &s);
	QString normalizePath(const QString &s) const;
	QString escapeQmakeVar(const QString &s) const;
	inline QString escapePath(const QString &s) /* prepare fs path for qmake file */
	{ return escapeQmakeVar(normalizePath(s)); }
	QString escapedIncludes() const;
	QString escapedLibs() const;

	bool exec();

	void debug(const QString &s);

	QString expandIncludes(const QString &inc);
	QString expandLibs(const QString &lib);

	int doCommand(const QString &s, QByteArray *out = 0);
	int doCommand(const QString &prog, const QStringList &args, QByteArray *out = 0);

	bool doCompileAndLink(const QString &filedata, const QStringList &incs, const QString &libs, const QString &proextra, int *retcode = 0);
	bool checkHeader(const QString &path, const QString &h);
	bool findHeader(const QString &h, const QStringList &ext, QString *inc);
	bool checkLibrary(const QString &path, const QString &name);
	bool findLibrary(const QString &name, QString *lib);
	QString findProgram(const QString &prog);
	bool findSimpleLibrary(const QString &incvar, const QString &libvar, const QString &incname, const QString &libname, QString *incpath, QString *libs);
	bool findFooConfig(const QString &path, QString *version, QStringList *incs, QString *libs, QString *otherflags);
	bool findPkgConfig(const QString &name, VersionMode mode, const QString &req_version, QString *version, QStringList *incs, QString *libs, QString *otherflags);

	void addDefine(const QString &str);
	void addLib(const QString &str);
	void addIncludePath(const QString &str);
	void addExtra(const QString &str);

private:
	bool first_debug;

	friend class ConfObj;
	void added(ConfObj *o);
};

#endif
