/*=============================================================================#
 # Copyright (c) 2009, 2019 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.lang.reflect.InvocationTargetException;
import java.util.List;

import org.eclipse.statet.jcommons.collections.ImList;

import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.ast.core.AstVisitor;
import org.eclipse.statet.r.core.rlang.RTerminal;


/**
 * Node for a documentation comment (currently always Roxygen)
 * 
 * The children are its comment lines.
 * The documentation structure is accessible via {@link #getTags()}.
 */
public final class DocuComment extends RAstNode {
	
	
	int nextOffset= NA_OFFSET;
	Comment[] lines;
	ImList<DocuTag> tags;
	
	
	public DocuComment() {
	}
	
	
	@Override
	public final NodeType getNodeType() {
		return NodeType.DOCU_AGGREGATION;
	}
	
	@Override
	public final RTerminal getOperator(final int index) {
		return RTerminal.ROXYGEN_COMMENT;
	}
	
	public final int getSubsequentNodeOffset() {
		return this.nextOffset;
	}
	
	
	public List<DocuTag> getTags() {
		return this.tags;
	}
	
	@Override
	public final boolean hasChildren() {
		return (this.lines.length > 0);
	}
	
	@Override
	public final int getChildCount() {
		return this.lines.length;
	}
	
	@Override
	public final Comment getChild(final int index) {
		return this.lines[index];
	}
	
	@Override
	public final RAstNode[] getChildren() {
		final RAstNode[] children= new RAstNode[this.lines.length];
		System.arraycopy(this.lines, 0, children, 0, this.lines.length);
		return children;
	}
	
	@Override
	public final int getChildIndex(final AstNode child) {
		for (int i= 0; i < this.lines.length; i++) {
			if (this.lines[i] == child) {
				return i;
			}
		}
		return -1;
	}
	
	
	@Override
	public final void acceptInR(final RAstVisitor visitor) throws InvocationTargetException {
		visitor.visit(this);
	}
	
	@Override
	public final void acceptInRChildren(final RAstVisitor visitor) throws InvocationTargetException {
		for (final Comment child : this.lines) {
			visitor.visit(child);
		}
	}
	
	public final void acceptInRDocu(final RAstVisitor visitor) throws InvocationTargetException {
		for (final DocuTag tag : this.tags) {
			visitor.visit(tag);
		}
	}
	
	@Override
	public final void acceptInChildren(final AstVisitor visitor) throws InvocationTargetException {
		for (int i= 0; i < this.lines.length; i++) {
			visitor.visit(this.lines[i]);
		}
	}
	
	
	@Override
	final Expression getExpr(final RAstNode child) {
		return null;
	}
	
	@Override
	final Expression getLeftExpr() {
		return null;
	}
	
	@Override
	final Expression getRightExpr() {
		return null;
	}
	
	@Override
	public final boolean equalsSingle(final RAstNode element) {
		if (element.getNodeType() != NodeType.F_CALL) {
			return false;
		}
		return true;
	}
	
	
	@Override
	final int getMissingExprStatus(final Expression expr) {
		throw new IllegalArgumentException();
	}
	
	@Override
	final void updateEndOffset() {
	}
	
}
