/* gnu.classpath.tools.gjdoc.DocImpl
   Copyright (C) 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

package gnu.classpath.tools.gjdoc;

import com.sun.javadoc.*;
import java.util.*;
import java.text.*;
import java.io.File;
import javax.swing.text.Segment;

/**
 *  Represents the least common denominator of all Javadoc
 *  comment classes.
 */
public abstract class DocImpl implements Doc, TagContainer {

   protected static Tag[] seeTagEmptyArr = new SeeTagImpl[0];
   protected static Tag[] linkTagEmptyArr = new LinkTagImpl[0];
   protected static Tag[] paramTagEmptyArr = new ParamTagImpl[0];
   protected static Tag[] throwsTagEmptyArr = new ThrowsTagImpl[0];
   protected SourcePosition position;
   private String boilerplateComment;

   // Return the text of the comment for this doc item. 
   public String commentText() {

      StringBuffer rc=new StringBuffer();

      Tag[] textTags=(Tag[])tagMap.get("text");
      if (textTags!=null) {
	 for (int i=0; i<textTags.length; ++i) {
	    rc.append(textTags[i].text());
	 }
      }
      return rc.toString();
   }

   // Compares this Object with the specified Object for order. 
   public int compareTo(java.lang.Object o) {
      return Main.getInstance().getCollator().compare(name(), ((Doc)o).name());
   } 

   // Return the first sentence of the comment as tags. 
   public Tag[] firstSentenceTags() {

      Tag[] rc=(Tag[])tagMap.get("first");
      if (rc==null) rc=new Tag[0];
      return rc;
   }

   // Return the full unprocessed text of the comment. 
   public String getRawCommentText() {
      if (rawDocumentation!=null)
	  return rawDocumentation;
      else if (rawDocOffset>=0)
	 return Main.getRootDoc().readRawComment(rawDocOffset);      
      else
	 return null;
   } 

   // Return comment as tags. 
   public Tag[] inlineTags() {

      Tag[] rc=(Tag[])tagMap.get("inline");
      if (rc==null) rc=new Tag[0];
      return rc;
   }

   // Is this Doc item a class. 
   public boolean isClass() {
      return false;
   } 

   // Is this Doc item a constructor? False until overridden. 
   public boolean isConstructor() {
      return false;
   } 

   // Is this Doc item a error class? False until overridden. 
   public boolean isError() {
      return false;
   } 

   // Is this Doc item a exception class? False until overridden. 
   public boolean isException() {
      return false;
   } 

   // Is this Doc item a field? False until overridden. 
   public boolean isField() {
      return false;
   } 

   // return true if this Doc is include in the active set. 
   public boolean isIncluded() {
      return false;
   } 

   // Is this Doc item a interface? False until overridden. 
   public boolean isInterface() {
      return false;
   } 

   // Is this Doc item a simple method (i.e. 
   public boolean isMethod() {
      return false;
   } 

   public boolean isPackage() {
      return false;
   } 

   // Is this Doc item a ordinary class (i.e. 
   public boolean isOrdinaryClass() {
      return false;
   } 

   // Return the see also tags in this Doc item. 
   public SeeTag[] seeTags() {
      return (SeeTag[])getTagArr("see", seeTagEmptyArr);
   }

   protected Tag[] getTagArr(String kindOfTag, Tag[] defaultRc) {
      Tag[] rc=(Tag[])tagMap.get(kindOfTag);
      if (rc==null) rc=defaultRc;
      return rc;
   } 

   // Set the full unprocessed text of the comment. 
   public void setRawCommentText(String rawDocumentation) {
      this.rawDocumentation=rawDocumentation;
   } 

