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

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>? §topic§</code>
 * <code>§type§ ? §topic§</code>
 */
@NonNullByDefault
public final class Help extends RAstNode {
	
	
	final Expression leftExpr= new Expression();
	final Expression rightExpr= new Expression();
	
	
	Help() {
	}
	
	
	@Override
	public final NodeType getNodeType() {
		return NodeType.HELP;
	}
	
	@Override
	public final RTerminal getOperator(final int index) {
		return RTerminal.QUESTIONMARK;
	}
	
	@Override
	public final boolean hasChildren() {
		return true;
	}
	
	@Override
	public final int getChildCount() {
		return (this.leftExpr.node != null) ? 2 : 1;
	}
	
	@Override
	public final RAstNode getChild(final int index) {
		final RAstNode typeNode= this.leftExpr.node;
		if (typeNode != null) {
			switch (index) {
			case 0:
				return typeNode;
			case 1:
				return this.rightExpr.node;
			default:
				break;
			}
		}
		else if (index == 0) {
			return this.rightExpr.node;
		}
		throw new IndexOutOfBoundsException();
	}
	
	@Override
	public final RAstNode[] getChildren() {
		final RAstNode typeNode= this.leftExpr.node;
		if (typeNode != null) {
			return new RAstNode[] { typeNode, this.rightExpr.node };
		}
		return new RAstNode[] { 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;
	}
	
	public final RAstNode getTypeChild() {
		return this.leftExpr.node;
	}
	
	public final boolean hasType() {
		return (this.leftExpr.node != null);
	}
	
	public final RAstNode getTopicChild() {
		return this.rightExpr.node;
	}
	
	@Override
	public final void acceptInR(final RAstVisitor visitor) throws InvocationTargetException {
		visitor.visit(this);
	}
	
	@Override
	public final void acceptInRChildren(final RAstVisitor visitor) throws InvocationTargetException {
		final RAstNode typeNode= this.leftExpr.node;
		if (typeNode != null) {
			typeNode.acceptInR(visitor);
		}
		this.rightExpr.node.acceptInR(visitor);
	}
	
	@Override
	public final void acceptInChildren(final AstVisitor visitor) throws InvocationTargetException {
		final RAstNode typeNode= this.leftExpr.node;
		if (typeNode != null) {
			visitor.visit(typeNode);
		}
		this.rightExpr.node.accept(visitor);
	}
	
	
	@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
	public final boolean equalsSingle(final RAstNode element) {
		return (NodeType.HELP == element.getNodeType());
	}
	
	
	@Override
	final int getMissingExprStatus(final Expression expr) {
		if (this.rightExpr == expr) {
			return STATUS2_SYNTAX_EXPR_AFTER_OP_MISSING;
		}
		if (this.leftExpr == expr) {
			return STATUS_OK;
		}
		throw new IllegalArgumentException();
	}
	
	final void updateOffsets() {
		final RAstNode leftNode= this.leftExpr.node;
		if (leftNode != null) {
			this.startOffset= leftNode.startOffset;
		}
		this.endOffset= getTopicChild().endOffset;
	}
	
}
