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

import java.util.Map;
import java.util.concurrent.locks.Lock;

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

import org.eclipse.statet.ecommons.preferences.AbstractPreferencesModelObject;
import org.eclipse.statet.ecommons.preferences.core.Preference;
import org.eclipse.statet.ecommons.preferences.core.Preference.BooleanPref;
import org.eclipse.statet.ecommons.preferences.core.Preference.EnumPref;
import org.eclipse.statet.ecommons.preferences.core.Preference.IntPref;
import org.eclipse.statet.ecommons.preferences.core.PreferenceAccess;
import org.eclipse.statet.ecommons.text.IIndentSettings;


/**
 * Settings for style of R code.
 */
@NonNullByDefault
public class RCodeStyleSettings extends AbstractPreferencesModelObject
		implements IIndentSettings {
	
	public static final String INDENT_GROUP_ID= "r/r.codestyle/indent"; //$NON-NLS-1$
	public static final String WS_GROUP_ID= "r/r.codestyle/ws"; //$NON-NLS-1$
	
	public static final String[] ALL_GROUP_IDS= new String[] { INDENT_GROUP_ID, WS_GROUP_ID };
	
	
	public static final IntPref TAB_SIZE_PREF= new IntPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Tab.size"); //$NON-NLS-1$
	
	public static final EnumPref<IndentationType> INDENT_DEFAULT_TYPE_PREF= new EnumPref<>(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Indent.Default.type", IndentationType.class, //$NON-NLS-1$
			IndentationType.TAB );
	
	public static final IntPref INDENT_SPACES_COUNT_PREF= new IntPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Indent.Spaces.count"); //$NON-NLS-1$
	
	public static final BooleanPref REPLACE_TABS_WITH_SPACES_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Indent.ReplaceTabs.enable"); //$NON-NLS-1$
	
	public static final BooleanPref REPLACE_CONVERSATIVE_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Indent.ReplaceStrategy"); //$NON-NLS-1$
	
	
	public static final IntPref INDENT_BLOCK_DEPTH_PREF= new IntPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Indent.Block.depth"); //$NON-NLS-1$
	public static final String INDENT_BLOCK_DEPTH_PROP= "indentBlockDepth"; //$NON-NLS-1$
	
	public static final IntPref INDENT_GROUP_DEPTH_PREF= new IntPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Indent.Group.depth"); //$NON-NLS-1$
	public static final String INDENT_GROUP_DEPTH_PROP= "indentGroupDepth"; //$NON-NLS-1$
	
	public static final IntPref INDENT_WRAPPED_COMMAND_DEPTH_PREF= new IntPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Indent.WrappedCommand.depth"); //$NON-NLS-1$
	public static final String INDENT_WRAPPED_COMMAND_DEPTH_PROP= "indentWrappedCommandDepth"; //$NON-NLS-1$
	
	
	public static final BooleanPref WS_ASSIGN_BEFORE_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Whitespace.Assign.before"); //$NON-NLS-1$
	public static final String WS_ASSIGN_BEFORE_PROP= "whitespaceAssignBefore"; //$NON-NLS-1$
	
	public static final BooleanPref WS_ASSIGN_AFTER_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Whitespace.Assign.after"); //$NON-NLS-1$
	public static final String WS_ASSIGN_AFTER_PROP= "whitespaceAssignAfter"; //$NON-NLS-1$
	
	public static final BooleanPref WS_ARGASSIGN_BEFORE_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Whitespace.ArgAssign.before"); //$NON-NLS-1$
	public static final String WS_ARGASSIGN_BEFORE_PROP= "whitespaceArgAssignBefore"; //$NON-NLS-1$
	
	public static final BooleanPref WS_ARGASSIGN_AFTER_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Whitespace.ArgAssign.after"); //$NON-NLS-1$
	public static final String WS_ARGASSIGN_AFTER_PROP= "whitespaceArgAssignAfter"; //$NON-NLS-1$
	
	public static final BooleanPref WS_OTHEROP_BEFORE_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Whitespace.OtherOp.before"); //$NON-NLS-1$
	public static final String WS_OTHEROP_BEFORE_PROP= "whitespaceOtherOpBefore"; //$NON-NLS-1$
	
	public static final BooleanPref WS_OTHEROP_AFTER_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "Whitespace.OtherOp.after"); //$NON-NLS-1$
	public static final String WS_OTHEROP_AFTER_PROP= "whitespaceOtherOpAfter"; //$NON-NLS-1$
	
	public static final BooleanPref NL_FDEF_BODYBLOCK_BEFORE_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "NewLine.FDef.BodyBlock.before"); //$NON-NLS-1$
	public static final String NL_FDEF_BODYBLOCK_BEFORE_PROP= "newlineFDefBodyBlockBefore"; //$NON-NLS-1$
	
	
	private int tabSize;
	private IndentationType indentDefaultType;
	private int indentSpacesCount;
	private int indentBlockDepth;
	private int indentGroupDepth;
	private int indentWrappedCommandDepth;
	private boolean replaceOtherTabsWithSpaces;
	private boolean replaceConservative;
	
	private boolean wsAssignBefore;
	private boolean wsAssignAfter;
	private boolean wsArgAssignBefore;
	private boolean wsArgAssignAfter;
	private boolean wsOtherOpBefore;
	private boolean wsOtherOpAfter;
	private boolean nlFDefBodyBlockBefore;
	
	
	/**
	 * Creates an instance with default settings.
	 */
	public RCodeStyleSettings(final int mode) {
		if (mode >= 1) {
			installLock();
		}
		loadDefaults();
		resetDirty();
	}
	
	
	@Override
	public String[] getNodeQualifiers() {
		return new String[] { RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER };
	}
	
	@Override
	public void loadDefaults() {
		setTabSize(4);
		setIndentDefaultType(INDENT_DEFAULT_TYPE_PREF.store2Usage(null));
		setIndentSpacesCount(4);
		setIndentBlockDepth(1);
		setIndentGroupDepth(1);
		setIndentWrappedCommandDepth(2);
		setReplaceOtherTabsWithSpaces(false);
		setReplaceConservative(false);
		
		setWhitespaceAssignBefore(true);
		setWhitespaceAssignAfter(true);
		setWhitespaceArgAssignBefore(true);
		setWhitespaceArgAssignAfter(true);
		setWhitespaceOtherOpBefore(true);
		setWhitespaceOtherOpAfter(true);
		setNewlineFDefBodyBlockBefore(false);
	}
	
	@Override
	public void load(final PreferenceAccess prefs) {
		setTabSize(prefs.getPreferenceValue(TAB_SIZE_PREF));
		setIndentDefaultType(prefs.getPreferenceValue(INDENT_DEFAULT_TYPE_PREF));
		setIndentSpacesCount(prefs.getPreferenceValue(INDENT_SPACES_COUNT_PREF));
		setReplaceOtherTabsWithSpaces(prefs.getPreferenceValue(REPLACE_TABS_WITH_SPACES_PREF));
		setIndentBlockDepth(prefs.getPreferenceValue(INDENT_BLOCK_DEPTH_PREF));
		setIndentGroupDepth(prefs.getPreferenceValue(INDENT_GROUP_DEPTH_PREF));
		setIndentWrappedCommandDepth(prefs.getPreferenceValue(INDENT_WRAPPED_COMMAND_DEPTH_PREF));
		setReplaceConservative(prefs.getPreferenceValue(REPLACE_CONVERSATIVE_PREF));
		
		setWhitespaceAssignBefore(prefs.getPreferenceValue(WS_ASSIGN_BEFORE_PREF));
		setWhitespaceAssignAfter(prefs.getPreferenceValue(WS_ASSIGN_AFTER_PREF));
		setWhitespaceArgAssignBefore(prefs.getPreferenceValue(WS_ARGASSIGN_BEFORE_PREF));
		setWhitespaceArgAssignAfter(prefs.getPreferenceValue(WS_ARGASSIGN_AFTER_PREF));
		setWhitespaceOtherOpBefore(prefs.getPreferenceValue(WS_OTHEROP_BEFORE_PREF));
		setWhitespaceOtherOpAfter(prefs.getPreferenceValue(WS_OTHEROP_AFTER_PREF));
		setNewlineFDefBodyBlockBefore(prefs.getPreferenceValue(NL_FDEF_BODYBLOCK_BEFORE_PREF));
	}
	
	public void load(final RCodeStyleSettings source) {
		final Lock writeLock= getWriteLock();
		final Lock sourceLock= source.getReadLock();
		try {
			sourceLock.lock();
			writeLock.lock();
			
			setTabSize(source.tabSize);
			setIndentDefaultType(source.indentDefaultType);
			setIndentSpacesCount(source.indentSpacesCount);
			setReplaceOtherTabsWithSpaces(source.replaceOtherTabsWithSpaces);
			setIndentBlockDepth(source.indentBlockDepth);
			setIndentGroupDepth(source.indentGroupDepth);
			setIndentWrappedCommandDepth(source.indentWrappedCommandDepth);
			setReplaceConservative(source.replaceConservative);
			
			setWhitespaceAssignBefore(source.wsAssignBefore);
			setWhitespaceAssignAfter(source.wsAssignAfter);
			setWhitespaceArgAssignBefore(source.wsArgAssignBefore);
			setWhitespaceArgAssignAfter(source.wsArgAssignAfter);
			setWhitespaceOtherOpBefore(source.wsOtherOpBefore);
			setWhitespaceOtherOpAfter(source.wsOtherOpAfter);
			setNewlineFDefBodyBlockBefore(source.nlFDefBodyBlockBefore);
		}
		finally {
			sourceLock.unlock();
			writeLock.unlock();
		}
	}
	
	@Override
	public Map<Preference<?>, Object> deliverToPreferencesMap(final Map<Preference<?>, Object> map) {
		map.put(TAB_SIZE_PREF, getTabSize());
		map.put(INDENT_DEFAULT_TYPE_PREF, getIndentDefaultType());
		map.put(INDENT_SPACES_COUNT_PREF, getIndentSpacesCount());
		map.put(REPLACE_TABS_WITH_SPACES_PREF, getReplaceOtherTabsWithSpaces());
		map.put(INDENT_BLOCK_DEPTH_PREF, getIndentBlockDepth());
		map.put(INDENT_GROUP_DEPTH_PREF, getIndentGroupDepth());
		map.put(INDENT_WRAPPED_COMMAND_DEPTH_PREF, getIndentWrappedCommandDepth());
		map.put(REPLACE_CONVERSATIVE_PREF, getReplaceConservative());
		
		map.put(WS_ASSIGN_BEFORE_PREF, getWhitespaceAssignBefore());
		map.put(WS_ASSIGN_AFTER_PREF, getWhitespaceAssignAfter());
		map.put(WS_ARGASSIGN_BEFORE_PREF, getWhitespaceArgAssignBefore());
		map.put(WS_ARGASSIGN_AFTER_PREF, getWhitespaceArgAssignAfter());
		map.put(WS_OTHEROP_BEFORE_PREF, getWhitespaceOtherOpBefore());
		map.put(WS_OTHEROP_AFTER_PREF, getWhitespaceOtherOpAfter());
		map.put(NL_FDEF_BODYBLOCK_BEFORE_PREF, getNewlineFDefBodyBlockBefore());
		return map;
	}
	
	
