/****************************************************************************
**
** Copyright (C) 1992-2008 Nokia. All rights reserved.
**
** This file is part of Qt Jambi.
**
** * Commercial Usage
* Licensees holding valid Qt Commercial licenses may use this file in
* accordance with the Qt Commercial License Agreement provided with the
* Software or, alternatively, in accordance with the terms contained in
* a written agreement between you and Nokia.
*
*
* GNU General Public License Usage
* Alternatively, this file may be used under the terms of the GNU
* General Public License versions 2.0 or 3.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.fsf.org/licensing/licenses/info/GPLv2.html and
* http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
* exception, Nokia gives you certain additional rights. These rights
* are described in the Nokia Qt GPL Exception version 1.2, included in
* the file GPL_EXCEPTION.txt in this package.
* 
* Qt for Windows(R) Licensees
* As a special exception, Nokia, as the sole copyright holder for Qt
* Designer, grants users of the Qt/Eclipse Integration plug-in the
* right for the Qt/Eclipse Integration to link to functionality
* provided by Qt Designer and its related libraries.
*
*
* If you are unsure which license is appropriate for your use, please
* contact the sales department at qt-sales@nokia.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 JAVAGENERATOR_H
#define JAVAGENERATOR_H

#include "generator.h"
#include "metajava.h"

#include <QTextStream>

class DocParser;

class JavaGenerator : public Generator
{
    Q_OBJECT

public:
    JavaGenerator();

    static QString translateType(const AbstractMetaType *java_type, const AbstractMetaClass *context, Option option = NoOption);

    void writeInjectedCode(QTextStream &s,
                           const AbstractMetaFunction *java_function,
                           CodeSnip::Position position);
    static void writeArgument(QTextStream &s,
                       const AbstractMetaFunction *java_function,
                       const AbstractMetaArgument *java_argument,
                       uint options = 0);
    static QString argumentString(const AbstractMetaFunction *java_function,
                                  const AbstractMetaArgument *java_argument,
                                  uint options = 0);
    void writeEnum(QTextStream &s, const AbstractMetaEnum *java_enum);
    void writeIntegerEnum(QTextStream &s, const AbstractMetaEnum *java_enum);
    void writeSignal(QTextStream &s, const AbstractMetaFunction *java_function);
    void writeFunction(QTextStream &s, const AbstractMetaFunction *java_function,
                       uint included_attributes = 0, uint excluded_attributes = 0);
    void writeFieldAccessors(QTextStream &s, const AbstractMetaField *field);
    void write(QTextStream &s, const AbstractMetaClass *java_class);

    void writeFunctionOverloads(QTextStream &s, const AbstractMetaFunction *java_function,
                                uint included_attributes, uint excluded_attributes);
    void writeEnumOverload(QTextStream &s, const AbstractMetaFunction *java_function,
                           uint include_attributes, uint exclude_attributes);
    void writeExtraFunctions(QTextStream &s, const AbstractMetaClass *java_class);
    void writeToStringFunction(QTextStream &s, const AbstractMetaClass *java_class);
    void writeCloneFunction(QTextStream &s, const AbstractMetaClass *java_class);
    void writeFunctionAttributes(QTextStream &s, const AbstractMetaFunction *java_function,
                                 uint included_attributes = 0, uint excluded_attributes = 0,
                                 uint options = 0);
    void writeConstructorContents(QTextStream &s, const AbstractMetaFunction *java_function);
    void writeFunctionArguments(QTextStream &s, const AbstractMetaFunction *java_function,
        int count = -1, uint options = 0);
    void writeJavaCallThroughContents(QTextStream &s, const AbstractMetaFunction *java_function, uint attributes = 0);
    void writeOwnershipForContainer(QTextStream &s, TypeSystem::Ownership ownership, AbstractMetaArgument *arg);
    void writeOwnershipForContainer(QTextStream &s, TypeSystem::Ownership ownership, AbstractMetaType *type,
                                    const QString &arg_name);
    void writePrivateNativeFunction(QTextStream &s, const AbstractMetaFunction *java_function);
    void writeJavaLangObjectOverrideFunctions(QTextStream &s, const AbstractMetaClass *cls);
    void writeReferenceCount(QTextStream &s, const ReferenceCount &refCount, const QString &argumentName);
    void retrieveModifications(const AbstractMetaFunction *f, const AbstractMetaClass *java_class,
         uint *exclude_attributes, uint *include_attributes) const;
    QString functionSignature(const AbstractMetaFunction *java_function,
                              uint included_attributes,
                              uint excluded_attributes,
                              Option option = NoOption,
                              int arg_count = -1);
    void setupForFunction(const AbstractMetaFunction *java_function,
       uint *included_attributes, uint *excluded_attributes) const;

    virtual QString subDirectoryForClass(const AbstractMetaClass *java_class) const
    { return subDirectoryForPackage(java_class->package()); }

    virtual QString fileNameForClass(const AbstractMetaClass *java_class) const;

    bool isComparable(const AbstractMetaClass *cls) const;

#if 0
    void write1_dot_5_enum(QTextStream &s, const AbstractMetaEnum *java_enum);
#endif

    bool shouldGenerate(const AbstractMetaClass *java_class) const {
        return !java_class->typeEntry()->isContainer() && !java_class->typeEntry()->isVariant()
               && (java_class->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang);
    }

    QString documentationDirectory() const { return m_doc_directory; }
    void setDocumentationDirectory(const QString &docDir) { m_doc_directory = docDir; }

    bool documentationEnabled() const { return m_docs_enabled; }
    void setDocumentationEnabled(bool e) { m_docs_enabled = e; }
    void generate();

    inline bool nativeJumpTable() const { return m_native_jump_table; }
    inline void setNativeJumpTable(bool n) { m_native_jump_table = n; }

private:
    QString subDirectoryForPackage(const QString &package) const { return QString(package).replace(".", "/"); }
    void writeInstantiatedType(QTextStream &s, const AbstractMetaType *abstractMetaType) const;

protected:
    QString m_package_name;
    QString m_doc_directory;
    DocParser *m_doc_parser;
    bool m_docs_enabled;
    bool m_native_jump_table;
    QList<const AbstractMetaFunction *> m_nativepointer_functions;
    QList<const AbstractMetaFunction *> m_resettable_object_functions;
    QList<const AbstractMetaFunction *> m_reference_count_candidate_functions;
};

#endif // JAVAGENERATOR_H
