/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.netbeans.modules.javascript2.editor.doc;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.swing.ImageIcon;
import org.netbeans.modules.csl.api.CompletionProposal;
import org.netbeans.modules.csl.api.ElementHandle;
import org.netbeans.modules.csl.api.ElementKind;
import org.netbeans.modules.csl.api.HtmlFormatter;
import org.netbeans.modules.csl.api.Modifier;
import org.netbeans.modules.javascript2.editor.JsCompletionItem;
import org.netbeans.modules.javascript2.doc.api.JsDocumentationSupport;
import org.netbeans.modules.javascript2.doc.spi.AnnotationCompletionTag;
import org.netbeans.modules.javascript2.doc.spi.AnnotationCompletionTagProvider;
import org.netbeans.modules.javascript2.doc.spi.JsDocumentationProvider;
import org.netbeans.modules.javascript2.doc.spi.ParameterFormat;
import org.openide.util.ImageUtilities;

/**
 *
 * @author Martin Fousek <marfous@netbeans.org>
 */
public class JsDocumentationCodeCompletion {

    private static final String TAG_PREFIX = "@"; //NOI18N

    public static void complete(JsCompletionItem.CompletionRequest request, List<CompletionProposal> resultList) {
        int originalOffset = request.info.getSnapshot().getOriginalOffset(request.anchor);
        if (request.prefix != null && request.prefix.startsWith(TAG_PREFIX)) {
            completeAnnotation(request, resultList, originalOffset);
        } else {
            CharSequence text = request.info.getSnapshot().getText();
            if (TAG_PREFIX.charAt(0) == text.charAt(request.anchor - 1)) {
                request.prefix = request.prefix == null ? TAG_PREFIX : TAG_PREFIX + request.prefix;
                completeAnnotation(request, resultList, originalOffset - 1);
            }
        }
    }

    private static void completeAnnotation(JsCompletionItem.CompletionRequest request, List<CompletionProposal> resultList, int anchor) {
        JsDocumentationProvider documentationProvider = JsDocumentationSupport.getDocumentationProvider(request.result);

        // XXX - list of annotations could differ per context as in PHP (i.e. for type, method, field, ...)
        int orderingBase = 0;
        for (AnnotationCompletionTagProvider provider : documentationProvider.getAnnotationsProvider()) {
            orderingBase++;
            for (AnnotationCompletionTag tag : provider.getAnnotations()) {
                if (tag.getName().startsWith(request.prefix)) {
                    resultList.add(new JsDocumentationCodeCompletionItem(anchor, tag, provider.getName(), orderingBase));
                }
            }
        }
    }

    public static class JsDocumentationCodeCompletionItem implements CompletionProposal {

        private static final String ANNOTATION_ICON = "org/netbeans/modules/csl/source/resources/icons/annotation.png"; //NOI18N
        private static final ImageIcon IMAGE_ICON = new ImageIcon(ImageUtilities.loadImage(ANNOTATION_ICON));

        private final AnnotationCompletionTag tag;
        private final int anchorOffset;
        private final JsDocumentationElement elem;
        private final String providerName;
        private final int priority;

        public JsDocumentationCodeCompletionItem(int anchorOffset, AnnotationCompletionTag tag, String providerName, int priority) {
            this.tag = tag;
            this.anchorOffset = anchorOffset;
            this.providerName= providerName;
            this.priority = priority;
            elem = new JsDocumentationElement(tag.getName(), tag.getDocumentation());
        }

        @Override
        public int getAnchorOffset() {
            return anchorOffset;
        }

        @Override
        public ElementHandle getElement() {
            return elem;
        }

        @Override
        public String getName() {
            return tag.getName(); //NOI18N
        }

        @Override
        public String getInsertPrefix() {
            return getName();
        }

        @Override
        public String getSortText() {
            return priority + providerName + getName();
        }

        @Override
        public int getSortPrioOverride() {
            return 0;
        }

        @Override
        public String getLhsHtml(HtmlFormatter formatter) {
            formatter.name(getKind(), true);
            formatter.appendText(getName());
            formatter.name(getKind(), false);
            List<ParameterFormat> formats = tag.getParameters();
            if (formats != null) {
                for (ParameterFormat f : formats) {
                    String pre = f.getPre();
                    if (pre != null) {
                        formatter.appendText(pre);
                    }
                    formatter.parameters(true);
                    formatter.appendText(f.getParam());
                    formatter.parameters(false);
                    String post = f.getPost();
                    if (post != null) {
                        formatter.appendText(post);
                    }
                }
            }
            return formatter.getText();
        }

        @Override
        public String getRhsHtml(HtmlFormatter formatter) {
            return providerName;
        }

        @Override
        public ElementKind getKind() {
            return elem.getKind();
        }

        @Override
        public ImageIcon getIcon() {
            return IMAGE_ICON;
        }

        @Override
        public Set<Modifier> getModifiers() {
            return Collections.<Modifier>emptySet();
        }

        @Override
        public boolean isSmart() {
            return false;
        }

        @Override
        public String getCustomInsertTemplate() {
            return tag.getInsertTemplate();
        }
    }

}
