/*
 * Copyright (c) 2010-2012, 2015 Eike Stepper (Berlin, Germany) and others.
 * 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:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.net4j.util.ui.container;

import org.eclipse.net4j.util.container.FactoryNotFoundException;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.event.INotifier;
import org.eclipse.net4j.util.event.Notifier;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.net4j.util.ui.ValidationContext;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author Eike Stepper
 * @since 3.1
 */
public abstract class ElementWizardComposite extends Composite implements IListener
{
  private static final IElementWizard NO_WIZARD = new ElementWizard()
  {
    @Override
    protected void create(Composite parent)
    {
      // Do nothing
    }
  };

  private String productGroup;

  private String label;

  private List<String> factoryTypes;

  private String defaultFactoryType;

  private List<IElementWizard> wizards;

  private Map<IElementWizard, List<Control>> wizardControls = new HashMap<IElementWizard, List<Control>>();

  private Map<Control, IElementWizard> controlWizards = new HashMap<Control, IElementWizard>();

  private ValidationContext validationContext;

  private boolean firstLayout = true;

  private Notifier notifier = new Notifier();

  public ElementWizardComposite(Composite parent, int style, String productGroup, String label)
  {
    this(parent, style, productGroup, label, null);
  }

  /**
   * @since 3.2
   */
  public ElementWizardComposite(Composite parent, int style, String productGroup, String label,
      ValidationContext validationContext)
  {
    this(parent, style, productGroup, label, validationContext, null);
  }

  /**
   * @since 3.2
   */
  public ElementWizardComposite(Composite parent, int style, String productGroup, String label,
      ValidationContext validationContext, String defaultFactoryType)
  {
    super(parent, style);
    this.productGroup = productGroup;
    this.label = label;
    this.defaultFactoryType = defaultFactoryType;

    setValidationContext(validationContext);
    create();
  }

  public String getProductGroup()
  {
    return productGroup;
  }

  public String getLabel()
  {
    return label;
  }

  public void setValidationContext(ValidationContext validationContext)
  {
    this.validationContext = validationContext;
  }

  /**
   * @since 3.2
   */
  public String getDefaultFactoryType()
  {
    return defaultFactoryType;
  }

  /**
   * Can be overridden by subclasses.
   */
  public String getDefaultDescription(String factoryType)
  {
    return null;
  }

  /**
   * @deprecated Override {@link #getDefaultDescription(String)} instead.
   */
  @Deprecated
  public void setDefaultDescription(String factoryType, String value)
  {
    // Do nothing
  }

  protected void init()
  {
    IManagedContainer container = getContainer();
    factoryTypes = new ArrayList<String>(container.getFactoryTypes(getProductGroup()));
    Collections.sort(factoryTypes);

    wizards = new ArrayList<IElementWizard>();
    wizardControls.put(NO_WIZARD, new ArrayList<Control>());

    for (Iterator<String> it = factoryTypes.iterator(); it.hasNext();)
    {
      String factoryType = it.next();

      try
      {
        IElementWizard wizard = (IElementWizard)container.getElement(ElementWizardFactory.PRODUCT_GROUP,
            getProductGroup() + ":" + factoryType, null);

        wizards.add(wizard);
        wizardControls.put(wizard, new ArrayList<Control>());

        if (wizard instanceof ElementWizard)
        {
          ElementWizard impl = (ElementWizard)wizard;
          impl.addListener(this);
        }
      }
      catch (FactoryNotFoundException ex)
      {
        it.remove();
      }
    }
  }

  /**
   * @since 3.2
   */
  public void notifyEvent(IEvent event)
  {
    notifier.fireEvent(event);
  }

  protected List<String> getFactoryTypes()
  {
    return factoryTypes;
  }

  protected void create()
  {
    init();
    setLayout(new GridLayout(2, false));

    {
      Label label = new Label(this, SWT.NONE);
      label.setText(getLabel());
      label.setLayoutData(UIUtil.createGridData(false, false));

      createFactoryTypeControl();
      harvestControls(NO_WIZARD);
    }

    for (int i = 0; i < wizards.size(); i++)
    {
      String factoryType = factoryTypes.get(i);
      String defaultDescription = getDefaultDescription(factoryType);

      IElementWizard wizard = wizards.get(i);
      wizard.create(this, getContainer(), productGroup, factoryType, defaultDescription, validationContext);
      harvestControls(wizard);
    }

    if (defaultFactoryType != null)
    {
      setFactoryType(defaultFactoryType);
    }
    else if (!factoryTypes.isEmpty())
    {
      setFactoryType(factoryTypes.get(0));
    }
  }

  protected void factoryTypeChanged()
  {
    String newFactoryType = getFactoryType();
    List<Control> controlsToRefresh = new ArrayList<Control>();

    for (int i = 0; i < wizards.size(); i++)
    {
      IElementWizard wizard = wizards.get(i);

      String factoryType = factoryTypes.get(i);
      boolean visible = factoryType.equals(newFactoryType);

      for (Control control : wizardControls.get(wizard))
      {
        control.setVisible(visible);

        if (!visible)
        {
          control.moveBelow(null);
        }

        controlsToRefresh.add(control);
      }
    }

    // layout(controlsToRefresh.toArray(new Control[controlsToRefresh.size()]));
    // layout(getChildren());

    layout();
    notifier.fireEvent();
  }

