package jp.sourceforge.projects.ee2e.core.wizards;

import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.operation.*;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import java.io.*;
import org.eclipse.ui.*;
import jp.sourceforge.projects.ee2e.core.relax.*;
import jp.sourceforge.projects.ee2e.core.EE2EPlugin;
import jp.sourceforge.projects.ee2e.core.editors.EE2EToolkit;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.ui.part.*;

/**
 * This is a sample new wizard. Its role is to create a new file 
 * resource in the provided container. If the container resource
 * (a folder or a project) is selected in the workspace 
 * when the wizard is opened, it will accept it as the target
 * container. The wizard creates one file with the extension
 * If a sample multi-page editor (also available
 * as a template) is registered for the same extension, it will
 * be able to open it.
 */
public abstract class EE2EAbstractNewWizard extends Wizard implements INewWizard {
	private EE2ENewWizardPage page;
	private ISelection structuredSelection;

	/** */
	protected EE2ENewWizardPage getPage() {
		return this.page;
	}

	/** */
	protected void setPage(EE2ENewWizardPage page) {
		this.page = page;
	}

	/** */
	protected ISelection getISelection() {
		return this.structuredSelection;
	}

	/**
	 * Constructor for EE2EWizardSdoc.
	 */
	public EE2EAbstractNewWizard() {
		super();
		setNeedsProgressMonitor(true);
	}
	
	/**
	 * Adding the page to the wizard.
	 */
    public final void addPages() {
        String targetKey = this.getTargetKey();
        int targetIndex = this.getTargetIndex();
        ISelection iSelection = this.getISelection();
        ImageDescriptor image;
        try {
            URL prefix = new URL(EE2EPlugin.getDefault().getDescriptor().getInstallURL(), "icons/");
            image = ImageDescriptor.createFromURL(new URL(prefix, targetKey + ".gif"));
        } catch (MalformedURLException e) {
            image = null;
        }
        this.setDefaultPageImageDescriptor(image);
        EE2ENewWizardPage wizardPage = new EE2ENewWizardPage(iSelection,image,targetKey,targetIndex);
        this.setPage(wizardPage);
        addPage(this.getPage());
    }

	/**
	 * This method is called when 'Finish' button is pressed in
	 * the wizard. We will create an operation and run it
	 * using wizard as execution context.
	 */
	public boolean performFinish() {
		final String containerName = page.getContainerName();
		final String fileName = page.getFileName();
		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InvocationTargetException {
				try {
					doFinish(containerName, fileName, monitor);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				} finally {
					monitor.done();
				}
			}
		};
		try {
			getContainer().run(true, false, op);
		} catch (InterruptedException e) {
			return false;
		} catch (InvocationTargetException e) {
			Throwable realException = e.getTargetException();
			MessageDialog.openError(getShell(), "Error", realException.getMessage());
			return false;
		}
		return true;
	}
	
	/**
	 * The worker method. It will find the container, create the
	 * file if missing or just replace its contents, and open
	 * the editor on the newly created file.
	 */

	private void doFinish(
		String containerName,
		String fileName,
		IProgressMonitor monitor)
		throws CoreException {
		// create a sample file
		monitor.beginTask("Creating " + fileName, 2);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IResource resource = root.findMember(new Path(containerName));
		if (!resource.exists() || !(resource instanceof IContainer)) {
			throwCoreException("Container \"" + containerName + "\" does not exist.");
		}
		IContainer container = (IContainer) resource;
		final IFile file = container.getFile(new Path(fileName));
		try {
			InputStream stream = openMyContentStream();
			if (file.exists()) {
				file.setContents(stream, true, true, monitor);
			} else {
				file.create(stream, true, monitor);
			}
			stream.close();
		} catch (IOException e) {
		}
		monitor.worked(1);
		monitor.setTaskName("Opening file for editing...");
		getShell().getDisplay().asyncExec(new Runnable() {
			public void run() {
				IWorkbenchPage benchPage =
					PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
                IEditorInput input = new FileEditorInput(file);
                try {
					benchPage.openEditor(input,IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID);
				} catch (PartInitException e) {
				}
			}
		});
		monitor.worked(1);
	}
	
    public abstract String getTargetKey();
    public abstract int getTargetIndex();

	/**
	 * We will initialize file contents with a sample text.
	 */
	protected InputStream openMyContentStream() {
        String key = this.getTargetKey();
        int index = getTargetIndex();
        EE2REe2e ee2e = EE2EToolkit.get().getEe2e(key);
        if((index < 0) && (index < ee2e.getTemplateListCount())) {
            return new ByteArrayInputStream(((String)"").getBytes());
        }
        EE2RTemplateList templateList = ee2e.getTemplateList(index);
        if(templateList == null) {
            return new ByteArrayInputStream(((String)"").getBytes());
        }
        StringBuffer buffer = new StringBuffer();
        for(int i = 0 ; i < templateList.getTemplateCount() ; i++) {
            EE2RTemplate template = templateList.getTemplate(i);
            String string = template.getName();
            if ( (string != null) && (!string.equals("")) ) {
                StringBuffer sb = new StringBuffer(string);
                while (0 <= sb.indexOf("\\n")) {
                    int of = sb.indexOf("\\n");
                    sb.replace(of, of + 2, "\n");
                }
                while (0 <= sb.indexOf("\\t")) {
                    int of = sb.indexOf("\\t");
                    sb.replace(of, of + 2, "\t");
                }
                buffer.append(sb);
            } else {
                String type = template.getType();
                IPreferenceStore store = EE2EPlugin.getDefault().getPreferenceStore();
                if (type.equals(EE2EPlugin.P_CONTRY)) {
                    buffer.append(store.getString(EE2EPlugin.P_CONTRY));
                } else if(type.equals(EE2EPlugin.P_LOCALE)) {
                    buffer.append(store.getString(EE2EPlugin.P_LOCALE));
                } else {
                    buffer.append(EE2EPlugin.getResourceString(type));
                }
            }
        }
        String contents = buffer.toString();
        return new ByteArrayInputStream(contents.getBytes());
    }

	private void throwCoreException(String message) throws CoreException {
		IStatus status =
			new Status(IStatus.ERROR, EE2EPlugin.PLUGIN_ID , IStatus.OK, message, null);
		throw new CoreException(status);
	}

	/**
	 * We will accept the structuredSelection in the workbench to see if
	 * we can initialize from it.
	 * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
	 */
	public void init(IWorkbench workbench, IStructuredSelection selection) {
		this.structuredSelection = selection;
	}
}