package com.game.libgdx.roguelikeengine;
/*
Copyright (C) 2013 Ferran Fabregas (ferri.fc@gmail.com)
This program 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.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
public class PopupInfoText {
protected HashMap<String, LinkedList<WordRectangle>> renderWords = new HashMap<String, LinkedList<WordRectangle>>();
protected HashMap<String, LinkedList<WordClickAction>> wordClickListeners = new HashMap<String, LinkedList<WordClickAction>>();
private String mouseOverElement = "";
private NinePatch background;
private int x;
private int y;
private int width;
private int height;
private int textoffsetx;
private int textoffsety;
private int lineCount = 0;
protected String lastMessage = "";
protected String instructions = (Gdx.app.getType() == ApplicationType.Android ? "Touch " : "Click ") + " to Continue";
protected Color instructionsColor = Color.GREEN;
protected final String colorPattern = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$";
public PopupInfoText (int x,int y, String file, int xsize,int ysize) {
this.x=x;
this.y=y;
this.width=xsize;
this.height=ysize;
this.background = new NinePatch(new Texture(Gdx.files.internal(file)));
}
// sets
public void update_x(int x) {
this.x=x;
}
public void update_y(int y) {
this.y=y;
}
public void settextoffset(int x, int y) {
this.textoffsetx=x;
this.textoffsety=y;
}
// gets
public int get_x() {
return this.x;
}
public int get_y() {
return this.y;
}
public void drawScreen(SpriteBatch batch, BitmapFont font,String text,float fadein,int linedist,Color color) {
drawScreen(batch, font, text, fadein, linedist, color, false);
}
public void drawScreen(SpriteBatch batch, BitmapFont font,String text,float fadein,int linedist,Color color, boolean resize) {
float scaleX = font.getScaleX();
float scaleY = font.getScaleY();
update_x((int) (Gdx.graphics.getWidth() * 0.5f - this.width * 0.5f));
update_y((int) (Gdx.graphics.getHeight() * 0.5f - this.height * 0.5f));
mouseOverElement = "";
if(!lastMessage.equals(text) || resize){
this.clearRenderWords();
lineCount = 0;
int linepos = 0;
int currentWidth = textoffsetx;
int nextWidth = 0;
int maxWidth = (int) (width - textoffsetx);
String[] words = null;
for (String line : text.split("\n")) {
lineCount = lineCount + 1;
currentWidth = textoffsetx;
words = line.split(" ");
for(String word : words) {
if(word.contains("\t")) {
word = word.replace("\t", " ");
}
Color wordColor = color;
if(word.length() > 7) {
String hex = word.substring(0, 7);
if(Pattern.matches(colorPattern, hex)) {
wordColor = this.hex2Rgb(hex);
word = word.replace(hex, "");
}
}
nextWidth = (int) (currentWidth + font.getBounds(word + " ").width);
if(nextWidth > maxWidth) {
currentWidth = textoffsetx;
nextWidth = (int) (currentWidth + font.getBounds(word + " ").width);
linepos = linepos + 1;
lineCount = lineCount + 1;
}
int wordx = currentWidth;
int wordy = height-((textoffsety)+(linepos*linedist));
this.addWordToRender(word, new WordRectangle(wordx, wordy, font.getBounds(word + " ").width, font.getLineHeight()).withColor(wordColor));
currentWidth = nextWidth;
}
linepos++;
currentWidth = x + textoffsetx;
}
}
this.background.draw(batch, x, y, width, height);
while(((lineCount * font.getLineHeight() + lineCount * linedist) * font.getScaleY()) > height - textoffsety) {
font.setScale(font.getScaleY() - 0.1f);
}
if(font.getScaleY() != scaleY) {
drawScreen(batch, font, text, fadein, linedist, color, true);
font.setScale(scaleX, scaleY);
return;
}
boolean anyClickable = false;
Set<Entry<String, LinkedList<WordRectangle>>> keys = renderWords.entrySet();
for(Entry<String, LinkedList<WordRectangle>> entry : keys) {
for(WordRectangle rect : entry.getValue()) {
font.setColor(rect.color.r, rect.color.g, rect.color.b, fadein);
if(wordClickListeners.containsKey(entry.getKey())) {
if(mouseOverWord(rect, font)) {
font.setColor(Color.BLUE.r, Color.BLUE.g, Color.BLUE.b, fadein);
mouseOverElement = entry.getKey();
} else {
font.setColor(Color.CYAN);
font.setColor(Color.CYAN.r, Color.CYAN.g, Color.CYAN.b, fadein);
}
anyClickable = true;
}
font.draw(batch, entry.getKey().replace("_", " "), rect.x+x, rect.y+y);
}
}
if(!anyClickable) {
Color c = font.getColor();
font.setColor(instructionsColor.r, instructionsColor.g, instructionsColor.b, fadein);
font.draw(batch, instructions, x + (width * 0.5f) - (font.getBounds(instructions).width * 0.5f), y + font.getBounds(instructions).height + Gdx.graphics.getHeight() * 0.05f);
font.setColor(c);
}
lastMessage = text;
font.setScale(scaleX, scaleY);
}
protected boolean mouseOverWord(Rectangle rect, BitmapFont font) {
int mouseX = Gdx.input.getX();
int mouseY = Gdx.graphics.getHeight() + ((int)font.getLineHeight()) - Gdx.input.getY();
rect.x += x;
rect.y += y;
boolean result = rect.contains(mouseX, mouseY);
rect.x -= x;
rect.y -= y;
return result;
}
protected boolean xyOverWord(Rectangle rect, int x, int y) {
return rect.contains(x, y);
}
protected void addWordToRender(String word, WordRectangle position) {
if(renderWords.containsKey(word)) {
renderWords.get(word).push(position);
} else {
renderWords.put(word, new LinkedList<WordRectangle>());
addWordToRender(word, position);
}
}
protected void clearRenderWords() {
renderWords.clear();
}
public void addWordClickListener(String word, WordClickAction listener) {
if(wordClickListeners.containsKey(word)) {
wordClickListeners.get(word).push(listener);
} else {
wordClickListeners.put(word, new LinkedList<WordClickAction>());
addWordClickListener(word, listener);
}
}
public void removeWordClickListener(String word, WordClickAction listener) {
if(wordClickListeners.containsKey(word)) {
wordClickListeners.get(word).remove(listener);
}
}
public boolean onMouseClicked() {
if(wordClickListeners.containsKey(mouseOverElement)) {
for(WordClickAction action : wordClickListeners.get(mouseOverElement)) {
action.onClicked(mouseOverElement);
}
return true;
}
if(GameplayScreen.instance != null && GameplayScreen.instance.just_interact > 0 && new Rectangle(x, y, width, height).contains(Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY())) {
GameplayScreen.instance.just_interact = 0;
return true;
}
return false;
}
public boolean mouseOverElement() {
return wordClickListeners.containsKey(mouseOverElement);
}
public void handleClosed() {
this.mouseOverElement = "";
}
@SuppressWarnings("serial")
protected class WordRectangle extends Rectangle {
public Color color;
public WordRectangle(float x, float y, float width, float height) {
super(x, y, width, height);
}
public WordRectangle withColor(Color color) {
this.color = color;
return this;
}
}
public Color hex2Rgb(String colorStr) {
return new Color(Integer.valueOf( colorStr.substring( 1, 3 ), 16 ), Integer.valueOf( colorStr.substring( 3, 5 ), 16 ), Integer.valueOf( colorStr.substring( 5, 7 ), 16 ), 1f );
}
}