/*=============================================================================#
 # Copyright (c) 2007, 2021 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.wikitext.r;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.osgi.framework.BundleContext;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.text.templates.ContextTypeRegistry;
import org.eclipse.jface.text.templates.persistence.TemplateStore;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import org.eclipse.statet.jcommons.lang.Disposable;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.ui.util.ImageRegistryUtil;

import org.eclipse.statet.docmlet.wikitext.ui.sourceediting.WikitextEditingSettings;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.internal.redocs.wikitext.r.ui.editors.WikidocRweaveDocumentProvider;
import org.eclipse.statet.ltk.ui.LTKUIPreferences;
import org.eclipse.statet.ltk.ui.sourceediting.assist.ContentAssistComputerRegistry;
import org.eclipse.statet.ltk.ui.templates.WaContributionContextTypeRegistry;
import org.eclipse.statet.ltk.ui.util.CombinedPreferenceStore;
import org.eclipse.statet.redocs.wikitext.r.core.WikitextRweaveCore;
import org.eclipse.statet.redocs.wikitext.r.ui.WikitextRweaveUI;


/**
 * The activator class controls the plug-in life cycle
 */
@NonNullByDefault
public class RedocsWikitextRPlugin extends AbstractUIPlugin {
	
	
/*- Images --------------------------------------------------------------------*/
	
	private static final String NS= "org.eclipse.statet.redocs.wikitext.r"; //$NON-NLS-1$
	
	public static final String OBJ_WIKIDOCRWEAVE_IMAGE_ID= NS + "/image/obj/WikidocRweave"; //$NON-NLS-1$
	
	public static final String TOOL_NEW_WIKIDOCRWEAVE_IMAGE_ID= NS + "/image/tool/New-WikidocRweave"; //$NON-NLS-1$
	
	public static final String WIZBAN_NEW_WIKIDOCRWEAVE_FILE_IMAGE_ID= NS + "/image/wizban/New-WikidocRweaveFile"; //$NON-NLS-1$
	
/*- Prefs ---------------------------------------------------------------------*/
	
	public static final String WIKITEXT_RWEAVE_EDITOR_NODE= WikitextRweaveUI.BUNDLE_ID + "/rweavetex.editor/options"; //$NON-NLS-1$
	
	
	private static @Nullable RedocsWikitextRPlugin instance;
	
	/**
	 * Returns the shared plug-in instance
	 *
	 * @return the shared instance
	 */
	public static RedocsWikitextRPlugin getInstance() {
		return instance;
	}
	
	
	public static void log(final IStatus status) {
		final Plugin plugin= getInstance();
		if (plugin != null) {
			plugin.getLog().log(status);
		}
	}
	
	
	private boolean started;
	
	private List<Disposable> disposables;
	
	private @Nullable WikidocRweaveDocumentProvider docRDocumentProvider;
	
	private @Nullable IPreferenceStore editorPreferenceStore;
	
	private @Nullable ContextTypeRegistry codegenTemplateContextTypeRegistry;
	private @Nullable TemplateStore codegenTemplateStore;
	
	private @Nullable ContextTypeRegistry docTemplateContextTypeRegistry;
	private @Nullable TemplateStore docTemplateStore;
	
	private @Nullable ContentAssistComputerRegistry wikidocRweaveEditorContentAssistRegistry;
	
	
	/**
	 * The constructor
	 */
	public RedocsWikitextRPlugin() {
	}
	
	@Override
	public void start(final BundleContext context) throws Exception {
		super.start(context);
		instance= this;
		
		this.disposables= new ArrayList<>();
		
		this.started= true;
	}
	
	
	@Override
	public void stop(final BundleContext context) throws Exception {
		try {
			synchronized (this) {
				this.started= false;
				
				this.editorPreferenceStore= null;
				this.codegenTemplateContextTypeRegistry= null;
				this.codegenTemplateStore= null;
				this.docTemplateContextTypeRegistry= null;
				this.docTemplateStore= null;
				this.wikidocRweaveEditorContentAssistRegistry= null;
			}
			
			for (final Disposable listener : this.disposables) {
				try {
					listener.dispose();
				}
				catch (final Throwable e) {
					log(new Status(IStatus.ERROR, WikitextRweaveUI.BUNDLE_ID,
							"Error occured while disposing a module.", //$NON-NLS-1$
							e ));
				}
			}
			this.disposables= null;
		}
		finally {
			instance= null;
			super.stop(context);
		}
	}
	
	
	@Override
	protected void initializeImageRegistry(final ImageRegistry reg) {
		final ImageRegistryUtil util= new ImageRegistryUtil(this);
		
		util.register(OBJ_WIKIDOCRWEAVE_IMAGE_ID, ImageRegistryUtil.T_OBJ, "wikidoc_rweave-file.png"); //$NON-NLS-1$
		
		util.register(TOOL_NEW_WIKIDOCRWEAVE_IMAGE_ID, ImageRegistryUtil.T_TOOL, "new-wikidoc_rweave-file.png"); //$NON-NLS-1$
		
		util.register(WIZBAN_NEW_WIKIDOCRWEAVE_FILE_IMAGE_ID, ImageRegistryUtil.T_WIZBAN, "new-wikidoc_rweave-file.png"); //$NON-NLS-1$
	}
	
	
	public synchronized WikidocRweaveDocumentProvider getDocRDocumentProvider() {
		WikidocRweaveDocumentProvider documentProvider= this.docRDocumentProvider;
		if (documentProvider == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			documentProvider= new WikidocRweaveDocumentProvider();
			this.disposables.add(documentProvider);
			this.docRDocumentProvider= documentProvider;
		}
		return documentProvider;
	}
	
	
	/**
	 * Returns the template context type registry for the code generation templates.
	 * 
	 * @return the template context type registry
	 */
	public synchronized ContextTypeRegistry getCodegenTemplateContextTypeRegistry() {
		ContextTypeRegistry templateContextTypeRegistry= this.codegenTemplateContextTypeRegistry;
		if (templateContextTypeRegistry == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			templateContextTypeRegistry= new WaContributionContextTypeRegistry(
					"org.eclipse.statet.redocs.templates.WikitextRweaveCodegen" ); //$NON-NLS-1$
			this.codegenTemplateContextTypeRegistry= templateContextTypeRegistry;
		}
		return templateContextTypeRegistry;
	}
	
