/*******************************************************************************
 * Copyright (c) 2004 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.command.internal.env.ui.widgets;

import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.wst.command.internal.env.context.PersistentResourceContext;
import org.eclipse.wst.command.internal.env.core.data.DataFlowManager;
import org.eclipse.wst.command.internal.env.core.data.DataMappingRegistryImpl;
import org.eclipse.wst.command.internal.env.core.fragment.CommandFragment;
import org.eclipse.wst.command.internal.env.core.fragment.SequenceFragment;
import org.eclipse.wst.command.internal.env.core.fragment.SimpleFragment;
import org.eclipse.wst.command.internal.env.ui.eclipse.EclipseEnvironment;
import org.eclipse.wst.command.internal.env.ui.eclipse.EclipseProgressMonitor;
import org.eclipse.wst.command.internal.env.ui.eclipse.EclipseStatusHandler;
import org.eclipse.wst.command.internal.provisional.env.core.common.Condition;
import org.eclipse.wst.command.internal.provisional.env.core.common.MessageUtils;
import org.osgi.framework.Bundle;


/**
 * This class is used to add dynamic wizards into Eclipse.  When adding
 * a dynamic wizard into eclipse two entries need to be made in the plugin.xml
 * file.  This first entry tells Eclipse that a new wizard should be added
 * and it references this class.  The second entry specifies detailed information
 * that is specific to the wizard to be added.  These two plugin.xml entries
 * are linked together via their id attributes.  For example here is an
 * entry that registers a new wizard with eclipse.  Note the class attribute
 * references this class.
 * <pre>
 *   &lt;extension
 *        point="org.eclipse.ui.newWizards"&gt;
 *     &lt;wizard
 *           name="%PLUGIN_NEW_WIZARD_NAME_WS_CLIENT"
 *           icon="icons/full/ctool16/newclient_webserv_wiz.gif"
 *           category="org.eclipse.jst.ws.ui.new"
 *           class="org.eclipse.wst.command.env.ui.widgets.DynamicWizard"
 *           id="org.eclipse.jst.ws.consumption.ui.wizard.client.clientwizard"&gt;
 *        &lt;description&gt;
 *           %PLUGIN_NEW_WIZARD_DESC_WS_CLIENT
 *        &lt;/description&gt;
 *        &lt;selection
 *              class="org.eclipse.core.resources.IResource"&gt;
 *        &lt;/selection&gt;
 *     &lt;/wizard&gt;
 *   &lt;/extension&gt;
 *
 * </pre>
 * Here is the dynamicWizard entry for this particular wizard.  This id attributes
 * link these two entries together.  The class attribute must specify a class that
 * implements the org.eclipse.wst.command.env.ui.widgets.CommandWidgetBinding interface.  This
 * interface specifies what the UI should look like and the commands the should
 * be executed in the wizard.
 * 
 * <pre>
 *   &lt;extension
 *        point="org.eclipse.wst.command.env.dynamicWizard"&gt;
 *     &lt;dynamicWizard
 *           iconbanner="icons/full/wizban/webservicesclient_wiz.gif"
 *           class="org.eclipse.jst.ws.consumption.ui.widgets.binding.ClientWidgetBinding"
 *           title="%WIZARD_TITLE_WSC"
 *           id="org.eclipse.jst.ws.consumption.ui.wizard.client.clientwizard"&gt;
 *     &lt;/dynamicWizard&gt;
 *   &lt;/extension&gt;
 * </pre>
 *
 */
public class DynamicWizard extends Wizard implements INewWizard, IExecutableExtension
{
  private   String                  iconBannerName_;
  private   Bundle                  bundle_;
  private   SimpleCanFinishRegistry canFinishRegistry_; 
  private   WizardPageManager       pageManager_;
  private   String                  wizardTitle_;
  private   IWizardPage             startPage_ = null;
  
  protected IConfigurationElement   wizardElement_;
  protected IConfigurationElement   originalElement_;
  protected CommandWidgetBinding    commandWidgetBinding_;
  
