/**
*******************************************************************************
* Copyright (C) 2002-2011, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*/

package com.ibm.icu.dev.tool.docs;

import java.text.BreakIterator;
import java.util.Locale;
import java.util.Map;

import com.sun.javadoc.Doc;
import com.sun.javadoc.Tag;
import com.sun.tools.doclets.internal.toolkit.taglets.Taglet;
import com.sun.tools.doclets.internal.toolkit.taglets.TagletOutput;
import com.sun.tools.doclets.internal.toolkit.taglets.TagletWriter;

public abstract class ICUTaglet implements Taglet {
    protected final String name;
    protected final int mask;

    protected static final int MASK_FIELD = 1;
    protected static final int MASK_CONSTRUCTOR = 2;
    protected static final int MASK_METHOD = 4;
    protected static final int MASK_OVERVIEW = 8;
    protected static final int MASK_PACKAGE = 16;
    protected static final int MASK_TYPE = 32;
    protected static final int MASK_INLINE = 64;

    protected static final int MASK_DEFAULT = 0x003f; // no inline
    protected static final int MASK_DEFAULT_INLINE = 0x007f; // includes inline
    protected static final int MASK_VALID = 0x007f;

    public static void register(Map taglets) {
        ICUInternalTaglet.register(taglets);
        ICUDraftTaglet.register(taglets);
        ICUStableTaglet.register(taglets);
        ICUProvisionalTaglet.register(taglets);
        ICUObsoleteTaglet.register(taglets);
        ICUIgnoreTaglet.register(taglets);
        ICUNewTaglet.register(taglets);
        ICUNoteTaglet.register(taglets);
        ICUEnhancedTaglet.register(taglets);
    }

    protected ICUTaglet(String name, int mask) {
        this.name = name;
        this.mask = mask & MASK_VALID;
    }

    public boolean inField() {
        return (mask & MASK_FIELD) != 0;
    }

    public boolean inConstructor() {
        return (mask & MASK_CONSTRUCTOR) != 0;
    }

    public boolean inMethod() {
        return (mask & MASK_METHOD) != 0;
    }

    public boolean inOverview() {
        return (mask & MASK_OVERVIEW) != 0;
    }

    public boolean inPackage() {
        return (mask & MASK_PACKAGE) != 0;
    }

    public boolean inType() {
        return (mask & MASK_TYPE) != 0;
    }

    public boolean isInlineTag() {
        return (mask & MASK_INLINE) != 0;
    }

    public String getName() {
        return name;
    }

    public String toString(Tag tag) {
        return tag.text();
    }

    public String toString(Tag[] tags) {
      if (!isInlineTag() && tags != null) {
            if (tags.length > 1) {
                String msg = "Should not have more than one ICU tag per element:\n";
                for (int i = 0; i < tags.length; ++i) {
                    msg += "  [" + i + "] " + tags[i] + "\n";
                }
                throw new IllegalStateException(msg);
            } else if (tags.length > 0) {
                return toString(tags[0]);
            }
        }
        return null;
    }

    public TagletOutput getTagletOutput(Tag tag, TagletWriter writer)
        throws IllegalArgumentException {

        TagletOutput out = writer.getTagletOutputInstance();
        out.setOutput(toString(tag));
        return out;
    }

    public TagletOutput getTagletOutput(Doc holder, TagletWriter writer)
        throws IllegalArgumentException {

        TagletOutput out = writer.getTagletOutputInstance();
        Tag[] tags = holder.tags(getName());
        if (tags.length == 0) {
            return null;
        }
        out.setOutput(toString(tags[0]));
        return out;
    }

    protected static final String STATUS = "<dt><b>Status:</b></dt>";

    public static class ICUInternalTaglet extends ICUTaglet {
        private static final String NAME = "internal";

        public static void register(Map taglets) {
            taglets.put(NAME, new ICUInternalTaglet());
        }

        private ICUInternalTaglet() {
            super(NAME, MASK_DEFAULT);
        }

        public String toString(Tag tag) {
            if (tag.text().toLowerCase(Locale.US).indexOf("technology preview") >= 0) {
                return STATUS + "<dd><em>Technology Preview</em>. <font color='red'>" +
                    "This API is still in the early stages of development. Use at your own risk.</font></dd>";
            }
            return STATUS + "<dd><em>Internal</em>. <font color='red'>" +
                "This API is <em>ICU internal only</em>.</font></dd>";
        }
    }

    public static class ICUDraftTaglet extends ICUTaglet {
        private static final String NAME = "draft";

        public static void register(Map taglets) {
            taglets.put(NAME, new ICUDraftTaglet());
        }

        private ICUDraftTaglet() {
            super(NAME, MASK_DEFAULT);
        }

        public String toString(Tag tag) {
            String text = tag.text();
            if (text.length() == 0) {
                System.err.println("Warning: empty draft tag");
            }
            return STATUS + "<dd>Draft " + tag.text() + ".</dd>";
        }
    }

    public static class ICUStableTaglet extends ICUTaglet {
        private static final String NAME = "stable";

        public static void register(Map taglets) {
            taglets.put(NAME, new ICUStableTaglet());
        }

        private ICUStableTaglet() {
            super(NAME, MASK_DEFAULT);
        }

        public String toString(Tag tag) {
            String text = tag.text();
            if (text.length() > 0) {
                return STATUS + "<dd>Stable " + text + ".</dd>";
            } else {
                return STATUS + "<dd>Stable.</dd>";
            }
        }
    }

