/*=============================================================================#
 # Copyright (c) 2007, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.redocs.tex.r.ui;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.ecommons.text.TextUtil;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;

import org.eclipse.statet.internal.redocs.tex.r.RedocsTexRPlugin;
import org.eclipse.statet.ltk.core.LTK;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.ui.templates.NewDocTemplateGenerateWizardPage;
import org.eclipse.statet.ltk.ui.templates.TemplateUtils.EvaluatedTemplate;
import org.eclipse.statet.ltk.ui.wizards.NewElementWizard;
import org.eclipse.statet.redocs.tex.r.core.TexRweaveCore;
import org.eclipse.statet.redocs.tex.r.ui.TexRweaveUI;
import org.eclipse.statet.redocs.tex.r.ui.codegen.CodeGeneration;


public class NewLtxRweaveDocCreationWizard extends NewElementWizard {
	
	
	private static class NewRweaveFile extends NewFile {
		
		private final Template template;
		
		public NewRweaveFile(final IPath containerPath, final String resourceName,
				final Template template) {
			super(containerPath, resourceName, TexRweaveCore.LTX_R_CONTENT_TYPE);
			this.template= template;
		}
		
		@Override
		protected String getInitialFileContent(final IFile newFileHandle, final SubMonitor m) {
			final String lineDelimiter= TextUtil.getLineDelimiter(newFileHandle.getProject());
			final ISourceUnit su= LTK.getSourceUnitManager().getSourceUnit(
					LTK.PERSISTENCE_CONTEXT, newFileHandle, getContentType(newFileHandle),
					true, m );
			try {
				final EvaluatedTemplate data= CodeGeneration.getNewDocContent(su, lineDelimiter,
						this.template );
				if (data != null) {
					this.initialSelection= data.getRegionToSelect();
					return data.getContent();
				}
			}
			catch (final CoreException e) {
				StatusManager.getManager().handle(new Status(IStatus.ERROR, TexRweaveUI.BUNDLE_ID, 0,
						Messages.NewDocWizard_error_ApplyTemplate_message,
						e ));
			}
			finally {
				if (su != null) {
					su.disconnect(m);
				}
			}
			return null;
		}
		
	}
	
	
	private NewLtxRweaveDocCreationWizardPage firstPage;
	private NewFile newDocFile;
	private NewDocTemplateGenerateWizardPage templatePage;
	
	
	public NewLtxRweaveDocCreationWizard() {
		setDialogSettings(DialogUtils.getDialogSettings(RedocsTexRPlugin.getInstance(), "NewElementWizard")); //$NON-NLS-1$
		setDefaultPageImageDescriptor(RedocsTexRPlugin.getInstance().getImageRegistry().getDescriptor(
				RedocsTexRPlugin.WIZBAN_NEW_LTXRWEAVE_FILE_IMAGE_ID ));
		setWindowTitle(Messages.NewDocWizard_title);
	}
	
	
	@Override
	public void addPages() {
		super.addPages();
		this.firstPage= new NewLtxRweaveDocCreationWizardPage(getSelection());
		addPage(this.firstPage);
		this.templatePage= new NewDocTemplateGenerateWizardPage(
				new NewDocTemplateCategoryConfiguration(),
				LtxRweaveTemplates.NEWDOC_TEMPLATE_CATEGORY_ID );
		addPage(this.templatePage);
	}
	
	@Override // for lazy loading
	public void createPageControls(final Composite pageContainer) {
		this.firstPage.createControl(pageContainer);
	}
	
	@Override
	protected ISchedulingRule getSchedulingRule() {
		final ISchedulingRule rule= createRule(this.newDocFile.getResource());
		if (rule != null) {
			return rule;
		}
		
		return super.getSchedulingRule();
	}
	
	@Override
	public boolean performFinish() {
		// befor super, so it can be used in getSchedulingRule
		this.newDocFile= new NewRweaveFile(
				this.firstPage.resourceGroup.getContainerFullPath(),
				this.firstPage.resourceGroup.getResourceName(),
				this.templatePage.getTemplate() );
		
		final boolean result= super.performFinish();
		
		final IFile newFile= this.newDocFile.getResource();
		if (result && newFile != null) {
			// select and open file
			selectAndReveal(newFile);
			openResource(this.newDocFile);
		}
		
		return result;
	}
	
	@Override
	protected void performOperations(final IProgressMonitor monitor) throws InterruptedException, CoreException, InvocationTargetException {
		final SubMonitor m= SubMonitor.convert(monitor, Messages.NewDocWizard_Task_label, 10 + 1);
		
		this.newDocFile.createFile(m.newChild(10));
		m.worked(0);
		
		this.firstPage.saveSettings();
		m.worked(1);
	}
	
}
