package it.albertus.cycles.engine; import java.beans.Introspector; import it.albertus.cycles.model.Bike; import it.albertus.cycles.model.BikesInf; import it.albertus.cycles.model.Gearbox; import it.albertus.cycles.model.Setting; import it.albertus.cycles.model.Settings; import it.albertus.cycles.model.Torque; import it.albertus.cycles.resources.Messages; import it.albertus.util.StringUtils; public abstract class CyclesModEngine { private static final String MSG_KEY_ERR_UNSUPPORTED_PROPERTY = "err.unsupported.property"; private NumeralSystem numeralSystem = NumeralSystem.DEFAULT; private BikesInf bikesInf; public NumeralSystem getNumeralSystem() { return numeralSystem; } public void setNumeralSystem(NumeralSystem numeralSystem) { this.numeralSystem = numeralSystem; } public BikesInf getBikesInf() { return bikesInf; } public void setBikesInf(BikesInf bikesInf) { this.bikesInf = bikesInf; } public static boolean isNumeric(final String value, final int radix) { try { Long.parseLong(value, radix); } catch (final NumberFormatException nfe) { return false; } return true; } public boolean isNumeric(final String value) { return isNumeric(value, numeralSystem.getRadix()); } protected boolean applyProperty(final String key, final String value, final boolean lenient) { boolean applied = false; try { if (value == null || value.trim().length() == 0 || !isNumeric(value.trim())) { throw new InvalidPropertyException(Messages.get(MSG_KEY_ERR_UNSUPPORTED_PROPERTY, key, value)); } // Settings if (isSettingsProperty(key)) { applied = applySettingProperty(key, value); } // Gearbox else if (isGearboxProperty(key)) { applied = applyGearboxProperty(key, value); } // Torque else if (isTorqueProperty(key)) { applied = applyTorqueProperty(key, value); } else { throw new InvalidPropertyException(Messages.get(MSG_KEY_ERR_UNSUPPORTED_PROPERTY, key, value)); } } catch (InvalidPropertyException ipe) { if (!lenient) { throw ipe; } } return applied; } public boolean isTorqueProperty(final String key) { return StringUtils.substringAfter(key, ".").startsWith(Introspector.decapitalize(Torque.class.getSimpleName())); } public boolean isGearboxProperty(final String key) { return StringUtils.substringAfter(key, ".").startsWith(Introspector.decapitalize(Gearbox.class.getSimpleName())); } public boolean isSettingsProperty(final String key) { return StringUtils.substringAfter(key, ".").startsWith(Introspector.decapitalize(Settings.class.getSimpleName())); } private boolean applyTorqueProperty(final String key, final String value) { boolean applied = false; final short newValue = Torque.parse(key, value, numeralSystem.getRadix()); final Bike bike = getBike(key, value); final String suffix = StringUtils.substringAfter(key, Introspector.decapitalize(Torque.class.getSimpleName()) + '.'); if (StringUtils.isNotEmpty(suffix) && StringUtils.isNumeric(suffix) && Integer.parseInt(suffix) < bike.getTorque().getCurve().length) { final int index = Integer.parseInt(suffix); final short defaultValue = bike.getTorque().getCurve()[index]; if (defaultValue != newValue) { bike.getTorque().getCurve()[index] = newValue; applied = true; logChange(key, defaultValue, newValue); } } else { throw new InvalidPropertyException(Messages.get(MSG_KEY_ERR_UNSUPPORTED_PROPERTY, key, value)); } return applied; } private boolean applyGearboxProperty(final String key, final String value) { boolean applied = false; final int newValue = Gearbox.parse(key, value, numeralSystem.getRadix()); final Bike bike = getBike(key, value); final String suffix = StringUtils.substringAfter(key, Introspector.decapitalize(Gearbox.class.getSimpleName()) + '.'); if (StringUtils.isNotEmpty(suffix) && StringUtils.isNumeric(suffix) && Integer.parseInt(suffix) < bike.getGearbox().getRatios().length) { final int index = Integer.parseInt(suffix); final int defaultValue = bike.getGearbox().getRatios()[index]; if (defaultValue != newValue) { bike.getGearbox().getRatios()[index] = newValue; applied = true; logChange(key, defaultValue, newValue); } } else { throw new InvalidPropertyException(Messages.get(MSG_KEY_ERR_UNSUPPORTED_PROPERTY, key, value)); } return applied; } private boolean applySettingProperty(final String key, final String value) { boolean applied = false; final int newValue = Settings.parse(key, value, numeralSystem.getRadix()); final Bike bike = getBike(key, value); final String suffix = StringUtils.substringAfter(key, Introspector.decapitalize(Settings.class.getSimpleName()) + '.'); final Setting setting = Setting.getSetting(suffix); if (setting != null) { final int defaultValue = bike.getSettings().getValues().get(setting); if (newValue != defaultValue) { bike.getSettings().getValues().put(setting, newValue); applied = true; logChange(key, defaultValue, newValue); } } else { throw new InvalidPropertyException(Messages.get(MSG_KEY_ERR_UNSUPPORTED_PROPERTY, key, value)); } return applied; } private void logChange(final String key, final int defaultValue, final int newValue) { System.out.println(Messages.get("msg.custom.value.detected", key, newValue, String.format("%X", newValue), defaultValue, String.format("%X", defaultValue))); } private Bike getBike(final String key, final String value) { final Bike bike = bikesInf.getBike(Integer.parseInt(StringUtils.substringBefore(key, "."))); if (bike == null) { throw new InvalidPropertyException(Messages.get(MSG_KEY_ERR_UNSUPPORTED_PROPERTY, key, value)); } return bike; } }