   public void resolveComments() {
      
      if (rawDocumentation!=null && tagMap.isEmpty()) {
         char[] charArray = rawDocumentation.toCharArray();
         int length = rawDocumentation.length();
         int startOffset = 0;
         int endOffset = 0;
         if (charArray[0] == '/' 
             && charArray[1] == '*' 
             && charArray[2] == '*'
             && charArray[length - 2] == '*'
             && charArray[length - 1] == '/') {

            startOffset = 3;
            endOffset = 2;
         }

         this.tagMap=parseCommentTags(charArray,
                                      startOffset,
                                      length - endOffset,
                                      getContextClass(),
                                      getContextMember(),
                                      null,
                                      boilerplateComment);

         if (Main.getInstance().isCacheRawComments()) {
            rawDocOffset=Main.getRootDoc().writeRawComment(rawDocumentation);
            rawDocumentation=null;
         }

	 resolveTags();
      }
      else if (tagMap.isEmpty() && null != boilerplateComment) {
         tagMap.put("all", new Tag[] { new TagImpl("@boilerplate", boilerplateComment,getContextClass(),null) });
         tagMap.put("@boilerplate", new Tag[] { new TagImpl("@boilerplate", boilerplateComment,getContextClass(),null) });
      }
   }

   public static int skipHtmlWhitespace(char[] buffer, int startIndex) {
      while (startIndex < buffer.length) {
	 char c=buffer[startIndex];
         if (!Parser.isWhitespace(c)) {
            break;
         }
         else {
            ++ startIndex;
         }
      }
      return startIndex;
   }
   
   /**
    *  Looks for an end-of-sentence marker in <code>text</code>,
    *  starting at <code>startIndex</code> and stopping at
    *  <code>endIndex</code>. 
    *
    *  @param text  the text to be searched
    *  @param startIndex  index in <code>text</code> at which to start
    *  @param endIndex  index in <code>text</code> at which to stop
    *
    *  @return the index of the character following the end-of-sentence 
    *    marker, <code>endIndex</code> if no end-of-sentence
    *    marker could be found, or -1 if not implemented.
    */
   private static int findEndOfSentence(char[] text, int startIndex,
		   			int endIndex)
   {
      if (Main.getInstance().isUseBreakIterator()) {
         Segment segment = new Segment(text, startIndex, endIndex - startIndex);
         BreakIterator breakIterator = BreakIterator.getSentenceInstance(Main.getInstance().getLocale());
         breakIterator.setText(segment);
         int result = breakIterator.next();
         if (BreakIterator.DONE == result) {
            return endIndex;
         }
         else {
            return result;
         }
      }
      else {
         while (startIndex < endIndex) {
            if (text[startIndex] == '.'
                && (startIndex+1 == endIndex
                    || Character.isWhitespace(text[startIndex+1])
                    || isHTMLBreakTag(text, startIndex+1, endIndex)
                    )) {
               return startIndex;
            }
            
	    startIndex++;
         }
         return endIndex;
      }
   }

   /**
    * Returns true is the text from start to end begins with a 'p' or 'br' tag.
    */
   private static boolean isHTMLBreakTag(char[] text, int start, int end)
   {
      String[] breakTags = {
         "p>", "/p>", "h1>", "h2>", "h3>", "h4>", "h5>", "h6>", "hr>",
         "pre>", "/pre>"
      };

      if (text[start] == '<') {

      outer:
         for (int i=0; i<breakTags.length; ++i) {
            String tag = breakTags[i];
            int len = tag.length();
            if (start + len < end) {
               for (int j=0; j<len; ++j) {
                  char c = tag.charAt(j);
                  if (Character.toLowerCase(text[start + 1 + j]) != c) {
                     continue outer;
                  }
               }
               return true;
            }
         }
      }
      return false;
   }

   //private static final StringBuffer buf=new StringBuffer(32768);
   private static final StringBuffer whitespaceBuf=new StringBuffer();
   private static char[] charBuf = new char[60000];
   private static int bufPos = 0;

   private static void appendToBuf(char c)
   {
      if (bufPos < charBuf.length) {
         charBuf[bufPos++] = c;
      }
      else {
         //
      }
   }

