/* This file was generated by SableCC (http://www.sablecc.org/). */

package com.google.clearsilver.jsilver.syntax.node;

import com.google.clearsilver.jsilver.syntax.analysis.*;

@SuppressWarnings("nls")
public final class ALoopCommand extends PCommand
{
    private PPosition _position_;
    private PVariable _variable_;
    private PExpression _start_;
    private PExpression _end_;
    private PCommand _command_;

    public ALoopCommand()
    {
        // Constructor
    }

    public ALoopCommand(
        @SuppressWarnings("hiding") PPosition _position_,
        @SuppressWarnings("hiding") PVariable _variable_,
        @SuppressWarnings("hiding") PExpression _start_,
        @SuppressWarnings("hiding") PExpression _end_,
        @SuppressWarnings("hiding") PCommand _command_)
    {
        // Constructor
        setPosition(_position_);

        setVariable(_variable_);

        setStart(_start_);

        setEnd(_end_);

        setCommand(_command_);

    }

    @Override
    public Object clone()
    {
        return new ALoopCommand(
            cloneNode(this._position_),
            cloneNode(this._variable_),
            cloneNode(this._start_),
            cloneNode(this._end_),
            cloneNode(this._command_));
    }

    public void apply(Switch sw)
    {
        ((Analysis) sw).caseALoopCommand(this);
    }

    public PPosition getPosition()
    {
        return this._position_;
    }

    public void setPosition(PPosition node)
    {
        if(this._position_ != null)
        {
            this._position_.parent(null);
        }

        if(node != null)
        {
            if(node.parent() != null)
            {
                node.parent().removeChild(node);
            }

            node.parent(this);
        }

        this._position_ = node;
    }

    public PVariable getVariable()
    {
        return this._variable_;
    }

    public void setVariable(PVariable node)
    {
        if(this._variable_ != null)
        {
            this._variable_.parent(null);
        }

        if(node != null)
        {
            if(node.parent() != null)
            {
                node.parent().removeChild(node);
            }

            node.parent(this);
        }

        this._variable_ = node;
    }

    public PExpression getStart()
    {
        return this._start_;
    }

    public void setStart(PExpression node)
    {
        if(this._start_ != null)
        {
            this._start_.parent(null);
        }

        if(node != null)
        {
            if(node.parent() != null)
            {
                node.parent().removeChild(node);
            }

            node.parent(this);
        }

        this._start_ = node;
    }

    public PExpression getEnd()
    {
        return this._end_;
    }

    public void setEnd(PExpression node)
    {
        if(this._end_ != null)
        {
            this._end_.parent(null);
        }

        if(node != null)
        {
            if(node.parent() != null)
            {
                node.parent().removeChild(node);
            }

            node.parent(this);
        }

        this._end_ = node;
    }

    public PCommand getCommand()
    {
        return this._command_;
    }

    public void setCommand(PCommand node)
    {
        if(this._command_ != null)
        {
            this._command_.parent(null);
        }

        if(node != null)
        {
            if(node.parent() != null)
            {
                node.parent().removeChild(node);
            }

            node.parent(this);
        }

        this._command_ = node;
    }

    @Override
    public String toString()
    {
        return ""
            + toString(this._position_)
            + toString(this._variable_)
            + toString(this._start_)
            + toString(this._end_)
            + toString(this._command_);
    }

    @Override
    void removeChild(@SuppressWarnings("unused") Node child)
    {
        // Remove child
        if(this._position_ == child)
        {
            this._position_ = null;
            return;
        }

        if(this._variable_ == child)
        {
            this._variable_ = null;
            return;
        }

        if(this._start_ == child)
        {
            this._start_ = null;
            return;
        }

        if(this._end_ == child)
        {
            this._end_ = null;
            return;
        }

        if(this._command_ == child)
        {
            this._command_ = null;
            return;
        }

        throw new RuntimeException("Not a child.");
    }

    @Override
    void replaceChild(@SuppressWarnings("unused") Node oldChild, @SuppressWarnings("unused") Node newChild)
    {
        // Replace child
        if(this._position_ == oldChild)
        {
            setPosition((PPosition) newChild);
            return;
        }

        if(this._variable_ == oldChild)
        {
            setVariable((PVariable) newChild);
            return;
        }

        if(this._start_ == oldChild)
        {
            setStart((PExpression) newChild);
            return;
        }

        if(this._end_ == oldChild)
        {
            setEnd((PExpression) newChild);
            return;
        }

        if(this._command_ == oldChild)
        {
            setCommand((PCommand) newChild);
            return;
        }

        throw new RuntimeException("Not a child.");
    }
}
