/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsdl.ui.internal.dialogs;

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

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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 org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.PageBook;
import org.eclipse.wst.wsdl.internal.generator.BaseGenerator;
import org.eclipse.wst.wsdl.internal.generator.ContentGenerator;
import org.eclipse.wst.wsdl.internal.generator.extension.ContentGeneratorExtensionFactoryRegistry;
import org.eclipse.wst.wsdl.ui.internal.Messages;
import org.eclipse.wst.wsdl.ui.internal.wizards.ContentGeneratorOptionsPage;

public abstract class ProtocolComponentControl extends Composite implements SelectionListener, ModifyListener
{
  protected BaseGenerator generator;

  protected Text componentNameField;
  protected Combo refNameCombo;
  protected Button refBrowseButton;
  protected Combo protocolCombo;
  protected Button overwriteButton;
  protected PageBook pageBook;
  protected Composite emptySettingsPage;
  protected Map pageMap = new HashMap();

  // List of ContentGenerators for each Protocol found in protocolCombo
  protected List contentGenerators;
  
  //protected boolean isBindingComponent = true;
  //protected boolean isNewComponent = true;
  protected String name;
  protected String refName;

  protected String UNSPECIFIED = Messages.getString("_UI_UNSPECIFIED"); //$NON-NLS-1$
  //protected BindingGenerator bindingGenerator;

  public ProtocolComponentControl(Composite parent, BaseGenerator generator, boolean showOverwriteButton)
  {
    super(parent, SWT.NONE);
    this.generator = generator;
	contentGenerators = new ArrayList();

    GridLayout layout = new GridLayout();
    layout.marginWidth = 0;
    setLayout(layout);
    setLayoutData(createGridData(true, 1));

    Composite labelValueComposite = new Composite(this, SWT.NONE);
    labelValueComposite.setLayout(new GridLayout(2, false));
    labelValueComposite.setLayoutData(createGridData(false, 1));

    // row 1
    //
    Label componentNameLabel = new Label(labelValueComposite, SWT.NONE);
    componentNameLabel.setText(getComponentNameLabelText()); //$NON-NLS-1$

    componentNameField = new Text(labelValueComposite, SWT.BORDER);
    GridData gdName= new GridData();
    gdName.horizontalAlignment= GridData.FILL;
    gdName.grabExcessHorizontalSpace= true;
    componentNameField.setLayoutData(gdName);
    componentNameField.addModifyListener(this);
    //createPlaceHolder(labelValueComposite);

    // row 2
    //
    Label refNameLabel = new Label(labelValueComposite, SWT.NONE);
    refNameLabel.setText(getRefNameLabelText()); //$NON-NLS-1$	
    refNameCombo = new Combo(labelValueComposite, SWT.READ_ONLY);
    GridData gdRefName= new GridData();
    gdRefName.horizontalAlignment= GridData.FILL;
    gdRefName.grabExcessHorizontalSpace= true;
    refNameCombo.setLayoutData(gdRefName);
    refNameCombo.addSelectionListener(this);

    //refBrowseButton = new Button(labelValueComposite, SWT.NONE);
    //refBrowseButton.setText("  ...  ");
    //GridData gd = new GridData();
    //gd.grabExcessHorizontalSpace = false;
    //gd.heightHint = 17;
    //gd.widthHint = 24;
    //refBrowseButton.setLayoutData(gd);
    //refBrowseButton.addSelectionListener(this);
    //createPlaceHolder(labelValueComposite);

    // row 3
    //
    Label protocolLabel = new Label(labelValueComposite, SWT.NONE);
    protocolLabel.setText(Messages.getString("_UI_LABEL_BINDING_PROTOCOL")); //$NON-NLS-1$
    protocolCombo = new Combo(labelValueComposite, SWT.READ_ONLY);
    GridData gdProtocol= new GridData();
    gdProtocol.horizontalAlignment= GridData.FILL;
    gdProtocol.grabExcessHorizontalSpace= true;
    protocolCombo.setLayoutData(gdProtocol);
    protocolCombo.addSelectionListener(this);
    //createPlaceHolder(labelValueComposite);

    // optional overwrite button
    //
    if (showOverwriteButton)
    {
      overwriteButton = new Button(this, SWT.CHECK);
      overwriteButton.setText(Messages.getString("_UI_CHECKBOX_OVERWRITE")); //$NON-NLS-1$
      overwriteButton.addSelectionListener(this);
    }

    // protocol specific settings
    //
    pageBook = new PageBook(this, SWT.NONE);
    GridData gdFill= new GridData();
    gdFill.horizontalAlignment= GridData.FILL;
    gdFill.grabExcessHorizontalSpace= true;
    gdFill.verticalAlignment= GridData.FILL;
    gdFill.grabExcessVerticalSpace= true;
    pageBook.setLayoutData(gdFill);

    emptySettingsPage = new Composite(pageBook, SWT.NONE);
    for (int i = 0; i < 6; i++)
    {
      new Label(emptySettingsPage, SWT.NONE);
    }
  }

  public void initFields()
  {
    // prime the fields
    //
    componentNameField.setText(getDefaultName());
    updateRefNameCombo();
    updateProtocolCombo();
    updatePageBook(generator.getProtocol());
  }

  public Text getComponentNameField()
  {
    return componentNameField;
  }

