/*=============================================================================#
 # Copyright (c) 2009, 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.yaml.ui;

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.text.TextAttribute;
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.ecommons.preferences.PreferencesUtil;
import org.eclipse.statet.ecommons.text.ui.settings.JFaceTextStyleManager;
import org.eclipse.statet.ecommons.text.ui.settings.PreferenceStoreTextStyleManager;

import org.eclipse.statet.internal.yaml.ui.editors.YamlDocumentProvider;
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.yaml.core.YamlCore;
import org.eclipse.statet.yaml.ui.YamlUI;
import org.eclipse.statet.yaml.ui.sourceediting.YamlEditingSettings;
import org.eclipse.statet.yaml.ui.text.YamlTextStyles;


public class YamlUIPlugin extends AbstractUIPlugin {
	
	
	private static YamlUIPlugin instance;
	
	/**
	 * Returns the shared plug-in instance
	 *
	 * @return the shared instance
	 */
	public static YamlUIPlugin getInstance() {
		return instance;
	}
	
	
	public static final void log(final IStatus status) {
		final Plugin plugin= getInstance();
		if (plugin != null) {
			plugin.getLog().log(status);
		}
	}
	
	
	private boolean started;
	
	private final List<Disposable> disposables= new ArrayList<>();
	
	private IPreferenceStore editorPreferenceStore;
	
	private YamlDocumentProvider yamlDocumentProvider;
	
	private JFaceTextStyleManager yamlTextStyles;
	
	private ContextTypeRegistry yamlEditorTemplateContextTypeRegistry;
	private TemplateStore yamlEditorTemplateStore;
	
	private ContentAssistComputerRegistry yamlEditorContentAssistRegistry;
	
	
	public YamlUIPlugin() {
	}
	
	
	@Override
	public void start(final BundleContext context) throws Exception {
		super.start(context);
		instance= this;
		
		this.started= true;
	}
	
	@Override
	public void stop(final BundleContext context) throws Exception {
		try {
			synchronized (this) {
				this.started= false;
				
				this.editorPreferenceStore= null;
				
				this.yamlDocumentProvider= null;
			}
			
			for (final Disposable listener : this.disposables) {
				try {
					listener.dispose();
				}
				catch (final Throwable e) {
					log(new Status(IStatus.ERROR, YamlUI.BUNDLE_ID,
							"Error occured when dispose module", //$NON-NLS-1$
							e ));
				}
			}
			this.disposables.clear();
		}
		finally {
			instance= null;
			super.stop(context);
		}
	}
	
	
	public void addStoppingListener(final Disposable listener) {
		if (listener == null) {
			throw new NullPointerException();
		}
		synchronized (this) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			this.disposables.add(listener);
		}
	}
	
	
//	@Override
//	protected void initializeImageRegistry(final ImageRegistry reg) {
//		if (!this.started) {
//			throw new IllegalStateException("Plug-in is not started.");
//		}
//		final ImageRegistryUtil util= new ImageRegistryUtil(this);
//		
//		util.register(YamlUIResources.OBJ_LABEL_IMAGE_ID, ImageRegistryUtil.T_OBJ, "label.png");
//	}
	
	
	public synchronized IPreferenceStore getEditorPreferenceStore() {
		if (this.editorPreferenceStore == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			this.editorPreferenceStore= CombinedPreferenceStore.createStore(
					getPreferenceStore(),
					EditorsUI.getPreferenceStore() );
		}
		return this.editorPreferenceStore;
	}
	
	public synchronized YamlDocumentProvider getYamlDocumentProvider() {
		if (this.yamlDocumentProvider == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			this.yamlDocumentProvider= new YamlDocumentProvider();
			this.disposables.add(this.yamlDocumentProvider);
		}
		return this.yamlDocumentProvider;
	}
	
	public synchronized PreferenceStoreTextStyleManager<TextAttribute> getYamlTextStyles() {
		if (this.yamlTextStyles == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			this.yamlTextStyles= new JFaceTextStyleManager(getPreferenceStore(),
					YamlTextStyles.YAML_TEXTSTYLE_CONFIG_QUALIFIER );
			PreferencesUtil.getSettingsChangeNotifier().addManageListener(this.yamlTextStyles);
		}
		return this.yamlTextStyles;
	}
	
	public synchronized ContextTypeRegistry getYamlEditorTemplateContextTypeRegistry() {
		if (this.yamlEditorTemplateContextTypeRegistry == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			this.yamlEditorTemplateContextTypeRegistry= new WaContributionContextTypeRegistry(
					"org.eclipse.statet.yaml.templates.YamlEditor" ); //$NON-NLS-1$;
		}
		return this.yamlEditorTemplateContextTypeRegistry;
	}
	
	public synchronized TemplateStore getYamlEditorTemplateStore() {
		if (this.yamlEditorTemplateStore == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			this.yamlEditorTemplateStore= new ContributionTemplateStore(
					getYamlEditorTemplateContextTypeRegistry(), getPreferenceStore(),
					"editor/assist/Yaml/EditorTemplates.store" );
			try {
				this.yamlEditorTemplateStore.load();
			}
			catch (final IOException e) {
				getLog().log(new Status(IStatus.ERROR, YamlUI.BUNDLE_ID, 0,
						"An error occured when loading 'YAML Editor' template store.", e )); 
			}
		}
		return this.yamlEditorTemplateStore;
	}
	
	public synchronized ContentAssistComputerRegistry getYamlEditorContentAssistRegistry() {
		if (this.yamlEditorContentAssistRegistry == null) {
			if (!this.started) {
				throw new IllegalStateException("Plug-in is not started.");
			}
			this.yamlEditorContentAssistRegistry= new ContentAssistComputerRegistry(
					YamlCore.YAML_CONTENT_ID, 
					YamlEditingSettings.ASSIST_YAML_PREF_QUALIFIER ); 
			this.disposables.add(this.yamlEditorContentAssistRegistry);
		}
		return this.yamlEditorContentAssistRegistry;
	}
	
}
