/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   copyright (C) 2004-2006                                               *
 *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
 ***************************************************************************/

/*  This code generated by:
 *      Author : thomas
 *      Date   : Mon Jun 30 2003
 */

#include "javacodeoperation.h"

#include "javaclassifiercodedocument.h"
#include "javacodedocumentation.h"
#include "javacodegenerator.h"
#include "../uml.h"

// Constructors/Destructors
//

JavaCodeOperation::JavaCodeOperation
 ( JavaClassifierCodeDocument * doc, UMLOperation *parent, const TQString & body, const TQString & comment )
        : CodeOperation (doc, parent, body, comment)
{
    // lets not go with the default comment and instead use
    // full-blown java documentation object instead
    setComment(new JavaCodeDocumentation(doc));

    // these things never change..
    setOverallIndentationLevel(1);

    updateMethodDeclaration();
    updateContent();
}

JavaCodeOperation::~JavaCodeOperation ( ) { }

// Other methods
//

// we basically want to update the doc and start text of this method
void JavaCodeOperation::updateMethodDeclaration()
{

    CodeDocument * doc = getParentDocument();
    JavaClassifierCodeDocument * javadoc = dynamic_cast<JavaClassifierCodeDocument*>(doc);
    UMLOperation * o = getParentOperation();
    bool isInterface = javadoc->getParentClassifier()->isInterface();
    TQString endLine = getNewLineEndingChars();

    // now, the starting text.
    TQString strVis = javadoc->scopeToJavaDecl(o->getVisibility());
    // no return type for constructors
    TQString fixedReturn = JavaCodeGenerator::fixTypeName(o->getTypeName());
    TQString returnType = o->isConstructorOperation() ? TQString("") : (fixedReturn + TQString(" "));
    TQString methodName = o->getName();
    TQString paramStr = TQString("");

    // assemble parameters
    UMLAttributeList list = getParentOperation()->getParmList();
    int nrofParam = list.count();
    int paramNum = 0;
    for(UMLAttribute* parm = list.first(); parm; parm=list.next())
    {
        TQString rType = parm->getTypeName();
        TQString paramName = parm->getName();
        paramStr += rType + ' ' + paramName;
        paramNum++;

        if (paramNum != nrofParam )
            paramStr  += ", ";
    }
    TQString maybeStatic;
    if (o->getStatic())
        maybeStatic = "static ";
    TQString startText = strVis + ' ' + maybeStatic + returnType + methodName + " (" + paramStr + ')';

    // IF the parent is an interface, our operations look different
    // e.g. they have no body
    if(isInterface) {
        startText += ';';
        setEndMethodText("");
    } else {
        startText += " {";
        setEndMethodText("}");
    }

    setStartMethodText(startText);

    // Lastly, for text content generation, we fix the comment on the
    // operation, IF the codeop is autogenerated & currently empty
    TQString comment = o->getDoc();
    if(comment.isEmpty() && getContentType() == CodeBlock::AutoGenerated)
    {
        UMLAttributeList parameters = o->getParmList();
        for(UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) {
            comment += endLine + "@param " + iterator.current()->getName() + ' ';
            comment += iterator.current()->getDoc();
        }
        // add a returns statement too
        if(!returnType.isEmpty())
            comment += endLine + "@return " + returnType + ' ';
        getComment()->setText(comment);
    }


    // In Java, for interfaces..we DON'T write out non-public
    // method declarations.
    if(isInterface)
    {
        UMLOperation * o = getParentOperation();
        if(o->getVisibility() != Uml::Visibility::Public)
            setWriteOutText(false);
    }

}

int JavaCodeOperation::lastEditableLine() {
    ClassifierCodeDocument * doc = dynamic_cast<ClassifierCodeDocument*>(getParentDocument());
    if(doc->parentIsInterface())
        return -1; // very last line is NOT editable as its a one-line declaration w/ no body in
    // an interface.
    return 0;
}

#include "javacodeoperation.moc"
