/*=============================================================================#
 # 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.rsource.ast;

import static org.eclipse.statet.r.core.rsource.IRSourceConstants.STATUS2_SYNTAX_EXPR_AFTER_OP_MISSING;
import static org.eclipse.statet.r.core.rsource.IRSourceConstants.STATUS2_SYNTAX_EXPR_BEFORE_OP_MISSING;

import java.lang.reflect.InvocationTargetException;

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

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


/**
 * 
 */
@NonNullByDefault
abstract class StdBinary extends RAstNode {
	
	
	final Expression leftExpr= new Expression();
	final Expression rightExpr= new Expression();
	
	
	StdBinary() {
	}
	
	
	@Override
	public final boolean hasChildren() {
		return true;
	}
	
	@Override
	public final int getChildCount() {
		return 2;
	}
	
	@Override
	public final RAstNode getChild(final int index) {
		switch (index) {
		case 0:
			return this.leftExpr.node;
		case 1:
			return this.rightExpr.node;
		default:
			throw new IndexOutOfBoundsException();
		}
	}
	
	@Override
	public final RAstNode[] getChildren() {
		return new RAstNode[] { this.leftExpr.node, this.rightExpr.node };
	}
	
	public final RAstNode getLeftChild() {
		return this.leftExpr.node;
	}
	
	public final RAstNode getRightChild() {
		return this.rightExpr.node;
	}
	
	@Override
	public final int getChildIndex(final AstNode child) {
		if (this.leftExpr.node == child) {
			return 0;
		}
		if (this.rightExpr.node == child) {
			return 1;
		}
		return -1;
	}
	
	@Override
	public final void acceptInRChildren(final RAstVisitor visitor) throws InvocationTargetException {
		this.leftExpr.node.acceptInR(visitor);
		this.rightExpr.node.acceptInR(visitor);
	}
	
	@Override
	public final void acceptInChildren(final AstVisitor visitor) throws InvocationTargetException {
		visitor.visit(this.leftExpr.node);
		visitor.visit(this.rightExpr.node);
	}
	
	
	@Override
	final @Nullable Expression getExpr(final RAstNode child) {
		if (this.rightExpr.node == child) {
			return this.rightExpr;
		}
		if (this.leftExpr.node == child) {
			return this.leftExpr;
		}
		return null;
	}
	
	@Override
	final Expression getLeftExpr() {
		return this.leftExpr;
	}
	
	@Override
	final Expression getRightExpr() {
		return this.rightExpr;
	}
	
	
	@Override
	final int getMissingExprStatus(final Expression expr) {
		if (this.leftExpr == expr) {
			return STATUS2_SYNTAX_EXPR_BEFORE_OP_MISSING;
		}
		if (this.rightExpr == expr) {
			return STATUS2_SYNTAX_EXPR_AFTER_OP_MISSING;
		}
		throw new IllegalArgumentException();
	}
	
	final void updateOffsets() {
		this.startOffset= this.leftExpr.node.startOffset;
		this.endOffset= this.rightExpr.node.endOffset;
	}
	
}
