/*******************************************************************************
 * Copyright (c) 2016 ALL4TEC & CEA LIST.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     ALL4TEC & CEA LIST - initial API and implementation
 ******************************************************************************/
package org.polarsys.esf.core.common.ui.widget.listener;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
import org.polarsys.esf.core.common.ui.CommonUIActivator;
import org.polarsys.esf.core.common.ui.CommonUIActivator.Implementation;

/**
 * Selection listener used to hide / show a composite on action.
 * It can typically be used for an advanced button.
 * 
 * @author $Author: jdumont $
 * @version $Revision: 83 $
 * 
 */
public class ShowHideAdapter
    extends SelectionAdapter {

    /** Default image. */
    public static final Image DEFAULT_SHOW_IMAGE = CommonUIActivator.getPlugin().getImageRegistry()
        .get(Implementation.ICON_ADVANCED_SHOW_KEY);

    /** Default image. */
    public static final Image DEFAULT_HIDE_IMAGE = CommonUIActivator.getPlugin().getImageRegistry()
        .get(Implementation.ICON_ADVANCED_HIDE_KEY);

    /** Default label. */
    public static final String DEFAULT_SHOW_LABEL =
        CommonUIActivator.getMessages().getString("ShowHideAdapter.default.show"); //$NON-NLS-1$

    /** Default label. */
    public static final String DEFAULT_HIDE_LABEL =
        CommonUIActivator.getMessages().getString("ShowHideAdapter.default.hide"); //$NON-NLS-1$

    /** Image for advanced button. */
    private Image mShowAdvancedImage = DEFAULT_SHOW_IMAGE;

    /** Image for advanced button. */
    private Image mHideAdvancedImage = DEFAULT_HIDE_IMAGE;

    /** Label for advanced button. */
    private String mShowAdvancedLabel = DEFAULT_SHOW_LABEL;

    /** Label for advanced button. */
    private String mHideAdvancedLabel = DEFAULT_HIDE_LABEL;

    /** Memorise last status of composite to hide. */
    private boolean mHidden = false;

    /** Composite to hide/show. */
    private Composite mCompositeToToggle = null;

    /** Button click to hide/show composite. */
    private Button mToggleButton = null;

    /** Map of default values associated to controls. */
    private Map<Control, Object> mDefaultControlsValue = null;

    /**
     * Default constructor, with default.
     * 
     * @param pAdvancedComposite Composite for which hide/show ability must be implemented
     * @param pButton Button which trigger a switch
     */
    public ShowHideAdapter(final Button pButton, final Composite pAdvancedComposite) {

        super();

        mCompositeToToggle = pAdvancedComposite;
        mToggleButton = pButton;

        // Initialise map of default control values
        snapshotControlStates();

    }

    /**
     * Refresh (or create) snapshot of control states.
     * 
     * This method is automatically call by constructor.
     * External call should only be used if composite to show/hide have a structure modification.
     */
    public void snapshotControlStates() {
        if (mCompositeToToggle != null) {
            mDefaultControlsValue = new HashMap<Control, Object>();
            rememberDefaultValues(mCompositeToToggle);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void widgetSelected(final SelectionEvent pEvent) {
        // Negate the hidden status
        mHidden = !mHidden;
        switchComposite();
    }

    /**
     * Switch Composite, based on hidden status.
     */
    private void switchComposite() {

        if (mCompositeToToggle != null) {
            // Show / hide composite
            if (mHidden) {
                hideComposite();
            } else {
                showComposite();
            }
        }

    }

    /**
     * Show composite.
     */
    private void showComposite() {
        mCompositeToToggle.setVisible(true);
        mToggleButton.setText(mHideAdvancedLabel);
        mToggleButton.setImage(mHideAdvancedImage);

        resizeButton();
    }

    /**
     * Hide composite.
     */
    private void hideComposite() {
        mCompositeToToggle.setVisible(false);
        mToggleButton.setText(mShowAdvancedLabel);
        mToggleButton.setImage(mShowAdvancedImage);

        restoreDefaultValues(mCompositeToToggle);

        resizeButton();
    }

    /**
     * Resize button.
     */
    private void resizeButton() {
        // Compute the button size as the label length can change
        Point vComputedSize = mToggleButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
        mToggleButton.setSize(vComputedSize);
    }

    /**
     * Construct a map of control / value to be able to restore when main composite is hidden.
     * It is a recursive method.
     * 
     * This method must be recall if composite structure changes.
     * 
     * @param pComposite The parent in which children are search
     */
    private void rememberDefaultValues(final Composite pComposite) {

        // Iterate through all children of this composite
        for (Control vChildrenControl : pComposite.getChildren()) {
            // If this children is itself a composite and have children, explore its children too
            if (vChildrenControl instanceof Composite) {
                Composite vCompositeChildren = (Composite) vChildrenControl;
                if (vCompositeChildren.getChildren().length > 0) {
                    rememberDefaultValues(vCompositeChildren);
                }
            } else {
                // Remember default value for this child
                mDefaultControlsValue.put(vChildrenControl, getDefaultValue(vChildrenControl));
            }
        }

    }

    /**
     * From map constructed before, restore default values for children control of given composite.
     * It is a recursive method.
     * 
     * @param pComposite The parent in which children are search
     */
    private void restoreDefaultValues(final Composite pComposite) {

        // Iterate through all children of this composite
        for (Control vChildrenControl : pComposite.getChildren()) {

            // If this children is itself a composite and have children, explore its children too
            if (vChildrenControl instanceof Composite) {
                Composite vCompositeChildren = (Composite) vChildrenControl;
                if (vCompositeChildren.getChildren().length > 0) {
                    restoreDefaultValues(vCompositeChildren);
                }
            } else {
                // Restore value for this child
                Object vDefaultValue = mDefaultControlsValue.get(vChildrenControl);
                if (vDefaultValue != null) {
                    restoreDefaultValue(vChildrenControl, vDefaultValue);
                }
            }
        }
    }

    /**
     * Restore default value for a specific children control.
     * 
     * No control are done on default value parameter, because map construction is internal.
     * 
     * This method can be override to offer a more specific approach of how value should be restored.
     * 
     * @param pChildrenControl Control for which default value will be restore
     * @param pDefaultValue Default value to restore
     */
    protected void restoreDefaultValue(final Control pChildrenControl, final Object pDefaultValue) {
        if (pChildrenControl instanceof Text) {
            ((Text) pChildrenControl).setText((String) pDefaultValue);
        } else if (pChildrenControl instanceof Button) {
            // For a button, restore selection value. This is a minimal behaviour, not specific. It is because
            // there is no pretty sure solution to define which kind of widget a button is.
            Button vButton = (Button) pChildrenControl;
            vButton.setSelection((Boolean) pDefaultValue);
        }
    }

    /**
     * Find default value for a given control.
     * Mean of "default value" is specific to kind of control. For a check box, it will be the selected status for
     * example.
     * 
     * This method can be override to offer a more specific approach of how value should be read.
     * 
     * @param pChildrenControl Control for which default value is search
     * @return The default value, null if no one found
     */
    protected Object getDefaultValue(final Control pChildrenControl) {
        Object vDefaultValue = null;

        if (pChildrenControl instanceof Text) {
            vDefaultValue = ((Text) pChildrenControl).getText();
        } else if (pChildrenControl instanceof Button) {
            // For a button, get selection value. This is a minimal behaviour, totally not specific. It is because
            // there is no pretty sure solution to define which kind of widget a button is.
            Button vButton = (Button) pChildrenControl;
            vDefaultValue = vButton.getSelection();
        }

        return vDefaultValue;
    }

    /**
     * @return The showAdvancedImage
     */
    public Image getShowAdvancedImage() {
        return mShowAdvancedImage;
    }

    /**
     * @param pShowAdvancedImage The showAdvancedImage to set
     */
    public void setShowAdvancedImage(final Image pShowAdvancedImage) {
        mShowAdvancedImage = pShowAdvancedImage;
    }

    /**
     * @return The hideAdvancedImage
     */
    public Image getHideAdvancedImage() {
        return mHideAdvancedImage;
    }

    /**
     * @param pHideAdvancedImage The hideAdvancedImage to set
     */
    public void setHideAdvancedImage(final Image pHideAdvancedImage) {
        mHideAdvancedImage = pHideAdvancedImage;
    }

    /**
     * @return The hidden
     */
    public boolean isHidden() {
        return mHidden;
    }

    /**
     * Set hidden status, and switch composite if possible.
     * 
     * @param pHidden The hidden to set
     */
    public void setHidden(final boolean pHidden) {
        mHidden = pHidden;
        switchComposite();
    }

    /**
     * @return The compositeToToggle
     */
    public Composite getCompositeToToggle() {
        return mCompositeToToggle;
    }

    /**
     * @param pCompositeToToggle The compositeToToggle to set
     */
    public void setCompositeToToggle(final Composite pCompositeToToggle) {
        mCompositeToToggle = pCompositeToToggle;
    }

    /**
     * @return The toggleButton
     */
    public Button getToggleButton() {
        return mToggleButton;
    }

    /**
     * @param pToggleButton The toggleButton to set
     */
    public void setToggleButton(final Button pToggleButton) {
        mToggleButton = pToggleButton;
    }

    /**
     * @return The showAdvancedLabel
     */
    public String getShowAdvancedLabel() {
        return mShowAdvancedLabel;
    }

    /**
     * @param pShowAdvancedLabel The showAdvancedLabel to set
     */
    public void setShowAdvancedLabel(final String pShowAdvancedLabel) {
        mShowAdvancedLabel = pShowAdvancedLabel;
    }

    /**
     * @return The hideAdvancedLabel
     */
    public String getHideAdvancedLabel() {
        return mHideAdvancedLabel;
    }

    /**
     * @param pHideAdvancedLabel The hideAdvancedLabel to set
     */
    public void setHideAdvancedLabel(final String pHideAdvancedLabel) {
        mHideAdvancedLabel = pHideAdvancedLabel;
    }

    /**
     * @return The defaultControlsValue
     */
    public Map<Control, Object> getDefaultControlsValue() {
        return mDefaultControlsValue;
    }

    /**
     * @param pDefaultControlsValue The defaultControlsValue to set
     */
    public void setDefaultControlsValue(final Map<Control, Object> pDefaultControlsValue) {
        mDefaultControlsValue = pDefaultControlsValue;
    }

}
