/*
 * Copyright (C) 2012 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.layout.properties;

import static com.android.SdkConstants.ANDROID_PKG;
import static com.android.SdkConstants.ANDROID_PREFIX;
import static com.android.SdkConstants.ANDROID_THEME_PREFIX;
import static com.android.SdkConstants.NEW_ID_PREFIX;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.PREFIX_THEME_REF;

import com.android.ide.common.resources.ResourceItem;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.resources.ResourceType;
import com.android.utils.SdkUtils;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.fieldassist.ContentProposal;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Resource value completion for the given property
 * <p>
 * TODO:
 * <ul>
 * <li>also offer other values seen in the app
 * <li>also offer previously set values for this property
 * <li>also complete on properties
 * </ul>
 */
class ResourceValueCompleter implements IContentProposalProvider {
    protected final XmlProperty xmlProperty;

    ResourceValueCompleter(XmlProperty xmlProperty) {
        this.xmlProperty = xmlProperty;
    }

    @Override
    public IContentProposal[] getProposals(String contents, int position) {
        if (contents.startsWith(PREFIX_RESOURCE_REF)) {
            CommonXmlEditor editor = this.xmlProperty.getXmlEditor();
            if (editor != null) {
                String[] matches = computeResourceStringMatches(
                        editor,
                        this.xmlProperty.mDescriptor, contents.substring(0, position));
                List<IContentProposal> proposals = null;
                if (matches != null && matches.length > 0) {
                    proposals = new ArrayList<IContentProposal>(matches.length);
                    for (String match : matches) {
                        proposals.add(new ContentProposal(match));
                    }
                    return proposals.toArray(new IContentProposal[proposals.size()]);
                }
            }
        }

        return new IContentProposal[0];
    }

    /**
     * Similar to {@link UiResourceAttributeNode#computeResourceStringMatches}
     * but computes complete results up front rather than dividing it up into
     * smaller chunks like @{code @android:}, {@code string/}, and {@code ok}.
     */
    static String[] computeResourceStringMatches(AndroidXmlEditor editor,
            AttributeDescriptor attributeDescriptor, String prefix) {
        List<String> results = new ArrayList<String>(200);

        // System matches: only do this if the value already matches at least @a,
        // and doesn't start with something that can't possibly be @android
        if (prefix.startsWith("@a") && //$NON-NLS-1$
                prefix.regionMatches(true /* ignoreCase */, 0, ANDROID_PREFIX, 0,
                        Math.min(prefix.length() - 1, ANDROID_PREFIX.length()))) {
            AndroidTargetData data = editor.getTargetData();
            if (data != null) {
                ResourceRepository repository = data.getFrameworkResources();
                addMatches(repository, prefix, true /* isSystem */, results);
            }
        } else if (prefix.startsWith("?") && //$NON-NLS-1$
                prefix.regionMatches(true /* ignoreCase */, 0, ANDROID_THEME_PREFIX, 0,
                        Math.min(prefix.length() - 1, ANDROID_THEME_PREFIX.length()))) {
            AndroidTargetData data = editor.getTargetData();
            if (data != null) {
                ResourceRepository repository = data.getFrameworkResources();
                addMatches(repository, prefix, true /* isSystem */, results);
            }
        }


        // When completing project resources skip framework resources unless
        // the prefix possibly completes both, such as "@an" which can match
        // both the project resource @animator as well as @android:string
        if (!prefix.startsWith("@and") && !prefix.startsWith("?and")) { //$NON-NLS-1$ //$NON-NLS-2$
            IProject project = editor.getProject();
            if (project != null) {
                // get the resource repository for this project and the system resources.
                ResourceManager manager = ResourceManager.getInstance();
                ResourceRepository repository = manager.getProjectResources(project);
                if (repository != null) {
                    // We have a style name and a repository. Find all resources that match this
                    // type and recreate suggestions out of them.
                    addMatches(repository, prefix, false /* isSystem */, results);
                }

            }
        }

        if (attributeDescriptor != null) {
            UiResourceAttributeNode.sortAttributeChoices(attributeDescriptor, results);
        } else {
            Collections.sort(results);
        }

        return results.toArray(new String[results.size()]);
    }

    private static void addMatches(ResourceRepository repository, String prefix, boolean isSystem,
            List<String> results) {
        int typeStart = isSystem
                ? ANDROID_PREFIX.length() : PREFIX_RESOURCE_REF.length();

        for (ResourceType type : repository.getAvailableResourceTypes()) {
            if (prefix.regionMatches(typeStart, type.getName(), 0,
                    Math.min(type.getName().length(), prefix.length() - typeStart))) {
                StringBuilder sb = new StringBuilder();
                if (prefix.length() == 0 || prefix.startsWith(PREFIX_RESOURCE_REF)) {
                    sb.append(PREFIX_RESOURCE_REF);
                } else {
                    if (type != ResourceType.ATTR) {
                        continue;
                    }
                    sb.append(PREFIX_THEME_REF);
                }

                if (type == ResourceType.ID && prefix.startsWith(NEW_ID_PREFIX)) {
                    sb.append('+');
                }

                if (isSystem) {
                    sb.append(ANDROID_PKG).append(':');
                }

                sb.append(type.getName()).append('/');
                String base = sb.toString();

                int nameStart = typeStart + type.getName().length() + 1; // +1: add "/" divider
                String namePrefix =
                        prefix.length() <= nameStart ? "" : prefix.substring(nameStart);
                for (ResourceItem item : repository.getResourceItemsOfType(type)) {
                    String name = item.getName();
                    if (SdkUtils.startsWithIgnoreCase(name, namePrefix)) {
                        results.add(base + name);
                    }
                }
            }
        }
    }
}
