/****************************************************************************
**
** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
**
** This file is part of Qt Jambi.
**
** ** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://www.trolltech.com/products/qt/opensource.html
**
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://www.trolltech.com/products/qt/licensing.html or contact the
** sales department at sales@trolltech.com.

**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

#ifndef METAINFOGENERATOR_H
#define METAINFOGENERATOR_H

#include "generator.h"
#include "javagenerator.h"
#include "cppgenerator.h"

class MetaInfoGenerator : public JavaGenerator
{
public:
    MetaInfoGenerator(PriGenerator *pri);

    enum GenerationFlags {
        GeneratedJavaClasses = 0x1,
        GeneratedMetaInfo = 0x2
    };

    enum OutputDirectoryType {
        CppDirectory,
        JavaDirectory
    };

    MetaInfoGenerator();

    virtual void generate();
    virtual QString fileNameForClass(const AbstractMetaClass *java_class) const;
    virtual void write(QTextStream &s, const AbstractMetaClass *java_class);

    void setFilenameStub(const QString &stub) { m_filenameStub = stub; }
    QString filenameStub() const { return m_filenameStub; }

    QString headerFilename() const { return filenameStub() + ".h"; }
    QString cppFilename() const { return filenameStub() + ".cpp"; }

    virtual QString subDirectoryForClass(const AbstractMetaClass *, OutputDirectoryType type) const;
    virtual QString subDirectoryForPackage(const QString &package, OutputDirectoryType type) const;
    virtual bool shouldGenerate(const AbstractMetaClass *) const;

    bool generated(const AbstractMetaClass *cls) const;
    bool generatedJavaClasses(const QString &package) const;
    bool generatedMetaInfo(const QString &package) const;

private:
    void writeCppFile();
    void writeHeaderFile();
    void writeLibraryInitializers();
    void writeInclude(QTextStream &s, const Include &inc);
    void writeIncludeStatements(QTextStream &s, const AbstractMetaClassList &classList, const QString &package);
    void writeInitializationFunctionName(QTextStream &s, const QString &package, bool fullSignature);
    void writeInitialization(QTextStream &s, const TypeEntry *entry, const AbstractMetaClass *cls, bool registerMetaType = true);
    void writeCustomStructors(QTextStream &s, const TypeEntry *entry);
    void writeDestructors(QTextStream &s, const AbstractMetaClass *cls);
    void writeCodeBlock(QTextStream &s, const QString &code);
    void writeSignalsAndSlots(QTextStream &s, const QString &package);
    void writeEnums(QTextStream &s, const QString &package);
    void writeRegisterSignalsAndSlots(QTextStream &s);
    void writeRegisterEnums(QTextStream &s);
    QStringList writePolymorphicHandler(QTextStream &s, const QString &package, const AbstractMetaClassList &clss);
    bool shouldGenerate(const TypeEntry *entry) const;
    void buildSkipList();

#if defined(QTJAMBI_DEBUG_TOOLS)
    void writeNameLiteral(QTextStream &, const TypeEntry *, const QString &fileName);
#endif

    QHash<QString, int> m_skip_list;
    QString m_filenameStub;

    QHash<OutputDirectoryType, QString> m_out_dir;

    const AbstractMetaClass* lookupClassWithPublicDestructor(const AbstractMetaClass *cls);

    PriGenerator *priGenerator;
};

#endif // METAINFOGENERATOR_H