   private static void appendToBuf(StringBuffer s)
   {
      if (bufPos + s.length() <= charBuf.length) {
         s.getChars(0, s.length(), charBuf, bufPos);
         bufPos += s.length();
      }
      else {
         //
      }
   }

   private static void setBufLength(int length)
   {
      bufPos = 0;
   }

   private static String bufToString()
   {
      return new String(charBuf, 0, bufPos);
   }

   private static int bufLength()
   {
      return bufPos;
   }

   public static Map parseCommentTags(char[] comment, int startIndex, int endIndex, 
                                      ClassDocImpl contextClass, MemberDocImpl contextMember,
                                      AbstractTagImpl contextTag, String boilerplateComment) {

      int rawDocStart=skipHtmlWhitespace(comment, startIndex);

      int firstSentenceEnd = 0;

      if (comment.length>rawDocStart) {

	 firstSentenceEnd = findEndOfSentence(comment, rawDocStart, comment.length);
	 
	 if (firstSentenceEnd < 0) {
	    BreakIterator boundary = BreakIterator.getSentenceInstance(Locale.ENGLISH);
	    boundary.setText(new ArrayCharacterIterator(comment, rawDocStart));
	    boundary.first();
	    boundary.next();
	    firstSentenceEnd = boundary.current();
	 }

	 // Always include period at end of sentence if there is one.
	 if (firstSentenceEnd < comment.length
			 && '.' == comment[firstSentenceEnd]) {
	    ++ firstSentenceEnd;
	 }
      }

      final int	STATE_BEGOFLINE		   = 1;
      final int	STATE_TEXT		   = 2;
      final int	STATE_PARAM		   = 3;
      final int	STATE_PARAMVALUE	   = 4;
      final int	STATE_PARAMWRAP		   = 5;
      final int	STATE_INLINEPARAM	   = 6;
      final int	STATE_INLINEPARAMVALUE	   = 7;
      final int	STATE_WHITESPACE	   = 8;
      final int	STATE_INLINEPARAMVALUE_BOL = 9;
      final int	STATE_IPV_WHITESPACE       = 10;

      int state=STATE_BEGOFLINE;
      int prevState=STATE_TEXT;

      setBufLength(0);
      whitespaceBuf.setLength(0);

      String paramName="", paramValue="";

      Map tags=new HashMap();
      tags.put("inline", new LinkedList());
      tags.put("first", new LinkedList());
      tags.put("all", new LinkedList());

      final char EOL=(char)-1;

      for (int i=rawDocStart; i<=endIndex; ++i) {
	 char c=(i<endIndex)?comment[i]:EOL;
	 char peek=(i<endIndex-1)?comment[i+1]:EOL;

	 switch (state){

	 case STATE_BEGOFLINE:
	    if (i==firstSentenceEnd) {
	       AbstractTagImpl newTag = addTag(tags, "text", bufToString(), true, contextClass, contextMember, contextTag, false);
               if (null != newTag) {
                  contextTag = newTag;
               }
	       setBufLength(0);
	    }

	    if (Parser.isWhitespace(c)) {
	       // ignore
	    }
	    else if (c=='*') {
	       // ignore, but go to STATE_TEXT
	       if (peek!='*' && peek!='@' && peek!=EOL) {
		  state=STATE_WHITESPACE;
	       }
	    }
	    else if (c=='@' || (c=='{' && peek=='@') || c==EOL) {
	       if (bufLength()>0) { 
		  addTag(tags, "text", bufToString(), i<firstSentenceEnd, contextClass, contextMember, contextTag, false);
		  setBufLength(0);
	       }
	       if (c=='{') {
		  ++i;
		  state=STATE_INLINEPARAM;
	       }
	       else {
		  state=STATE_PARAM;
	       }
	    }
	    else {
	       state=STATE_TEXT;
	       appendToBuf(whitespaceBuf);
	       whitespaceBuf.setLength(0);
	       appendToBuf(c);
	    }
	    break;

	 case STATE_WHITESPACE:
	    if (i==firstSentenceEnd) {
	       AbstractTagImpl newTag = addTag(tags, "text", bufToString(), true, contextClass, contextMember, contextTag, false);
               if (null != newTag) {
                  contextTag = newTag;
               }
	       setBufLength(0);
	    }

	    if (c=='\n') {
	       whitespaceBuf.append(c);
	       state=STATE_BEGOFLINE;
	    }
	    else if (Parser.isWhitespace(c)) {
	       whitespaceBuf.append(c);
	    }
	    else if (c=='@' || (c=='{' && peek=='@') || c==EOL) {
	       if (bufLength()>0) { 
		  AbstractTagImpl newTag = addTag(tags, "text", bufToString(), i<firstSentenceEnd, contextClass, contextMember, contextTag, false);
                  if (null != newTag) {
                     contextTag = newTag;
                  }
		  setBufLength(0);
	       }
	       if (c=='{') {
		  ++i;
		  state=STATE_INLINEPARAM;
	       }
	       else {
		  state=STATE_PARAM;
	       }
	    }
	    else {
	       appendToBuf(whitespaceBuf);
	       whitespaceBuf.setLength(0);
	       appendToBuf(c);
	       state=STATE_TEXT;
	    }
	    break;

	 case STATE_PARAMWRAP:
	    if (c=='\n') {
	       appendToBuf(c);
	    }
	    else if (Parser.isWhitespace(c)) {
	       // ignore
	    }
	    else if (c=='*') {
	       // ignore, but go to STATE_TEXT
	       /*
	       if (i<endIndex && comment[i+1]!='*' && comment[i+1]!='@') {
		  state=STATE_PARAMVALUE;
	       }
	       */
	    }
	    else if (c=='@' || c==EOL) {
	       paramValue=bufToString();
	       AbstractTagImpl newTag = addTag(tags, paramName, paramValue, i<firstSentenceEnd, contextClass, contextMember, contextTag, false);
               if (null != newTag) {
                  contextTag = newTag;
               }
	       setBufLength(0);
	       if (c=='{') {
		  ++i;
		  state=STATE_INLINEPARAM;
	       }
	       else {
		  state=STATE_PARAM;
	       }
	    }
	    else {
	       state=STATE_PARAMVALUE;
	       appendToBuf(c);
	    }
	    break;

	 case STATE_PARAM:
	    if (!(c==EOL || Parser.isWhitespace(c))) {
	       appendToBuf(c);
	    }
	    else if (c=='\n') {
	       paramName=bufToString();
	       setBufLength(0);
	       state=STATE_PARAMWRAP;
	    }
	    else {
	       paramName=bufToString();
	       setBufLength(0);
	       state=STATE_PARAMVALUE;
	    }
	    break;

	 case STATE_INLINEPARAM:
	    if (c=='}') {
               // tag without value
	       paramName=bufToString();
	       AbstractTagImpl newTag = addTag(tags, paramName, "", i<firstSentenceEnd, contextClass, contextMember, contextTag, true);
               if (null != newTag) {
                  contextTag = newTag;
               }
               state=prevState;
               setBufLength(0);
            }
	    else if (!(c==EOL || Parser.isWhitespace(c))) {
	       appendToBuf(c);
	    }
	    else if (c=='\n') {
	       paramName=bufToString();
	       setBufLength(0);
	       state=STATE_INLINEPARAMVALUE_BOL;
	    }
	    else {
	       paramName=bufToString();
	       setBufLength(0);
	       state=STATE_INLINEPARAMVALUE;
	    }
	    break;

	 case STATE_PARAMVALUE:
	    if (c==EOL) {
	       paramValue=bufToString();
	       AbstractTagImpl newTag = addTag(tags, paramName, paramValue, i<firstSentenceEnd, contextClass, contextMember, contextTag, false);
               if (null != newTag) {
                  contextTag = newTag;
               }
	    }
	    else if (c=='\n') {
	       appendToBuf(c);
	       state=STATE_PARAMWRAP;
	    }
	    else {
	       appendToBuf(c);
	    }
	    break;

	 case STATE_INLINEPARAMVALUE:
	    if (c=='\n') {
	       appendToBuf(c);
	       state=STATE_INLINEPARAMVALUE_BOL;
	    }
	    else if (c==EOL || c=='}') {
	       paramValue=bufToString();
	       AbstractTagImpl newTag = addTag(tags, paramName, paramValue, i<firstSentenceEnd, contextClass, contextMember, contextTag, true);
               if (null != newTag) {
                  contextTag = newTag;
               }
	       state=prevState;
	       setBufLength(0);
	    }
	    else {
	       appendToBuf(c);
	    }
	    break;

	 case STATE_INLINEPARAMVALUE_BOL:
	    if (Parser.isWhitespace(c)) {
	       // ignore
	    }
	    else if (c=='*') {
	       // ignore, but go to STATE_TEXT
	       if (i<endIndex && peek!='*') {
		  state=STATE_IPV_WHITESPACE;
	       }
	    }
	    else if (c==EOL) {
	       if (bufLength()>0) { 
		  AbstractTagImpl newTag = addTag(tags, "text", bufToString(), i<firstSentenceEnd, contextClass, contextMember, contextTag, false);
                  if (null != newTag) {
                     contextTag = newTag;
                  }
	       }
	    }
	    else {
	       state=STATE_INLINEPARAMVALUE;
	       appendToBuf(whitespaceBuf);
	       whitespaceBuf.setLength(0);
	       appendToBuf(c);
	    }
	    break;

	 case STATE_IPV_WHITESPACE:
	    if (c=='\n') {
	       whitespaceBuf.append(c);
	       state=STATE_INLINEPARAMVALUE_BOL;
	    }
	    else if (Parser.isWhitespace(c)) {
	       whitespaceBuf.append(c);
	    }
	    else if (c==EOL) {
	       if (bufLength()>0) { 
		  AbstractTagImpl newTag = addTag(tags, "text", bufToString(), i<firstSentenceEnd, contextClass, contextMember, contextTag, false);
                  if (null != newTag) {
                     contextTag = newTag;
                  }
		  setBufLength(0);
	       }
	    }
	    else {
	       appendToBuf(whitespaceBuf);
	       whitespaceBuf.setLength(0);
	       appendToBuf(c);
	       state=STATE_INLINEPARAMVALUE;
	    }
	    break;

	 case STATE_TEXT:
	    if (i==firstSentenceEnd) {
	       AbstractTagImpl newTag = addTag(tags, "text", bufToString(), true, contextClass, contextMember, contextTag, false);
               if (null != newTag) {
                  contextTag = newTag;
               }
	       setBufLength(0);
	    }

	    if (c==EOL) {
	       paramValue=bufToString();
	       AbstractTagImpl newTag = addTag(tags, "text", paramValue, i<firstSentenceEnd, contextClass, contextMember, contextTag, false);
               if (null != newTag) {
                  contextTag = newTag;
               }
	    }
	    else if (c=='\n') {
	       appendToBuf(c);
	       state=STATE_BEGOFLINE;
	    }
	    else if (c=='{' && peek=='@') {
	       paramValue=bufToString();
	       AbstractTagImpl newTag = addTag(tags, "text", paramValue, i<firstSentenceEnd, contextClass, contextMember, contextTag, false);
               if (null != newTag) {
                  contextTag = newTag;
               }
	       ++i;
               setBufLength(0);
	       state=STATE_INLINEPARAM;
	    }
	    else {
	       appendToBuf(c);
	    }
	    break;

	 default:
	    throw new Error("illegal state "+state);
	 }
      }


      if (null == contextMember && null != boilerplateComment && Main.getInstance().isCopyLicenseText()) {
         addTag(tags, "@boilerplate", boilerplateComment, false, contextClass, null, null, false);
      }

      Map rc=new HashMap();

      for (Iterator it=tags.keySet().iterator(); it.hasNext(); ) {
	 String key=(String)it.next();
	 Tag[] templateArr;
	 List list=(List)tags.get(key);

	 if ("see".equals(key))
	    templateArr=new SeeTag[list.size()];
	 else if ("param".equals(key))
	    templateArr=new ParamTag[list.size()];
	 else if ("serialField".equals(key))
	    templateArr=new SerialFieldTag[list.size()];
	 else if ("throws".equals(key) || "exception".equals(key))
	    templateArr=new ThrowsTag[list.size()];
	 else {
	    templateArr=new Tag[list.size()];
	 }

	 rc.put(key, list.toArray(templateArr));
      }

      return rc;
   }

