/***************************************************************************
 *                                                                         *
 *   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-2007                                               *
 *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
 ***************************************************************************/

/*  This code generated by:
 *      Author : thomas
 *      Date   : Tue Jun 24 2003
 */

// own header
#include "javaantcodedocument.h"

// qt/kde includes
#include <tqregexp.h>
#include <kdebug.h>

// local includes
#include "javacodegenerator.h"
#include "xmlcodecomment.h"
#include "xmlelementcodeblock.h"
#include "codegenfactory.h"
#include "../umldoc.h"
#include "../uml.h"


// Constructors/Destructors
//

JavaANTCodeDocument::JavaANTCodeDocument ( )
{
    setFileName("build"); // default name
    setFileExtension(".xml");
    setID("ANTDOC"); // default id tag for this type of document
}

JavaANTCodeDocument::~JavaANTCodeDocument ( ) { }

//
// Methods
//

// Other methods
//

/**
 * create a new CodeBlockWithComments object belonging to this CodeDocument.
 * @return      CodeBlockWithComments
 */
/*
CodeBlockWithComments * JavaANTCodeDocument::newCodeBlockWithComments ( ) {
        return new XMLElementCodeBlock(this,"empty");
}
*/

HierarchicalCodeBlock * JavaANTCodeDocument::newHierarchicalCodeBlock ( ) {
    return new XMLElementCodeBlock(this,"empty");
}

// Sigh. NOT optimal. The only reason that we need to have this
// is so we can create the XMLNodes, if needed.
// would be better if we could create a handler interface that each
// codeblock used so all we have to do here is add the handler
void JavaANTCodeDocument::loadChildTextBlocksFromNode ( TQDomElement & root)
{

    TQDomNode tnode = root.firstChild();
    TQDomElement telement = tnode.toElement();
    bool loadCheckForChildrenOK = false;
    while( !telement.isNull() ) {
        TQString nodeName = telement.tagName();

        if( nodeName == "textblocks" ) {

            TQDomNode node = telement.firstChild();
            TQDomElement element = node.toElement();

            // if there is nothing to begin with, then we don't worry about it
            loadCheckForChildrenOK = element.isNull() ? true : false;

            while( !element.isNull() ) {
                TQString name = element.tagName();

                if( name == "codecomment" ) {
                    CodeComment * block = new XMLCodeComment(this);
                    block->loadFromXMI(element);
                    if(!addTextBlock(block))
                    {
                        kError()<<"Unable to add codeComment to :"<<this<<endl;
                        block->deleteLater();
                    } else
                        loadCheckForChildrenOK= true;
                } else
                    if( name == "codeaccessormethod" ||
                            name == "ccfdeclarationcodeblock"
                      ) {
                        TQString acctag = element.attribute("tag","");
                        // search for our method in the
                        TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
                        if(!tb || !addTextBlock(tb))
                        {
                            kError()<<"Unable to add codeclassfield child method to:"<<this<<endl;
                            // DON'T delete
                        } else
                            loadCheckForChildrenOK= true;

                    } else
                        if( name == "codeblock" ) {
                            CodeBlock * block = newCodeBlock();
                            block->loadFromXMI(element);
                            if(!addTextBlock(block))
                            {
                                kError()<<"Unable to add codeBlock to :"<<this<<endl;
                                block->deleteLater();
                            } else
                                loadCheckForChildrenOK= true;
                        } else
                            if( name == "codeblockwithcomments" ) {
                                CodeBlockWithComments * block = newCodeBlockWithComments();
                                block->loadFromXMI(element);
                                if(!addTextBlock(block))
                                {
                                    kError()<<"Unable to add codeBlockwithcomments to:"<<this<<endl;
                                    block->deleteLater();
                                } else
                                    loadCheckForChildrenOK= true;
                            } else
                                if( name == "header" ) {
                                    // do nothing.. this is treated elsewhere
                                } else
                                    if( name == "hierarchicalcodeblock" ) {
                                        HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
                                        block->loadFromXMI(element);
                                        if(!addTextBlock(block))
                                        {
                                            kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
                                            block->deleteLater();
                                        } else
                                            loadCheckForChildrenOK= true;
                                    } else
                                        if( name == "codeoperation" ) {
                                            // find the code operation by id
                                            TQString id = element.attribute("parent_id","-1");
                                            UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
                                            UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
                                            if(op) {
                                                CodeOperation * block = 0;
                                                kError() << "TODO: implement CodeGenFactory::newCodeOperation() for JavaANTCodeDocument" << endl;
                                                break;  // remove when above is implemented
                                                block->loadFromXMI(element);
                                                if(addTextBlock(block))
                                                    loadCheckForChildrenOK= true;
                                                else
                                                {
                                                    kError()<<"Unable to add codeoperation to:"<<this<<endl;
                                                    block->deleteLater();
                                                }
                                            } else
                                                kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
                                        } else
                                            if( name == "xmlelementblock" ) {
                                                TQString xmltag = element.attribute("nodeName","UNKNOWN");
                                                XMLElementCodeBlock * block = new XMLElementCodeBlock(this,xmltag);
                                                block->loadFromXMI(element);
                                                if(!addTextBlock(block))
                                                {
                                                    kError()<<"Unable to add XMLelement to Java ANT document:"<<this<<endl;
                                                    block->deleteLater();
                                                } else
                                                    loadCheckForChildrenOK= true;
                                            }
                /*
                                                // only needed for extreme debugging conditions (E.g. making new codeclassdocument loader)
                                                else
                                                        kDebug()<<" LoadFromXMI: Got strange tag in text block stack:"<<name<<", ignorning"<<endl;
                */

                node = element.nextSibling();
                element = node.toElement();
            }
            break;
        }

        tnode = telement.nextSibling();
        telement = tnode.toElement();
    }

    if(!loadCheckForChildrenOK)
    {
        CodeDocument * test = dynamic_cast<CodeDocument*>(this);
        if(test)
        {
            kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
        } else {
            HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
            if(hb)
                kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
            else
                kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
        }
    }

}