    public static class ICUProvisionalTaglet extends ICUTaglet {
        private static final String NAME = "provisional";

        public static void register(Map taglets) {
            taglets.remove(NAME); // override standard deprecated taglet
            taglets.put(NAME, new ICUProvisionalTaglet());
        }

        private ICUProvisionalTaglet() {
            super(NAME, MASK_DEFAULT);
        }

        public String toString(Tag tag) {
            return null;
        }
    }

    public static class ICUObsoleteTaglet extends ICUTaglet {
        private static final String NAME = "obsolete";

        public static void register(Map taglets) {
            taglets.put(NAME, new ICUObsoleteTaglet());
        }

        private ICUObsoleteTaglet() {
            super(NAME, MASK_DEFAULT);
        }

        public String toString(Tag tag) {
            BreakIterator bi = BreakIterator.getSentenceInstance(Locale.US);
            String text = tag.text();
            bi.setText(text);
            int first = bi.first();
            int next = bi.next();
            if (text.length() == 0) {
                first = next = 0;
            }
            return STATUS + "<dd><em>Obsolete.</em> <font color='red'>Will be removed in " +
                text.substring(first, next) + "</font>. " + text.substring(next) + "</dd>";

        }
    }

    public static class ICUIgnoreTaglet extends ICUTaglet {
        private static ICUTaglet singleton;

        public static void register(Map taglets) {
            if (singleton == null) {
                singleton = new ICUIgnoreTaglet();
            }
            taglets.put("bug", singleton);
            taglets.put("test", singleton);
            taglets.put("summary", singleton);
        }

        private ICUIgnoreTaglet() {
            super(".ignore", MASK_DEFAULT);
        }

        public String toString(Tag tag) {
            return null;
        }
    }

    private static String ICU_LABEL = "<strong><font color=red>[icu]</font></strong>";

    /**
     * This taglet should be used in the first line of the class description of classes
     * that are enhancements of JDK classes that similar names and APIs.  The text should
     * provide the full package and name of the JDK class.  A period should follow the
     * tag.  This puts an 'icu enhancement' message into the first line of the class docs,
     * where it will also appear in the class summary.
     *
     * <p>Following this tag (and period), ideally in the first paragraph, the '@icu' tag
     * should be used with the text '_label_' to generate the standard boilerplate about
     * how that tag is used in the class docs.  See {@link ICUNewTaglet}.
     *
     * <p>This cumbersome process is necessary because the javadoc code that handles
     * taglets doesn't look at punctuation in the substitution text to determine when to
     * end the first line, it looks in the original javadoc comment.  So we need a tag to
     * identify the related java class, then a period, then another tag.
     */
     public static class ICUEnhancedTaglet extends ICUTaglet {
        private static final String NAME = "icuenhanced";

        public static void register(Map taglets) {
            taglets.put(NAME, new ICUEnhancedTaglet());
        }

        private ICUEnhancedTaglet() {
            super(NAME, MASK_DEFAULT_INLINE);
        }

        public String toString(Tag tag) {
            String text = tag.text().trim();

            boolean isClassDoc = tag.holder().isClass() || tag.holder().isInterface();
            if (isClassDoc && text.length() > 0) {
                StringBuilder sb = new StringBuilder();
                return sb.append("<strong><font color=red>[icu enhancement]</font></strong> ")
                    .append("ICU's replacement for <code>")
                    .append(text)
                    .append("</code>")
                    .toString();
            }
            return "";
        }
    }

    /**
     * This taglet should be used in the first line of any icu-specific members in a class
     * that is an enhancement of a JDK class (see {@link ICUEnhancedTaglet}). It generates
     * the '[icu]' marker followed by the &lt;strong&gt; text, if any.  This does not
     * start or end a paragraph or provide additional leading or trailing punctuation such
     * as spaces or periods.
     *
     * <p>Note: if the text is '_usage_' (without quotes) this spits out a boilerplate
     * message describing the meaning of the '[icu]' tag.  This should be done in the
     * first paragraph of the class docs of any class containing '@icu' tags.
     */
    public static class ICUNewTaglet extends ICUTaglet {
        private static final String NAME = "icu";

        public static void register(Map taglets) {
            taglets.put(NAME, new ICUNewTaglet());
        }

        private ICUNewTaglet() {
            super(NAME, MASK_DEFAULT_INLINE);
        }

        public String toString(Tag tag) {
            String text = tag.text().trim();
            StringBuilder sb = new StringBuilder();
            if ("_usage_".equals(text)) {
                return sb.append(" Methods, fields, and other functionality specific to ICU ")
                    .append("are labeled '" + ICU_LABEL + "'.</p>")
                    .toString();
            }

            sb.append("<strong><font color=red>[icu]</font>");
            if (text.length() > 0) {
                sb.append(" ").append(text);
            }
            sb.append("</strong>");
            return sb.toString();
        }
    }

    /**
     * This taglet should be used in class or member documentation, after the first line,
     * where the behavior of the ICU method or class has notable differences from its JDK
     * counterpart. It starts a new paragraph and generates an '[icu] Note:' header.
     */
    public static class ICUNoteTaglet extends ICUTaglet {
        private static final String NAME = "icunote";

        public static void register(Map taglets) {
            taglets.put(NAME, new ICUNoteTaglet());
        }

        private ICUNoteTaglet() {
            super(NAME, MASK_DEFAULT_INLINE);
        }

        public String toString(Tag tag) {
            return "<p><strong><font color=red>[icu]</font> Note:</strong> ";
        }
    }
}