	/**
	 * Returns the template store for the code generation templates.
	 * 
	 * @return the template store
	 */
	public synchronized TemplateStore getCodegenTemplateStore() {
		TemplateStore templateStore= this.codegenTemplateStore;
		if (templateStore == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			templateStore= new ContributionTemplateStore(
					getCodegenTemplateContextTypeRegistry(), getPreferenceStore(),
					"codegen/CodeTemplates_store" ); //$NON-NLS-1$
			try {
				templateStore.load();
			}
			catch (final IOException e) {
				log(new Status(IStatus.ERROR, WikitextRweaveUI.BUNDLE_ID,
						"An error occured when loading 'Wikitext+R code generation' template store.",
						e ));
			}
			this.codegenTemplateStore= templateStore;
		}
		return templateStore;
	}
	
	/**
	 * Returns the template context type registry for the new documents templates.
	 * 
	 * @return the template context type registry
	 */
	public synchronized ContextTypeRegistry getDocTemplateContextTypeRegistry() {
		ContextTypeRegistry templateContextTypeRegistry= this.docTemplateContextTypeRegistry;
		if (templateContextTypeRegistry == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			templateContextTypeRegistry= new WaContributionContextTypeRegistry(
					"org.eclipse.statet.redocs.templates.WikitextRweaveDoc" ); //$NON-NLS-1$
			this.docTemplateContextTypeRegistry= templateContextTypeRegistry;
		}
		return templateContextTypeRegistry;
	}
	
	/**
	 * Returns the template store for the new documents templates.
	 * 
	 * @return the template store
	 */
	public synchronized TemplateStore getDocTemplateStore() {
		TemplateStore templateStore= this.docTemplateStore;
		if (templateStore == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			templateStore= new ContributionTemplateStore(
					getDocTemplateContextTypeRegistry(), getPreferenceStore(),
					"codegen/DocTemplates_store" ); //$NON-NLS-1$
			try {
				templateStore.load();
			}
			catch (final IOException e) {
				log(new Status(IStatus.ERROR, WikitextRweaveUI.BUNDLE_ID, 0,
						"An error occured when loading 'Wikitext+R document' template store.",
						e ));
			}
			this.docTemplateStore= templateStore;
		}
		return templateStore;
	}
	
	
	public synchronized IPreferenceStore getEditorPreferenceStore() {
		IPreferenceStore preferenceStore= this.editorPreferenceStore;
		if (preferenceStore == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			preferenceStore= CombinedPreferenceStore.createStore(
					getPreferenceStore(),
					WikitextEditingSettings.getPreferenceStore(),
					RUIPlugin.getInstance().getPreferenceStore(),
					LTKUIPreferences.getPreferenceStore(),
					EditorsUI.getPreferenceStore() );
			this.editorPreferenceStore= preferenceStore;
		}
		return preferenceStore;
	}
	
	/** Only used for chunk */
	public synchronized ContentAssistComputerRegistry getWikidocRweaveEditorContentAssistRegistry() {
		ContentAssistComputerRegistry contentAssistRegistry= this.wikidocRweaveEditorContentAssistRegistry;
		if (contentAssistRegistry == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			contentAssistRegistry= new ContentAssistComputerRegistry(
					WikitextRweaveCore.WIKIDOC_R_CONTENT_ID,
					WIKITEXT_RWEAVE_EDITOR_NODE ); 
			this.disposables.add(contentAssistRegistry);
			this.wikidocRweaveEditorContentAssistRegistry= contentAssistRegistry;
		}
		return contentAssistRegistry;
	}
	
}