/** set the class attributes of this object from
 * the passed element node.
 */
void JavaANTCodeDocument::setAttributesFromNode ( TQDomElement & root)
{

    // superclass save
    CodeDocument::setAttributesFromNode(root);

    // now set local attributes
    // setPackage(root.attribute("package",""));

}

/**
 * load params from the appropriate XMI element node.
 */
void JavaANTCodeDocument::loadFromXMI ( TQDomElement & root ) {
    setAttributesFromNode(root);
}

/** set attributes of the node that represents this class
 * in the XMI document.
 */
void JavaANTCodeDocument::setAttributesOnNode ( TQDomDocument & doc, TQDomElement & docElement)
{

    // superclass call
    CodeDocument::setAttributesOnNode(doc,docElement);

    // now set local attributes/fields
    //FIX
}

/**
 * Save the XMI representation of this object
 */
void JavaANTCodeDocument::saveToXMI ( TQDomDocument & doc, TQDomElement & root ) {
    TQDomElement docElement = doc.createElement( "codedocument" );

    setAttributesOnNode(doc, docElement);

    root.appendChild( docElement );
}

// we add in our code blocks that describe how to generate
// the project here...
void JavaANTCodeDocument::updateContent( ) {
    // FIX : fill in more content based on classes
    // which exist
    CodeBlockWithComments * xmlDecl = getCodeBlockWithComments("xmlDecl","",0);
    xmlDecl->setText("<?xml version=\"1.0\"?>");
    addTextBlock(xmlDecl);

    XMLElementCodeBlock * rootNode = new XMLElementCodeBlock(this, "project", "Java ANT build document");
    rootNode->setTag("projectDecl");
    addTextBlock(rootNode);

    // <project name="XDF" default="help" basedir=".">
    //HierarchicalCodeBlock * projDecl = xmlDecl->getHierarchicalCodeBlock("projectDecl", "Java ANT build document", 1);

    // set some global properties for the build
    /*
      <!-- set global properties for this build -->
      <!-- paths -->
      <property name="docApi.dir"  value="docs/api"/>
      <property name="path" value="gov/nasa/gsfc/adc/xdf"/>
      <property name="src" value="src/${path}/"/>
      <property name="top" value="."/>
      <property name="build" value="${top}/gov"/>
      <property name="buildDir" value="${path}"/>
      <!-- compiler directives -->
      <property name="build.compiler" value="modern"/>
      <property name="useDeprecation" value="no"/>
      <property name="jarname" value="${project}.jar"/>
    */

}

// We overwritten by Java language implementation to get lowercase path
TQString JavaANTCodeDocument::getPath ( )
{

    TQString path = getPackage();

    // Replace all white spaces with blanks
    path.simplifyWhiteSpace();

    // Replace all blanks with underscore
    path.replace(TQRegExp(" "), "_");

    path.replace(TQRegExp("\\."),"/");
    path.replace(TQRegExp("::"), "/");

    path.lower();

    return path;

}


#include "javaantcodedocument.moc"
