001/*
002 * This file is part of Baritone.
003 *
004 * Baritone is free software: you can redistribute it and/or modify
005 * it under the terms of the GNU Lesser General Public License as published by
006 * the Free Software Foundation, either version 3 of the License, or
007 * (at your option) any later version.
008 *
009 * Baritone is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public License
015 * along with Baritone.  If not, see <https://www.gnu.org/licenses/>.
016 */
017
018package baritone.api.utils;
019
020import baritone.api.BaritoneAPI;
021import net.minecraft.client.Minecraft;
022import net.minecraft.util.text.ITextComponent;
023import net.minecraft.util.text.TextComponentString;
024import net.minecraft.util.text.TextFormatting;
025
026import java.util.Arrays;
027import java.util.Calendar;
028import java.util.stream.Stream;
029
030/**
031 * An ease-of-access interface to provide the {@link Minecraft} game instance,
032 * chat and console logging mechanisms, and the Baritone chat prefix.
033 *
034 * @author Brady
035 * @since 8/1/2018
036 */
037public interface Helper {
038
039    /**
040     * Instance of {@link Helper}. Used for static-context reference.
041     */
042    Helper HELPER = new Helper() {};
043
044    /**
045     * Instance of the game
046     */
047    Minecraft mc = Minecraft.getMinecraft();
048
049    static ITextComponent getPrefix() {
050        // Inner text component
051        final Calendar now = Calendar.getInstance();
052        final boolean xd = now.get(Calendar.MONTH) == Calendar.APRIL && now.get(Calendar.DAY_OF_MONTH) <= 3;
053        ITextComponent baritone = new TextComponentString(xd ? "Baritoe" : BaritoneAPI.getSettings().shortBaritonePrefix.value ? "B" : "Baritone");
054        baritone.getStyle().setColor(TextFormatting.LIGHT_PURPLE);
055
056        // Outer brackets
057        ITextComponent prefix = new TextComponentString("");
058        prefix.getStyle().setColor(TextFormatting.DARK_PURPLE);
059        prefix.appendText("[");
060        prefix.appendSibling(baritone);
061        prefix.appendText("]");
062
063        return prefix;
064    }
065
066    /**
067     * Send a message to display as a toast popup
068     *
069     * @param title   The title to display in the popup
070     * @param message The message to display in the popup
071     */
072    default void logToast(ITextComponent title, ITextComponent message) {
073        mc.addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message));
074    }
075
076    /**
077     * Send a message to display as a toast popup
078     *
079     * @param title   The title to display in the popup
080     * @param message The message to display in the popup
081     */
082    default void logToast(String title, String message) {
083        logToast(new TextComponentString(title), new TextComponentString(message));
084    }
085
086    /**
087     * Send a message to display as a toast popup
088     *
089     * @param message The message to display in the popup
090     */
091    default void logToast(String message) {
092        logToast(Helper.getPrefix(), new TextComponentString(message));
093    }
094
095    /**
096     * Send a message as a desktop notification
097     *
098     * @param message The message to display in the notification
099     */
100    default void logNotification(String message) {
101        logNotification(message, false);
102    }
103
104    /**
105     * Send a message as a desktop notification
106     *
107     * @param message The message to display in the notification
108     * @param error   Whether to log as an error
109     */
110    default void logNotification(String message, boolean error) {
111        if (BaritoneAPI.getSettings().desktopNotifications.value) {
112            logNotificationDirect(message, error);
113        }
114    }
115
116    /**
117     * Send a message as a desktop notification regardless of desktopNotifications
118     * (should only be used for critically important messages)
119     *
120     * @param message The message to display in the notification
121     */
122    default void logNotificationDirect(String message) {
123        logNotificationDirect(message, false);
124    }
125
126    /**
127     * Send a message as a desktop notification regardless of desktopNotifications
128     * (should only be used for critically important messages)
129     *
130     * @param message The message to display in the notification
131     * @param error   Whether to log as an error
132     */
133    default void logNotificationDirect(String message, boolean error) {
134        mc.addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error));
135    }
136
137    /**
138     * Send a message to chat only if chatDebug is on
139     *
140     * @param message The message to display in chat
141     */
142    default void logDebug(String message) {
143        if (!BaritoneAPI.getSettings().chatDebug.value) {
144            //System.out.println("Suppressed debug message:");
145            //System.out.println(message);
146            return;
147        }
148        // We won't log debug chat into toasts
149        // Because only a madman would want that extreme spam -_-
150        logDirect(message, false);
151    }
152
153    /**
154     * Send components to chat with the [Baritone] prefix
155     *
156     * @param logAsToast Whether to log as a toast notification
157     * @param components The components to send
158     */
159    default void logDirect(boolean logAsToast, ITextComponent... components) {
160        ITextComponent component = new TextComponentString("");
161        if (!logAsToast) {
162            // If we are not logging as a Toast
163            // Append the prefix to the base component line
164            component.appendSibling(getPrefix());
165            component.appendSibling(new TextComponentString(" "));
166        }
167        Arrays.asList(components).forEach(component::appendSibling);
168        if (logAsToast) {
169            logToast(getPrefix(), component);
170        } else {
171            mc.addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
172        }
173    }
174
175    /**
176     * Send components to chat with the [Baritone] prefix
177     *
178     * @param components The components to send
179     */
180    default void logDirect(ITextComponent... components) {
181        logDirect(BaritoneAPI.getSettings().logAsToast.value, components);
182    }
183
184    /**
185     * Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a
186     * direct response to a chat command)
187     *
188     * @param message    The message to display in chat
189     * @param color      The color to print that message in
190     * @param logAsToast Whether to log as a toast notification
191     */
192    default void logDirect(String message, TextFormatting color, boolean logAsToast) {
193        Stream.of(message.split("\n")).forEach(line -> {
194            ITextComponent component = new TextComponentString(line.replace("\t", "    "));
195            component.getStyle().setColor(color);
196            logDirect(logAsToast, component);
197        });
198    }
199
200    /**
201     * Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a
202     * direct response to a chat command)
203     *
204     * @param message The message to display in chat
205     * @param color   The color to print that message in
206     */
207    default void logDirect(String message, TextFormatting color) {
208        logDirect(message, color, BaritoneAPI.getSettings().logAsToast.value);
209    }
210
211    /**
212     * Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a
213     * direct response to a chat command)
214     *
215     * @param message    The message to display in chat
216     * @param logAsToast Whether to log as a toast notification
217     */
218    default void logDirect(String message, boolean logAsToast) {
219        logDirect(message, TextFormatting.GRAY, logAsToast);
220    }
221
222    /**
223     * Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a
224     * direct response to a chat command)
225     *
226     * @param message The message to display in chat
227     */
228    default void logDirect(String message) {
229        logDirect(message, BaritoneAPI.getSettings().logAsToast.value);
230    }
231}