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

import java.util.EnumSet;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.preferences.core.Preference;
import org.eclipse.statet.ecommons.preferences.core.Preference.BooleanPref;
import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess;
import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils;
import org.eclipse.statet.ecommons.preferences.ui.RGBPref;
import org.eclipse.statet.ecommons.text.ui.presentation.ITextPresentationConstants;
import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.nico.core.runtime.SubmitType;
import org.eclipse.statet.nico.core.runtime.ToolController;
import org.eclipse.statet.nico.core.runtime.ToolProcess;
import org.eclipse.statet.nico.core.runtime.ToolStreamProxy;
import org.eclipse.statet.nico.ui.NicoUIPreferences;


/**
 * Connects a console to the streams of a tool process/controller.
 */
public class NIConsoleColorAdapter {
	
	
	private static final List<String> STREAM_IDS= ImCollections.newList(
			NIConsoleOutputStream.INFO_STREAM_ID,
			NIConsoleOutputStream.STD_INPUT_STREAM_ID,
			NIConsoleOutputStream.STD_OUTPUT_STREAM_ID,
			NIConsoleOutputStream.STD_ERROR_STREAM_ID,
			NIConsoleOutputStream.SYSTEM_OUTPUT_STREAM_ID,
			NIConsoleOutputStream.OTHER_TASKS_INFO_STREAM_ID,
			NIConsoleOutputStream.OTHER_TASKS_STD_INPUT_STREAM_ID,
			NIConsoleOutputStream.OTHER_TASKS_STD_OUTPUT_STREAM_ID,
			NIConsoleOutputStream.OTHER_TASKS_STD_ERROR_STREAM_ID );
	
	
	private NIConsole console;
	
	private final PreferenceAccess prefAccess;
	
	
	public NIConsoleColorAdapter() {
		this.prefAccess= PreferenceUtils.getInstancePrefs();
	}
	
	
	public List<String> getStreamIds() {
		return STREAM_IDS;
	}
	
	void connect(final ToolProcess process, final NIConsole console) {
		this.console= console;
		
		final ToolController controller= process.getController();
		if (controller != null) {
			final ToolStreamProxy proxy= controller.getStreams();
			
			final PreferenceAccess prefs= PreferenceUtils.getInstancePrefs();
			final EnumSet<SubmitType> includeSet= prefs.getPreferenceValue(
					NicoUIPreferences.OUTPUT_FILTER_SUBMITTYPES_INCLUDE_PREF );
			
			final EnumSet<SubmitType> allTypes= EnumSet.allOf(SubmitType.class);
			final EnumSet<SubmitType> otherTypes= EnumSet.of(SubmitType.OTHER);
			final EnumSet<SubmitType> defaultTypes= EnumSet.complementOf(otherTypes);
			
			console.connect(proxy.getInfoStreamMonitor(),
					NIConsoleOutputStream.INFO_STREAM_ID, defaultTypes );
			console.connect(proxy.getInfoStreamMonitor(),
					NIConsoleOutputStream.OTHER_TASKS_INFO_STREAM_ID, otherTypes );
			console.connect(proxy.getInputStreamMonitor(),
					NIConsoleOutputStream.STD_INPUT_STREAM_ID, defaultTypes );
			console.connect(proxy.getOutputStreamMonitor(),
					NIConsoleOutputStream.STD_OUTPUT_STREAM_ID, defaultTypes );
			console.connect(proxy.getErrorStreamMonitor(),
					NIConsoleOutputStream.STD_ERROR_STREAM_ID, defaultTypes );
			if (includeSet.contains(SubmitType.OTHER)) {
				console.connect(proxy.getInputStreamMonitor(),
						NIConsoleOutputStream.OTHER_TASKS_STD_INPUT_STREAM_ID, otherTypes );
				console.connect(proxy.getOutputStreamMonitor(),
						NIConsoleOutputStream.OTHER_TASKS_STD_OUTPUT_STREAM_ID, otherTypes );
				console.connect(proxy.getErrorStreamMonitor(),
						NIConsoleOutputStream.OTHER_TASKS_STD_ERROR_STREAM_ID, otherTypes );
			}
			console.connect(proxy.getSystemOutputMonitor(),
					NIConsoleOutputStream.SYSTEM_OUTPUT_STREAM_ID,
					(includeSet.contains(SubmitType.OTHER)) ? allTypes : defaultTypes );
			
			updateSettings();
		}
	}
	
