/*
 * Copyright (C) 2008 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.ui;

import com.android.ide.common.resources.ResourceItem;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.layout.properties.PropertyFactory;
import com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringRefactoring;
import com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringWizard;
import com.android.resources.ResourceType;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.dialogs.SelectionStatusDialog;

import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A dialog to let the user choose a reference to a resource.
 *
 */
public class ReferenceChooserDialog extends SelectionStatusDialog {

    private static Pattern sResourcePattern = Pattern.compile("@(.*)/(.+)"); //$NON-NLS-1$
    private static Pattern sInlineIdResourcePattern = Pattern.compile("@\\+id/(.+)"); //$NON-NLS-1$

    private static IDialogSettings sDialogSettings = new DialogSettings("");

    private ResourceRepository mProjectResources;
    private String mCurrentResource;
    private FilteredTree mFilteredTree;
    private Button mNewResButton;
    private final IProject mProject;
    private TreeViewer mTreeViewer;
    private ResourcePreviewHelper mPreviewHelper;

    /**
     * @param project
     * @param parent
     */
    public ReferenceChooserDialog(IProject project, ResourceRepository projectResources,
            Shell parent) {
        super(parent);
        mProject = project;
        mProjectResources = projectResources;

        int shellStyle = getShellStyle();
        setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);

        setTitle("Reference Chooser");
        setMessage(String.format("Choose a resource"));