   private ClassDocImpl getContextClass() {
      if (isClass() || isInterface()) {
	 return (ClassDocImpl)this;
      }
      else if (isField() || isMethod() || isConstructor()) {
	 return (ClassDocImpl)((MemberDocImpl)this).containingClass();
      }
      else {
	 return null;
      }
   }

   private MemberDocImpl getContextMember() {
      if (isField() || isMethod() || isConstructor()) {
	 return (MemberDocImpl)this;
      }
      else {
	 return null;
      }
   }

   protected static AbstractTagImpl addTag(Map tags, String name,
                                           String value, boolean isFirstSentence,
                                           ClassDocImpl contextClass,
                                           MemberDocImpl contextMember,
                                           AbstractTagImpl contextTag,
                                           boolean isInline) {

      AbstractTagImpl tag = null;

      boolean haveValue = (0 != value.trim().length());

      String emptyWarning = "Empty @" + name + " tag.";

      if (name.equals("param")) {
         if (haveValue) {
            tag=new ParamTagImpl(value, contextClass, contextMember);
         }
         else {
            //printWarning(emptyWarning);
         }
      }
      else if (name.equals("see")) {
         if (haveValue) {
            tag=new SeeTagImpl(value, contextClass);
         }
         else {
            //printWarning(emptyWarning);
         }
      }
      else if (name.equals("link") || name.equals("linkplain")) {
         if (haveValue) {
            tag=new LinkTagImpl("@" + name, value, contextClass);
            isInline = true;
         }
         else {
            //printWarning(emptyWarning);
         }
      }
      else if (name.equals("value")) {
         if (haveValue) {
            tag=new ValueTagImpl(value, contextClass);
            isInline = true;
         }
         else {
            //printWarning(emptyWarning);
         }
      }
      else if (name.equals("inheritDoc")) {
         if (haveValue) {
            //printWarning("@inheritDoc tags are not supposed to have any content.");
         }
	 tag=new InheritDocTagImpl(contextClass, contextMember, contextTag);
         isInline = true;
      }
      else if (name.equals("serialField")) {
         if (haveValue) {
            tag=new SerialFieldTagImpl(value, contextClass, contextMember);
         }
         else {
            //printWarning(emptyWarning);
         }
      }
      else if (name.equals("throws") || name.equals("exception")) {
         if (haveValue) {
            tag=new ThrowsTagImpl(value, contextClass, contextMember);
         }
         else {
            //printWarning(emptyWarning);
         }
	 name="throws";
      }
      else if (name.equals("text")) {
	 tag=new TextTagImpl(value);
         isInline = true;
      }
      else {
	 tag=new TagImpl("@"+name, value.trim(), contextClass, contextMember);
         // FIXME: consider taglets
      }

      if (tag != null) {
         if (isInline) {
            ((List)tags.get("inline")).add(tag);
            if (isFirstSentence) {
               if (name.equals("text")) {
                  String txt = ((TextTagImpl)tag).getText();
                  Tag newTag;
                  if (txt.startsWith("<p>")) {
                     newTag = new TextTagImpl(txt.substring(3));
                  }
                  else if (txt.endsWith("</p>")) {
                     newTag = new TextTagImpl(txt.substring(0, txt.length() - 4));
                  }
                  else {
                     newTag = tag;
                  }
                  ((List)tags.get("first")).add(newTag);
               
               }
               else {
                  ((List)tags.get("first")).add(tag);
               }
            }
         }
         else {
            ((List)tags.get("all")).add(tag);
         }

         List l=((List)tags.get(name));
         if (l==null) {
            l=new LinkedList();
            tags.put(name,l);
         }
         l.add(tag);

         return isInline ? tag : contextTag;
      }
      else {
         return null;
      }
   }

