/*******************************************************************************
 * Copyright (c) 2004, 2007 QNX Software Systems 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:
 *     QNX Software Systems - initial API and implementation
 *     IBM Corporation
 *     Anton Leherbauer (Wind River Systems)
 *     Sergey Prigogin (Google)
 *******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards.filewizard;

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

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.views.contentoutline.ContentOutline;

import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.utils.PathUtil;

import org.eclipse.cdt.internal.corext.util.CModelUtil;

import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.preferences.CodeTemplatePreferencePage;
import org.eclipse.cdt.internal.ui.viewsupport.IViewPartInputProvider;
import org.eclipse.cdt.internal.ui.wizards.NewElementWizardPage;
import org.eclipse.cdt.internal.ui.wizards.SourceFolderSelectionDialog;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.ComboDialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.Separator;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.StringButtonDialogField;

public abstract class AbstractFileCreationWizardPage extends NewElementWizardPage {

	private static final int MAX_FIELD_CHARS = 50;
	private static final String NO_TEMPLATE = ""; //$NON-NLS-1$
	
	private IWorkspaceRoot fWorkspaceRoot;

	// field IDs
	private static final int SOURCE_FOLDER_ID = 1;
	protected static final int NEW_FILE_ID = 2;
	private static final int ALL_FIELDS = SOURCE_FOLDER_ID | NEW_FILE_ID;
	int fLastFocusedField = 0;
	private StringButtonDialogField fSourceFolderDialogField;
	private IStatus fSourceFolderStatus;
	private IStatus fNewFileStatus;
	private final IStatus STATUS_OK = new StatusInfo();
	
	/**
     * This flag isFirstTime is used to keep a note
     * that the file creation wizard has just been 
     * created.
     */
    private boolean isFirstTime = false;

	private Template[] fTemplates;

	private ComboDialogField fTemplateDialogField;
	
	public AbstractFileCreationWizardPage(String name) {
		super(name);

		setDescription(NewFileWizardMessages.AbstractFileCreationWizardPage_description); 
		
		fWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		
		SourceFolderFieldAdapter sourceFolderAdapter = new SourceFolderFieldAdapter();
		fSourceFolderDialogField = new StringButtonDialogField(sourceFolderAdapter);
		fSourceFolderDialogField.setDialogFieldListener(sourceFolderAdapter);
		fSourceFolderDialogField.setLabelText(NewFileWizardMessages.AbstractFileCreationWizardPage_sourceFolder_label); 
		fSourceFolderDialogField.setButtonLabel(NewFileWizardMessages.AbstractFileCreationWizardPage_sourceFolder_button); 

		fTemplates= getApplicableTemplates();
		if (fTemplates != null && fTemplates.length > 0) {
			fTemplateDialogField= new ComboDialogField(SWT.NONE);
			fTemplateDialogField.setLabelText(NewFileWizardMessages.AbstractFileCreationWizardPage_template_label);
		}

		fSourceFolderStatus = STATUS_OK;
		fNewFileStatus = STATUS_OK;
		fLastFocusedField = 0;
		
		isFirstTime = true;
		
	}
	
	// -------- UI Creation ---------

	public void createControl(Composite parent) {
        initializeDialogUnits(parent);
        
        Composite composite = new Composite(parent, SWT.NONE);
        int nColumns = 3;
        
        GridLayout layout = new GridLayout();
        layout.numColumns = nColumns;
        composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		composite.setFont(parent.getFont());
        
        createSourceFolderControls(composite, nColumns);
        
        createFileControls(composite, nColumns - 1);
        // Placeholder for the right column.
        (new Composite(composite, SWT.NO_FOCUS)).setLayoutData(new GridData(1, 1));

        createTemplateControls(composite, nColumns);

		composite.layout();

		setErrorMessage(null);
		setMessage(null);
		setControl(composite);
    }
	
	/**
	 * Creates a separator line. Expects a <code>GridLayout</code> with at least 1 column.
	 * 
	 * @param composite the parent composite
	 * @param nColumns number of columns to span
	 */
	protected void createSeparator(Composite composite, int nColumns) {
		(new Separator(SWT.SEPARATOR | SWT.HORIZONTAL)).doFillIntoGrid(composite, nColumns, convertHeightInCharsToPixels(1));		
	}

	/**
	 * Creates the necessary controls (label, text field and browse button) to edit
	 * the source folder location. The method expects that the parent composite
	 * uses a <code>GridLayout</code> as its layout manager and that the
	 * grid layout has at least 3 columns.
	 * 
	 * @param parent the parent composite
	 * @param nColumns the number of columns to span. This number must be
	 *  greater or equal three
	 */
	protected void createSourceFolderControls(Composite parent, int nColumns) {
		fSourceFolderDialogField.doFillIntoGrid(parent, nColumns);
		Text textControl = fSourceFolderDialogField.getTextControl(null);
		LayoutUtil.setWidthHint(textControl, getMaxFieldWidth());
		textControl.addFocusListener(new StatusFocusListener(SOURCE_FOLDER_ID));
	}
	
	/**
	 * Creates the controls for the file name field. Expects a <code>GridLayout</code> with at 
	 * least 2 columns.
	 * 
	 * @param parent the parent composite
	 * @param nColumns number of columns to span
	 */		
	protected abstract void createFileControls(Composite parent, int nColumns);

	/**
	 * Creates the controls for the file template field. Expects a <code>GridLayout</code> with at 
	 * least 3 columns.
	 * 
	 * @param parent the parent composite
	 * @param columns number of columns to span
	 */		
	protected void createTemplateControls(Composite parent, int columns) {
		if (fTemplateDialogField != null) {
			fTemplateDialogField.doFillIntoGrid(parent, columns - 1);
			Button configureButton= new Button(parent, SWT.PUSH);
			configureButton.setText(NewFileWizardMessages.AbstractFileCreationWizardPage_configure_label);
			configureButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
			configureButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					editTemplates();
				}
			});
			Combo comboControl= fTemplateDialogField.getComboControl(null);
			LayoutUtil.setWidthHint(comboControl, getMaxFieldWidth());
		}
	}

	protected void editTemplates() {
		String prefPageId= CodeTemplatePreferencePage.PREF_ID;
		Map<String, String> data= null;
		String templateName= null;
		Template template= getSelectedTemplate();
		if (template != null) {
			templateName= template.getName();
		}
		if (templateName != null) {
			data= new HashMap<String, String>();
			data.put(CodeTemplatePreferencePage.DATA_SELECT_TEMPLATE, templateName);
		}
		PreferenceDialog dialog= PreferencesUtil.createPreferenceDialogOn(getShell(), prefPageId, new String[] { prefPageId }, data);
		if (dialog.open() == Window.OK) {
			updateTemplates();
		}
	}

	protected void updateTemplates() {
		Template selected= getSelectedTemplate();
		String name = selected != null ?
				selected.getName() :
				getLastUsedTemplateName();
		fTemplates= getApplicableTemplates();
		int idx= NO_TEMPLATE.equals(name) ? 0 : 1;
		String[] names= new String[fTemplates.length + 1];
		for (int i = 0; i < fTemplates.length; i++) {
			names[i + 1]= fTemplates[i].getName();
			if (name != null && name.equals(names[i + 1])) {
				idx= i + 1;
			}
		}
		names[0]= NewFileWizardMessages.AbstractFileCreationWizardPage_noTemplate;
		fTemplateDialogField.setItems(names);
		fTemplateDialogField.selectItem(idx);
	}

	/**
     * Configure the set of templates to select from.
	 * @return the set of templates
	 */
	protected abstract Template[] getApplicableTemplates();

	/**
	 * Returns the selected template and saves its name for future use.
	 *  
	 * @return the selected template or <code>null</code> if none.
	 */
	protected Template getTemplate() {
		Template template = getSelectedTemplate();
		saveLastUsedTemplateName(template != null ? template.getName() : NO_TEMPLATE);
		return template;
	}

	private Template getSelectedTemplate() {
		if (fTemplateDialogField != null) {
			int index= fTemplateDialogField.getSelectionIndex() - 1;
			if (index >= 0 && index < fTemplates.length) {
				return fTemplates[index];
			}
		}
		return null;
	}
	
    /**
     * The wizard owning this page is responsible for calling this method with the
     * current selection. The selection is used to initialize the fields of the wizard 
     * page.
     * 
     * @param selection used to initialize the fields
     */
    public void init(IStructuredSelection selection) {
    	ICElement celem = getInitialCElement(selection);
    	initFields(celem);
    	doStatusUpdate();
    }
	
    /**
     * Utility method to inspect a selection to find a C element. 
     * 
     * @param selection the selection to be inspected
     * @return a C element to be used as the initial selection, or <code>null</code>,
     * if no C element exists in the given selection
     */
    protected ICElement getInitialCElement(IStructuredSelection selection) {
    	ICElement celem = null;
    	if (selection != null && !selection.isEmpty()) {
    		Object selectedElement = selection.getFirstElement();
    		if (selectedElement instanceof IAdaptable) {
    			IAdaptable adaptable = (IAdaptable) selectedElement;			
    			
    			celem = (ICElement) adaptable.getAdapter(ICElement.class);
    			if (celem == null) {
    				IResource resource = (IResource) adaptable.getAdapter(IResource.class);
    				if (resource != null && resource.getType() != IResource.ROOT) {
    					while (celem == null && resource.getType() != IResource.PROJECT) {
    						celem = (ICElement) resource.getAdapter(ICElement.class);
    						resource = resource.getParent();
    					}
    					if (celem == null) {
    						celem = CoreModel.getDefault().create(resource); // c project
    					}
    				}
    			}
    		}
    	}
    	if (celem == null) {
    		IWorkbenchPart part = CUIPlugin.getActivePage().getActivePart();
    		if (part instanceof ContentOutline) {
    			part = CUIPlugin.getActivePage().getActiveEditor();
    		}
    		
    		if (part instanceof IViewPartInputProvider) {
    			Object elem = ((IViewPartInputProvider)part).getViewPartInput();
    			if (elem instanceof ICElement) {
    				celem = (ICElement) elem;
    			}
    		}

    		if (celem == null && part instanceof CEditor) {
		    	IEditorInput input = ((IEditorPart)part).getEditorInput();
		    	if (input != null) {
					final IResource res = (IResource) input.getAdapter(IResource.class);
					if (res != null && res instanceof IFile) {
					    celem = CoreModel.getDefault().create((IFile)res);
					}
		    	}
    		}
    	}
    
    	if (celem == null || celem.getElementType() == ICElement.C_MODEL) {
    		try {
    			ICProject[] projects = CoreModel.create(getWorkspaceRoot()).getCProjects();
    			if (projects.length == 1) {
    				celem = projects[0];
    			}
    		} catch (CModelException e) {
    			CUIPlugin.log(e);
    		}
    	}
    	return celem;
    }

	/**
     * Initializes all fields provided by the page with a given selection.
     * 
     * @param elem the selection used to initialize this page or <code>
     * null</code> if no selection was available
     */
    protected void initFields(ICElement elem) {
	    initSourceFolder(elem);
	    updateTemplates();
    	handleFieldChanged(ALL_FIELDS);
    }

    /**
     * Initializes the source folder field.
     * 
     * @param elem the C element used to compute the initial folder
     */
    protected void initSourceFolder(ICElement elem) {
    	ICContainer folder = null;
    	if (elem != null) {
    	    folder = CModelUtil.getSourceFolder(elem);
    		if (folder == null) {
    			ICProject cproject = elem.getCProject();
    			if (cproject != null) {
    				try {
    					if (cproject.exists()) {
    					    ISourceRoot[] roots = cproject.getSourceRoots();
    					    if (roots != null && roots.length > 0)
    					        folder = roots[0];
    					}
    				} catch (CModelException e) {
    					CUIPlugin.log(e);
    				}
    				if (folder == null) {
    				    folder = cproject.findSourceRoot(cproject.getResource());
    				}
    			}
    		}
    	}
	    setSourceFolderFullPath(folder != null ? folder.getResource().getFullPath() : null, false);
    }
	
     /**
	 * Returns the recommended maximum width for text fields (in pixels). This
	 * method requires that createContent has been called before this method is
	 * call. Subclasses may override to change the maximum width for text 
	 * fields.
	 * 
	 * @return the recommended maximum width for text fields.
	 */
	protected int getMaxFieldWidth() {
		return convertWidthInCharsToPixels(MAX_FIELD_CHARS);
	}

    /**
     * Returns the test selection of the current editor. <code>null</code> is returned
     * when the current editor does not have focus or does not return a text selection.
     * @return Returns the test selection of the current editor or <code>null</code>.
     *
     * @since 3.0 
     */
    protected ITextSelection getCurrentTextSelection() {
    	IWorkbenchPart part = CUIPlugin.getActivePage().getActivePart();
    	if (part instanceof IEditorPart) {
    		ISelectionProvider selectionProvider = part.getSite().getSelectionProvider();
    		if (selectionProvider != null) {
    			ISelection selection = selectionProvider.getSelection();
    			if (selection instanceof ITextSelection) {
    				return (ITextSelection) selection;
    			}
    		}
    	}
    	return null;
    }
	
	/**
	 * Sets the focus to the source folder's text field.
	 */	
	protected void setFocusOnSourceFolder() {
		fSourceFolderDialogField.setFocus();
	}

    protected final class StatusFocusListener implements FocusListener {
        private int fieldID;

        public StatusFocusListener(int fieldID) {
            this.fieldID = fieldID;
        }
        
        public void focusGained(FocusEvent e) {
            fLastFocusedField = this.fieldID;
            doStatusUpdate();
        }
        
        public void focusLost(FocusEvent e) {
            fLastFocusedField = 0;
            doStatusUpdate();
        }
    }

    private class SourceFolderFieldAdapter implements IStringButtonAdapter, IDialogFieldListener {
		public void changeControlPressed(DialogField field) {
		    IPath oldFolderPath = getSourceFolderFullPath();
			IPath newFolderPath = chooseSourceFolder(oldFolderPath);
			if (newFolderPath != null) {
				setSourceFolderFullPath(newFolderPath, false);
				handleFieldChanged(ALL_FIELDS);
			}
		}
		
		public void dialogFieldChanged(DialogField field) {
			handleFieldChanged(ALL_FIELDS);
		}
	}
	
    // ----------- validation ----------
			
	/**
	 * This method is a hook which gets called after the source folder's
	 * text input field has changed. This default implementation updates
	 * the model and returns an error status. The underlying model
	 * is only valid if the returned status is OK.
	 * 
	 * @return the model's error status
	 */
	protected IStatus sourceFolderChanged() {
		StatusInfo status = new StatusInfo();
		
		IPath folderPath = getSourceFolderFullPath();
		if (folderPath == null) {
			status.setError(NewFileWizardMessages.AbstractFileCreationWizardPage_error_EnterSourceFolderName); 
			return status;
		}

		IResource res = fWorkspaceRoot.findMember(folderPath);
		if (res != null && res.exists()) {
			int resType = res.getType();
			if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
				IProject proj = res.getProject();
				if (!proj.isOpen()) {
					status.setError(NLS.bind(NewFileWizardMessages.AbstractFileCreationWizardPage_error_NotAFolder, folderPath)); 
					return status;
				}
			    if (!CoreModel.hasCCNature(proj) && !CoreModel.hasCNature(proj)) {
					if (resType == IResource.PROJECT) {
						status.setError(NewFileWizardMessages.AbstractFileCreationWizardPage_warning_NotACProject); 
						return status;
					}
					status.setWarning(NewFileWizardMessages.AbstractFileCreationWizardPage_warning_NotInACProject); 
				}
			    ICElement e = CoreModel.getDefault().create(res.getFullPath());
			    if (CModelUtil.getSourceFolder(e) == null) {
					status.setError(NLS.bind(NewFileWizardMessages.AbstractFileCreationWizardPage_error_NotASourceFolder, folderPath)); 
					return status;
				}
			} else {
				status.setError(NLS.bind(NewFileWizardMessages.AbstractFileCreationWizardPage_error_NotAFolder, folderPath)); 
				return status;
			}
		} else {
			status.setError(NLS.bind(NewFileWizardMessages.AbstractFileCreationWizardPage_error_FolderDoesNotExist, folderPath)); 
			return status;
		}

		return status;
	}
		
	/**
	 * Hook method that gets called when a field on this page has changed.
	 * 
	 * @param fields Bitwise-OR'd ids of the fields that changed.
	 */
	protected void handleFieldChanged(int fields) {
	    if (fields == 0)
	        return;	// no change

	    if (fieldChanged(fields, SOURCE_FOLDER_ID)) {
			fSourceFolderStatus = sourceFolderChanged();
	    }
	    if (fieldChanged(fields, NEW_FILE_ID)) {
	    	if( isFirstTime ){
	    		isFirstTime = false;
	    		return;
	    	}
	    	fNewFileStatus = fileNameChanged();
	    }
		doStatusUpdate();
	}

	private boolean fieldChanged(int fields, int fieldID) {
	    return ((fields & fieldID) != 0);
	}

	protected void doStatusUpdate() {
	    // do the last focused field first
	    IStatus lastStatus = getLastFocusedStatus();

	    // status of all used components
		IStatus[] status = new IStatus[] {
	        lastStatus,
			(fSourceFolderStatus != lastStatus) ? fSourceFolderStatus : STATUS_OK,
			(fNewFileStatus != lastStatus) ? fNewFileStatus : STATUS_OK,
		};
		
		// the mode severe status will be displayed and the ok button enabled/disabled.
		updateStatus(status);
	}

	private IStatus getLastFocusedStatus() {
	    switch (fLastFocusedField) {
	    	case SOURCE_FOLDER_ID:
	    	    return fSourceFolderStatus;
	    	case NEW_FILE_ID:
	    	    return fNewFileStatus;
    	   default:
               return STATUS_OK;
	    }
    }

	public IPath getSourceFolderFullPath() {
		String text = fSourceFolderDialogField.getText();
		if (text.length() > 0)
		    return new Path(text).makeAbsolute();
	    return null;
	}

	public void setSourceFolderFullPath(IPath folderPath, boolean update) {
		String str = (folderPath != null) ? folderPath.makeRelative().toString() : ""; //.makeRelative().toString(); //$NON-NLS-1$
		fSourceFolderDialogField.setTextWithoutUpdate(str);
		if (update) {
		    fSourceFolderDialogField.dialogFieldChanged();
		}
	}
	
	protected IProject getCurrentProject() {
	    IPath folderPath = getSourceFolderFullPath();
	    if (folderPath != null) {
	        return PathUtil.getEnclosingProject(folderPath);
	    }
	    return null;
	}

    /**
	 * Returns the workspace root.
	 * 
	 * @return the workspace root
	 */ 
	protected IWorkspaceRoot getWorkspaceRoot() {
		return fWorkspaceRoot;
	}	
	
	/*
	 * @see WizardPage#becomesVisible
	 */
	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			setFocus();
		}
	}

	/**
	 * Sets the focus on the starting input field.
	 */		
	protected abstract void setFocus();
				
	IPath chooseSourceFolder(IPath initialPath) {
	    ICElement initElement = getSourceFolderFromPath(initialPath);
	    if (initElement instanceof ISourceRoot) {
	        ICProject cProject = initElement.getCProject();
	        ISourceRoot projRoot = cProject.findSourceRoot(cProject.getProject());
	        if (projRoot != null && projRoot.equals(initElement))
	            initElement = cProject;
	    }
		
		SourceFolderSelectionDialog dialog = new SourceFolderSelectionDialog(getShell());
		dialog.setInput(CoreModel.create(fWorkspaceRoot));
		dialog.setInitialSelection(initElement);
		
		if (dialog.open() == Window.OK) {
			Object result = dialog.getFirstResult();
			if (result instanceof ICElement) {
			    ICElement element = (ICElement)result;
				if (element instanceof ICProject) {
					ICProject cproject = (ICProject)element;
					ISourceRoot folder = cproject.findSourceRoot(cproject.getProject());
					if (folder != null)
					    return folder.getResource().getFullPath();
				}
				return element.getResource().getFullPath();
			}
		}
		return null;
	}

	private ICElement getSourceFolderFromPath(IPath path) {
	    if (path == null)
	        return null;
	    while (path.segmentCount() > 0) {
		    IResource res = fWorkspaceRoot.findMember(path);
			if (res != null && res.exists()) {
				int resType = res.getType();
				if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
				    ICElement elem = CoreModel.getDefault().create(res.getFullPath());
				    ICContainer sourceFolder = CModelUtil.getSourceFolder(elem);
				    if (sourceFolder != null)
				        return sourceFolder;
				    if (resType == IResource.PROJECT) {
				        return elem;
				    }
				}
			}
			path = path.removeLastSegments(1);
	    }
		return null;
	}

	/**
	 * Returns the full path computed from the file name field
	 * and the source folder.
	 * 
	 * @return the file path
	 */
	public abstract IPath getFileFullPath();
	
	/**
	 * Hook method that gets called when the file name has changed. The method validates the 
	 * file name and returns the status of the validation.
	 * 
	 * @return the status of the validation
	 */
	protected abstract IStatus fileNameChanged();

	/**
	 * Creates the new file using the entered field values.
	 * 
	 * @param monitor a progress monitor to report progress.
	 * @throws CoreException Thrown when the creation failed.
	 */
	public abstract void createFile(IProgressMonitor monitor) throws CoreException;
	
	/**
	 * Returns the created file. The method only returns a valid translation unit 
	 * after <code>createFile</code> has been called.
	 * 
	 * @return the created translation unit
	 * @see #createFile(IProgressMonitor)
	 */			
	public abstract ITranslationUnit getCreatedFileTU();
	
	/**
	 * @return the name of the template used in the previous dialog invocation. 
	 */
	public abstract String getLastUsedTemplateName();
	
	/**
	 * Saves the name of the last used template.
	 * 
	 * @param name the name of a template, or an empty string for no template.
	 */
	public abstract void saveLastUsedTemplateName(String name);
}
