/*******************************************************************************
 * Copyright (c) 2004, 2007 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
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060223   129232 pmoogk@ca.ibm.com - Peter Moogk
 * 20060313   130958 pmoogk@ca.ibm.com - Peter Moogk
 * 20070319   175721 pmoogk@ca.ibm.com - Peter Moogk
 * 20070328   173345 pmoogk@ca.ibm.com - Peter Moogk, Peek next page problem
 *******************************************************************************/
package org.eclipse.wst.command.internal.env.ui.widgets;

import java.util.Hashtable;
import java.util.Stack;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.wst.command.internal.env.core.data.DataFlowManager;
import org.eclipse.wst.command.internal.env.core.fragment.CommandFragment;
import org.eclipse.wst.command.internal.env.eclipse.EclipseEnvironment;
import org.eclipse.wst.command.internal.env.ui.registry.WidgetRegistry;
import org.eclipse.wst.common.environment.ILog;



public class WizardPageManager extends SimpleCommandEngineManager
{
  private   WizardPageFactory      pageFactory_;
  private   Hashtable              pageTable_;
  private   IWizard                wizard_;
  protected SimpleWidgetRegistry   registry_;
  
  // These variables are used and set by our methods which is
  // why they are not initialized in the constructor.
  private PageWizardDataEvents currentPage_;
  private PageWizardDataEvents nextPage_;
  private PageWizardDataEvents nextPeekPage_;
  private PageWizardDataEvents firstPage_;
  private CommandFragment      lastUndoFragment_;
  private boolean              firstFragment_;
  
  private INamedWidgetContributorFactory widgetFactory_;
  private Stack                          widgetStack_;
  private Stack                          widgetStackStack_;
  private Hashtable                      widgetTable_;
  private WidgetRegistry                 widgetRegistry_;
  private Hashtable                      widgetFactoryTable_;
    
  public WizardPageManager( SimpleWidgetRegistry  registry,
                            WizardPageFactory     pageFactory,
                            IWizard               wizard,
                            DataFlowManager       dataManager,
                            EclipseEnvironment    environment )
  { 
    super( environment, dataManager );  
    
  	pageFactory_        = pageFactory;
  	pageTable_          = new Hashtable();  
  	registry_           = registry;
  	wizard_             = wizard;
	  widgetTable_        = new Hashtable();
	  widgetFactoryTable_ = new Hashtable();
	  widgetRegistry_     = WidgetRegistry.instance();
	  widgetStackStack_   = new Stack();
  }
  
  public  IWizardPage getStartingPage()
  {
    if( firstPage_ == null )
    {
      firstPage_ = (PageWizardDataEvents)getNextPage();
    }
    
    return firstPage_;
  }
  
  public IStatus runForwardToNextStop()
  {    
  	firstFragment_  = true;
  	nextPage_       = null;
 
  	IWizardContainer container = wizard_.getContainer();
  	
  	if( container == null || container.getCurrentPage() == null )
  	{
  	  container = null;
  	}
  	
  	return super.runForwardToNextStop( container );
  }
    
  public IWizardPage getCurrentPage()
  {
    return currentPage_;
  }
    
  public boolean hasNextPage()
  {	
	 
    nextPeekPage_ = null;
    
	try
	{
  	nextPeekPage_ = getNextPageInGroup( widgetFactory_, widgetStack_, false );
		
	  if( nextPeekPage_ == null )
	  {
	    // If a page is found nextPage_ will be set to its value in the method below.
  	    engine_.peekForwardToNextStop();
	  }
	}
	catch( Throwable exc )
	{
	  exc.printStackTrace();
	}
  	
    return nextPeekPage_ != null;
  }
  
  public IWizardPage getNextPage()
  {  	
	try
	{    
  	// Need to externalize the data for the current page so that
  	// when we move forward below the data is available.
  	if( currentPage_ != null ) currentPage_.getDataEvents().externalize();
  	
    if( environment_.getLog().isEnabled() )
    {
      environment_.getLog().log(ILog.INFO, "ws_dt_cmd_engine", 5010, this, "Cmd stack dump:", engine_ );
    }
    
	  nextPage_ = getNextPageInGroup( widgetFactory_, widgetStack_, true );
	
	  if( nextPage_ == null )
	  {
	    widgetFactory_ = null;
	    widgetStack_   = null;
		
  	  IStatus status = runForwardToNextStop();
  	
  	  if( status.getSeverity() == IStatus.ERROR )
  	  {
  	    // An error has occured so we need undo to the previous stop point.
  	    undoToLastPage();
  	  }
	  }
	
  	if( nextPage_ != null ) nextPage_.setWizard( wizard_ );
  	  	
  	return nextPage_;
	}
	catch( Throwable exc )
	{
	  exc.printStackTrace();	
	}
	
	return null;
  }
    
