JIrcBot/src/main/java/ru/bvn13/jircbot/listeners/calculator/CalculatorDialog.java

225 lines
7.3 KiB
Java

package ru.bvn13.jircbot.listeners.calculator;
import lombok.Data;
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
import org.pircbotx.hooks.types.GenericMessageEvent;
import ru.bvn13.fsm.Condition;
import ru.bvn13.fsm.Exceptions.FSMException;
import ru.bvn13.fsm.Exceptions.NotInitedException;
import ru.bvn13.fsm.FSM;
import ru.bvn13.fsm.State;
/**
* Created by bvn13 on 03.01.2018.
*/
@Data
public class CalculatorDialog extends FSM {
public static final String COMMAND = "?calc ";
private String command;
private String[] commands;
private GenericMessageEvent event;
private String expression;
private ExpressionBuilder expressionBuilder;
private Expression exp = null;
public static CalculatorDialog createDialog() throws FSMException {
CalculatorDialog dialog = new CalculatorDialog();
dialog.initState(new State("init") {
@Override
public void process() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
dialog.expression = dialog.command;
dialog.expressionBuilder = new ExpressionBuilder(dialog.expression);
dialog.event.respond("inited, expression: "+dialog.expression);
}
});
dialog.addTransition("init", new State("entering-vars") {
@Override
public void beforeEvent() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
dialog.event.respond("please enter variables (comma separated)");
}
@Override
public void process() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
dialog.enteringVars();
}
});
dialog.addTransition("entering-vars", new State("settings-vars") {
@Override
public void beforeEvent() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
dialog.event.respond("please set variable");
}
@Override
public void process() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
dialog.settingVars();
}
}, new Condition() {
@Override
public boolean check() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
return dialog.commands[0].equalsIgnoreCase("vars");
}
});
dialog.addTransition("settings-vars", "settings-vars", new Condition() {
@Override
public boolean check() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
return !dialog.commands[0].equalsIgnoreCase("done");
}
});
dialog.addTransition("settings-vars", new State("calculating", true) {
@Override
public void process() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
dialog.calculating();
}
}, new Condition() {
@Override
public boolean check() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
return dialog.commands[0].equalsIgnoreCase("done");
}
});
dialog.addTransition("entering-vars", "calculating", new Condition() {
@Override
public boolean check() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
return dialog.commands[0].equalsIgnoreCase("done");
}
});
dialog.addTransition("entering-vars", new State("helping-entering-vars") {
@Override
public void process() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
dialog.event.respond(dialog.helpMessage());
//dialog.event.respond("Please set vars");
try {
dialog.next();
} catch (FSMException e) {
e.printStackTrace();
}
}
}, new Condition() {
@Override
public boolean check() {
CalculatorDialog dialog = ((CalculatorDialog)this.getFSM());
return !dialog.commands[0].equalsIgnoreCase("done")
&& !dialog.commands[0].equalsIgnoreCase("vars");
}
});
dialog.addTransition("helping-entering-vars", "entering-vars");
return dialog;
}
private void enteringVars() {
exp = expressionBuilder.variables(commands[1].trim()).build();
event.respond("VARIABLES: "+commands[1].trim());
}
private void settingVars() {
String[] variableData = commands[1].trim().split("=", 2);
if (variableData.length < 2 || variableData[0].isEmpty() || variableData[1].isEmpty()) {
event.respond("FORMAT: variable = value");
} else {
if (exp == null) {
//currentEvent.respond("Variables are not set!");
exp = expressionBuilder.build();
} else {
Double value = Double.parseDouble(variableData[1].trim());
exp = exp.setVariable(variableData[0].trim(), value);
event.respond(String.format("VARIABLE SET: %s = %f", variableData[0].trim(), value));
}
}
}
private void calculating() {
if (exp == null) {
exp = expressionBuilder.build();
}
Double result = exp.evaluate();
event.respond(String.format("%s = %f", expression, result));
expressionBuilder = null;
exp = null;
return;
}
public void setEvent(GenericMessageEvent event) {
this.event = event;
}
public void processCommand(String userMessage) {
if (prepareCommand(userMessage)) {
return;
}
if (this.getCurrentState()==null || this.getCurrentState().isFinish()) {
try {
this.init();
} catch (NotInitedException e) {
e.printStackTrace();
}
}
try {
this.next();
} catch (FSMException e) {
e.printStackTrace();
}
}
private boolean prepareCommand(String userMessage) {
String message = userMessage.replace(COMMAND, "").trim();
this.commands = message.split(" ", 2);
if (commands.length == 0 || commands[0].isEmpty() || commands[0].trim().equalsIgnoreCase("help")) {
event.respond(this.helpMessage());
return true;
}
if (this.checkComand(commands[0].trim())) {
return false;
}
this.command = message;
return false;
}
private String helpMessage() {
return "CALCULATOR (powered by Exp4J) | "+
"Commands: | "+
"vars - set variables names delimetered by comma, i.e.: a, b | "+
"set - set variable, i.e.: a = 2 | "+
"done - evaluate expression";
}
private Boolean checkComand(String command) {
return command.equalsIgnoreCase("vars")
|| command.equalsIgnoreCase("set")
|| command.equalsIgnoreCase("done");
}
}