/*
 * 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.common;

import com.android.ide.common.resources.ResourceFolder;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.animator.AnimationEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.color.ColorEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.common.CommonXmlDelegate.IDelegateCreator;
import com.android.ide.eclipse.adt.internal.editors.drawable.DrawableEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.menu.MenuEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.otherxml.OtherXmlEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.otherxml.PlainXmlEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.values.ValuesEditorDelegate;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.resources.ResourceFolderType;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.ISourceViewerExtension2;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IShowEditorInput;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.editor.IFormPage;
import org.eclipse.ui.ide.IDE;
import org.w3c.dom.Document;

/**
 * Multi-page form editor for ALL /res XML files.
 * <p/>
 * This editor doesn't actually do anything. Instead, it defers actual implementation
 * to {@link CommonXmlDelegate} instances.
 */
public class CommonXmlEditor extends AndroidXmlEditor implements IShowEditorInput {

    public static final String ID = AdtConstants.EDITORS_NAMESPACE + ".CommonXmlEditor"; //$NON-NLS-1$

    /**
     * Registered {@link CommonXmlDelegate}s.
     * All delegates must have a {@code Creator} class which is instantiated
     * once here statically. All the creators are invoked in the order they
     * are defined and the first one to return a non-null delegate is used.
     */
    private static final IDelegateCreator[] DELEGATES = {
            new LayoutEditorDelegate.Creator(),
            new ValuesEditorDelegate.Creator(),
            new AnimationEditorDelegate.Creator(),
            new ColorEditorDelegate.Creator(),
            new DrawableEditorDelegate.Creator(),
            new MenuEditorDelegate.Creator(),
            new OtherXmlEditorDelegate.Creator(),
    };

    /**
     * IDs of legacy editors replaced by the {@link CommonXmlEditor}.
     */
    public static final String[] LEGACY_EDITOR_IDS = {
        LayoutEditorDelegate.LEGACY_EDITOR_ID,
        ValuesEditorDelegate.LEGACY_EDITOR_ID,
        AnimationEditorDelegate.LEGACY_EDITOR_ID,
        ColorEditorDelegate.LEGACY_EDITOR_ID,
        DrawableEditorDelegate.LEGACY_EDITOR_ID,
        MenuEditorDelegate.LEGACY_EDITOR_ID,
        OtherXmlEditorDelegate.LEGACY_EDITOR_ID,
    };

    private CommonXmlDelegate mDelegate = null;

    /**
     * Creates the form editor for resources XML files.
     */
    public CommonXmlEditor() {
        super();
    }

