/* MathArray.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.meta.MetaArray; import com.himamis.retex.editor.share.meta.MetaComponent; import com.himamis.retex.editor.share.meta.MetaModel; /** * Array/array. This class is part of model. * <p/> * array(i) * array(i*j) * vector(i) * array(i*j) * * @author Bea Petrovicova */ public class MathArray extends MathContainer { private int columns, rows; private MetaArray meta; public MathArray(MetaArray meta, int columns) { super(columns); this.meta = meta; this.columns = columns; this.rows = 1; } public MathArray(MetaArray meta, int columns, int rows) { super(columns * rows); this.meta = meta; this.columns = columns; this.rows = rows; } public void addRow() { for (int i = 0; i < columns; i++) { MathSequence argument = new MathSequence(); argument.setParent(this); arguments.add(argument); } rows += 1; } @Override public MathSequence getArgument(int i) { return (MathSequence) super.getArgument(i); } public void setArgument(int i, MathSequence argument) { super.setArgument(i, argument); } public void addArgument() { MathSequence argument = new MathSequence(); super.addArgument(argument); columns += 1; } @Override public void addArgument(MathComponent argument) { super.addArgument(argument); columns += 1; } @Override public void addArgument(int i, MathComponent argument) { super.addArgument(i, argument); columns += 1; } @Override public void delArgument(int i) { super.removeArgument(i); columns -= 1; } /** * Sets i-th row, j-th column cell. */ public void setArgument(int i, int j, MathSequence argument) { setArgument(i * columns + j, argument); } /** * Returns i-th row, j-th column cell. */ public MathSequence getArgument(int i, int j) { return getArgument(i * columns + j); } public MetaComponent getOpen() { return meta.getOpen(); } public char getOpenKey() { return meta.getOpenKey(); } public MetaComponent getClose() { return meta.getClose(); } public char getCloseKey() { return meta.getCloseKey(); } public MetaComponent getField() { return meta.getField(); } public char getFieldKey() { return meta.getFieldKey(); } public MetaComponent getRow() { return meta.getRow(); } public char getRowKey() { return meta.getRowKey(); } public boolean is1DArray() { return rows() == 1 && meta.isArray(); } public boolean isArray() { return meta.isArray(); } public boolean isVector() { return rows() == 1 && meta.isMatrix(); } public boolean isMatrix() { return meta.isMatrix(); } @Override public MathArray copy() { MathArray array = new MathArray(meta, columns, rows); array.copy(0, 0, this); return array; } /** * Copy array into this object (with silent clipping). * * @param ioffset leading empty rows * @param joffset leading empty columns. */ public void copy(int ioffset, int joffset, MathArray array) { for (int i = 0; (i < (rows + joffset) || i < array.rows); i++) { for (int j = 0; (j < (columns + ioffset) || j < array.columns); j++) { MathSequence component = array.getArgument(i, j); component = component.copy(); setArgument(i + ioffset, j + joffset, component); } } } /** * Number of columns. */ public int columns() { return columns; } /** * Number of rows. */ public int rows() { return rows; } public void checkMatrix(MetaModel metaModel) { int matrixWidth = numberOfColumns(metaModel); if (matrixWidth >= 0) { rows = size(); flattenMatrix(); columns = matrixWidth; meta = metaModel.getMatrix(); } } // Returns the number of columns or -1 if it's not a matrix private int numberOfColumns(MetaModel metaModel) { int matrixWidth = -1; for (int i = 0; i < size(); i++) { if (getArgument(i).size() == 1 && getArgument(i).getArgument(0) instanceof MathArray) { MathArray row = (MathArray) getArgument(i).getArgument(0); if (row.meta != metaModel.getArray(MetaArray.CURLY)) { return -1; } else if (matrixWidth == -1) { matrixWidth = row.size(); } else if (matrixWidth != row.size()) { return -1; } } else { return -1; } } return matrixWidth; } private void flattenMatrix() { ArrayList<MathComponent> entries = new ArrayList<MathComponent>(); for (int i = 0; i < size(); i++) { for (int j = 0; j < ((MathContainer) getArgument(i) .getArgument(0)).size(); j++) { MathComponent arg = ((MathContainer) getArgument(i) .getArgument(0)).getArgument(j); entries.add(arg); } } clearArguments(); for (MathComponent entry : entries) { addArgument(entry); } } }