package com.drawbridge.utils;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.SwingUtilities;
import com.drawbridge.dm.DMImageFactory.DMImage;
import com.drawbridge.dm.DMSimplePanel;
import com.drawbridge.jsengine.JsEngine;
import com.drawbridge.text.TextPanel;
import com.google.caja.lexer.FilePosition;
import com.google.caja.lexer.InputSource;
public class JSUtils
{
private static int nameIndex = 0;
/**
* Generates valid JavaScript code to display a given set of DMImages
* @param ArrayList of DMImages Assignment ps:
* @return JavaScript code
*/
public static String generateDMImageJS(List<DMImage> images){
String result = "// Draw the images on the canvas\n";
for(int i = 0; i < images.size(); i++){
String objectName = images.get(i).getName();
Point loc = images.get(i).getPreferredLocation();
Dimension size = images.get(i).getPreferredSize();
result += "var " + objectName + " = loadImage(" + i + ", " +
(int) loc.getX() + ", " +
(int) loc.getY() + ", " +
(int) (size.getWidth() - ( 2 * images.get(i).getHandleThickness())) + ", " +
(int) (size.getHeight() - ( 2 * images.get(i).getHandleThickness())) + ");";
result += (i != images.size() -1) ? "\n" : "";
}
return result;
}
/**
* Generates valid JavaScript code to display the canvas
* @param ArrayList of DMImages
* @return JavaScript code
*/
public static String generateCanvasJS(){
return "// Get the canvas so we can draw something\n" +
"var canvas = document.getElementById(\"myCanvas\");\n\n" +
"// Paint Background\n" +
"var myColour = Colour.getRGB(255, 255, 255);\n" +
"canvas.setBackgroundColour(myColour);\n";
}
public static String generateImageName(){
return "image" + nameIndex++;
}
public static final String JS_CANVAS_RESET = ("clear();");
private static HashSet<String> keywords = new HashSet<String>(){
private static final long serialVersionUID = 1019297538895274071L;
{
add("in");
add("if");
add("for");
add("while");
add("finally");
add("var");
add("new");
add("function");
add("do");
add("return");
add("void");
add("else");
add("break");
add("catch");
add("instanceof");
add("with");
add("throw");
add("case");
add("default");
add("try");
add("this");
add("switch");
add("continue");
add("typeof");
add("delete");
add("let");
add("yield");
add("const");
add("true");
add("false");
add("null");
add("undefined");
add("NaN");
add("Infinity");
}
;
};
public static ArrayList<HighlightElement> getHighlightElements(String javascript){
ArrayList<HighlightElement> results = new ArrayList<HighlightElement>();
ArrayList<HighlightElement> tokens = getMatchingKeywords(javascript);
ArrayList<HighlightElement> stringLiterals = getStringLiterals(javascript);
ArrayList<HighlightElement> literals = getLiterals(javascript);
ArrayList<HighlightElement> comments = getComments(javascript);
ArrayList<HighlightElement> functionCalls = getFunctionCalls(javascript);
results.addAll(literals);
results.addAll(tokens);
results.addAll(stringLiterals);
results.addAll(comments);
results.addAll(functionCalls);
return results;
}
public static ArrayList<HighlightElement> getMatchingKeywords(String string){
ArrayList<HighlightElement> tokens = new ArrayList<HighlightElement>();
String stringPattern = "(^|[\\s])[A-Za-z]+";
Pattern pattern = Pattern.compile(stringPattern);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
String result = matcher.group().replaceAll("[\\s]", "");
result = result.replaceAll("\\n", "");
if(keywords.contains(result)){
tokens.add(new HighlightElement(Color.decode("#BF2DA6"), matcher.start(), matcher.end()-1));
}
}
return tokens;
}
public static ArrayList<HighlightElement> getStringLiterals(String string){
ArrayList<HighlightElement> tokens = new ArrayList<HighlightElement>();
String stringPattern = "[\'][\']*[\']";
Pattern pattern = Pattern.compile(stringPattern);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
tokens.add(new HighlightElement(Color.decode("#D12B24"), matcher.start(), matcher.end()-1));
}
stringPattern = "[\"][^\"]*[\"]";
pattern = Pattern.compile(stringPattern);
matcher = pattern.matcher(string);
while (matcher.find()) {
tokens.add(new HighlightElement(Color.decode("#D12B24"), matcher.start(), matcher.end()-1));
}
return tokens;
}
public static ArrayList<HighlightElement> getComments(String string)
{
ArrayList<HighlightElement> tokens = new ArrayList<HighlightElement>();
String stringPattern = "[\\/][\\/].*";
Pattern pattern = Pattern.compile(stringPattern);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
tokens.add(new HighlightElement(Color.decode("#008425"), matcher.start(), matcher.end()-1));
}
return tokens;
}
public static ArrayList<HighlightElement> getFunctionCalls(String string)
{
ArrayList<HighlightElement> tokens = new ArrayList<HighlightElement>();
String stringPattern = "[A-Za-z]+[(]";
Pattern pattern = Pattern.compile(stringPattern);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
tokens.add(new HighlightElement(Color.decode("#42B5E7"), matcher.start(), matcher.end()-2));
}
return tokens;
}
public static ArrayList<HighlightElement> getLiterals(String string)
{
ArrayList<HighlightElement> tokens = new ArrayList<HighlightElement>();
String stringPattern = "[\\(\\=\\,\\+\\-\\\\\\s][0-9]+[.]?[0-9]*";
Pattern pattern = Pattern.compile(stringPattern);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
String startChar = string.substring(matcher.start(), matcher.start()+1);
String allowedStartChars = "( +-=,";
int start = matcher.start();
int end = matcher.end() - 1;
if(allowedStartChars.contains(startChar))
start++;
tokens.add(new HighlightElement(Color.decode("#049999"), start, end));
}
return tokens;
}
public static FilePosition getNewFilePosition(FilePosition oldFilePos, int newLength){
if(oldFilePos.length() < newLength){
return oldFilePos.narrowTo(0, newLength);
}
else{
int linePos = oldFilePos.startLineNo();
int oldStartCharInFile = oldFilePos.startCharInFile();
int xPos = TextPanel.getInstance().getDocument().getDocumentModel().getCharPositionFromStringIndex(oldStartCharInFile-1).x;
FilePosition newFilePos = FilePosition.instance(InputSource.UNKNOWN, linePos, oldStartCharInFile, xPos, newLength);
return newFilePos;
}
}
public static void printFilePosition(FilePosition filePosition)
{
Utils.out.println(JSUtils.class,"FilePosition: " + filePosition.startCharInFile() + ", " + filePosition.endCharInFile());
}
public static void executeStaticImageCode(LinkedList<DMImage> dmImages, final boolean requestAnimation)
{
// Follow on the update sequence with Code Generation
String code = JSUtils.generateCanvasJS() + "\n";
code += JSUtils.generateDMImageJS(dmImages);
final String resultCode = code;
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run()
{
if(TextPanel.hasInstance())
TextPanel.getInstance().setText(JSUtils.class, resultCode);
JsEngine.getInstance().executeCode(null, resultCode, false); //<- this used to be important
//Execute
if(requestAnimation){
Utils.out.println(this.getClass(),"Executing from DMModel");
DMSimplePanel.getInstance().requestAnimationStart();
}
}
});
}
public static void resetImageNameCounter()
{
nameIndex = 0;
}
}