    @Override
    public void init(IEditorSite site, final IEditorInput editorInput)
            throws PartInitException {
        if (editorInput instanceof IFileEditorInput) {

            IFileEditorInput fileInput = (IFileEditorInput) editorInput;
            IFile file = fileInput.getFile();

            // Adjust the default file editor ID

            IEditorDescriptor file_desc = IDE.getDefaultEditor(file);
            String id = file_desc == null ? null : file_desc.getId();
            boolean mustChange = id != null &&
                                 !id.equals(ID) &&
                                 id.startsWith(AdtConstants.EDITORS_NAMESPACE);
            if (!mustChange) {
                // Maybe this was opened by a manual Open With with a legacy ID?
                id = site.getId();
                mustChange = id != null &&
                             !id.equals(ID) &&
                             id.startsWith(AdtConstants.EDITORS_NAMESPACE);
            }

            if (mustChange) {
                // It starts by our editor namespace but it's not the right ID.
                // This is an old Android XML ID. Change it to our new ID.
                IDE.setDefaultEditor(file, ID);
                AdtPlugin.log(IStatus.INFO,
                        "Changed legacy editor ID %s for %s",   //$NON-NLS-1$
                        id,
                        file.getFullPath());
            }

            // Now find the delegate for the file.

            ResourceFolder resFolder = ResourceManager.getInstance().getResourceFolder(file);
            ResourceFolderType type = resFolder == null ? null : resFolder.getType();

            if (type == null) {
                // We lack any real resource information about that file.
                // Let's take a guess using the actual path.
                String folderName = AdtUtils.getParentFolderName(editorInput);
                type = ResourceFolderType.getFolderType(folderName);
            }

            if (type != null) {
                for (IDelegateCreator creator : DELEGATES) {
                    mDelegate = creator.createForFile(this, type);
                    if (mDelegate != null) {
                        break;
                    }
                }
            }

            if (mDelegate == null) {
                // We didn't find any editor.
                // We'll use the PlainXmlEditorDelegate as a catch-all editor.
                AdtPlugin.log(IStatus.INFO,
                        "No valid Android XML Editor Delegate found for file %1$s [Res %2$s, type %3$s]",
                        file.getFullPath(),
                        resFolder,
                        type);
                mDelegate = new PlainXmlEditorDelegate(this);
            }
        } else if (editorInput instanceof IURIEditorInput) {
            String folderName = AdtUtils.getParentFolderName(editorInput);
            ResourceFolderType type = ResourceFolderType.getFolderType(folderName);
            if (type == ResourceFolderType.LAYOUT) {
                // The layout editor has a lot of hardcoded requirements for real IFiles
                // and IProjects so for now just use a plain XML editor for project-less layout
                // files
                mDelegate = new OtherXmlEditorDelegate(this);
            } else if (type != null) {
                for (IDelegateCreator creator : DELEGATES) {
                    mDelegate = creator.createForFile(this, type);
                    if (mDelegate != null) {
                        break;
                    }
                }
            }

            if (mDelegate == null) {
                // We didn't find any editor.
                // We'll use the PlainXmlEditorDelegate as a catch-all editor.
                AdtPlugin.log(IStatus.INFO,
                        "No valid Android XML Editor Delegate found for file %1$s [Res %2$s, type %3$s]",
                        ((IURIEditorInput) editorInput).getURI().toString(),
                        folderName,
                        type);
                mDelegate = new PlainXmlEditorDelegate(this);
            }
        }

        if (mDelegate == null) {
            // We can't do anything if we don't have a valid file.
            AdtPlugin.log(IStatus.INFO,
                    "Android XML Editor cannot process non-file input %1$s",   //$NON-NLS-1$
                    (editorInput == null ? "null" : editorInput.toString()));   //$NON-NLS-1$
            throw new PartInitException("Android XML Editor cannot process this input.");
        } else {
            // Invoke the editor's init after setting up the delegate. This will call setInput().
            super.init(site, editorInput);
        }
    }

    /**
     * @return The root node of the UI element hierarchy
     */
    @Override
    public UiElementNode getUiRootNode() {
        return mDelegate == null ? null : mDelegate.getUiRootNode();
    }

    public CommonXmlDelegate getDelegate() {
        return mDelegate;
    }

    // ---- Base Class Overrides ----

    @Override
    public void dispose() {
        if (mDelegate != null) {
            mDelegate.dispose();
        }

        super.dispose();
    }

    /**
     * Save the XML.
     * <p/>
     * The actual save operation is done in the super class by committing
     * all data to the XML model and then having the Structured XML Editor
     * save the XML.
     * <p/>
     * Here we just need to tell the delegate that the model has
     * been saved.
     */
    @Override
    public void doSave(IProgressMonitor monitor) {
        super.doSave(monitor);
        if (mDelegate != null) {
            mDelegate.delegateDoSave(monitor);
        }
    }

    /**
     * Returns whether the "save as" operation is supported by this editor.
     * <p/>
     * Save-As is a valid operation for the ManifestEditor since it acts on a
     * single source file.
     *
     * @see IEditorPart
     */
    @Override
    public boolean isSaveAsAllowed() {
        return mDelegate == null ? false : mDelegate.isSaveAsAllowed();
    }

    /**
     * Create the various form pages.
     */
    @Override
    protected void createFormPages() {
        if (mDelegate != null) {
            mDelegate.delegateCreateFormPages();
        }
    }

    @Override
    protected void postCreatePages() {
        super.postCreatePages();

        if (mDelegate != null) {
            mDelegate.delegatePostCreatePages();
        }
    }

    @Override
    protected void addPages() {
        // Create the editor pages.
        // This will also create the EditorPart.
        super.addPages();

        // When the EditorPart is being created, it configures the SourceViewer
        // and will try to use our CommonSourceViewerConfig. Our config needs to
        // know which ContentAssist processor to use (since we have one per resource
        // folder type) but it doesn't have the necessary info to do so.
        // Consequently, once the part is created, we can now unconfigure the source
        // viewer and reconfigure it with the right settings.
        ISourceViewer ssv = getStructuredSourceViewer();
        if (mDelegate != null && ssv instanceof ISourceViewerExtension2) {
            ((ISourceViewerExtension2) ssv).unconfigure();
            ssv.configure(new CommonSourceViewerConfig(
                    mDelegate.getAndroidContentAssistProcessor()));
        }
    }

