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

import java.util.Objects;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.ast.core.AstVisitor;


/**
 * 
 */
@NonNullByDefault
abstract class SingleValue extends RAstNode {
	
	
	@Nullable String text;
	
	
	protected SingleValue() {
	}
	
	
	@Override
	public final @Nullable String getText() {
		return this.text;
	}
	
	abstract void setText(final @Nullable String text, final @Nullable TextRegion textRegion);
	
	@Override
	public final boolean hasChildren() {
		return false;
	}
	
	@Override
	public final int getChildCount() {
		return 0;
	}
	
	@Override
	public final RAstNode getChild(final int index) {
		throw new IndexOutOfBoundsException();
	}
	
	@Override
	public final RAstNode[] getChildren() {
		return NO_CHILDREN;
	}
	
	@Override
	public final int getChildIndex(final AstNode child) {
		return -1;
	}
	
	@Override
	public final void acceptInRChildren(final RAstVisitor visitor) {
	}
	
	@Override
	public final void acceptInChildren(final AstVisitor visitor) {
	}
	
	
	@Override
	final @Nullable Expression getExpr(final RAstNode child) {
		return null;
	}
	
	@Override
	final @Nullable Expression getLeftExpr() {
		return null;
	}
	
	@Override
	final @Nullable Expression getRightExpr() {
		return null;
	}
	
	
	@Override
	public boolean equalsValue(final RAstNode element) {
		if (getNodeType() == element.getNodeType()) {
			final SingleValue other= (SingleValue)element;
			return (Objects.equals(this.text, other.text));
		}
		return false;
	}
	
	@Override
	public String toString() {
		final StringBuilder s= new StringBuilder(super.toString());
		final String text= this.text;
		if (text != null) {
			s.append(" ◊ "); //$NON-NLS-1$
			appendEscaped(s, text);
		}
		return s.toString();
	}
	
	void appendEscaped(final StringBuilder builder, final CharSequence text) {
		for (int i= 0; i < text.length(); i++) {
			final char c= text.charAt(i);
			switch (c) {
			case '\\':
				builder.append("\\\\"); //$NON-NLS-1$
				break;
			case '\n':
				builder.append("\\n"); //$NON-NLS-1$
				break;
			case '\r':
				builder.append("\\r"); //$NON-NLS-1$
				break;
			case '\t':
				builder.append("\\t"); //$NON-NLS-1$
				break;
			default:
				builder.append(c);
				break;
			}
		}
		
	}
	
	
	@Override
	final int getMissingExprStatus(final Expression expr) {
		throw new IllegalArgumentException();
	}
	
}