        setDialogBoundsSettings(sDialogSettings, getDialogBoundsStrategy());
    }

    public void setPreviewHelper(ResourcePreviewHelper previewHelper) {
        mPreviewHelper = previewHelper;
    }

    public void setCurrentResource(String resource) {
        mCurrentResource = resource;
    }

    public String getCurrentResource() {
        return mCurrentResource;
    }


    /* (non-Javadoc)
     * @see org.eclipse.ui.dialogs.SelectionStatusDialog#computeResult()
     */
    @Override
    protected void computeResult() {
        // get the selection
        TreePath treeSelection = getSelection();
        if (treeSelection != null) {
            if (treeSelection.getSegmentCount() == 2) {
                // get the resource type and the resource item
                ResourceType resourceType = (ResourceType)treeSelection.getFirstSegment();
                ResourceItem resourceItem = (ResourceItem)treeSelection.getLastSegment();

                mCurrentResource = resourceItem.getXmlString(resourceType, false /* system */);
            }
        }
    }

    @Override
    protected Control createDialogArea(Composite parent) {
        Composite top = (Composite)super.createDialogArea(parent);

        // create the standard message area
        createMessageArea(top);

        // create the filtered tree
        createFilteredTree(top);

        // setup the initial selection
        if (mCurrentResource != null) {
            setupInitialSelection();
        }

        // create the "New Resource" button
        createNewResButtons(top);

        Composite workaround = PropertyFactory.addWorkaround(top);
        if (workaround != null) {
            workaround.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
        }

        return top;
    }

    /**
     * Creates the "New Resource" button.
     * @param top the parent composite
     */
    private void createNewResButtons(Composite top) {
        mNewResButton = new Button(top, SWT.NONE);
        mNewResButton.addSelectionListener(new OnNewResButtonSelected());
        updateNewResButton();
    }

    private void createFilteredTree(Composite parent) {
        mFilteredTree = new FilteredTree(parent, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION,
                new PatternFilter());

        GridData data = new GridData();
        data.widthHint = convertWidthInCharsToPixels(60);
        data.heightHint = convertHeightInCharsToPixels(18);
        data.grabExcessVerticalSpace = true;
        data.grabExcessHorizontalSpace = true;
        data.horizontalAlignment = GridData.FILL;
        data.verticalAlignment = GridData.FILL;
        mFilteredTree.setLayoutData(data);
        mFilteredTree.setFont(parent.getFont());

        mTreeViewer = mFilteredTree.getViewer();
        Tree tree = mTreeViewer.getTree();

        tree.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
                handleDoubleClick();
            }

            @Override
            public void widgetSelected(SelectionEvent e) {
                handleSelection();
            }
        });

        mTreeViewer.setLabelProvider(new ResourceLabelProvider());
        mTreeViewer.setContentProvider(new ResourceContentProvider(false /* fullLevels */));
        mTreeViewer.setInput(mProjectResources);
    }

    protected void handleSelection() {
        validateCurrentSelection();
        updateNewResButton();

        if (mPreviewHelper != null) {
            TreePath treeSelection = getSelection();
            ResourceType type = null;
            if (treeSelection != null && treeSelection.getSegmentCount() == 2) {
                Object segment = treeSelection.getSegment(0);
                if (segment instanceof ResourceType) {
                    type = (ResourceType) segment;
                    // Ensure that mCurrentResource is valid
                    computeResult();
                }
            }

            mPreviewHelper.updatePreview(type, mCurrentResource);
        }
    }

    protected void handleDoubleClick() {
        if (validateCurrentSelection()) {
            buttonPressed(IDialogConstants.OK_ID);
        }
    }

    /**
     * Returns the selected item in the tree as a {@link TreePath} object.
     * @return the <code>TreePath</code> object or <code>null</code> if there was no selection.
     */
    private TreePath getSelection() {
        ISelection selection = mFilteredTree.getViewer().getSelection();
        if (selection instanceof TreeSelection) {
            TreeSelection treeSelection = (TreeSelection)selection;
            TreePath[] treePaths = treeSelection.getPaths();

            // the selection mode is SWT.SINGLE, so we just get the first one.
            if (treePaths.length > 0) {
                return treePaths[0];
            }
        }

        return null;
    }

    private boolean validateCurrentSelection() {
        TreePath treeSelection = getSelection();

        IStatus status;
        if (treeSelection != null) {
            if (treeSelection.getSegmentCount() == 2) {
                status = new Status(IStatus.OK, AdtPlugin.PLUGIN_ID,
                        IStatus.OK, "", //$NON-NLS-1$
                        null);
            } else {
                status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                        IStatus.ERROR, "You must select a Resource Item",
                        null);
            }
        } else {
            status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    IStatus.ERROR, "", //$NON-NLS-1$
                    null);
        }

        updateStatus(status);

        return status.isOK();
    }

    /**
     * Updates the new res button when the list selection changes.
     * The name of the button changes depending on the resource.
     */
    private void updateNewResButton() {
        ResourceType type = getSelectedResourceType();

        // We only support adding new strings right now
        mNewResButton.setEnabled(type == ResourceType.STRING);

        String title = String.format("New %1$s...",
                type == null ? "Resource" : type.getDisplayName());
        mNewResButton.setText(title);
        mNewResButton.pack();
    }

    /**
     * Callback invoked when the mNewResButton is selected by the user.
     */
    private class OnNewResButtonSelected extends SelectionAdapter {
        @Override
         public void widgetSelected(SelectionEvent e) {
             super.widgetSelected(e);

             ResourceType type = getSelectedResourceType();

             // We currently only support strings
             if (type == ResourceType.STRING) {

                 ExtractStringRefactoring ref = new ExtractStringRefactoring(
                         mProject, true /*enforceNew*/);
                 RefactoringWizard wizard = new ExtractStringWizard(ref, mProject);
                 RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
                 try {
                     IWorkbench w = PlatformUI.getWorkbench();
                     if (op.run(w.getDisplay().getActiveShell(), wizard.getDefaultPageTitle()) ==
                             IDialogConstants.OK_ID) {
                         mTreeViewer.refresh();

                         // select it if possible
                         setupInitialSelection(type, ref.getXmlStringId());
                     }
                 } catch (InterruptedException ex) {
                     // Interrupted. Pass.
                 }
             }
         }
     }

    /**
     * Returns the {@link ResourceType} of the selected element, if any.
     * Returns null if nothing suitable is selected.
     */
    private ResourceType getSelectedResourceType() {
        ResourceType type = null;

        TreePath selection = getSelection();
        if (selection != null && selection.getSegmentCount() > 0) {
            Object first = selection.getFirstSegment();
            if (first instanceof ResourceType) {
                type = (ResourceType) first;
            }
        }
        return type;
    }

    /**
     * Sets up the initial selection.
     * <p/>
     * This parses {@link #mCurrentResource} to find out the resource type and the resource name.
     */
    private void setupInitialSelection() {
        // checks the inline id pattern first as it's more restrictive than the other one.
        Matcher m = sInlineIdResourcePattern.matcher(mCurrentResource);
        if (m.matches()) {
            // get the matching name
            String resourceName = m.group(1);

            // setup initial selection
            setupInitialSelection(ResourceType.ID, resourceName);
        } else {
            // attempts the inline id pattern
            m = sResourcePattern.matcher(mCurrentResource);
            if (m.matches()) {
                // get the resource type.
                ResourceType resourceType = ResourceType.getEnum(m.group(1));
                if (resourceType != null) {
                    // get the matching name
                    String resourceName = m.group(2);

                    // setup initial selection
                    setupInitialSelection(resourceType, resourceName);
                }
            }
        }
    }

    /**
     * Sets up the initial selection based on a {@link ResourceType} and a resource name.
     * @param resourceType the resource type.
     * @param resourceName the resource name.
     */
    private void setupInitialSelection(ResourceType resourceType, String resourceName) {
        // get all the resources of this type
        Collection<ResourceItem> resourceItems =
                mProjectResources.getResourceItemsOfType(resourceType);

        for (ResourceItem resourceItem : resourceItems) {
            if (resourceName.equals(resourceItem.getName())) {
                // name of the resource match, we select it,
                TreePath treePath = new TreePath(new Object[] { resourceType, resourceItem });
                mFilteredTree.getViewer().setSelection(
                        new TreeSelection(treePath),
                        true /*reveal*/);

                // and we're done.
                return;
            }
        }

        // if we get here, the resource type is valid, but the resource is missing.
        // we select and expand the resource type element.
        TreePath treePath = new TreePath(new Object[] { resourceType });
        mFilteredTree.getViewer().setSelection(
                new TreeSelection(treePath),
                true /*reveal*/);
        mFilteredTree.getViewer().setExpandedState(resourceType, true /* expanded */);
    }
}