  public DynamicWizard()
  {
	setNeedsProgressMonitor(true);
  }
  
  /**
   * This method is called when the Dynamic wizard is created by eclipse.
   * We need to find a dynamicWizard extension point that matches the id
   * for this wizard.  Once the extension point is found it will contain
   * a reference to a CommandWidgetBinding class which defines the widgets 
   * and commands for this wizard.
   * 
   * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
   */
  public void setInitializationData( IConfigurationElement config,
			                         String                propertyName,
			                         Object                data )
    throws CoreException
  {
    String wizardId   = config.getAttribute( "id" );
    
    setInitialData( wizardId );
    originalElement_ = config;
  }
  
  /**
   * This method should only be called if the Dynamic Wizard is being
   * launched through some other mechanise other than the Eclipse New Wizard
   * mechanism.
   * 
   * @param binding        the command widget binding for this wizard.
   * @param descriptor     the plugin descriptor where the icon banner is
   *                       located.
   * @param iconBannerPath the icon banner path for this wizard.  The path
   *                       is relative to the plugin specified by the 
   *                       descriptor parameter.
   * @param wizardTitle    the wizard title
   */
  public void setInitialData( CommandWidgetBinding binding,
                              Bundle               bundle,
                              String               iconBannerPath,
                              String               wizardTitle )
  {
    commandWidgetBinding_ = binding;
    bundle_               = bundle;
    iconBannerName_       = iconBannerPath;
    wizardTitle_          = wizardTitle;
  }
  
  /**
   * Sets the initial data based on the dynamic wizard id.
   * 
   * @param wizardId
   */
  public void setInitialData( String wizardId ) throws CoreException
  {
    IExtensionRegistry    registry      = Platform.getExtensionRegistry();
    IExtensionPoint       point         = registry.getExtensionPoint("org.eclipse.wst.command.env.dynamicWizard");
    IExtension[]          extensions    = point.getExtensions();
    int                   wizardIndex   = -1;
    
    for( int index = 0; index < extensions.length; index++) 
    {
      IConfigurationElement[] elements = extensions[index].getConfigurationElements();
      
      if( elements.length == 1 && elements[0].getName().equals( "dynamicWizard") ) 
      {
        String id = elements[0].getAttribute( "id" );
        
        if( id != null && id.equals( wizardId ) )
        {
          wizardElement_ = elements[0];
          wizardIndex   = index;
          break;
        }
      }
    }
    
    if( wizardElement_ != null )
    {
      commandWidgetBinding_ = (CommandWidgetBinding)wizardElement_.createExecutableExtension( "class" );
      bundle_               = Platform.getBundle(extensions[wizardIndex].getNamespace());
      iconBannerName_       = wizardElement_.getAttribute( "iconbanner" );
      wizardTitle_          = wizardElement_.getAttribute( "title" );
    }
    
    if( commandWidgetBinding_ == null )
    {
      MessageUtils msg = new MessageUtils( "org.eclipse.wst.command.env.ui.widgets.environment", this );
      Status status = new Status( Status.ERROR, "id", 0, msg.getMessage( "MSG_ERROR_WIZARD_ID_NOT_FOUND", new String[]{ wizardId}) , null );
      throw new CoreException( status );
    }
  }
    