  public String getComponentNameLabelText()
  {
    return Messages.getString("_UI_LABEL_NAME"); //$NON-NLS-1$
  }

  private GridData createGridData(boolean both, int span)
  {
    GridData gd = new GridData(both ? GridData.FILL_BOTH : GridData.FILL_HORIZONTAL);
    gd.horizontalSpan = span;
    return gd;
  }

//  private Control createPlaceHolder(Composite parent)
//  {
//    Label label = new Label(parent, SWT.NONE);
//    return label;
//  }
  public BaseGenerator getGenerator()
  {
    return generator;
  }

  // implements SelectionListener
  //
  public void widgetDefaultSelected(SelectionEvent event)
  {
  }

  public void widgetSelected(SelectionEvent event)
  {
    if (event.widget == overwriteButton && overwriteButton != null)
    {
      getGenerator().setOverwrite(overwriteButton.getSelection());
    }
    else if (event.widget == refNameCombo)
    {
      int index = refNameCombo.getSelectionIndex();
      String refName = refNameCombo.getItem(index);
	  if (refName.equals(UNSPECIFIED)) {
	      getGenerator().setRefName(""); //$NON-NLS-1$
	  }
	  else {
	      getGenerator().setRefName(refName);
	  }
    }
    else if (event.widget == protocolCombo)
    {
      int index = protocolCombo.getSelectionIndex();
      String protocol = (index != -1) ? protocolCombo.getItem(index) : null;
	  getGenerator().setContentGenerator((ContentGenerator) contentGenerators.get(index));
      updatePageBook(protocol);
    }
  }

  private static final String IS_OVERWRITE_APPLICABLE = "IS_OVERWRITE_APPLICABLE"; //$NON-NLS-1$
  protected void updatePageBook(String protocol)
  {
    if (protocol != null)
    {
	  ContentGeneratorOptionsPage page = (ContentGeneratorOptionsPage) pageMap.get(protocol);
      if (page == null)
      {
        page = createContentGeneratorOptionsPage(protocol);

        if (page != null)
        {
          page.init(getGenerator());
          Control control = page.createControl(pageBook);
          control.setData(IS_OVERWRITE_APPLICABLE, new Boolean(page.isOverwriteApplicable()));
          pageMap.put(protocol, page);
        }

//        if (page != null)
//        {
//          pageMap.put(protocol, page);
//        }
      }

      boolean enableOverwriteButton = true;
      if (page != null)
      {
        if (overwriteButton != null)
        {
          Boolean data = (Boolean) page.getControl().getData(IS_OVERWRITE_APPLICABLE);
          enableOverwriteButton = data == null || data.equals(Boolean.TRUE);
        }
        pageBook.showPage(page.getControl());
        pageBook.layout();
        pageBook.getParent().layout();
		
		page.setOptionsOnGenerator();
      }
      else
      {
        pageBook.showPage(emptySettingsPage);
      }

      if (overwriteButton != null)
      {
        if (enableOverwriteButton)
        {
          overwriteButton.setEnabled(true);
          overwriteButton.setSelection(generator.getOverwrite());
        }
        else
        {
          overwriteButton.setEnabled(false);
          overwriteButton.setSelection(true);
        }
      }
    }
  }

  protected void updateProtocolCombo()
  {
    protocolCombo.removeAll();

    List list = new ArrayList();
    list.add(UNSPECIFIED);
//    list.addAll(WSDLEditorPlugin.getInstance().getContentGeneratorExtensionRegistry().getBindingExtensionNames());
	list.addAll(ContentGeneratorExtensionFactoryRegistry.getInstance().getBindingExtensionNames());
	
    String protocolText = generator.getProtocol();

    for (Iterator i = list.iterator(); i.hasNext();)
    {
      String protocol = (String) i.next();
      protocolCombo.add(protocol);
	  
	  if (protocol.equals(UNSPECIFIED)) {
		  contentGenerators.add(null);
	  }
	  else {
		  ContentGenerator gen = ContentGeneratorExtensionFactoryRegistry.getInstance().getGeneratorClassFromName(protocol);
		  contentGenerators.add(gen);  
	  }
    }

    if (protocolText == null && protocolCombo.getItemCount() > 0)
    {
      protocolText = protocolCombo.getItem(0);
//      generator.setProtocol(!UNSPECIFIED.equals(protocolText) ? protocolText : null);
    }
    protocolCombo.setText(protocolText);

	ContentGenerator gen = ContentGeneratorExtensionFactoryRegistry.getInstance().getGeneratorClassFromName(protocolText);
	generator.setContentGenerator(gen);
  }

  protected void updateRefNameCombo()
  {
    refNameCombo.removeAll();

    refNameCombo.add(UNSPECIFIED);
    for (Iterator i = getRefNames().iterator(); i.hasNext();)
    {
      refNameCombo.add((String) i.next());
    }

    if (refNameCombo.getItemCount() > 0)
    {
      String refText = generator.getRefName();
      refNameCombo.setText(refText != null ? refText : UNSPECIFIED);
    }
  }

  public void modifyText(ModifyEvent e)
  {
    generator.setName(componentNameField.getText());
  }

  public abstract List getRefNames();
  public abstract String getRefNameLabelText();
  public abstract String getDefaultName();
  public abstract ContentGeneratorOptionsPage createContentGeneratorOptionsPage(String protocol);
}
