/*=============================================================================#
 # Copyright (c) 2007, 2017 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.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.
 */
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$
	
	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.replace_tabs.enable"); //$NON-NLS-1$
	
	public static final BooleanPref REPLACE_CONVERSATIVE_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "indent.replace_strategy"); //$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.wrapped_command.depth"); //$NON-NLS-1$
	public static final String INDENT_WRAPPED_COMMAND_DEPTH_PROP= "indentWrappedCommandDepth"; //$NON-NLS-1$
	
	
	public static final BooleanPref WS_ARGASSIGN_BEFORE_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "ws.arg_assign.before"); //$NON-NLS-1$
	public static final String WS_ARGASSIGN_BEFORE_PROP= "whitespaceArgAssignBefore"; //$NON-NLS-1$
	
	public static final BooleanPref WS_ARGASSIGN_BEHIND_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "ws.arg_assign.behind"); //$NON-NLS-1$
	public static final String WS_ARGASSIGN_BEHIND_PROP= "whitespaceArgAssignBehind"; //$NON-NLS-1$
	
	public static final BooleanPref NL_FDEF_BODYBLOCK_BEFORE_PREF= new BooleanPref(
			RCorePreferenceNodes.CAT_R_CODESTYLE_QUALIFIER, "nl.fdef_bodyblock.before"); //$NON-NLS-1$
	public static final String NL_FDEF_BODYBLOCK_BEFOREP_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 wsArgAssignBefore;
	private boolean wsArgAssignBehind;
	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(IndentationType.TAB);
		setIndentSpacesCount(4);
		setIndentBlockDepth(1);
		setIndentGroupDepth(1);
		setIndentWrappedCommandDepth(2);
		setReplaceOtherTabsWithSpaces(false);
		setReplaceConservative(false);
		
		setWhitespaceArgAssignBefore(true);
		setWhitespaceArgAssignBehind(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));
		
		setWhitespaceArgAssignBefore(prefs.getPreferenceValue(WS_ARGASSIGN_BEFORE_PREF));
		setWhitespaceArgAssignBehind(prefs.getPreferenceValue(WS_ARGASSIGN_BEHIND_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);
			
			setWhitespaceArgAssignBefore(source.wsArgAssignBefore);
			setWhitespaceArgAssignBehind(source.wsArgAssignBehind);
			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_ARGASSIGN_BEFORE_PREF, getWhitespaceArgAssignBefore());
		map.put(WS_ARGASSIGN_BEHIND_PREF, getWhitespaceArgAssignBehind());
		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 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 setWhitespaceArgAssignBehind(final boolean enable) {
		final boolean oldValue= this.wsArgAssignBehind;
		this.wsArgAssignBehind= enable;
		firePropertyChange(WS_ARGASSIGN_BEFORE_PROP, oldValue, enable);
	}
	public boolean getWhitespaceArgAssignBehind() {
		return this.wsArgAssignBehind;
	}
	
	public void setNewlineFDefBodyBlockBefore(final boolean enable) {
		final boolean oldValue= this.nlFDefBodyBlockBefore;
		this.nlFDefBodyBlockBefore= enable;
		firePropertyChange(NL_FDEF_BODYBLOCK_BEFOREP_PROP, oldValue, enable);
	}
	public boolean getNewlineFDefBodyBlockBefore() {
		return this.nlFDefBodyBlockBefore;
	}
	
	
	public String getArgAssignString() {
		return (this.wsArgAssignBefore ?
				(this.wsArgAssignBehind ? " = " : " =") :
				(this.wsArgAssignBefore ? "= " : "=") ); 
	}
	
}
