
package org.eclipse.birt.chart.ui.swt.wizard;

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

import org.eclipse.birt.chart.ui.swt.NavTree;
import org.eclipse.birt.core.ui.frameworks.taskwizard.CompoundTask;
import org.eclipse.birt.core.ui.frameworks.taskwizard.interfaces.ISubtaskSheet;
import org.eclipse.swt.SWT;
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.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

/**
 * 
 * Compound task realized for tree navigator.
 * 
 */

public class TreeCompoundTask extends CompoundTask
		implements
			SelectionListener
{

	private transient Composite cmpSubtaskContainer;
	private transient NavTree navTree;

	protected static final String INDEX_SEPARATOR = " - "; //$NON-NLS-1$

	// Cache for subtask selection next time
	private transient Map lastSubtaskRegistry = new HashMap( );

	// Cache for popup selection next time. This will override the subtask
	// selection to the popup.
	private transient Map lastPopupRegistry = new HashMap( );

	public TreeCompoundTask( String sLabel )
	{
		super( sLabel );
	}

	public void createControl( Composite parent )
	{
		if ( topControl == null || topControl.isDisposed( ) )
		{
			topControl = new Composite( parent, SWT.NONE );
			{
				GridLayout layout = new GridLayout( 2, false );
				layout.marginHeight = 0;
				layout.marginWidth = 0;
				layout.horizontalSpacing = 0;
				topControl.setLayout( layout );
				GridData gridData = new GridData( );
				gridData.horizontalAlignment = SWT.FILL;
				gridData.verticalAlignment = SWT.FILL;
				topControl.setLayoutData( gridData );
			}
			navTree = new NavTree( topControl, SWT.BORDER );
			{
				final GridData gridData = new GridData( GridData.HORIZONTAL_ALIGN_FILL
						| GridData.FILL_VERTICAL );
				gridData.widthHint = 127;
				navTree.setLayoutData( gridData );
				navTree.addSelectionListener( this );
			}
			cmpSubtaskContainer = createContainer( topControl );
		}
		populateSubtasks( );
		updateTreeItem( );
		setDefaultSelection( );
	}

	private void setDefaultSelection( )
	{
		TreeItem lastselection = navTree.findTreeItem( getSubtaskSelection( ) );
		if ( navTree.getSelection( ).length == 0 )
		{
			if ( lastselection != null )
			{
				switchToTreeItem( lastselection );
			}
			else if ( navTree.getItems( ).length > 0 )
			{
				switchToTreeItem( navTree.getItems( )[0] );
			}
		}
		else
		{
			switchToTreeItem( navTree.getSelection( )[0] );
		}
	}

	/**
	 * Creates the UI in the right of tree navigator
	 * 
	 * @param parent
	 *            parent composite
	 * @return top composite of the right part
	 */
	protected Composite createContainer( Composite parent )
	{
		return new Composite( parent, SWT.NONE );
	}

	protected void populateSubtasks( )
	{
		// Needs method overriden
	}

	protected void updateTreeItem( )
	{
		// Needs method overriden
	}

	protected ISubtaskSheet getSubtask( String sSubtaskPath )
	{
		int separatorIndex = sSubtaskPath.indexOf( INDEX_SEPARATOR );
		int subtaskIndex = 0;
		// If the subtask is present several times, need the node index to
		// distinguish between them
		if ( separatorIndex > -1 )
		{
			subtaskIndex = Integer.parseInt( sSubtaskPath.substring( separatorIndex
					+ INDEX_SEPARATOR.length( ) )
					.trim( ) ) - 1;
			sSubtaskPath = sSubtaskPath.substring( 0, separatorIndex ).trim( );
		}
		ISubtaskSheet itask = super.getSubtask( sSubtaskPath );
		itask.setIndex( subtaskIndex );
		return itask;
	}

	protected boolean containSubtask( String sSubtaskPath )
	{
		int separatorIndex = sSubtaskPath.indexOf( INDEX_SEPARATOR );
		// If the subtask is present several times, need the node index to
		// distinguish between them
		if ( separatorIndex > -1 )
		{
			sSubtaskPath = sSubtaskPath.substring( 0, separatorIndex ).trim( );
		}
		return super.containSubtask( sSubtaskPath );
	}

	public void switchTo( String sSubtaskPath )
	{
		super.switchTo( sSubtaskPath );
		createSubtaskArea( cmpSubtaskContainer, getSubtask( sSubtaskPath ) );
		cmpSubtaskContainer.layout( );
		container.packWizard( );

		// Save subtask selection
		setSubtaskSelection( sSubtaskPath );
		// Refresh help tray
		container.firePageChanged( getCurrentSubtask( ) );
	}

	/**
	 * Switches to the specified subtask and sets the selection
	 * 
	 * @param treeItem
	 *            Tree item corresponded to the subtask
	 */
	public void switchToTreeItem( TreeItem treeItem )
	{
		navTree.setSelection( new TreeItem[]{
			treeItem
		} );
		switchTo( navTree.getNodePath( treeItem ) );
	}

	protected void createSubtaskArea( Composite parent, ISubtaskSheet subtask )
	{
		if ( subtask != null )
		{
			subtask.createControl( parent );
			subtask.attachPopup( getPopupSelection( ) );
		}
	}

	public NavTree getNavigatorTree( )
	{
		return navTree;
	}

	public void widgetSelected( SelectionEvent e )
	{
		if ( e.getSource( ) instanceof Tree )
		{
			switchToTreeItem( (TreeItem) e.item );
		}
	}

	public void widgetDefaultSelected( SelectionEvent e )
	{
		// TODO Auto-generated method stub

	}

	/**
	 * Stores the last popup selection to open in the next time. If this
	 * selection is not existent in current subtask, to open the popup stored in
	 * the subtask.
	 * 
	 * @param popupName
	 *            popup key registered in the subtask.
	 */
	public void setPopupSelection( String popupName )
	{
		lastPopupRegistry.put( getContext( ).getWizardID( ), popupName );
	}

	protected String getPopupSelection( )
	{
		return (String) lastPopupRegistry.get( getContext( ).getWizardID( ) );
	}

	protected void setSubtaskSelection( String subtaskPath )
	{
		lastSubtaskRegistry.put( getContext( ).getWizardID( ), subtaskPath );
	}

	protected String getSubtaskSelection( )
	{
		return (String) lastSubtaskRegistry.get( getContext( ).getWizardID( ) );
	}

}