/* MathContainer.java * ========================================================================= * This file is part of the Mirai Math TN - http://mirai.sourceforge.net * * Copyright (C) 2008-2009 Bea Petrovicova * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * A copy of the GNU General Public License can be found in the file * LICENSE.txt provided with the source distribution of this program (see * the META-INF directory in the source jar). This license can also be * found on the GNU website at http://www.gnu.org/licenses/gpl.html. * * If you did not receive a copy of the GNU General Public License along * with this program, contact the lead developer, or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * */ package com.himamis.retex.editor.share.model; import java.util.ArrayList; import com.himamis.retex.editor.share.model.inspect.Inspecting; import com.himamis.retex.editor.share.model.traverse.Traversing; /** * This class represents abstract model element. * * @author Bea Petrovicova */ abstract public class MathContainer extends MathComponent { protected ArrayList<MathComponent> arguments = null; MathContainer(int size) { if (size > 0) { ensureArguments(size); } } protected void ensureArguments(int size) { if (arguments == null) { arguments = new ArrayList<MathComponent>(size); } else { arguments.ensureCapacity(size); } while (arguments.size() < size) { arguments.add(null); } } /** * Returns i-th argument. * * @param i * index * @return argument */ public MathComponent getArgument(int i) { return (arguments != null && arguments.size() > i && i >= 0 ? arguments.get(i) : null); } /** * Sets i-th argument. */ public void setArgument(int i, MathComponent argument) { if (arguments == null) { arguments = new ArrayList<MathComponent>(i + 1); } if (argument != null) { argument.setParent(this); } arguments.set(i, argument); } public void removeArgument(int i) { if (arguments == null) { arguments = new ArrayList<MathComponent>(i + 1); } if (arguments.get(i) != null) { arguments.get(i).setParent(null); } arguments.remove(i); } public void clearArguments() { if (arguments == null) { arguments = new ArrayList<MathComponent>(); } for (int i = arguments.size() - 1; i > -1; i--) { removeArgument(i); } } public void addArgument(MathComponent argument) { if (arguments == null) { arguments = new ArrayList<MathComponent>(1); } if (argument != null) { argument.setParent(this); } arguments.add(argument); } public void addArgument(int index, MathComponent argument) { if (arguments == null) { arguments = new ArrayList<MathComponent>(index + 1); } if (argument != null) { argument.setParent(this); } arguments.add(index, argument); } /** * Returns number of arguments. */ public int size() { return arguments != null ? arguments.size() : 0; } /** * Get index of first argument. */ public int first() { // strange but correct return next(-1); } /** * Get index of last argument. */ public int last() { return prev(arguments != null ? arguments.size() : 0); } /** * Is there a next argument? */ public boolean hasNext(int current) { for (int i = current + 1; i < (arguments != null ? arguments.size() : 0); i++) { if (getArgument(i) instanceof MathContainer) { return true; } } return false; } /** * Get index of next argument. */ public int next(int current) { for (int i = current + 1; i < (arguments != null ? arguments.size() : 0); i++) { if (getArgument(i) instanceof MathContainer) { return i; } } throw new ArrayIndexOutOfBoundsException( "Index out of array bounds."); } /** * Is there previous argument? */ public boolean hasPrev(int current) { for (int i = current - 1; i >= 0; i--) { if (getArgument(i) instanceof MathContainer) { return true; } } return false; } /** * Get index of previous argument. */ public int prev(int current) { for (int i = current - 1; i >= 0; i--) { if (getArgument(i) instanceof MathContainer) { return i; } } throw new ArrayIndexOutOfBoundsException( "Index out of array bounds."); } /** * Are there any arguments? */ public boolean hasChildren() { for (int i = 0; i < (arguments != null ? arguments.size() : 0); i++) { if (getArgument(i) instanceof MathContainer) { return true; } } return false; } public int getInsertIndex() { return 0; } public int getInitialIndex() { return 0; } @Override public MathComponent traverse(Traversing traversing) { MathComponent component = traversing.process(this); if (component != this) { return component; } for (int i = 0; i < size(); i++) { MathComponent argument = getArgument(i); setArgument(i, argument.traverse(traversing)); } return this; } @Override public boolean inspect(Inspecting inspecting) { if (inspecting.check(this)) { return true; } for (int i = 0; i < size(); i++) { MathComponent argument = getArgument(i); if (inspecting.check(argument)) { return true; } } return false; } @Override public abstract MathContainer copy(); public int indexOf(MathComponent argument) { return arguments.indexOf(argument); } public void delArgument(int i) { arguments.remove(i); } @Override public String toString() { StringBuilder sb = new StringBuilder(getClass().getSimpleName()); sb.append('['); for (int i = 0; i < size(); i++) { if (i > 0) { sb.append(", "); } sb.append(getArgument(i)); } sb.append(']'); return sb.toString(); } }