/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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 com.android.ide.eclipse.adt.internal.editors.animator;

import static com.android.SdkConstants.ANDROID_NS_NAME_PREFIX;
import static com.android.SdkConstants.ANDROID_PKG;

import com.android.annotations.VisibleForTesting;
import com.android.ide.common.api.IAttributeInfo.Format;
import com.android.ide.common.resources.ResourceItem;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist;
import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
import com.android.utils.Pair;

import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.w3c.dom.Node;

import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Content Assist Processor for /res/drawable XML files
 */
@VisibleForTesting
public final class AnimationContentAssist extends AndroidContentAssist {
    private static final String OBJECT_ANIMATOR = "objectAnimator"; //$NON-NLS-1$
    private static final String PROPERTY_NAME = "propertyName";  //$NON-NLS-1$
    private static final String INTERPOLATOR_PROPERTY_NAME = "interpolator"; //$NON-NLS-1$
    private static final String INTERPOLATOR_NAME_SUFFIX = "_interpolator"; //$NON-NLS-1$

    public AnimationContentAssist() {
        super(AndroidTargetData.DESCRIPTOR_ANIMATOR);
    }

    @Override
    protected int getRootDescriptorId() {
        String folderName = AdtUtils.getParentFolderName(mEditor.getEditorInput());
        ResourceFolderType folderType = ResourceFolderType.getFolderType(folderName);
        if (folderType == ResourceFolderType.ANIM) {
            return AndroidTargetData.DESCRIPTOR_ANIM;
        } else {
            return AndroidTargetData.DESCRIPTOR_ANIMATOR;
        }
    }

    @Override
    protected boolean computeAttributeValues(List<ICompletionProposal> proposals, int offset,
            String parentTagName, String attributeName, Node node, String wordPrefix,
            boolean skipEndTag, int replaceLength) {

        // Add value completion for the interpolator and propertyName attributes

        if (attributeName.endsWith(INTERPOLATOR_PROPERTY_NAME)) {
            if (!wordPrefix.startsWith("@android:anim/")) { //$NON-NLS-1$
                // List all framework interpolators with full path first
                AndroidTargetData data = mEditor.getTargetData();
                ResourceRepository repository = data.getFrameworkResources();
                List<String> interpolators = new ArrayList<String>();
                String base = '@' + ANDROID_PKG + ':' + ResourceType.ANIM.getName() + '/';
                for (ResourceItem item : repository.getResourceItemsOfType(ResourceType.ANIM)) {
                    String name = item.getName();
                    if (name.endsWith(INTERPOLATOR_NAME_SUFFIX)) {
                        interpolators.add(base + item.getName());
                    }
                }
                addMatchingProposals(proposals, interpolators.toArray(), offset, node, wordPrefix,
                        (char) 0 /* needTag */, true /* isAttribute */, false /* isNew */,
                        skipEndTag /* skipEndTag */, replaceLength);
            }


            return super.computeAttributeValues(proposals, offset, parentTagName, attributeName,
                    node, wordPrefix, skipEndTag, replaceLength);
        } else if (parentTagName.equals(OBJECT_ANIMATOR)
                && attributeName.endsWith(PROPERTY_NAME)) {

            // Special case: the user is code completing inside
            //    <objectAnimator propertyName="^">
            // In this case, offer ALL attribute names that make sense for animation
            // (e.g. all numeric ones)

            String attributePrefix = wordPrefix;
            if (startsWith(attributePrefix, ANDROID_NS_NAME_PREFIX)) {
                attributePrefix = attributePrefix.substring(ANDROID_NS_NAME_PREFIX.length());
            }

            AndroidTargetData data = mEditor.getTargetData();
            if (data != null) {
                IDescriptorProvider descriptorProvider =
                    data.getDescriptorProvider(AndroidTargetData.DESCRIPTOR_LAYOUT);
                if (descriptorProvider != null) {
                    ElementDescriptor[] rootElementDescriptors =
                        descriptorProvider.getRootElementDescriptors();
                    Map<String, AttributeDescriptor> matches =
                        new HashMap<String, AttributeDescriptor>(180);
                    for (ElementDescriptor elementDesc : rootElementDescriptors) {
                        for (AttributeDescriptor desc : elementDesc.getAttributes()) {
                            if (desc instanceof SeparatorAttributeDescriptor) {
                                continue;
                            }
                            String name = desc.getXmlLocalName();
                            if (startsWith(name, attributePrefix)) {
                                EnumSet<Format> formats = desc.getAttributeInfo().getFormats();
                                if (formats.contains(Format.INTEGER)
                                        || formats.contains(Format.FLOAT)) {
                                    // TODO: Filter out some common properties
                                    // that the user probably isn't trying to
                                    // animate:
                                    // num*, min*, max*, *Index, *Threshold,
                                    // *Duration, *Id, *Limit
                                    matches.put(name, desc);
                                }
                            }
                        }
                    }

                    List<AttributeDescriptor> sorted =
                        new ArrayList<AttributeDescriptor>(matches.size());
                    sorted.addAll(matches.values());
                    Collections.sort(sorted);
                    // Extract just the name+description pairs, since we don't want to
                    // use the full attribute descriptor (which forces the namespace
                    // prefix to be included)
                    List<Pair<String, String>> pairs =
                        new ArrayList<Pair<String, String>>(sorted.size());
                    for (AttributeDescriptor d : sorted) {
                        pairs.add(Pair.of(d.getXmlLocalName(), d.getAttributeInfo().getJavaDoc()));
                    }

                    addMatchingProposals(proposals, pairs.toArray(), offset, node, wordPrefix,
                            (char) 0 /* needTag */, true /* isAttribute */, false /* isNew */,
                            skipEndTag /* skipEndTag */, replaceLength);
                }
            }

            return false;
        } else {
            return super.computeAttributeValues(proposals, offset, parentTagName, attributeName,
                    node, wordPrefix, skipEndTag, replaceLength);
        }
    }
}
