/*******************************************************************************
 * Copyright (c) 2005 Actuate Corporation.
 * 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:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.designer.data.ui.dataset;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.birt.report.designer.data.ui.property.AbstractDescriptionPropertyPage;
import org.eclipse.birt.report.designer.data.ui.util.ControlProvider;
import org.eclipse.birt.report.designer.data.ui.util.DataSetExpressionProvider;
import org.eclipse.birt.report.designer.data.ui.util.Utility;
import org.eclipse.birt.report.designer.internal.ui.util.ExceptionHandler;
import org.eclipse.birt.report.designer.nls.Messages;
import org.eclipse.birt.report.designer.ui.dialogs.ExpressionBuilder;
import org.eclipse.birt.report.model.api.ComputedColumnHandle;
import org.eclipse.birt.report.model.api.DataSetHandle;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.PropertyHandle;
import org.eclipse.birt.report.model.api.activity.SemanticException;
import org.eclipse.birt.report.model.api.elements.DesignChoiceConstants;
import org.eclipse.birt.report.model.api.elements.structures.ComputedColumn;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;


/**
 * TODO: Please document
 * 
 * @version $Revision: 1.7.2.1 $ $Date: 2006/09/11 08:54:51 $
 */
public class DataSetComputedColumnsPage extends AbstractDescriptionPropertyPage
		implements
			ITableLabelProvider
{

    private transient PropertyHandle computedColumns = null;
    private transient PropertyHandleTableViewer viewer = null;
    private ComputedColumn originalStructure = null;
    
	private static String[] dataTypes = new String[]{
        DesignChoiceConstants.COLUMN_DATA_TYPE_ANY,
        DesignChoiceConstants.COLUMN_DATA_TYPE_DATETIME,
        DesignChoiceConstants.COLUMN_DATA_TYPE_DECIMAL,
        DesignChoiceConstants.COLUMN_DATA_TYPE_FLOAT,
        DesignChoiceConstants.COLUMN_DATA_TYPE_INTEGER,
        DesignChoiceConstants.COLUMN_DATA_TYPE_STRING,
        };    
    
    private static String[] dataTypeDisplayNames = new String[] {
        Messages.getString("datatypes.any"), //$NON-NLS-1$
        Messages.getString("datatypes.dateTime"), //$NON-NLS-1$
        Messages.getString("datatypes.decimal"), //$NON-NLS-1$
        Messages.getString("datatypes.float"), //$NON-NLS-1$
        Messages.getString("datatypes.integer"), //$NON-NLS-1$
        Messages.getString("datatypes.string") //$NON-NLS-1$
    };
    
    private static String[] cellLabels = new String[]{
			Messages.getString( "dataset.editor.title.columnName" ),//$NON-NLS-1$
			Messages.getString( "dataset.editor.title.dataType" ),//$NON-NLS-1$
			Messages.getString( "dataset.editor.title.expression" )//$NON-NLS-1$
	};
 
	private static String[] cellProperties = new String[]{
			ComputedColumn.NAME_MEMBER, ComputedColumn.DATA_TYPE_MEMBER, ComputedColumn.EXPRESSION_MEMBER
	};
    
    // boolean variable to indicate whether model is changed, if so, then refresh columns
    
    /**
     * 
     */
    public DataSetComputedColumnsPage()
    {
        super();
    }

    /* (non-Javadoc)
     * @see org.eclipse.birt.report.designer.ui.dialogs.properties.IPropertyPage#createPageControl(org.eclipse.swt.widgets.Composite)
     */
    public Control createContents(Composite parent)
    {
        computedColumns = ( (DataSetHandle) getContainer( ).getModel( ) ).getPropertyHandle( DataSetHandle.COMPUTED_COLUMNS_PROP );;
        viewer = new PropertyHandleTableViewer( parent, true, true, true );
        TableColumn column = new TableColumn( viewer.getViewer().getTable( ),
                SWT.LEFT );
        column.setText( cellLabels[Utility.findIndex( cellProperties,
				ComputedColumn.NAME_MEMBER )] ); //$NON-NLS-1$
        column.setWidth( 150 );
        column = new TableColumn( viewer.getViewer().getTable( ), SWT.LEFT );
        column.setText( cellLabels[Utility.findIndex( cellProperties,
				ComputedColumn.DATA_TYPE_MEMBER )] ); //$NON-NLS-1$
        column.setWidth( 200 );
        column = new TableColumn( viewer.getViewer().getTable( ), SWT.LEFT );
        column.setText( cellLabels[Utility.findIndex( cellProperties,
				ComputedColumn.EXPRESSION_MEMBER )] ); //$NON-NLS-1$
        column.setWidth( 200 );
        viewer.getViewer().setContentProvider( new IStructuredContentProvider( ) {

            public Object[] getElements( Object inputElement )
            {
                ArrayList computedColumnsList = new ArrayList( 10 );
                Iterator iter = computedColumns.iterator( );
                if ( iter != null )
                {
                    while ( iter.hasNext( ) )
                    {
                        computedColumnsList.add( iter.next( ) );
                    }
                }
                return computedColumnsList.toArray( );
            }

            public void dispose( )
            {

            }

            public void inputChanged( Viewer viewer, Object oldInput,
                    Object newInput )
            {

            }
        } );
        viewer.getViewer().setLabelProvider( this );
        viewer.getViewer().setInput( computedColumns );
        addListeners();
        setToolTips();
        return viewer.getControl();
    }
    
    /* (non-Javadoc)
     * @see org.eclipse.birt.report.designer.ui.dialogs.properties.IPropertyPage#pageActivated()
     */
    public void pageActivated( )
	{
		refreshColumnNames( );
		getContainer( ).setMessage( Messages.getString( "dataset.editor.computedColumns" ), IMessageProvider.NONE ); // $-NON-NLS-1
		// //$NON-NLS-1$
		setPageProperties( );
        
		computedColumns = ( (DataSetHandle) getContainer( ).getModel( ) ).getPropertyHandle( DataSetHandle.COMPUTED_COLUMNS_PROP );;
		viewer.getViewer( ).setInput( computedColumns );
		viewer.getViewer( ).getTable( ).select( 0 );
	}
    
    /**
	 * Refresh columns meta data
	 */
	private void refreshColumnNames( )
	{
		( (DataSetEditor) this.getContainer( ) ).getCurrentItemModel( true,
				true );
	}
    
    private void addListeners()
    {
    	viewer.getNewButton( ).addSelectionListener( new SelectionAdapter( ) {

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

		viewer.getEditButton( ).addSelectionListener( new SelectionAdapter( ) {

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

		viewer.getViewer( ).getTable( ).addMouseListener( new MouseAdapter( ) {

			public void mouseDoubleClick( MouseEvent e )
			{
				doEdit( );
			}
		} );
    	
        viewer.getViewer().getTable().addKeyListener(new KeyListener(){

            public void keyPressed(KeyEvent e)
            {
            }

            public void keyReleased(KeyEvent e)
            {
                if ( e.keyCode == SWT.DEL )
                {
                    setPageProperties();
                }
            }
            
        });
        
        viewer.getRemoveButton().addSelectionListener(new SelectionListener(){

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

            public void widgetDefaultSelected(SelectionEvent e)
            {
            }
            
        });
        
        viewer.getRemoveMenuItem().addSelectionListener(new SelectionListener(){
            public void widgetSelected(SelectionEvent e)
            {
                setPageProperties();
            }

            public void widgetDefaultSelected(SelectionEvent e)
            {
            }
            
            
        });
        
        viewer.getRemoveAllMenuItem( )
				.addSelectionListener( new SelectionListener( ) {

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

					public void widgetDefaultSelected( SelectionEvent e )
					{
						widgetSelected( e );
					}
				} );
        
        viewer.getViewer().addSelectionChangedListener( new ViewerSelectionListener());
    }
    
	private void doNew( )
	{
		doEdit( new ComputedColumn( ) );
	}

	private void doEdit( )
	{
		int index = viewer.getViewer( ).getTable( ).getSelectionIndex( );
		if ( index == -1 )
			return;

		ComputedColumnHandle handle = (ComputedColumnHandle) viewer.getViewer( )
				.getTable( )
				.getItem( index )
				.getData( );
		originalStructure = (ComputedColumn) handle.getStructure( ).copy( );

		// replace typeName with displayTypeName
		Utility.setStructureProperty( handle.getStructure( ),
				ComputedColumn.DATA_TYPE_MEMBER,
				getTypeDisplayName( Utility.getStructureProperty( handle.getStructure( ),
						ComputedColumn.DATA_TYPE_MEMBER ) ) );

		doEdit( handle );
	}

	private void doEdit( Object structureOrHandle )
	{
		ComputedColumnInputDialog dlg = new ComputedColumnInputDialog( structureOrHandle );

		if ( dlg.open( ) == Window.OK )
		{
			update( structureOrHandle );
		}
	}
	
	private void update( Object structureOrHandle )
	{
		ComputedColumn structure = getStructure( structureOrHandle );
		
		// replace displayTypeName with typeName
		try
		{
			Utility.setProperty( structureOrHandle,
					ComputedColumn.DATA_TYPE_MEMBER,
					getTypeName( Utility.getStructureProperty( structure,
							ComputedColumn.DATA_TYPE_MEMBER ) ) );
		}
		catch ( Exception e )
		{
			ExceptionHandler.handle( e );
		}

		if ( structureOrHandle instanceof ComputedColumn )
		{
			ComputedColumn column = (ComputedColumn) structureOrHandle;

			try
			{
				computedColumns.addItem( column );
				viewer.getViewer( ).refresh( );
			}
			catch ( SemanticException e )
			{
				ExceptionHandler.handle( e );
			}
		}
		else
		{
			viewer.getViewer( ).update( structureOrHandle, null );
		}

		if ( validateAllComputedColumns( ) )
			getContainer( ).setMessage( Messages.getString( "dataset.editor.computedColumns" ),
					IMessageProvider.NONE );
	}
	
	private ComputedColumn getStructure( Object structureOrHandle )
	{
		ComputedColumn structure = null;
		if ( structureOrHandle instanceof ComputedColumn )
		{
			structure = (ComputedColumn) structureOrHandle;
		}
		else
		{
			structure = (ComputedColumn) ( (ComputedColumnHandle) structureOrHandle ).getStructure( );
		}

		return structure;
	}
	
	private final String getTypeName( String typeDisplayName )
	{
		for ( int n = 0; n < dataTypeDisplayNames.length; n++ )
		{
			if ( dataTypeDisplayNames[n].equals( typeDisplayName ) )
			{
				return dataTypes[n];
			}
		}

		return dataTypes[0];
	}

	private final String getTypeDisplayName( String typeName )
	{
		for ( int n = 0; n < dataTypes.length; n++ )
		{
			if ( dataTypes[n].equals( typeName ) )
			{
				return dataTypeDisplayNames[n];
			}
		}

		return dataTypeDisplayNames[0];
	}
    
    private void setToolTips( )
	{
		viewer.getNewButton( )
				.setToolTipText( Messages.getString( "DataSetComputedColumnsPage.toolTipText.New" ) );//$NON-NLS-1$
		viewer.getEditButton( )
				.setToolTipText( Messages.getString( "DataSetComputedColumnsPage.toolTipText.Edit" ) );//$NON-NLS-1$
		viewer.getRemoveButton( )
				.setToolTipText( Messages.getString( "DataSetComputedColumnsPage.toolTipText.Remove" ) );//$NON-NLS-1$
		viewer.getUpButton( )
				.setToolTipText( Messages.getString( "DataSetComputedColumnsPage.toolTipText.Up" ) );//$NON-NLS-1$
		viewer.getDownButton( )
				.setToolTipText( Messages.getString( "DataSetComputedColumnsPage.toolTipText.Down" ) );//$NON-NLS-1$
	}
    
    /*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
	 *      int)
	 */
    public Image getColumnImage(Object element, int columnIndex)
    {
        return null;
    }

    /*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
	 *      int)
	 */
    public String getColumnText(Object element, int columnIndex)
    {
		String value = null;
		ComputedColumn computedColumn = getStructure( element );

		try
		{
			switch ( columnIndex )
			{
				case 0 :
				{
					value = Utility.getStructureProperty( computedColumn,
							ComputedColumn.NAME_MEMBER ); //$NON-NLS-1$
					break;
				}
				case 1 :
				{
					value = getTypeDisplayName( Utility.getStructureProperty( computedColumn,
							ComputedColumn.DATA_TYPE_MEMBER ) ); //$NON-NLS-1$
					break;
				}
				case 2 :
				{
					value = Utility.getStructureProperty( computedColumn,
							ComputedColumn.EXPRESSION_MEMBER ); //$NON-NLS-1$
					break;
				}
			}
		}
		catch ( Exception e )
		{
			ExceptionHandler.handle( e );
		}
		
		return ( value == null ? "" : value ); //$NON-NLS-1$
	}

    /*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
	 */
    public void addListener(ILabelProviderListener listener)
    {
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
     */
    public void dispose()
    {
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
     */
    public boolean isLabelProperty(Object element, String property)
    {
        return false;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
     */
    public void removeListener(ILabelProviderListener listener)
    {
    }
    
    /*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.report.designer.ui.dialogs.properties.AbstractDescriptionPropertyPage#getPageDescription()
	 */
    public String getPageDescription()
    {
        return Messages.getString("DataSetComputedColumnsPage.description"); //$NON-NLS-1$
    }    

    /* (non-Javadoc)
     * @see org.eclipse.birt.report.designer.ui.dialogs.properties.AbstractPropertyPage#performOk()
     */
    public boolean performOk()
    {
        if(validateAllComputedColumns())
        {
        	return super.performOk();
        }
        return false;
    }
    
    private class ViewerSelectionListener implements ISelectionChangedListener
	{

		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
		 */
		public void selectionChanged(SelectionChangedEvent event) {
			// TODO Auto-generated method stub
			setPageProperties();
		}
    	
	}
    
	/**
	 * Depending on the Computed the properties of various controls
	 * on this page are set
	 */
	private void setPageProperties() 
	{
		boolean computedColumnsExist = false;
		
		computedColumnsExist = ( computedColumns != null && computedColumns.getListValue()!= null &&
				computedColumns.getListValue().size() > 0);
		viewer.getEditButton( ).setEnabled( computedColumnsExist );
		viewer.getDownButton( ).setEnabled( computedColumnsExist
				&& computedColumns.getListValue( ).size( ) > 1 );
		viewer.getUpButton( ).setEnabled( computedColumnsExist
				&& computedColumns.getListValue( ).size( ) > 1 );
		viewer.getRemoveButton().setEnabled(computedColumnsExist);
		viewer.getRemoveMenuItem( ).setEnabled( computedColumnsExist );
		viewer.getRemoveAllMenuItem( ).setEnabled( computedColumnsExist );
		validateAllComputedColumns();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.birt.report.designer.ui.dialogs.properties.IPropertyPage#getToolTip()
	 */
	public String getToolTip( )
	{
		return Messages.getString("DataSetComputedColumnsPage.ComputedColumns.Tooltip"); //$NON-NLS-1$
	}
	
	public boolean canLeave( )
	{
		return validateAllComputedColumns( );
	}
	
	/*
	 * Exam whether all registered computed columns are valid. Set the message of dialog as appropriated
	 */
	private boolean validateAllComputedColumns( )
	{
		if ( computedColumns != null)
		{
			Iterator iter = computedColumns.iterator();
            if(iter != null)
            {
                while(iter.hasNext())
                {
                    Object o = iter.next();
                	ComputedColumn computedColumn = null;
                    if(o instanceof ComputedColumnHandle)
                    {
                        computedColumn = (ComputedColumn)((ComputedColumnHandle)o).getStructure();
                    }
                    else
                    {
                        computedColumn = (ComputedColumn)o;
                    }
                	if ( !validateSingleColumn(computedColumn))
                   	return false;
                }
            }
		}
		return true;
	}
	
	/*
	 * Exam whether one computed column is valid or not.
	 */
	private boolean validateSingleColumn( ComputedColumn computedColumn)
	{
        if( computedColumn.getName() == null 
            	|| computedColumn.getName().trim().length() == 0 )
            {
                getContainer().setMessage(Messages.getFormattedString("dataset.editor.error.missingComputedColumnName", new Object[]{computedColumn.getName()}), IMessageProvider.ERROR); //$NON-NLS-1$
                return false;
            }
            if( computedColumn.getExpression() == null
				|| computedColumn.getExpression().trim().length() == 0)
            {
            	getContainer().setMessage(Messages.getFormattedString("dataset.editor.error.missingComputedColumnExpression", new Object[]{computedColumn.getName()}), IMessageProvider.ERROR); //$NON-NLS-1$
            	return false;
            }
			return true;
	}
	
	private class ComputedColumnInputDialog extends PropertyHandleInputDialog
	{

		private ComputedColumn structure = null;

		private ComputedColumnInputDialog( Object structureOrHandle )
		{
			super( structureOrHandle );

			structure = getStructure( structureOrHandle );
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.birt.report.designer.data.ui.dataset.PropertyHandleInputDialog#createCustomControls(org.eclipse.swt.widgets.Composite)
		 */
		protected void createCustomControls( Composite parent )
		{
			createTextCell( parent, Utility.findIndex( cellProperties,
					ComputedColumn.NAME_MEMBER ) );
			createComboBoxCell( parent, Utility.findIndex( cellProperties,
					ComputedColumn.DATA_TYPE_MEMBER ) );
			createExpressionCell( parent, Utility.findIndex( cellProperties,
					ComputedColumn.EXPRESSION_MEMBER ) );
		}

		private void createTextCell( Composite parent, final int index )
		{
			ControlProvider.createLabel( parent, cellLabels[index] );

			final Text tx = ControlProvider.createText( parent,
					Utility.getStructureProperty( structure,
							cellProperties[index] ) );
			tx.setLayoutData( ControlProvider.getGridDataWithHSpan( 2 ) );
			tx.addModifyListener( new ModifyListener( ) {

				public void modifyText( ModifyEvent e )
				{
					Utility.setStructureProperty( structure,
							cellProperties[index],
							tx.getText( ) );
					validateSyntax( );
				}

			} );
		}

		private void createComboBoxCell( Composite parent, final int index )
		{
			ControlProvider.createLabel( parent, cellLabels[index] );

			final Combo cb = ControlProvider.createCombo( parent, SWT.READ_ONLY );
			cb.setLayoutData( ControlProvider.getGridDataWithHSpan( 2 ) );
			cb.setItems( dataTypeDisplayNames );
			cb.select( Utility.findIndex( cb.getItems( ),
					Utility.getStructureProperty( structure,
							cellProperties[index] ) ) );
			cb.addSelectionListener( new SelectionAdapter( ) {

				public void widgetSelected( SelectionEvent e )
				{
					Utility.setStructureProperty( structure,
							cellProperties[index],
							cb.getText( ) );
					validateSyntax( );
				}

			} );
			// special case for a new structure with default value
			if ( getStructureOrHandle( ) instanceof ComputedColumn )
			{
				Utility.setStructureProperty( structure,
						cellProperties[index],
						cb.getText( ) );
			}
		}

		private void createExpressionCell( Composite parent, final int index )
		{
			ControlProvider.createLabel( parent, cellLabels[index] );

			Composite composite = ControlProvider.getDefaultComposite( parent );
			final Text tx = ControlProvider.createText( composite,
					Utility.getStructureProperty( structure,
							cellProperties[index] ) );
			tx.setLayoutData( ControlProvider.getGridDataWithHSpan( 1 ) );
			tx.addModifyListener( new ModifyListener( ) {

				public void modifyText( ModifyEvent e )
				{
					Utility.setStructureProperty( structure,
							cellProperties[index],
							tx.getText( ) );
					validateSyntax( );
				}

			} );

			SelectionAdapter listener = new SelectionAdapter( ) {

				public void widgetSelected( SelectionEvent event )
				{
					ExpressionBuilder expressionBuilder = new ExpressionBuilder( tx.getText( ) );
					expressionBuilder.setExpressionProvier( new DataSetExpressionProvider( (DesignElementHandle) getContainer( ).getModel( ) ) );

					if ( expressionBuilder.open( ) == OK )
					{
						tx.setText( expressionBuilder.getResult( ).trim( ) );
					}
				}
			};

			ControlProvider.createButton( composite, SWT.PUSH, listener );
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.birt.report.designer.data.ui.dataset.PropertyHandleInputDialog#validateSemantics(java.lang.Object)
		 */
		protected IStatus validateSemantics( Object structureOrHandle )
		{
			// duplicated columnName check
			for ( int i = 0; i < cellProperties.length; i++ )
			{
				if ( cellProperties[i].equals( ComputedColumn.NAME_MEMBER ) //$NON-NLS-1$
						&& !isUniqueColumnName( structureOrHandle,
								Utility.getStructureProperty( structure,
										cellProperties[i] ) ) )
				{
					return new Status( IStatus.ERROR,
							PlatformUI.PLUGIN_ID,
							IStatus.OK,
							Messages.getString( "DataSetComputedColumnsPage.duplicatedName" ),
							null );
				}
			}

			return new Status( IStatus.OK,
					PlatformUI.PLUGIN_ID,
					IStatus.OK,
					"",
					null );
		}

		private final boolean isUniqueColumnName( Object structureOrHandle,
				String name )
		{
			ComputedColumn column = getStructure( structureOrHandle );
			Iterator iter = computedColumns.iterator( );
			if ( iter != null )
			{
				while ( iter.hasNext( ) )
				{
					ComputedColumnHandle handle = (ComputedColumnHandle) iter.next( );
					if ( column != handle.getStructure( )
							&& handle.getName( ).equals( name ) )
					{
						return false;
					}
				}
			}
			return true;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.birt.report.designer.data.ui.dataset.PropertyHandleInputDialog#validateSyntax(java.lang.Object)
		 */
		protected IStatus validateSyntax( Object structureOrHandle )
		{
			// blankProperty check
			for ( int i = 0; i < cellProperties.length; i++ )
			{
				if ( Utility.getStructureProperty( structure, cellProperties[i] )
						.trim( )
						.length( ) == 0 )
				{
					return getBlankPropertyStatus( cellLabels[i] );
				}
			}

			return new Status( IStatus.OK,
					PlatformUI.PLUGIN_ID,
					IStatus.OK,
					"",
					null );
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.birt.report.designer.data.ui.dataset.PropertyHandleInputDialog#rollback()
		 */
		protected void rollback( )
		{
			if ( originalStructure != null )
			{
				for ( int i = 0; i < cellProperties.length; i++ )
				{
					Utility.setStructureProperty( structure,
							cellProperties[i],
							Utility.getStructureProperty( originalStructure,
									cellProperties[i] ) );
				}
				originalStructure = null;
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.birt.report.designer.data.ui.dataset.PropertyHandleInputDialog#getTitle()
		 */
		protected String getTitle( )
		{
			return super.getTitle( )
					+ " " + Messages.getString( "DataSetComputedColumnsPage.title.ComputedColumnInputDialog" );//$NON-NLS-1$
		}

	}

}