   // Return all tags in this Doc item. 
   public Tag[] tags() {
      Tag[] rc=(Tag[])tagMap.get("all");
      if (rc==null) rc=new Tag[0];
      return rc;
   } 

   // Return tags of the specified kind in this Doc item. 
   public Tag[] tags(java.lang.String tagname) {
      Tag[] rc=(Tag[])tagMap.get(tagname);
      if (rc==null) rc=new Tag[0];
      return rc;
   } 

   protected String rawDocumentation;
   protected long rawDocOffset=-1;

   protected Map tagMap = new HashMap();

   public Map getTagMap() { return tagMap; }

   protected void resolveTags() {

      Tag[] tags=tags();
      for (int i=0; i<tags.length; ++i) {
	 ((AbstractTagImpl)tags[i]).resolve();
      }

      Tag[] inlineTags=inlineTags();
      for (int i=0; i<inlineTags.length; ++i) {
	 ((AbstractTagImpl)inlineTags[i]).resolve();
      }
   }

   private static Map classDocToFileMap = new HashMap();

   private static File getFile(ClassDoc classDoc) {
      File result = (File)classDocToFileMap.get(classDoc);
      if (null == result) {
         result = new File(((GjdocPackageDoc)classDoc.containingPackage()).packageDirectory(),
                           classDoc.name() + ".java");
         classDocToFileMap.put(classDoc, result);
      }
      return result;
   }

