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

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.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.services.IDisposable;

import org.eclipse.statet.ecommons.emf.ui.forms.EFColors;
import org.eclipse.statet.ecommons.ui.util.ImageRegistryUtil;


public class RtModelUIPlugin extends AbstractUIPlugin {
	
	
	public static final String BUNDLE_ID= "org.eclipse.statet.rtm.base.ui"; //$NON-NLS-1$
	
	
	public static final String R_GRAPHICS_PERSPECTIVE_ID= "org.eclipse.statet.rtm.base.perspectives.RGraphics"; //$NON-NLS-1$
	
	public static final String R_TASK_EDITOR_CONTEXT_ID= "org.eclipse.statet.rtm.contexts.RTaskEditor"; //$NON-NLS-1$
	
	public static final String RUN_R_TASK_COMMAND_ID= "org.eclipse.statet.rtm.commands.RunRTask"; //$NON-NLS-1$
	
	public static final String OBJ_UNKOWN_TYPE_IMAGE_ID= BUNDLE_ID + "/obj/rtype-unknown"; //$NON-NLS-1$
	
	public static final String OBJ_REXPR_TYPE_IMAGE_ID= BUNDLE_ID + "/obj/rtype-expr"; //$NON-NLS-1$
	public static final String OBJ_DATAFRAME_TYPE_IMAGE_ID= BUNDLE_ID + "/obj/rtype-dataframe"; //$NON-NLS-1$
	public static final String OBJ_COLUMN_TYPE_IMAGE_ID= BUNDLE_ID + "/obj/rtype-column"; //$NON-NLS-1$
	public static final String OBJ_COLOR_TYPE_IMAGE_ID= BUNDLE_ID + "/obj/rtype-color"; //$NON-NLS-1$
	public static final String OBJ_TEXT_TYPE_IMAGE_ID= BUNDLE_ID + "/obj/rtype-text"; //$NON-NLS-1$
	
	public static final boolean DEBUG= false;
	
	
	private static RtModelUIPlugin instance;
	
	/**
	 * Returns the shared plug-in instance
	 *
	 * @return the shared instance
	 */
	public static RtModelUIPlugin 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<IDisposable> disposables= new ArrayList<>();
	
	private EFColors formColors;
	
	
	public RtModelUIPlugin() {
	}
	
	
	@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;
			}
			if (this.formColors != null) {
				this.formColors.dispose();
				this.formColors= null;
			}
			
			for (final IDisposable listener : this.disposables) {
				try {
					listener.dispose();
				}
				catch (final Throwable e) {
					log(new Status(IStatus.ERROR, BUNDLE_ID,
							"An error occured when disposing the plug-in.",
							e ));
				}
			}
			this.disposables.clear();
		}
		finally {
			instance= null;
			super.stop(context);
		}
	}
	
	
	public void addStoppingListener(final IDisposable listener) {
		if (listener == null) {
			throw new NullPointerException();
		}
		synchronized (this) {
			if (!this.started) {
				throw new IllegalStateException("The plug-in is not started.");
			}
			this.disposables.add(listener);
		}
	}
	
	
	@Override
	protected void initializeImageRegistry(final ImageRegistry reg) {
		if (!this.started) {
			throw new IllegalStateException("The plug-in is not started.");
		}
		final ImageRegistryUtil util= new ImageRegistryUtil(this);
		
		reg.put(OBJ_UNKOWN_TYPE_IMAGE_ID, ImageDescriptor.getMissingImageDescriptor());
		
		util.register(OBJ_REXPR_TYPE_IMAGE_ID, ImageRegistryUtil.T_OBJ, "rtyped-expr.png");
		util.register(OBJ_DATAFRAME_TYPE_IMAGE_ID, ImageRegistryUtil.T_OBJ, "rtyped-dataframe.png");
		util.register(OBJ_COLUMN_TYPE_IMAGE_ID, ImageRegistryUtil.T_OBJ, "rtyped-column.png");
		util.register(OBJ_COLOR_TYPE_IMAGE_ID, ImageRegistryUtil.T_OBJ, "rtyped-color.png");
		util.register(OBJ_TEXT_TYPE_IMAGE_ID, ImageRegistryUtil.T_OBJ, "rtyped-text.png");
	}
	
	public EFColors getFormColors(final Display display) {
		if (this.formColors == null) {
			if (!this.started) {
				throw new IllegalStateException("The plug-in is not started.");
			}
			this.formColors= new EFColors(display);
			this.formColors.markShared();
		}
		return this.formColors;
	}
	
}
