/*******************************************************************************
 * Copyright (c) 2018 Obeo
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.editor.properties.sections.description.layoutoption;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.sirius.diagram.description.BooleanLayoutOption;
import org.eclipse.sirius.diagram.description.CustomLayoutConfiguration;
import org.eclipse.sirius.diagram.description.DescriptionPackage;
import org.eclipse.sirius.diagram.description.DoubleLayoutOption;
import org.eclipse.sirius.diagram.description.EnumLayoutOption;
import org.eclipse.sirius.diagram.description.EnumSetLayoutOption;
import org.eclipse.sirius.diagram.description.IntegerLayoutOption;
import org.eclipse.sirius.diagram.description.LayoutOption;
import org.eclipse.sirius.diagram.description.StringLayoutOption;
import org.eclipse.sirius.editor.properties.ViewpointPropertySheetPage;
import org.eclipse.sirius.editor.properties.sections.common.AbstractViewpointPropertySection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

/**
 * A custom property section displaying all layout options for a given {@link CustomLayoutConfiguration}.
 * 
 * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a>
 *
 */
public class LayoutOptionPropertySection extends AbstractViewpointPropertySection {

    /**
     * A list containing all layout option sections.
     */
    private List<AbstractPropertySection> allLayoutOptionSections;

    /**
     * A list containing all composites associated to layout option sections allowing to edit those options.
     */
    private List<Composite> allLayoutOptionComposites;

    /**
     * The widget allowing to add an option override
     */
    private AddOptionOverridePropertySection propertyOverridePropertySection;

    /**
     * The property section of the layout configuration description.
     */
    private AbstractViewpointPropertySection descriptionPropertySection;

    /**
     * THe page composite displaying all {@link CustomLayoutConfiguration} sections.
     */
    private Composite pageComposite;

    /**
     * A map associating a layout option section to its semantic element. Allow to keep section input when we rebuild
     * sections.
     */
    private Map<AbstractPropertySection, LayoutOption> optionSection2SemanticElement;

    @Override
    protected void makeReadonly() {
    }

    @Override
    protected void makeWrittable() {

    }

    @Override
    protected EStructuralFeature getFeature() {
        return DescriptionPackage.eINSTANCE.getCustomLayoutConfiguration_LayoutOptions();
    }

    @Override
    public void createControls(Composite sectionComposite, TabbedPropertySheetPage aTabbedPropertySheetPage) {
        if (aTabbedPropertySheetPage instanceof ViewpointPropertySheetPage)
            super.createControls(sectionComposite, (ViewpointPropertySheetPage) aTabbedPropertySheetPage);
        else
            super.createControls(sectionComposite, aTabbedPropertySheetPage);

        pageComposite = sectionComposite.getParent();

        descriptionPropertySection = new CustomLayoutConfigurationDescriptionPropertySection();
        descriptionPropertySection.createControls(sectionComposite, aTabbedPropertySheetPage);

        propertyOverridePropertySection = new AddOptionOverridePropertySection();
        Composite addOverrideSectionComposite = createSectionComposite(pageComposite, aTabbedPropertySheetPage, propertyOverridePropertySection);
        propertyOverridePropertySection.createControls(addOverrideSectionComposite, aTabbedPropertySheetPage);

        allLayoutOptionSections = new ArrayList<>();
        allLayoutOptionComposites = new ArrayList<>();
        optionSection2SemanticElement = new HashMap<>();
        initializeLayoutOptionSections(propertySheetPage, false, getLayoutOptions());
    }