  @Override
  public void layout()
  {
    if (firstLayout)
    {
      super.layout();
      firstLayout = false;
    }
    else
    {
      super.layout(getChildren());
    }
  }

  protected void harvestControls(IElementWizard wizard)
  {
    for (Control child : getChildren())
    {
      if (!controlWizards.containsKey(child))
      {
        controlWizards.put(child, wizard);
        wizardControls.get(wizard).add(child);
      }
    }
  }

  protected IManagedContainer getContainer()
  {
    return IPluginContainer.INSTANCE;
  }

  /**
   * @since 3.2
   */
  public final INotifier getNotifier()
  {
    return notifier;
  }

  public String getDescription()
  {
    String resultType = getFactoryType();
    for (int i = 0; i < wizards.size(); i++)
    {
      String factoryType = factoryTypes.get(i);
      if (resultType.equals(factoryType))
      {
        return wizards.get(i).getResultDescription();
      }
    }

    return null;
  }

  public abstract String getFactoryType();

  protected abstract void setFactoryType(String factoryType);

  protected abstract void createFactoryTypeControl();

  /**
   * @author Eike Stepper
   */
  public static class WithCombo extends ElementWizardComposite implements SelectionListener
  {
    private Combo combo;

    public WithCombo(Composite parent, int style, String productGroup, String label)
    {
      super(parent, style, productGroup, label);
    }

    /**
     * @since 3.2
     */
    public WithCombo(Composite parent, int style, String productGroup, String label,
        ValidationContext validationContext)
    {
      super(parent, style, productGroup, label, validationContext);
    }

    /**
     * @since 3.2
     */
    public WithCombo(Composite parent, int style, String productGroup, String label,
        ValidationContext validationContext, String defaultFactoryType)
    {
      super(parent, style, productGroup, label, validationContext, defaultFactoryType);
    }

    public void widgetSelected(SelectionEvent e)
    {
      factoryTypeChanged();
    }

    public void widgetDefaultSelected(SelectionEvent e)
    {
    }

    @Override
    public String getFactoryType()
    {
      return combo.getText();
    }

    @Override
    protected void setFactoryType(String factoryType)
    {
      int index = getFactoryTypes().indexOf(factoryType);
      if (index == -1)
      {
        combo.setText(factoryType);
      }
      else
      {
        combo.select(index);
      }

      factoryTypeChanged();
    }

    @Override
    protected void createFactoryTypeControl()
    {
      combo = new Combo(this, SWT.SINGLE);
      for (String factoryType : getFactoryTypes())
      {
        combo.add(factoryType);
      }

      combo.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
      combo.addSelectionListener(this);
    }
  }

  /**
   * @author Eike Stepper
   */
  public static class WithRadios extends ElementWizardComposite implements SelectionListener
  {
    private Composite composite;

    public WithRadios(Composite parent, int style, String productGroup, String label)
    {
      super(parent, style, productGroup, label);
    }

    /**
     * @since 3.2
     */
    public WithRadios(Composite parent, int style, String productGroup, String label,
        ValidationContext validationContext)
    {
      super(parent, style, productGroup, label, validationContext);
    }

    /**
     * @since 3.2
     */
    public WithRadios(Composite parent, int style, String productGroup, String label,
        ValidationContext validationContext, String defaultFactoryType)
    {
      super(parent, style, productGroup, label, validationContext, defaultFactoryType);
    }

    public void widgetSelected(SelectionEvent e)
    {
      factoryTypeChanged();
    }

    public void widgetDefaultSelected(SelectionEvent e)
    {
    }

    @Override
    public String getFactoryType()
    {
      Control[] choices = composite.getChildren();

      for (int i = 0; i < choices.length; i++)
      {
        Button choice = (Button)choices[i];
        if (choice.getSelection())
        {
          return getFactoryTypes().get(i);
        }
      }

      return null;
    }

    @Override
    protected void setFactoryType(String factoryType)
    {
      List<String> factoryTypes = getFactoryTypes();
      Control[] choices = composite.getChildren();

      for (int i = 0; i < factoryTypes.size(); i++)
      {
        Button choice = (Button)choices[i];
        choice.setSelection(factoryTypes.get(i).equals(factoryType));
      }

      factoryTypeChanged();
    }

    @Override
    protected void createFactoryTypeControl()
    {
      composite = new Composite(this, SWT.SINGLE);
      composite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
      composite.setLayout(new FillLayout());
      for (String factoryType : getFactoryTypes())
      {
        Button choice = new Button(composite, SWT.RADIO);
        choice.setText(factoryType);
        choice.addSelectionListener(this);
      }
    }
  }
}