/*-- Properties --------------------------------------------------------------*/
	
	public void setTabSize(final int size) {
		final int oldValue= this.tabSize;
		this.tabSize= size;
		firePropertyChange(TAB_SIZE_PROP, oldValue, size);
	}
	@Override
	public int getTabSize() {
		return this.tabSize;
	}
	
	public void setIndentDefaultType(final IndentationType type) {
		final IndentationType oldValue= this.indentDefaultType;
		this.indentDefaultType= type;
		firePropertyChange(INDENT_DEFAULT_TYPE_PROP, oldValue, type);
	}
	@Override
	public IndentationType getIndentDefaultType() {
		return this.indentDefaultType;
	}
	
	public void setIndentSpacesCount(final int count) {
		final int oldValue= this.indentSpacesCount;
		this.indentSpacesCount= count;
		firePropertyChange(INDENT_SPACES_COUNT_PROP, oldValue, count);
	}
	@Override
	public int getIndentSpacesCount() {
		return this.indentSpacesCount;
	}
	
	public final void setIndentBlockDepth(final int depth) {
		final int oldValue= this.indentBlockDepth;
		this.indentBlockDepth= depth;
		firePropertyChange(INDENT_BLOCK_DEPTH_PROP, oldValue, depth);
	}
	public final int getIndentBlockDepth() {
		return this.indentBlockDepth;
	}
	
	public final void setIndentGroupDepth(final int depth) {
		final int oldValue= this.indentGroupDepth;
		this.indentGroupDepth= depth;
		firePropertyChange(INDENT_GROUP_DEPTH_PROP, oldValue, depth);
	}
	public final int getIndentGroupDepth() {
		return this.indentGroupDepth;
	}
	
	public final void setIndentWrappedCommandDepth(final int depth) {
		final int oldValue= this.indentWrappedCommandDepth;
		this.indentWrappedCommandDepth= depth;
		firePropertyChange(INDENT_WRAPPED_COMMAND_DEPTH_PROP, oldValue, depth);
	}
	public final int getIndentWrappedCommandDepth() {
		return this.indentWrappedCommandDepth;
	}
	
	public void setReplaceOtherTabsWithSpaces(final boolean enable) {
		final boolean oldValue= this.replaceOtherTabsWithSpaces;
		this.replaceOtherTabsWithSpaces= enable;
		firePropertyChange(REPLACE_TABS_WITH_SPACES_PROP, oldValue, getReplaceOtherTabsWithSpaces());
	}
	@Override
	public boolean getReplaceOtherTabsWithSpaces() {
		return this.replaceOtherTabsWithSpaces;
	}
	
	public void setReplaceConservative(final boolean enable) {
		final boolean oldValue= this.replaceConservative;
		this.replaceConservative= enable;
		firePropertyChange(REPLACE_CONSERVATIVE_PROP, oldValue, enable);
	}
	@Override
	public boolean getReplaceConservative() {
		return this.replaceConservative;
	}
	
	
	@Override
	public int getLineWidth() {
		return -1;
	}
	
	
	public void setWhitespaceAssignBefore(final boolean enable) {
		final boolean oldValue= this.wsAssignBefore;
		this.wsAssignBefore= enable;
		firePropertyChange(WS_ASSIGN_BEFORE_PROP, oldValue, enable);
	}
	public boolean getWhitespaceAssignBefore() {
		return this.wsAssignBefore;
	}
	
	public void setWhitespaceAssignAfter(final boolean enable) {
		final boolean oldValue= this.wsAssignAfter;
		this.wsAssignAfter= enable;
		firePropertyChange(WS_ASSIGN_AFTER_PROP, oldValue, enable);
	}
	public boolean getWhitespaceAssignAfter() {
		return this.wsAssignAfter;
	}
	
	public void setWhitespaceArgAssignBefore(final boolean enable) {
		final boolean oldValue= this.wsArgAssignBefore;
		this.wsArgAssignBefore= enable;
		firePropertyChange(WS_ARGASSIGN_BEFORE_PROP, oldValue, enable);
	}
	public boolean getWhitespaceArgAssignBefore() {
		return this.wsArgAssignBefore;
	}
	
	public void setWhitespaceArgAssignAfter(final boolean enable) {
		final boolean oldValue= this.wsArgAssignAfter;
		this.wsArgAssignAfter= enable;
		firePropertyChange(WS_ARGASSIGN_AFTER_PROP, oldValue, enable);
	}
	public boolean getWhitespaceArgAssignAfter() {
		return this.wsArgAssignAfter;
	}
	
	public void setWhitespaceOtherOpBefore(final boolean enable) {
		final boolean oldValue= this.wsOtherOpBefore;
		this.wsOtherOpBefore= enable;
		firePropertyChange(WS_OTHEROP_BEFORE_PROP, oldValue, enable);
	}
	public boolean getWhitespaceOtherOpBefore() {
		return this.wsOtherOpBefore;
	}
	
	public void setWhitespaceOtherOpAfter(final boolean enable) {
		final boolean oldValue= this.wsOtherOpAfter;
		this.wsOtherOpAfter= enable;
		firePropertyChange(WS_OTHEROP_AFTER_PROP, oldValue, enable);
	}
	public boolean getWhitespaceOtherOpAfter() {
		return this.wsOtherOpAfter;
	}
	
	public void setNewlineFDefBodyBlockBefore(final boolean enable) {
		final boolean oldValue= this.nlFDefBodyBlockBefore;
		this.nlFDefBodyBlockBefore= enable;
		firePropertyChange(NL_FDEF_BODYBLOCK_BEFORE_PROP, oldValue, enable);
	}
	public boolean getNewlineFDefBodyBlockBefore() {
		return this.nlFDefBodyBlockBefore;
	}
	
	
	public String getArgAssignString() {
		return (this.wsArgAssignBefore ?
				(this.wsArgAssignAfter ? " = " : " =") :
				(this.wsArgAssignBefore ? "= " : "=") );
	}
	
}
