/* * This file is part of Matter Overdrive * Copyright (c) 2015., Simeon Radivoev, All rights reserved. * * Matter Overdrive 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, either version 3 of the License, or * (at your option) any later version. * * Matter Overdrive is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Matter Overdrive. If not, see <http://www.gnu.org/licenses>. */ package matteroverdrive.guide; import cofh.api.energy.IEnergyContainerItem; import matteroverdrive.gui.GuiDataPad; import matteroverdrive.util.MOEnergyHelper; import net.minecraft.client.gui.FontRenderer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; import org.w3c.dom.Element; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by Simeon on 8/31/2015. */ public abstract class GuideElementTextAbstract extends GuideElementAbstract { private static String shortcodePattern = "\\[(.*?)\\]"; private static String shortcodePatternSplitter = "((?<="+shortcodePattern+")|(?="+shortcodePattern+"))"; @Override public void loadElement(MOGuideEntry entry, Element element,Map<String,String> styleSheetMap,int width,int height) { getFontRenderer().setUnicodeFlag(true); Map<String,String> styleMap = buildStyleMap(styleSheetMap, element); loadStyles(entry,element,styleMap,width,height); this.width = calculateWidth(styleMap,width); loadContent(entry, element, width, height); calculateDimentions(entry,element,styleMap,width,height); getFontRenderer().setUnicodeFlag(false); } protected List<TextLine> handleTextFormatting(MOGuideEntry entry,String text,int width) { List<Object> shortCodeSplits = new ArrayList<>(); Matcher matcher = Pattern.compile(shortcodePattern).matcher(text); int lastEnd = 0; while (matcher.find()) { shortCodeSplits.add(text.substring(lastEnd,matcher.start())); String shortcode = matcher.group(); shortCodeSplits.add(handleShortCode(decodeShortcode(shortcode))); lastEnd = matcher.end(); } shortCodeSplits.add(text.substring(lastEnd, text.length())); List<TextChunk> textChunks = new ArrayList<>(); for (Object o : shortCodeSplits) { if (o instanceof String) { for (String s : ((String) o).split(" ")) { if (!s.isEmpty()) { textChunks.add(new TextChunk(handleVariables(s.trim(), entry), getFontRenderer())); } } } else if (o instanceof TextChunk) { textChunks.add((TextChunk)o); } } List<TextLine> lines = new ArrayList<>(); TextLine line = new TextLine(); lines.add(line); for (int i = 0; i < textChunks.size();i++) { int w = calculateWidth(null,textChunks.get(i),null); if (i > 0 && i < textChunks.size()-1) { w = calculateWidth(textChunks.get(i-1),textChunks.get(i),textChunks.get(i+1)); } if (line.getWidth() + w > width) { line = new TextLine(); lines.add(line); } line.addChunk(textChunks.get(i)); } return lines; } protected TextChunk handleShortCode(Map<String,String> shortcodeMap) { if (shortcodeMap.get("type").equalsIgnoreCase("block") || shortcodeMap.get("type").equalsIgnoreCase("item")) { ItemStack stack = shortCodeToStack(shortcodeMap); if (stack != null) { String guideName = shortcodeMap.containsKey("guide") ? shortcodeMap.get("guide") : null; int guidePage = shortcodeMap.containsKey("page") ? Integer.parseInt(shortcodeMap.get("page")) : 0; return new ItemstackTextLinkChunk(EnumChatFormatting.GREEN + stack.getDisplayName() + EnumChatFormatting.RESET,getFontRenderer(),stack,guideName,guidePage); } } else if(shortcodeMap.get("type").equalsIgnoreCase("rf")) { if (shortcodeMap.containsKey("itemType")) shortcodeMap.put("type",shortcodeMap.get("itemType")); ItemStack stack = shortCodeToStack(shortcodeMap); if (stack != null && stack.getItem() != null && stack.getItem() instanceof IEnergyContainerItem) { return new TextChunk(((IEnergyContainerItem) stack.getItem()).getMaxEnergyStored(stack) + MOEnergyHelper.ENERGY_UNIT,getFontRenderer()); } } else if (shortcodeMap.get("type").equalsIgnoreCase("guide")) { MOGuideEntry entry = MatterOverdriveGuide.findGuide(shortcodeMap.get("name")); if (entry != null) { int page = shortcodeMap.containsKey("page") ? Integer.parseInt(shortcodeMap.get("page")) : 0; return new GuideTextLinkChunk(EnumChatFormatting.YELLOW + entry.getDisplayName() + EnumChatFormatting.RESET,getFontRenderer(),entry,page); } } return null; } protected String handleVariables(String text,MOGuideEntry entry) { text = text.replace("$itemName",formatVariableReplace("$itemName",((entry.getStackIcons().length > 0 && entry.getStackIcons()[0] != null) ? entry.getStackIcons()[0].getDisplayName() : entry.getDisplayName()))); return text; } protected String formatVariableReplace(String variable,String replace) { return replace; } protected int calculateWidth(TextChunk before,TextChunk main,TextChunk after) { if (after != null && (after.getText().matches("[.,!\"')}]"))) { return main.getWidth(); } if (main.getText().matches("[({]")) { return main.getWidth(); } else { return main.getWidth() + getFontRenderer().getCharWidth(' '); } } protected class TextLine { List<TextChunk> chunks; public TextLine() { this.chunks = new ArrayList<>(); } public void addChunk(TextChunk chunk) { chunks.add(chunk); } public int getWidth() { int width = 0; for (TextChunk chunk : chunks) { width += chunk.getWidth() + getFontRenderer().getCharWidth(' '); } return width; } } public class TextChunk { String text; int width; public TextChunk(String text,FontRenderer fontRenderer) { this.text = text; width = fontRenderer.getStringWidth(text); } public int getWidth() { return width; } public String getText(){return text;} } public abstract class TextChunkLink extends TextChunk { public TextChunkLink(String text,FontRenderer fontRenderer) { super(text,fontRenderer); } public abstract void onClick(GuiDataPad guiDataPad); } public class GuideTextLinkChunk extends TextChunkLink { MOGuideEntry entry; int page; public GuideTextLinkChunk(String text,FontRenderer fontRenderer,MOGuideEntry entry,int page) { super(text,fontRenderer); this.entry = entry; this.page = page; } @Override public void onClick(GuiDataPad guiDataPad) { ((GuiDataPad) gui).getGuideDescription().OpenGuide(entry.getId(),page,true); } } public class ItemstackTextLinkChunk extends TextChunkLink { String guideEntryName; int page; ItemStack stack; public ItemstackTextLinkChunk(String text,FontRenderer fontRenderer,ItemStack stack) { super(text,fontRenderer); this.stack = stack; } public ItemstackTextLinkChunk(String text,FontRenderer fontRenderer,ItemStack stack,String guideEntryName,int page) { super(text,fontRenderer); this.stack = stack; this.guideEntryName = guideEntryName; this.page = page; } @Override public void onClick(GuiDataPad guiDataPad) { MOGuideEntry entry; if (guideEntryName != null) { entry = MatterOverdriveGuide.findGuide(guideEntryName); }else { entry = MatterOverdriveGuide.findGuide(stack.getUnlocalizedName()); } if (entry != null) { ((GuiDataPad) gui).getGuideDescription().OpenGuide(entry.getId(),page,true); } } } }