    /**
     * Initialize all UI Components allowing to edit given layout options.
     * 
     * @param aTabbedPropertySheetPage
     * @param setInput
     *            true if the input must be set again in created {@link AbstractPropertySection}. False otherwise.
     * @param layoutOptions
     *            the layout options from which UI components to edit those must be initialized.
     */
    private void initializeLayoutOptionSections(TabbedPropertySheetPage aTabbedPropertySheetPage, boolean setInput, EList<LayoutOption> layoutOptions) {
        ECollections.sort(layoutOptions, new Comparator<LayoutOption>() {
            @Override
            public int compare(LayoutOption o1, LayoutOption o2) {
                String l1 = o1.getLabel();
                String l2 = o2.getLabel();
                if (l1 == null) {
                    l1 = "";
                }
                if (l2 == null) {
                    l2 = "";
                }
                return l1.compareTo(l2);
            }
        });
        for (LayoutOption layoutOption : layoutOptions) {
            if (layoutOption instanceof StringLayoutOption) {
                StringLayoutOptionValuePropertySectionSpec stringLayoutOptionValuePropertySection = new StringLayoutOptionValuePropertySectionSpec(layoutOption);
                initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, stringLayoutOptionValuePropertySection);
                if (setInput) {
                    stringLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
                }
            } else if (layoutOption instanceof BooleanLayoutOption) {
                BooleanLayoutOptionValuePropertySectionSpec booleanLayoutOptionValuePropertySection = new BooleanLayoutOptionValuePropertySectionSpec(layoutOption);
                initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, booleanLayoutOptionValuePropertySection);
                if (setInput) {
                    booleanLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
                }
            } else if (layoutOption instanceof IntegerLayoutOption) {
                IntegerLayoutOptionValuePropertySectionSpec integerLayoutOptionValuePropertySection = new IntegerLayoutOptionValuePropertySectionSpec(layoutOption);
                initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, integerLayoutOptionValuePropertySection);
                if (setInput) {
                    integerLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
                }
            } else if (layoutOption instanceof DoubleLayoutOption) {
                DoubleLayoutOptionValuePropertySectionSpec doubleLayoutOptionValuePropertySection = new DoubleLayoutOptionValuePropertySectionSpec(layoutOption);
                initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, doubleLayoutOptionValuePropertySection);
                if (setInput) {
                    doubleLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
                }
            } else if (layoutOption instanceof EnumSetLayoutOption) {
                EnumSetLayoutOptionValuePropertySection enumSetLayoutOptionValuePropertySection = new EnumSetLayoutOptionValuePropertySection(layoutOption);
                initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, enumSetLayoutOptionValuePropertySection);
                if (setInput) {
                    enumSetLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
                }
            } else if (layoutOption instanceof EnumLayoutOption) {
                EnumLayoutOptionValuePropertySection enumLayoutOptionValuePropertySection = new EnumLayoutOptionValuePropertySection(layoutOption);
                initLayoutOptionCompositeAndControls(aTabbedPropertySheetPage, layoutOption, enumLayoutOptionValuePropertySection);
                if (setInput) {
                    enumLayoutOptionValuePropertySection.setInput(getPart(), new StructuredSelection(layoutOption));
                }
            }

        }
    }

    /**
     * Initialize the UI components allowing to edit the given layout option.
     * 
     * @param aTabbedPropertySheetPage
     *            the current property sheet page where we display layout options.
     * @param layoutOption
     *            the layout option from which we initialize its UI components.
     * @param layoutOptionValuePropertySection
     *            the {@link AbstractPropertySection} of the layout option containing widgets for edition of the option.
     */
    private void initLayoutOptionCompositeAndControls(TabbedPropertySheetPage aTabbedPropertySheetPage, LayoutOption layoutOption, AbstractPropertySection layoutOptionValuePropertySection) {
        Composite stringOptionSectionComposite = createSectionComposite(pageComposite, aTabbedPropertySheetPage, layoutOptionValuePropertySection);
        allLayoutOptionComposites.add(stringOptionSectionComposite);
        layoutOptionValuePropertySection.createControls(stringOptionSectionComposite, aTabbedPropertySheetPage);
        allLayoutOptionSections.add(layoutOptionValuePropertySection);
        optionSection2SemanticElement.put(layoutOptionValuePropertySection, layoutOption);
        layoutOptionValuePropertySection.refresh();
    }

    /**
     * Returns the layout options associated to the {@link CustomLayoutConfiguration} from which we are showing layout
     * options.
     * 
     * @return the layout options.
     */
    private EList<LayoutOption> getLayoutOptions() {
        CustomLayoutConfiguration layoutConfiguration = (CustomLayoutConfiguration) eObject;
        EList<LayoutOption> layoutOptions = layoutConfiguration.getLayoutOptions();
        return layoutOptions;
    }

    /**
     * Creates the composite showing the layout option.
     * 
     * @param parent
     *            the composite parent where to put the new section composite.
     * @param aTabbedPropertySheetPage
     *            the sheet page from which we retrieve the widget factory.
     * @param propertySection
     *            the property section from which we retrieve information to build its composite container.
     * @return the newly created section composite that will contains layout option widgets.
     */
    private Composite createSectionComposite(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage, AbstractPropertySection propertySection) {
        Composite sectionComposite = aTabbedPropertySheetPage.getWidgetFactory().createComposite(parent, SWT.NO_FOCUS);
        sectionComposite.setLayout(new FillLayout());
        int style = (propertySection.shouldUseExtraSpace()) ? GridData.FILL_BOTH : GridData.FILL_HORIZONTAL;
        GridData data = new GridData(style);
        data.heightHint = propertySection.getMinimumHeight();
        sectionComposite.setLayoutData(data);
        return sectionComposite;
    }

    @Override
    public void dispose() {
        for (AbstractPropertySection propertySection : allLayoutOptionSections) {
            propertySection.dispose();
        }
        for (Composite composite : allLayoutOptionComposites) {
            composite.dispose();
        }
        descriptionPropertySection.dispose();
        propertyOverridePropertySection.dispose();
        optionSection2SemanticElement.clear();
        super.dispose();
    }

    @Override
    public void refresh() {
        List<LayoutOption> layoutOptions = getLayoutOptions();
        if (layoutOptions.size() != allLayoutOptionSections.size()) {

            // A layout option has been added or removed. We dispose all layout options and rebuild those with the new
            // or without the old one.
            for (AbstractPropertySection propertySection : allLayoutOptionSections) {
                propertySection.dispose();
            }
            for (Composite composite : allLayoutOptionComposites) {
                composite.dispose();
            }
            allLayoutOptionSections.clear();
            allLayoutOptionComposites.clear();
            optionSection2SemanticElement.clear();
            initializeLayoutOptionSections(propertySheetPage, true, getLayoutOptions());
            pageComposite.layout();

        }
        for (AbstractPropertySection propertySection : allLayoutOptionSections) {
            propertySection.refresh();
        }

    }

    @Override
    public void setInput(IWorkbenchPart part, ISelection selection) {
        super.setInput(part, selection);
        for (AbstractPropertySection propertySection : allLayoutOptionSections) {
            propertySection.setInput(part, new StructuredSelection(optionSection2SemanticElement.get(propertySection)));
        }
    }

}