  public void handlePageVisible( PageWizardDataEvents page, boolean isPageVisible )
  {
    if( !isPageVisible && page == firstPage_ && page == currentPage_ )
    {
      // We are moving back one page from the first page.  This can't happen with popup wizards
      // since the previous button would be greyed out.  But when the new wizard launches this wizard
      // the previous button is not greyed out and brings the user back to the list wizards to select.
      // Therefore, we must unwind the command engine and get ready for the user to invoke this wizard 
      // again.  We are assuming here that the first page is never part of a widget group!
  	  undoToLastPage();	  
      currentPage_ = null;
      firstPage_   = null;
    }
  	if( currentPage_ != null && page == currentPage_.getPreviousPage() && isPageVisible )
  	{
  	  // We are moving back one page.
  	  // Note: we don't internalize the previous page and we do not externalize the current page.
  	  //       we are basically just leaving the current page without retrieving its state and
  	  //       moving to the previous page which already has its state set.
	
	    if( widgetFactory_ != null )
	    {
		    if( widgetStack_.size() > 0 )
		    {
		      widgetStack_.pop();
		    }
		
		    if( widgetStack_.size() == 0 )
		    {
		      widgetFactory_ = null;
		      widgetStack_ = null;
		      widgetStackStack_.pop();
		    }
	    }
	  
	    if( widgetFactory_ == null )
	    {
  	    undoToLastPage();
	    }
	  
      // Since we are moving backwards we need to remove the
      // current page object from the mapping table.
      dataManager_.unprocess( currentPage_.getDataEvents() );
      
  	  currentPage_ = page;
  	}	
  	else if( isPageVisible )
  	{
	    try
	    {
  	    // We are moving forward one page.
  	    WidgetDataEvents dataEvents = page.getDataEvents();
  	  
  	    dataManager_.process( dataEvents );  // Push model data into the new page.
  	    dataEvents.internalize();
  	  
  	    page.validatePageToStatus();  	  
	    }
	    catch( Throwable exc )
	    {
		    exc.printStackTrace();
	    }
	    finally
	    {
	  	  if( currentPage_ != null ) page.setPreviousPage( currentPage_ );
	    	  
	  	  currentPage_ = page;  
	    }
  	}
  }
  
  public boolean performFinish()
  { 	
  	// We need to simulate the next button being pressed until there are no more pages.
  	// If an error occurs we will return false and reset the command stack back our original state.
  	boolean              doneOk         = true;
  	PageWizardDataEvents startPage      = currentPage_;
    int                  stackStackSize = widgetStackStack_.size();
    
    INamedWidgetContributorFactory currentFactory = widgetFactory_;
  	
  	// Externalize the current page.
  	currentPage_.getDataEvents().externalize();
  	
  	// Loop through subsequent pages.
  	do
  	{  	  
  	  IStatus status = runForwardToNextStop();	  
  	  
  	  if( status.getSeverity() == IStatus.ERROR )
  	  {
  	  	// An error occured in one of the commands.
  	  	doneOk = false;
  	  }
  	}
  	while( nextPage_ != null && doneOk);
  	
  	if( !doneOk )
  	{
  	  // An error occured, so we need to return the command stack to it's
  	  // orginal state.
  	  PageWizardDataEvents page = null;
  	  boolean              done = false;
  	  
  	  do
  	  {
  	    done = engine_.undoToLastStop();
  	    page = getPage( lastUndoFragment_ );
        
        if( page == null && 
            currentFactory != null && 
            lastUndoFragment_ != null &&
            getWidgetFactory( lastUndoFragment_.getId() ) == currentFactory )
        {
          // The current widget factory is associated with the last fragment that was undone.
          // Therefore, we are back to where we started.
          done = true;    
          
          // Restore the widgetStackStack back to the state it was in before
          // running forward.
          widgetStackStack_.setSize( stackStackSize );
          
          StackEntry entry = (StackEntry)widgetStackStack_.peek();
          
          widgetFactory_ = entry.factory_;
          widgetStack_   = entry.stack_;
        }
        else if( page != null )
        {
          widgetFactory_ = null;
          widgetStack_ = null;
        }
  	  }
  	  while( page != startPage && !done ); 	  
  	}
  	
  	return doneOk;
  }
  
  public boolean performCancel()
  {
  	while( !engine_.undoToLastStop() ){}
  	
  	return true;
  }
    
  protected boolean peekFragment( CommandFragment fragment )
  {     	
    // Check to see if this fragment is in our page table.
    nextPeekPage_ = getPage( fragment );
          	
	  if( nextPeekPage_ == null )
	  {
	    INamedWidgetContributorFactory factory = getWidgetFactory( fragment.getId() );
	  
	    if( factory != null )
	    {
		    nextPeekPage_ = getNextPageInGroup( factory, null, false );  
	    }
	  }
	
    return nextPeekPage_ == null;
  }
  
