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

import static org.eclipse.statet.r.core.rsource.IRSourceConstants.STATUS2_SYNTAX_EXPR_AS_BODY_MISSING;
import static org.eclipse.statet.r.core.rsource.IRSourceConstants.STATUS3_REPEAT;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.statet.ltk.ast.core.IAstNode;
import org.eclipse.statet.ltk.ast.core.ICommonAstVisitor;
import org.eclipse.statet.r.core.rlang.RTerminal;


/**
 * <code>repeat §cont§</code>
 */
public final class CRepeatLoop extends RAstNode {
	
	
	final Expression loopExpr= new Expression();
	
	
	CRepeatLoop() {
	}
	
	
	@Override
	public final NodeType getNodeType() {
		return NodeType.C_REPEAT;
	}
	
	@Override
	public final RTerminal getOperator(final int index) {
		return RTerminal.WHILE;
	}
	
	
	@Override
	public final boolean hasChildren() {
		return true;
	}
	
	@Override
	public final int getChildCount() {
		return 1;
	}
	
	@Override
	public final RAstNode getChild(final int index) {
		switch (index) {
		case 0:
			return this.loopExpr.node;
		default:
			throw new IndexOutOfBoundsException();
		}
	}
	
	@Override
	public final RAstNode[] getChildren() {
		return new RAstNode[] { this.loopExpr.node };
	}
	
	@Override
	public final int getChildIndex(final IAstNode child) {
		if (this.loopExpr.node == child) {
			return 0;
		}
		return -1;
	}
	
	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.loopExpr.node.acceptInR(visitor);
	}
	
	@Override
	public final void acceptInChildren(final ICommonAstVisitor visitor) throws InvocationTargetException {
		visitor.visit(this.loopExpr.node);
	}
	
	
	@Override
	final Expression getExpr(final RAstNode child) {
		if (this.loopExpr.node == child) {
			return this.loopExpr;
		}
		return null;
	}
	
	@Override
	final Expression getLeftExpr() {
		return null;
	}
	
	@Override
	final Expression getRightExpr() {
		return this.loopExpr;
	}
	
	@Override
	public final boolean equalsSingle(final RAstNode element) {
		return (element.getNodeType() == NodeType.C_REPEAT);
	}
	
	
	@Override
	final int getMissingExprStatus(final Expression expr) {
		if (this.loopExpr == expr) {
			return (STATUS2_SYNTAX_EXPR_AS_BODY_MISSING | STATUS3_REPEAT);
		}
		throw new IllegalArgumentException();
	}
	
	@Override
	final void updateStopOffset() {
		this.stopOffset= this.loopExpr.node.stopOffset;
	}
	
}