  /**
   * This method is called by the eclipse framework to initialize the
   * wizard. 
   * 
   * @param workbench the eclipse workbench
   * @param selection the initial selection that the user has made within
   *                  eclipse.
   */
  public void init ( IWorkbench workbench, IStructuredSelection selection )
  {    
    PersistentResourceContext context        = PersistentResourceContext.getInstance();
    EclipseStatusHandler      handler        = new EclipseStatusHandler();
    EclipseProgressMonitor    monitor        = new EclipseProgressMonitor();
    EclipseEnvironment        environment    = new EclipseEnvironment( null, context, monitor, handler );
    
    DataMappingRegistryImpl dataRegistry_   = new DataMappingRegistryImpl();
    SimpleWidgetRegistry    widgetRegistry_ = new SimpleWidgetRegistry();
    
    DataFlowManager    dataManager    = new DataFlowManager( dataRegistry_, environment );
    
    startPage_         = null;
    canFinishRegistry_ = new SimpleCanFinishRegistry(); 
    pageManager_       = new WizardPageManager( widgetRegistry_, 
                                                getWizardPageFactory(), 
				                                this,
				                                dataManager,
				                                environment );  
    
    pageManager_.setRootFragment( getRootFragment( selection, pageManager_ ) );
    
    commandWidgetBinding_.registerWidgetMappings( widgetRegistry_ );
    commandWidgetBinding_.registerDataMappings( dataRegistry_ );
    commandWidgetBinding_.registerCanFinish( canFinishRegistry_ );
        
    // If a page is not complete ensure that canFinish is false.
    Condition canFinish = new Condition()
                          {
                            public boolean evaluate()
                            {
                              IWizardPage currentPage = pageManager_.getCurrentPage();
                              
                              return currentPage != null ? currentPage.isPageComplete() : true;
                            }
                          }; 
    
    canFinishRegistry_.add( canFinish );
    
    // Set that we need a progress monitor.
    setNeedsProgressMonitor( true );
    
    // Ensure that the next/back buttons are enabled.
	setForcePreviousAndNextButtons( true );
    
    // Set the icon banner if specified.
    if( iconBannerName_ != null && iconBannerName_.length() > 0 )
    {
      try
      {
        URL installURL        = bundle_.getEntry("/");
        URL imageURL          = new URL(installURL, iconBannerName_ );
        ImageDescriptor image = ImageDescriptor.createFromURL(imageURL);
        
        if( image != null )
        {
          setDefaultPageImageDescriptor( image );
        }
      }
      catch (MalformedURLException e)
      {
      }
    }
    
    if( wizardTitle_ != null && wizardTitle_.length() > 0 )
    {
      setWindowTitle( wizardTitle_ );
    }
  }
  
  // Subclasses can override this.
  protected WizardPageFactory getWizardPageFactory()
  {
    return new SimplePageFactory();
  }
  
  /**
  * Returns true if all pages are complete.
  * @return True if all pages are complete.
  */
  public boolean canFinish ()
  {
  	int     length = canFinishRegistry_.size();
  	boolean result = true;
  	
    for( int index = 0; index < length; index++ )
    {
      Condition condition = (Condition)canFinishRegistry_.elementAt( index );
    
      result = condition.evaluate();
      
      if( !result ) break;
    }
    
    return result;
  }

  /**
    * Returns the first page for this wizard.
    *
    * @return the first page for this wizard.
  **/
  public IWizardPage getStartingPage()
  {
  	if( startPage_ == null )
  	{
  		startPage_ = pageManager_.getNextPage();
  	}
  	
    return startPage_;
  }

  /**
    * Returns the next page after page and
    * runs the appropriate tasks.
    *
    * @return the next page after page.
  **/
  public IWizardPage getNextPage( IWizardPage page )
  {   
    return pageManager_.getNextPage();
  }
  
  /**
  */
  public boolean performFinish ()
  { 
  	return pageManager_.performFinish();
  }

  /**
   * Undo fragments
  */
  public boolean performCancel ()
  {
  	return pageManager_.performCancel();
  }  
      
  protected CommandFragment getRootFragment( IStructuredSelection selection, WizardPageManager pageManager )
  {
    SequenceFragment root = new SequenceFragment();
    
    root.add( new SimpleFragment( new SelectionCommand( selection ), "" ) );
    root.add( new SimpleFragment( new CurrentPageCommand( pageManager ), "" ) );
    root.add( commandWidgetBinding_.create().create() );
    
    return root;
  }
  
  protected IConfigurationElement getConfigElement()
  {
    return wizardElement_;
  }
}