   public static SourcePosition getPosition(ClassDoc classDoc)
   {
      return new SourcePositionImpl(getFile(classDoc), 0, 0);
   }

   public static SourcePosition getPosition(ClassDoc classDoc, char[] source, int startIndex)
   {
      int column = 0;
      int line = 0;
      for (int i=0; i<startIndex; ++i) {
         if (10 == source[i]) {
            ++ line;
            column = 0;
         }
         else if (13 != source[i]) {
            ++ column;
         }
      }
      while (true) {
         ClassDoc containingClassDoc = classDoc.containingClass();
         if (null != containingClassDoc) {
            classDoc = containingClassDoc;
         }
         else {
            break;
         }
      }

      File file = getFile(classDoc);
      
      return new SourcePositionImpl(file, line + 1, column + 1);
   }

   public SourcePosition position()
   {
      return this.position;
   }

   public DocImpl(SourcePosition position)
   {
      this.position = position;
   }

   public void setPosition(SourcePosition position)
   {
      this.position = position;
   }

   private static TagContainer checkForInheritedDoc(ClassDoc classDoc,
                                                    MemberDocImpl memberDoc,
                                                    AbstractTagImpl tag)
   {
      DocImpl result;

      if (!(classDoc instanceof ClassDocImpl)) {
         result = null;
      }
      else if (null == memberDoc) {
         result = (DocImpl)classDoc;
      }
      else if (memberDoc.isField()) {
         result = (DocImpl)((ClassDocImpl)classDoc).getFieldDoc(memberDoc.name());
      }
      else if (memberDoc.isMethod()) {
         result = (DocImpl)((ClassDocImpl)classDoc).getMethodDoc(memberDoc.name(), 
                                                                 ((MethodDoc)memberDoc).signature());
      }
      else if (memberDoc.isConstructor()) {
         result = (DocImpl)((ClassDocImpl)classDoc).getConstructorDoc(((ConstructorDoc)memberDoc).signature());
      }
      else {
         //assert(false);
         throw new RuntimeException("memberDoc is supposed to be field, method or constructor");
      }

      if (null != result
          && null != memberDoc
          && null != tag) {

         TagContainer tagDoc = null;

         Tag[] tags = result.tags();
         for (int i=0; i<tags.length; ++i) {
            if (tags[i].kind().equals(tag.kind())) {
               if ("@param".equals(tag.kind())) {
                  if (((ParamTagImpl)tags[i]).parameterName().equals(((ParamTagImpl)tag).parameterName())) {
                     tagDoc = (TagContainer)tags[i];
                     break;
                  }
               }
               else if ("@throws".equals(tag.kind())) {
                  if (((ThrowsTagImpl)tags[i]).exceptionName().equals(((ThrowsTagImpl)tag).exceptionName())) {
                     tagDoc = (TagContainer)tags[i];
                     break;
                  }
               }
               else if ("@return".equals(tag.kind())) {
                  tagDoc = (TagContainer)tags[i];
               }
            }
         }

         return tagDoc;
      }

      if (null == result || result.isEmptyDoc()) {
         return null;
      }
      else {
         return result;
      }
   }

