/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
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.
*/
package org.geogebra.common.kernel.advanced;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.algos.AlgoElement;
import org.geogebra.common.kernel.commands.Commands;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoList;
import org.geogebra.common.kernel.geos.GeoNumberValue;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.common.kernel.geos.GeoText;
/**
* Algorithm for searching in text or list
*
* @author Zbynek Konecny
*/
public class AlgoIndexOf extends AlgoElement {
private GeoElement hayStack; // input
private GeoElement needle; // input
private GeoNumeric index; // output
private GeoNumberValue start;
/**
* Creates new index of algorithm
*
* @param cons
* @param label
* @param needle
* what we want to find
* @param hayStack
* GeoList of GeoText in which we want to search
*/
public AlgoIndexOf(Construction cons, String label, GeoElement needle,
GeoElement hayStack) {
super(cons);
this.hayStack = hayStack;
this.needle = needle;
index = new GeoNumeric(cons);
setInputOutput();
compute();
index.setLabel(label);
}
/**
* Creates new index of algorithm
*
* @param cons
* @param label
* @param needle
* what we want to find
* @param hayStack
* GeoList of GeoText in which we want to search
* @param start
* start index (1 means "search from beginning")
*/
public AlgoIndexOf(Construction cons, String label, GeoElement needle,
GeoElement hayStack, GeoNumberValue start) {
super(cons);
this.hayStack = hayStack;
this.needle = needle;
this.start = start;
index = new GeoNumeric(cons);
setInputOutput();
compute();
index.setLabel(label);
}
@Override
public Commands getClassName() {
return Commands.IndexOf;
}
@Override
protected void setInputOutput() {
if (start == null) {
input = new GeoElement[2];
input[0] = needle;
input[1] = hayStack;
} else {
input = new GeoElement[3];
input[0] = needle;
input[1] = hayStack;
input[2] = start.toGeoElement();
}
setOutputLength(1);
setOutput(0, index);
setDependencies(); // done by AlgoElement
}
/**
* Returns the resulting index
*
* @return the resulting index
*/
public GeoNumeric getResult() {
return index;
}
@Override
public final void compute() {
index.setUndefined();
int startAt = start != null ? (int) start.getDouble() - 1 : 0;
if (startAt < 0) {
return;
}
if (hayStack.isGeoText()) {
// undefined haystack <=> getTextString is null
if (((GeoText) hayStack).getTextString() == null) {
index.setUndefined();
return;
}
int pos = ((GeoText) hayStack).getTextString()
.indexOf(((GeoText) needle).getTextString(), startAt);
if (pos > -1) {
index.setValue(pos + 1);
}
return;
}
int size = ((GeoList) hayStack).size();
for (int i = startAt; i < size; i++) {
GeoElement cmp = ((GeoList) hayStack).get(i);
if (needle.isEqual(cmp)) {
index.setValue(i + 1);
break;
}
}
}
}