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

import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.IPageImageProvider;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor;
import com.android.ide.eclipse.adt.internal.editors.manifest.descriptors.AndroidManifestDescriptors;
import com.android.ide.eclipse.adt.internal.editors.ui.tree.UiTreeBlock;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;

import java.util.ArrayList;
import java.util.HashSet;


/**
 * Page for overview settings, part of the AndroidManifest form editor.
 * <p/>
 * Useful reference:
 * <a href="http://www.eclipse.org/articles/Article-Forms/article.html">
 *   http://www.eclipse.org/articles/Article-Forms/article.html</a>
 */
public final class OverviewPage extends FormPage implements IPageImageProvider {

    /** Page id used for switching tabs programmatically */
    final static String PAGE_ID = "overview_page"; //$NON-NLS-1$

    /** Container editor */
    ManifestEditor mEditor;
    /** Overview part (attributes for manifest) */
    private OverviewInfoPart mOverviewPart;
    /** Overview link part */
    private OverviewLinksPart mOverviewLinkPart;

    private UiTreeBlock mTreeBlock;

    public OverviewPage(ManifestEditor editor) {
        super(editor, PAGE_ID, "Manifest");  // tab's label, user visible, keep it short
        mEditor = editor;
    }

    @Override
    public Image getPageImage() {
        return IconFactory.getInstance().getIcon("editor_page_design");  //$NON-NLS-1$
    }

    /**
     * Creates the content in the form hosted in this page.
     *
     * @param managedForm the form hosted in this page.
     */
    @Override
    protected void createFormContent(IManagedForm managedForm) {
        super.createFormContent(managedForm);
        ScrolledForm form = managedForm.getForm();
        form.setText("Android Manifest");
        form.setImage(AdtPlugin.getAndroidLogo());

        Composite body = form.getBody();
        FormToolkit toolkit = managedForm.getToolkit();

        // Usually we would set a ColumnLayout on body here. However the presence of the
        // UiTreeBlock forces a GridLayout with one column so we comply with it.

        mOverviewPart = new OverviewInfoPart(body, toolkit, mEditor);
        mOverviewPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
        managedForm.addPart(mOverviewPart);

        newManifestExtrasPart(managedForm);

        OverviewExportPart exportPart = new OverviewExportPart(this, body, toolkit, mEditor);
        exportPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
        managedForm.addPart(exportPart);

        mOverviewLinkPart = new OverviewLinksPart(body, toolkit, mEditor);
        mOverviewLinkPart.getSection().setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
        managedForm.addPart(mOverviewLinkPart);
    }

    private void newManifestExtrasPart(IManagedForm managedForm) {
        UiElementNode manifest = mEditor.getUiRootNode();
        mTreeBlock = new UiTreeBlock(mEditor, manifest,
                true /* autoCreateRoot */,
                computeManifestExtraFilters(),
                "Manifest Extras",
                "Extra manifest elements");
        mTreeBlock.createContent(managedForm);
    }

    /**
     * Changes and refreshes the Application UI node handled by the sub parts.
     */
    public void refreshUiApplicationNode() {
        if (mOverviewPart != null) {
            mOverviewPart.onSdkChanged();
        }

        if (mOverviewLinkPart != null) {
            mOverviewLinkPart.onSdkChanged();
        }

        if (mTreeBlock != null) {
            UiElementNode manifest = mEditor.getUiRootNode();
            mTreeBlock.changeRootAndDescriptors(manifest,
                    computeManifestExtraFilters(),
                    true /* refresh */);
        }
    }

    private ElementDescriptor[] computeManifestExtraFilters() {
        UiElementNode manifest = mEditor.getUiRootNode();
        AndroidManifestDescriptors manifestDescriptor = mEditor.getManifestDescriptors();

        if (manifestDescriptor == null) {
            return null;
        }

        // get the elements we want to exclude
        HashSet<ElementDescriptor> excludes = new HashSet<ElementDescriptor>();
        excludes.add(manifestDescriptor.getApplicationElement());
        excludes.add(manifestDescriptor.getInstrumentationElement());
        excludes.add(manifestDescriptor.getPermissionElement());
        excludes.add(manifestDescriptor.getPermissionGroupElement());
        excludes.add(manifestDescriptor.getPermissionTreeElement());
        excludes.add(manifestDescriptor.getUsesPermissionElement());

        // walk through the known children of the manifest descriptor and keep what's not excluded
        ArrayList<ElementDescriptor> descriptorFilters = new ArrayList<ElementDescriptor>();
        for (ElementDescriptor child : manifest.getDescriptor().getChildren()) {
            if (!excludes.contains(child)) {
                descriptorFilters.add(child);
            }
        }

        if (descriptorFilters.size() == 0) {
            return null;
        }
        return descriptorFilters.toArray(new ElementDescriptor[descriptorFilters.size()]);
    }
}
