/*=============================================================================#
 # 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 static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_AS_BODY_MISSING;
import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_AS_FORSEQ_MISSING;
import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS3_FOR;

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;
import org.eclipse.statet.r.core.rlang.RTerminal;


/**
 * <code>for ( §var§ in §cond§ ) §cont§</code>
 */
@NonNullByDefault
public final class CForLoop extends RAstNode {
	
	
	Symbol varSymbol;
	int condOpenOffset= NA_OFFSET;
	int inOffset= NA_OFFSET;
	final Expression condExpr= new Expression();
	int condCloseOffset= NA_OFFSET;
	final Expression loopExpr= new Expression();
	
	
	CForLoop() {
	}
	
	
	@Override
	public final NodeType getNodeType() {
		return NodeType.C_FOR;
	}
	
	@Override
	public final RTerminal getOperator(final int index) {
		return RTerminal.FOR;
	}
	
	
	@Override
	public final boolean hasChildren() {
		return true;
	}
	
	@Override
	public final int getChildCount() {
		return 3;
	}
	
	@Override
	public final RAstNode getChild(final int index) {
		switch (index) {
		case 0:
			return this.varSymbol;
		case 1:
			return this.condExpr.node;
		case 2:
			return this.loopExpr.node;
		default:
			throw new IndexOutOfBoundsException();
		}
	}
	
	@Override
	public final RAstNode[] getChildren() {
		return new RAstNode[] { this.varSymbol, this.condExpr.node, this.loopExpr.node };
	}
	
	@Override
	public final int getChildIndex(final AstNode child) {
		if (this.varSymbol == child) {
			return 0;
		}
		if (this.condExpr.node == child) {
			return 1;
		}
		if (this.loopExpr.node == child) {
			return 2;
		}
		return -1;
	}
	
	public final int getCondOpenOffset() {
		return this.condOpenOffset;
	}
	
	public final Symbol getVarChild() {
		return this.varSymbol;
	}
	
	public final RAstNode getCondChild() {
		return this.condExpr.node;
	}
	
	public final int getCondCloseOffset() {
		return this.condCloseOffset;
	}
	
	public final RAstNode getContChild() {
		return this.loopExpr.node;
	}
	
	@Override
	public final void acceptInR(final RAstVisitor visitor) throws InvocationTargetException {
		visitor.visit(this);
	}
	
	@Override
	public final void acceptInRChildren(final RAstVisitor visitor) throws InvocationTargetException {
		this.varSymbol.acceptInR(visitor);
		this.condExpr.node.acceptInR(visitor);
		this.loopExpr.node.acceptInR(visitor);
	}
	
	@Override
	public final void acceptInChildren(final AstVisitor visitor) throws InvocationTargetException {
		visitor.visit(this.varSymbol);
		visitor.visit(this.condExpr.node);
		visitor.visit(this.loopExpr.node);
	}
	
	
	@Override
	final @Nullable Expression getExpr(final RAstNode child) {
		if (this.loopExpr.node == child) {
			return this.loopExpr;
		}
		if (this.condExpr.node == child) {
			return this.condExpr;
		}
		return null;
	}
	
	@Override
	final @Nullable Expression getLeftExpr() {
		return null;
	}
	
	@Override
	final Expression getRightExpr() {
		return this.loopExpr;
	}
	
	@Override
	public final boolean equalsSingle(final RAstNode element) {
		return (NodeType.C_FOR == element.getNodeType());
	}
	
	
	@Override
	final int getMissingExprStatus(final Expression expr) {
		if (this.condExpr == expr) {
			return (STATUS2_SYNTAX_EXPR_AS_FORSEQ_MISSING | STATUS3_FOR);
		}
		if (this.loopExpr == expr) {
			return (STATUS2_SYNTAX_EXPR_AS_BODY_MISSING | STATUS3_FOR);
		}
		throw new IllegalArgumentException();
	}
	
	@SuppressWarnings("unused")
	final void updateOffsets() {
		if (this.loopExpr.node != null) {
			this.endOffset= this.loopExpr.node.endOffset;
		}
		else if (this.condCloseOffset != NA_OFFSET) {
			this.endOffset= this.condCloseOffset + 1;
		}
		else if (this.condExpr.node != null) {
			this.endOffset= this.condExpr.node.endOffset;
		}
		else if (this.inOffset != NA_OFFSET) {
			this.endOffset= this.inOffset + 2;
		}
		else if (this.varSymbol != null) {
			this.endOffset= this.varSymbol.endOffset;
		}
		else if (this.condOpenOffset != NA_OFFSET) {
			this.endOffset= this.condOpenOffset + 1;
		}
		else {
			this.endOffset= this.startOffset + 3;
		}
	}
	
}
