package JSci.doclet;

import java.io.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.*;
import com.sun.tools.doclets.standard.*;

public class ClassWriter extends com.sun.tools.doclets.standard.ClassWriter {
        public ClassWriter(String path, String filename, ClassDoc classdoc,
                        ClassDoc prev, ClassDoc next, ClassTree classtree,
                        boolean nopackage) throws IOException, DocletAbortException {
                super(path, filename, classdoc, prev, next, classtree, nopackage);
                methodSubWriter = new JSci.doclet.MethodSubWriter(this, classdoc);
                fieldSubWriter = new JSci.doclet.FieldSubWriter(this, classdoc);
        }

    /**
     * Generate a class page.
     *
     * @param prev the previous class to generated, or null if no previous.
     * @param classdoc the class to generate.
     * @param next the next class to be generated, or null if no next.
     */
    public static void generate(ClassDoc classdoc, ClassDoc prev, 
                             ClassDoc next, ClassTree classtree, 
                             boolean nopackage) throws DocletAbortException {
            ClassWriter clsgen;
            String path = 
               DirectoryManager.getDirectoryPath(classdoc.containingPackage());
            String filename = classdoc.name() + ".html";
            try {
                clsgen = new JSci.doclet.ClassWriter(path, filename, classdoc, 
                                         prev, next, classtree, nopackage);
                clsgen.generateClassFile();
                clsgen.close();
            } catch (IOException exc) {
                Standard.configuration().standardmessage.
                    error("doclet.exception_encountered",
                           exc.toString(), filename);
                throw new DocletAbortException();
            }
    }

    /**
     * Print tag information
     */
    public void generateTagInfo(Doc doc) {
        Tag[] sinces = doc.tags("since");
        Tag[] sees = doc.seeTags();
        Tag[] planetmaths = doc.tags("planetmath");
        Tag[] authors;
        Tag[] versions;
        if (Standard.configuration().showauthor) {
            authors = doc.tags("author");
        } else {
            authors = new Tag[0];
        }
        if (Standard.configuration().showversion) {
            versions = doc.tags("version");
        } else {
            versions = new Tag[0];
        }
        if (Standard.configuration().nosince) {
            sinces = new Tag[0];
        }
        if (sinces.length > 0
            || sees.length > 0
            || planetmaths.length > 0
            || authors.length > 0
            || versions.length > 0 
            || (doc.isClass() && ((ClassDoc)doc).isSerializable())) {
            dl();
            printSinceTag(doc);
            if (versions.length > 0) {
                // There is going to be only one Version tag.
                dt();
                boldText("doclet.Version");
                dd();
                printInlineComment(versions[0]);
                ddEnd();
            }
            if (authors.length > 0) {
                dt();
                boldText("doclet.Author");
                dd();
                for (int i = 0; i < authors.length; ++i) {
                    if (i > 0) {
                        print(", ");
                    } 
                    printInlineComment(authors[i]);
                }
                ddEnd();
            }
            printSeeTags(doc);
            printPlanetMathTags(doc);
            dlEnd();
        }
    }

        /**
        * Print the planetmath tags information given the doc comment.
        */
        public void printPlanetMathTags(Doc doc) {
                Tag[] planetmaths = doc.tags("planetmath");
                for(int i = 0; i < planetmaths.length; i++) {
                        if(i == 0) {
                                dt();
                                bold("PlanetMath references:");
                                dd();
                        } else {
                                println(", ");
                        }
                        printPlanetMathTag(planetmaths[i]);
                }
        }

        public void printPlanetMathTag(Tag planetmath) {
                String cname = planetmath.text();
                String link = "http://planetmath.org/?op=getobj&from=objects&name="+cname;
                String label = cname;
                printHyperLink(link, label);
        }
}

