/*
* Copyright 2013 serso aka se.solovyev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Contact details
*
* Email: se.solovyev@gmail.com
* Site: http://se.solovyev.org
*/
package org.solovyev.android.calculator.text;
import jscl.math.Generic;
import org.solovyev.android.calculator.Engine;
import org.solovyev.android.calculator.math.MathType;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
public class FromJsclSimplifyTextProcessor implements TextProcessor<String, Generic> {
private final List<MathType> mathTypes = Arrays.asList(MathType.function, MathType.constant);
@Nonnull
private final Engine engine;
public FromJsclSimplifyTextProcessor(@Nonnull Engine engine) {
this.engine = engine;
}
@Nonnull
@Override
public String process(@Nonnull Generic from) {
return fixMultiplicationSigns(from.toString());
}
public String process(@Nonnull String s) {
return fixMultiplicationSigns(s);
}
@Nonnull
private String fixMultiplicationSigns(String s) {
final StringBuilder sb = new StringBuilder();
final MathType.Results results = new MathType.Results();
MathType.Result mathTypeBefore = null;
MathType.Result mathType = null;
MathType.Result mathTypeAfter = null;
for (int i = 0; i < s.length(); i++) {
results.release(mathTypeBefore);
mathTypeBefore = mathType;
if (mathTypeAfter == null) {
mathType = MathType.getType(s, i, false, results.obtain(), engine);
} else {
mathType = mathTypeAfter;
}
char ch = s.charAt(i);
if (ch == '*') {
if (i + 1 < s.length()) {
mathTypeAfter = MathType.getType(s, i + 1, false, results.obtain(), engine);
} else {
mathTypeAfter = null;
}
if (needMultiplicationSign(mathTypeBefore == null ? null : mathTypeBefore.type, mathTypeAfter == null ? null : mathTypeAfter.type)) {
sb.append(engine.getMultiplicationSign());
}
} else {
if (mathType.type == MathType.constant || mathType.type == MathType.function || mathType.type == MathType.operator) {
sb.append(mathType.match);
i += mathType.match.length() - 1;
} else {
sb.append(ch);
}
mathTypeAfter = null;
}
}
return sb.toString();
}
private boolean needMultiplicationSign(@Nullable MathType mathTypeBefore, @Nullable MathType mathTypeAfter) {
if (mathTypeBefore == null || mathTypeAfter == null) {
return true;
} else if (mathTypes.contains(mathTypeBefore) || mathTypes.contains(mathTypeAfter)) {
return false;
} else if (mathTypeBefore == MathType.close_group_symbol) {
return false;
} else if (mathTypeAfter == MathType.open_group_symbol) {
return false;
}
return true;
}
}