    /* (non-java doc)
     * Change the tab/title name to include the name of the layout.
     */
    @Override
    protected void setInput(IEditorInput input) {
        super.setInput(input);
        assert mDelegate != null;
        if (mDelegate != null) {
            mDelegate.delegateSetInput(input);
        }
    }

    @Override
    public void setInputWithNotify(IEditorInput input) {
        super.setInputWithNotify(input);
        if (mDelegate instanceof LayoutEditorDelegate) {
            ((LayoutEditorDelegate) mDelegate).delegateSetInputWithNotify(input);
        }
    }

    /**
     * Processes the new XML Model, which XML root node is given.
     *
     * @param xml_doc The XML document, if available, or null if none exists.
     */
    @Override
    protected void xmlModelChanged(Document xml_doc) {
        if (mDelegate != null) {
            mDelegate.delegateXmlModelChanged(xml_doc);
        }
    }

    @Override
    protected Job runLint() {
        if (mDelegate != null && getEditorInput() instanceof IFileEditorInput) {
            return mDelegate.delegateRunLint();
        }
        return null;
    }

    /**
     * Returns the custom IContentOutlinePage or IPropertySheetPage when asked for it.
     */
    @Override
    public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
        if (mDelegate != null) {
            Object value = mDelegate.delegateGetAdapter(adapter);
            if (value != null) {
                return value;
            }
        }

        // return default
        return super.getAdapter(adapter);
    }

    @Override
    protected void pageChange(int newPageIndex) {
        if (mDelegate != null) {
            mDelegate.delegatePageChange(newPageIndex);
        }

        super.pageChange(newPageIndex);

        if (mDelegate != null) {
            mDelegate.delegatePostPageChange(newPageIndex);
        }
    }

    @Override
    protected int getPersistenceCategory() {
        if (mDelegate != null) {
            return mDelegate.delegateGetPersistenceCategory();
        }
        return CATEGORY_OTHER;
    }

    @Override
    public void initUiRootNode(boolean force) {
        if (mDelegate != null) {
            mDelegate.delegateInitUiRootNode(force);
        }
    }

    @Override
    public IFormPage setActivePage(String pageId) {
        IFormPage page = super.setActivePage(pageId);

        if (mDelegate != null) {
            return mDelegate.delegatePostSetActivePage(page, pageId);
        }

        return page;
    }

    /* Implements showEditorInput(...) in IShowEditorInput */
    @Override
    public void showEditorInput(IEditorInput editorInput) {
        if (mDelegate instanceof LayoutEditorDelegate) {
            ((LayoutEditorDelegate) mDelegate).showEditorInput(editorInput);
        }
    }

    @Override
    public boolean supportsFormatOnGuiEdit() {
        if (mDelegate != null) {
            return mDelegate.delegateSupportsFormatOnGuiEdit();
        }
        return super.supportsFormatOnGuiEdit();
    }

    @Override
    public void activated() {
        super.activated();
        if (mDelegate != null) {
            mDelegate.delegateActivated();
        }
    }

    @Override
    public void deactivated() {
        super.deactivated();
        if (mDelegate != null) {
            mDelegate.delegateDeactivated();
        }
    }

    @Override
    public String getPartName() {
        if (mDelegate != null) {
            String name = mDelegate.delegateGetPartName();
            if (name != null) {
                return name;
            }
        }

        return super.getPartName();
    }

    // --------------------
    // Base methods exposed so that XmlEditorDelegate can access them

    @Override
    public void setPartName(String partName) {
        super.setPartName(partName);
    }

    @Override
    public void setPageText(int pageIndex, String text) {
        super.setPageText(pageIndex, text);
    }

    @Override
    public void firePropertyChange(int propertyId) {
        super.firePropertyChange(propertyId);
    }

    @Override
    public int getPageCount() {
        return super.getPageCount();
    }

    @Override
    public int getCurrentPage() {
        return super.getCurrentPage();
    }
}
