package de.unisiegen.tpml.graphics.renderer;
import java.awt.Color;
import java.awt.Font;
import java.text.CharacterIterator;
import de.unisiegen.tpml.core.prettyprinter.PrettyCharIterator;
import de.unisiegen.tpml.core.prettyprinter.PrettyString;
import de.unisiegen.tpml.core.prettyprinter.PrettyStyle;
import de.unisiegen.tpml.core.util.Theme ;
/**
* This class provides the translation of {@link PrettyString} into HTML-Code
* This is used by the {@link CompoundExpressionTypeInference} to provide the tooltip of
* the A. This calss realy only translats the prettystring into html, the <html> and
* </html> are missing and must be added.
* @author Feivel
*
*/
public class PrettyStringToHTML
{
/**
* The hex values.
*/
private static final String[] HEX_VALUES =
{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$
"C", "D", "E", "F", "00" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
/**
* Ampersand replace.
*/
private static final String AMPERSAND_THAN_REPLACE = "&"; //$NON-NLS-1$
/**
* Lower than replace.
*/
private static final String LOWER_THAN_REPLACE = "<"; //$NON-NLS-1$
/**
* Greater than replace.
*/
private static final String GREATER_THAN_REPLACE = ">"; //$NON-NLS-1$
/**
* translates the given PrettyString to a HTML-Coded String
*
* @param s The PrettyString to translate
* @return hte HTML-coded Sring
*/
public static String toHTMLString(PrettyString s)
{
//build the result
String result = "";
//for performance, use the Stringbuilder
StringBuilder rb = new StringBuilder();
//the first font will be clesed directly
rb.append("<font color=\"#FFFFFF\">");
//these Strings will be inserted everytime a char is inserted
//if the Font is with style BOLD, they will get <b> and </b>
String boldAnte = "";
String boldPost = "";
//lets walk throug the PrettySting, char by char
int charIndex = 0;
//svae the last Syle: if the style change the color will be close (</font>)
PrettyStyle lastStyle = PrettyStyle.NONE;
PrettyCharIterator it = s.toCharacterIterator();
for (char c = it.setIndex(charIndex); c != CharacterIterator.DONE; c = it.next(), charIndex++)
{
//get the style
switch (it.getStyle())
{
case KEYWORD:
//if nothing changed
if (lastStyle == it.getStyle())
{
//add the actual char, surrounded with <b> and </b> if needed
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
//if the style changed, setup the new one
else
{
//save the new style
lastStyle = it.getStyle();
//buld up the color from theme
rb.append("</font>");
Color col = Theme.currentTheme().getKeywordColor();
String colH = getHTMLColor(col);
rb.append("<font color=\"#" + colH + "\">");
//set the boldString if the style ist BOLD
if (AbstractRenderer.keywordFont.getStyle() == Font.BOLD)
{
boldAnte = "<b>";
boldPost = "</b>";
}
//reset the BoldStrings if the style is not BOLD
else
{
boldAnte = "";
boldPost = "";
}
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
break;
//The same preseture with ervery style...
case IDENTIFIER:
if (lastStyle == it.getStyle())
{
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
else
{
rb.append("</font>");
lastStyle = it.getStyle();
Color col = Theme.currentTheme().getIdentifierColor();
String colH = getHTMLColor(col);
rb.append("<font color=\"#" + colH + "\">");
if (AbstractRenderer.identifierFont.getStyle() == Font.BOLD)
{
boldAnte = "<b>";
boldPost = "</b>";
}
else
{
boldAnte = "";
boldPost = "";
}
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
break;
case NONE:
if (lastStyle == it.getStyle())
{
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
else
{
rb.append("</font>");
lastStyle = it.getStyle();
Color col = Theme.currentTheme().getExpressionColor();
String colH = getHTMLColor(col);
rb.append("<font color=\"#" + colH + "\">");
if (AbstractRenderer.expFont.getStyle() == Font.BOLD)
{
boldAnte = "<b>";
boldPost = "</b>";
}
else
{
boldAnte = "";
boldPost = "";
}
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
break;
case CONSTANT:
if (lastStyle == it.getStyle())
{
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
else
{
rb.append("</font>");
lastStyle = it.getStyle();
Color col = Theme.currentTheme().getConstantColor();
String colH = getHTMLColor(col);
rb.append("<font color=\"#" + colH + "\">");
if (AbstractRenderer.constantFont.getStyle() == Font.BOLD)
{
boldAnte = "<b>";
boldPost = "</b>";
}
else
{
boldAnte = "";
boldPost = "";
}
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
break;
case COMMENT:
continue;
case TYPE:
if (lastStyle == it.getStyle())
{
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
else
{
rb.append("</font>");
lastStyle = it.getStyle();
Color col = Theme.currentTheme().getTypeColor();
String colH = getHTMLColor(col);
rb.append("<font color=\"#" + colH + "\">");
if (AbstractRenderer.typeFont.getStyle() == Font.BOLD)
{
boldAnte = "<b>";
boldPost = "</b>";
}
else
{
boldAnte = "";
boldPost = "";
}
rb.append(boldAnte + getHTMLCode(c) + boldPost);
}
break;
}
}
rb.append("</font>");
result = rb.toString();
return result;
}
/**
* Returns the color in HTML formatting.
*
* @param pColor The color which should be returned.
* @return The color in HTML formatting.
*/
public static final String getHTMLColor(Color pColor)
{
return (getHex(pColor.getRed()) + getHex(pColor.getGreen()) + getHex(pColor.getBlue()));
}
/**
* Returns the hex value of a given integer.
*
* @param pNumber The input integer value.
* @return The hex value of a given integer.
*/
private static final String getHex(int pNumber)
{
StringBuilder result = new StringBuilder();
int remainder = Math.abs(pNumber);
int base = 0;
if (remainder > 0)
{
while (remainder > 0)
{
base = remainder % 16;
remainder = (remainder / 16);
result.insert(0, HEX_VALUES[base]);
}
}
else
{
return HEX_VALUES[16];
}
return result.toString();
}
/**
* Returns the replaced <code>char</code>.
*
* @param pChar Input <code>char</code>.
* @return The replaced <code>char</code>.
*/
private static final String getHTMLCode(char pChar)
{
if (pChar == '&')
{
return AMPERSAND_THAN_REPLACE;
}
if (pChar == '<')
{
return LOWER_THAN_REPLACE;
}
if (pChar == '>')
{
return GREATER_THAN_REPLACE;
}
return String.valueOf(pChar);
}
}