   public static TagContainer findInheritedDoc(ClassDoc classDoc, 
                                               MemberDocImpl memberDoc, 
                                               AbstractTagImpl tag)
   {
      TagContainer result;

      // (Taken from Javadoc Solaris Tool documentation 1.5,
      // section "Automatic Copying of Method Comments")

      // Algorithm for Inheriting Method Comments - If a method does
      // not have a doc comment, or has an {@inheritDoc} tag, the
      // Javadoc tool searches for an applicable comment using the
      // following algorithm, which is designed to find the most
      // specific applicable doc comment, giving preference to
      // interfaces over superclasses:

      // 1. Look in each directly implemented (or extended) interface
      // in the order they appear following the word implements (or
      // extends) in the method declaration. Use the first doc comment
      // found for this method.
      
      ClassDoc[] interfaces = classDoc.interfaces();
      if (null != interfaces) {
         for (int i=0; i<interfaces.length; ++i) {
            result = checkForInheritedDoc(interfaces[i], memberDoc, tag);
            if (null != result) {
               return result;
            }
         }
      }

      // 2. If step 1 failed to find a doc comment, recursively apply
      // this entire algorithm to each directly implemented (or
      // extended) interface, in the same order they were examined
      // in step 1.

      if (null != interfaces) {
         for (int i=0; i<interfaces.length; ++i) {
            result = findInheritedDoc(interfaces[i], memberDoc, tag);
            if (null != result) {
               return result;
            }
         }
      }

      ClassDoc superclassDoc = classDoc.superclass();

      // 3. If step 2 failed to find a doc comment and this is a class
      // other than Object (not an interface):
      if (!classDoc.isInterface() 
          && null != superclassDoc
          && !"java.lang.Object".equals(classDoc.qualifiedTypeName())) {

         // 3a. If the superclass has a doc comment for this method, use it.

         result = checkForInheritedDoc(superclassDoc, memberDoc, tag);
         if (null != result) {
            return result;
         }

         // 3b. If step 3a failed to find a doc comment, recursively
         // apply this entire algorithm to the superclass.

         return findInheritedDoc(superclassDoc,
                                 memberDoc, tag);
      }
      else {
         return null;
      }
   }
   
   public boolean isEmptyDoc()
   {
      return tagMap.isEmpty();
   }

   void setBoilerplateComment(String boilerplateComment)
   {
      this.boilerplateComment = boilerplateComment;
   }
}