	void updateSettings() {
		final NIConsole console= this.console;
		if (console == null) {
			return;
		}
		UIAccess.getDisplay().syncExec(new Runnable() {
			@Override
			public void run() {
				for (final String streamId : STREAM_IDS) {
					final NIConsoleOutputStream stream= console.getStream(streamId);
					if (stream != null) {
						stream.setColor(SharedUIResources.getColors().getColor(
								getPrefValue(getForegroundColorPref(streamId)) ));
						stream.setBackgroundColor(SharedUIResources.getColors().getColor(
								getPrefValue(getBackgroundColorPref(streamId)) ));
						stream.setFontStyle(getFontStyle(streamId));
					}
				}
			}
		});
	}
	
	public void disconnect() {
		this.console= null;
	}
	
	private <T> @Nullable T getPrefValue(final @Nullable Preference<T> preference) {
		if (preference != null) {
			return this.prefAccess.getPreferenceValue(preference);
		}
		return null;
	}
	
	private int getFontStyle(final String streamId) {
		final String rootKey= getPrefRootKey(streamId);
		if (rootKey == null) {
			return 0;
		}
		int style= this.prefAccess.getPreferenceValue(new BooleanPref(
				NicoUIPreferences.OUTPUT_QUALIFIER,
				rootKey + ITextPresentationConstants.TEXTSTYLE_BOLD_SUFFIX )) ?
				SWT.BOLD : SWT.NORMAL;
		if (this.prefAccess.getPreferenceValue(new BooleanPref(
				NicoUIPreferences.OUTPUT_QUALIFIER,
				rootKey + ITextPresentationConstants.TEXTSTYLE_ITALIC_SUFFIX ))) {
			style |= SWT.ITALIC;
		}
		return style;
	}
	
	
	public static Preference<RGB> getForegroundColorPref(final String streamId) {
		final String rootKey= getPrefRootKey(streamId);
		if (rootKey != null) {
			return new RGBPref(NicoUIPreferences.OUTPUT_QUALIFIER,
					rootKey + ITextPresentationConstants.TEXTSTYLE_COLOR_SUFFIX );
		}
		return null;
	}
	
	public static Preference<RGB> getBackgroundColorPref(final String streamId) {
		if (streamId.endsWith(NIConsoleOutputStream.OTHER_TASKS_STREAM_SUFFIX)) {
			return NicoUIPreferences.OUTPUT_OTHER_TASKS_BACKGROUND_COLOR_PREF;
		}
		return null;
	}
	
	private static String getPrefRootKey(final String streamId) {
		if (streamId == NIConsoleOutputStream.INFO_STREAM_ID
				|| streamId == NIConsoleOutputStream.OTHER_TASKS_INFO_STREAM_ID) {
			return NicoUIPreferences.OUTPUT_INFO_STREAM_ROOT_KEY;
		}
		if (streamId == NIConsoleOutputStream.STD_INPUT_STREAM_ID
				|| streamId == NIConsoleOutputStream.OTHER_TASKS_STD_INPUT_STREAM_ID) {
			return NicoUIPreferences.OUTPUT_STD_INPUT_STREAM_ROOT_KEY;
		}
		if (streamId == NIConsoleOutputStream.STD_OUTPUT_STREAM_ID
				|| streamId == NIConsoleOutputStream.OTHER_TASKS_STD_OUTPUT_STREAM_ID) {
			return NicoUIPreferences.OUTPUT_STD_OUTPUT_ROOT_KEY;
		}
		if (streamId == NIConsoleOutputStream.STD_ERROR_STREAM_ID
				|| streamId == NIConsoleOutputStream.OTHER_TASKS_STD_ERROR_STREAM_ID) {
			return NicoUIPreferences.OUTPUT_STD_ERROR_STREAM_ROOT_KEY;
		}
		if (streamId == NIConsoleOutputStream.SYSTEM_OUTPUT_STREAM_ID) {
			return NicoUIPreferences.OUTPUT_SYSTEM_OUTPUT_STREAM_ROOT_KEY;
		}
		return null;
	}
	
}