  protected boolean nextFragment( CommandFragment fragment )
  {
    // If the super class nextFragment want us to stop then we will stop right away.
    if( !super.nextFragment( fragment ) ) return false;
    
  	// The first fragment is either at the start of the wizard
  	// or it is on a wizard page.  In either case we do not want 
  	// to stop if a page is found.
  	if( firstFragment_ )
  	{
  	  firstFragment_ = false;
  	}
  	else
  	{
	    widgetFactory_ = getWidgetFactory( fragment.getId() );
	  
	    if( widgetFactory_ != null )
	    {
		    widgetStack_ = new Stack();
        
        nextPage_ = getNextPageInGroup( widgetFactory_, widgetStack_, true );
		
        if( nextPage_ == null )
        {
          // We found a widget contributor for this fragment, but no page was delivered for it.
          // We will therefore, not put it on our stack of widget stacks.
          widgetStack_ = null;
          widgetFactory_ = null;
        }
        else
        {
		      StackEntry entry = new StackEntry();
		
		      entry.factory_ = widgetFactory_;
		      entry.stack_   = widgetStack_;
		      widgetStackStack_.push( entry );
        }
	    }
	    else
	    {
  	    nextPage_ = getPage( fragment );
	    }
  	}  	  	
  	
    return nextPage_ == null;
  }
  
  protected boolean undoFragment( CommandFragment fragment )
  {
  	lastUndoFragment_ = fragment;
  	
  	return true;
  }
  
  
  private PageWizardDataEvents getNextPageInGroup( INamedWidgetContributorFactory factory, Stack widgetStack, boolean pushNewWidget )
  {
	  PageWizardDataEvents page = null;
	
	  if( factory != null )
	  {	  
	    INamedWidgetContributor newWidget = null;
		  
	    if( widgetStack == null || widgetStack.size() == 0 )
	    {
		    newWidget = factory.getFirstNamedWidget();   
	    }
	    else
	    {
		    INamedWidgetContributor currentWidget = (INamedWidgetContributor)widgetStack.peek();
		    newWidget = factory.getNextNamedWidget( currentWidget ); 
	    }
		  
	    if( newWidget != null )
	    {
		    page = getPage( newWidget );
		
		    if( pushNewWidget )
		    {
		      widgetStack.push( newWidget );
		    }
	    }
	  }
		
	  return page;  
  }
  
  private void undoToLastPage()
  {
    boolean stackEmpty  = false;
	  boolean doneUndoing = false;
    
	  while( !doneUndoing )
	  {
	    stackEmpty = engine_.undoToLastStop();
	  
	    IWizardPage page = null;
	  
	    if( lastUndoFragment_ != null )
	    {
	      page = getPage( lastUndoFragment_ );
		
	      if( page == null )
	      {
		      // Check to see if a group page fragment was found.
		      INamedWidgetContributorFactory factory = getWidgetFactory( lastUndoFragment_.getId() );
		  
		      if( factory != null && !widgetStackStack_.empty() )
		      {
		        StackEntry entry = (StackEntry)widgetStackStack_.peek();
			
            if( entry.factory_ == factory )
            {
              // We found the factory for the entry at the top of the stack.
		          widgetFactory_ = entry.factory_;
		          widgetStack_   = entry.stack_;	
			
		          if( widgetStack_ != null && !widgetStack_.empty() )
		          {
		            INamedWidgetContributor currentWidget = (INamedWidgetContributor)widgetStack_.peek();
			
		            page = getPage( currentWidget );
		          }
            }
		      }
	      }
	    }
	  
	    doneUndoing = page != null || stackEmpty;
	  }
  }
  
  private PageWizardDataEvents getPage( CommandFragment fragment )
  {
    // Check to see if this fragment is in our page table.
  	PageWizardDataEvents page = (PageWizardDataEvents)pageTable_.get( fragment ); 
  	String      id   = fragment.getId();      	
          	
    if( page == null && id != null )
    {
      // Check to see if this fragment id is in the registry.
      PageInfo pageInfo = registry_.getPageInfo( id );          	  
              
      if( pageInfo != null )
      {
        page = pageFactory_.getPage( pageInfo, this );
        pageTable_.put( fragment, page );            	
      }
    }

    return page;
  }    
  
  private PageWizardDataEvents getPage( INamedWidgetContributor widget )
  {
	  PageWizardDataEvents page = (PageWizardDataEvents)widgetTable_.get( widget );

	  if( page == null )
	  {
	    PageInfo pageInfo = new PageInfo(widget.getTitle(), widget.getDescription(), widget.getWidgetContributorFactory() );
	  
	    page = pageFactory_.getPage( pageInfo, this );
	    widgetTable_.put( widget, page );
	  }
	
	  return page;
  }
  
  private INamedWidgetContributorFactory getWidgetFactory( String id )
  {
	  INamedWidgetContributorFactory factory = (INamedWidgetContributorFactory)widgetFactoryTable_.get( id );
	
	  if( factory == null )
	  {
	    // The factory is not in our table so we will try the registry.
	    factory = widgetRegistry_.getFactory( id );
	  
	    if( factory != null )
	    {
	      widgetFactoryTable_.put( id, factory );
	      factory.registerDataMappings( dataManager_.getMappingRegistry() );
		    dataManager_.process( factory );
	    }
	  }
	  else
	  {
	    dataManager_.process( factory );
	  }
	
	  return factory;
  }
  
  private class StackEntry
  {
    INamedWidgetContributorFactory factory_;
	  Stack                          stack_;
  }
}
