package GUI;
import Batch.BatchUtils;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.ImageObserver;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Dictionary;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JEditorPane;
import javax.swing.event.DocumentEvent;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyledDocument;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.Position.Bias;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.StyleSheet;
import javax.swing.text.html.HTML.Attribute;
import javax.swing.text.html.HTML.Tag;
public class MyImageView extends View implements ImageObserver, MouseListener, MouseMotionListener {
Class<?> c;
public static final String TOP = "top";
public static final String TEXTTOP = "texttop";
public static final String MIDDLE = "middle";
public static final String ABSMIDDLE = "absmiddle";
public static final String CENTER = "center";
public static final String BOTTOM = "bottom";
private static boolean sIsInc = true;
private static int sIncRate = 100;
private AttributeSet attr;
private Element fElement;
private Image fImage;
private int fHeight;
private int fWidth;
private Container fContainer;
private Rectangle fBounds;
private Component fComponent;
private Point fGrowBase;
private boolean fGrowProportionally;
private boolean loading;
private static Icon sPendingImageIcon;
private static Icon sMissingImageIcon;
private static final String PENDING_IMAGE_SRC = "icons/image-delayed.gif";
private static final String MISSING_IMAGE_SRC = "icons/image-failed.gif";
private static final boolean DEBUG = false;
static final String IMAGE_CACHE_PROPERTY = "imageCache";
private static final int DEFAULT_WIDTH = 32;
private static final int DEFAULT_HEIGHT = 32;
private static final int DEFAULT_BORDER = 2;
public MyImageView(Element elem, Class<?> c) {
super(elem);
this.c = c;
this.initialize(elem);
StyleSheet sheet = this.getStyleSheet();
this.attr = sheet.getViewAttributes(this);
}
private void initialize(Element elem) {
synchronized(this) {
this.loading = true;
this.fWidth = this.fHeight = 0;
}
int width = 0;
int height = 0;
boolean customWidth = false;
boolean customHeight = false;
try {
this.fElement = elem;
AttributeSet attr = elem.getAttributes();
if (this.isURL()) {
URL src = this.getSourceURL();
if (src != null) {
Dictionary cache = (Dictionary)this.getDocument().getProperty("imageCache");
if (cache != null) {
this.fImage = (Image)cache.get(src);
} else {
this.fImage = Toolkit.getDefaultToolkit().getImage(src);
}
}
} else {
String src = (String)this.fElement.getAttributes().getAttribute(Attribute.SRC);
src = src.replace("%20", " ");
src = src.replace("..", "");
InputStream ip = this.c.getResourceAsStream(src);
try {
this.fImage = ImageIO.read(ip);
} catch (IOException var21) {
Logger.getLogger(MyImageView.class.getName()).log(Level.SEVERE, null, var21);
}
try {
this.waitForImage();
} catch (InterruptedException var20) {
this.fImage = null;
}
}
height = this.getIntAttr(Attribute.HEIGHT, -1);
customHeight = height > 0;
if (!customHeight && this.fImage != null) {
height = this.fImage.getHeight(this);
}
if (height <= 0) {
height = 32;
}
width = this.getIntAttr(Attribute.WIDTH, -1);
customWidth = width > 0;
if (!customWidth && this.fImage != null) {
width = this.fImage.getWidth(this);
}
if (width <= 0) {
width = 32;
}
if (this.fImage != null) {
if (customWidth && customHeight) {
Toolkit.getDefaultToolkit().prepareImage(this.fImage, height, width, this);
} else {
Toolkit.getDefaultToolkit().prepareImage(this.fImage, -1, -1, this);
}
}
} finally {
synchronized(this) {
this.loading = false;
if (customWidth || this.fWidth == 0) {
this.fWidth = width;
}
if (customHeight || this.fHeight == 0) {
this.fHeight = height;
}
}
}
}
private boolean isURL() {
String src = (String)this.fElement.getAttributes().getAttribute(Attribute.SRC);
return src.toLowerCase().startsWith("file") || src.toLowerCase().startsWith("http");
}
private String processSrcPath(String src) {
String val = src;
File imageFile = new File(src);
if (imageFile.isAbsolute()) {
return src;
} else {
String imagePath = System.getProperty("system.image.path.key");
if (imagePath != null) {
val = new File(imagePath, imageFile.getPath()).toString();
}
return val;
}
}
private void waitForImage() throws InterruptedException {
int w = this.fImage.getWidth(this);
int h = this.fImage.getHeight(this);
while(true) {
int flags = Toolkit.getDefaultToolkit().checkImage(this.fImage, w, h, this);
if ((flags & 64) != 0 || (flags & 128) != 0) {
throw new InterruptedException();
}
if ((flags & 48) != 0) {
return;
}
Thread.sleep(10L);
}
}
@Override
public AttributeSet getAttributes() {
return this.attr;
}
boolean isLink() {
AttributeSet anchorAttr = (AttributeSet)this.fElement.getAttributes().getAttribute(Tag.A);
return anchorAttr != null ? anchorAttr.isDefined(Attribute.HREF) : false;
}
int getBorder() {
return this.getIntAttr(Attribute.BORDER, this.isLink() ? 2 : 0);
}
int getSpace(int axis) {
return this.getIntAttr(axis == 0 ? Attribute.HSPACE : Attribute.VSPACE, 0);
}
Color getBorderColor() {
StyledDocument doc = (StyledDocument)this.getDocument();
return doc.getForeground(this.getAttributes());
}
float getVerticalAlignment() {
String align = (String)this.fElement.getAttributes().getAttribute(Attribute.ALIGN);
if (align != null) {
align = align.toLowerCase();
if (align.equals("top") || align.equals("texttop")) {
return 0.0F;
}
if (align.equals("center") || align.equals("middle") || align.equals("absmiddle")) {
return 0.5F;
}
}
return 1.0F;
}
boolean hasPixels(ImageObserver obs) {
return this.fImage != null && this.fImage.getHeight(obs) > 0 && this.fImage.getWidth(obs) > 0;
}
private URL getSourceURL() {
String src = (String)this.fElement.getAttributes().getAttribute(Attribute.SRC);
if (src == null) {
return null;
} else {
URL reference = ((HTMLDocument)this.getDocument()).getBase();
try {
return new URL(reference, src);
} catch (MalformedURLException var4) {
return null;
}
}
}
private int getIntAttr(Attribute name, int deflt) {
AttributeSet attr = this.fElement.getAttributes();
if (attr.isDefined(name)) {
String val = (String)attr.getAttribute(name);
int i;
if (val == null) {
i = deflt;
} else {
try {
i = Math.max(0, Integer.parseInt(val));
} catch (NumberFormatException var7) {
i = deflt;
}
}
return i;
} else {
return deflt;
}
}
@Override
public void setParent(View parent) {
super.setParent(parent);
this.fContainer = parent != null ? this.getContainer() : null;
if (parent == null && this.fComponent != null) {
this.fComponent.getParent().remove(this.fComponent);
this.fComponent = null;
}
}
@Override
public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
super.changedUpdate(e, a, f);
float align = this.getVerticalAlignment();
int height = this.fHeight;
int width = this.fWidth;
this.initialize(this.getElement());
boolean hChanged = this.fHeight != height;
boolean wChanged = this.fWidth != width;
if (hChanged || wChanged || this.getVerticalAlignment() != align) {
this.getParent().preferenceChanged(this, hChanged, wChanged);
}
}
@Override
public void paint(Graphics g, Shape a) {
Color oldColor = g.getColor();
this.fBounds = a.getBounds();
int border = this.getBorder();
int x = this.fBounds.x + border + this.getSpace(0);
int y = this.fBounds.y + border + this.getSpace(1);
int width = this.fWidth;
int height = this.fHeight;
int sel = this.getSelectionState();
if (!this.hasPixels(this)) {
g.setColor(Color.lightGray);
g.drawRect(x, y, width - 1, height - 1);
g.setColor(oldColor);
this.loadIcons();
Icon icon = this.fImage == null ? sMissingImageIcon : sPendingImageIcon;
if (icon != null) {
icon.paintIcon(this.getContainer(), g, x, y);
}
}
if (this.fImage != null) {
g.drawImage(this.fImage, x, y, width, height, this);
}
Color bc = this.getBorderColor();
if (sel == 2) {
int delta = 2 - border;
if (delta > 0) {
x += delta;
y += delta;
width -= delta << 1;
height -= delta << 1;
border = 2;
}
bc = null;
g.setColor(Color.black);
g.fillRect(x + width - 5, y + height - 5, 5, 5);
}
if (border > 0) {
if (bc != null) {
g.setColor(bc);
}
for(int i = 1; i <= border; ++i) {
g.drawRect(x - i, y - i, width - 1 + i + i, height - 1 + i + i);
}
g.setColor(oldColor);
}
}
protected void repaint(long delay) {
if (this.fContainer != null && this.fBounds != null) {
this.fContainer.repaint(delay, this.fBounds.x, this.fBounds.y, this.fBounds.width, this.fBounds.height);
}
}
protected int getSelectionState() {
int p0 = this.fElement.getStartOffset();
int p1 = this.fElement.getEndOffset();
if (this.fContainer instanceof JTextComponent) {
JTextComponent textComp = (JTextComponent)this.fContainer;
int start = textComp.getSelectionStart();
int end = textComp.getSelectionEnd();
if (start <= p0 && end >= p1) {
if (start == p0 && end == p1 && this.isEditable()) {
return 2;
}
return 1;
}
}
return 0;
}
protected boolean isEditable() {
return this.fContainer instanceof JEditorPane && ((JEditorPane)this.fContainer).isEditable();
}
protected Color getHighlightColor() {
JTextComponent textComp = (JTextComponent)this.fContainer;
return textComp.getSelectionColor();
}
@Override
public boolean imageUpdate(Image img, int flags, int x, int y, int width, int height) {
if (this.fImage == null || this.fImage != img) {
return false;
} else if ((flags & 192) != 0) {
this.fImage = null;
this.repaint(0L);
return false;
} else {
short changed = 0;
if ((flags & 2) != 0 && !this.getElement().getAttributes().isDefined(Attribute.HEIGHT)) {
changed = (short)(changed | 1);
}
if ((flags & 1) != 0 && !this.getElement().getAttributes().isDefined(Attribute.WIDTH)) {
changed = (short)(changed | 2);
}
synchronized(this) {
if ((changed & 1) == 1) {
this.fWidth = width;
}
if ((changed & 2) == 2) {
this.fHeight = height;
}
if (this.loading) {
return true;
}
}
if (changed != 0) {
Document doc = this.getDocument();
try {
if (doc instanceof AbstractDocument) {
((AbstractDocument)doc).readLock();
}
this.preferenceChanged(this, true, true);
} finally {
if (doc instanceof AbstractDocument) {
((AbstractDocument)doc).readUnlock();
}
}
return true;
} else {
if ((flags & 48) != 0) {
this.repaint(0L);
} else if ((flags & 8) != 0 && sIsInc) {
this.repaint((long)sIncRate);
}
return (flags & 32) == 0;
}
}
}
@Override
public float getPreferredSpan(int axis) {
int extra = 2 * (this.getBorder() + this.getSpace(axis));
switch(axis) {
case 0:
return (float)(this.fWidth + extra);
case 1:
return (float)(this.fHeight + extra);
default:
throw new IllegalArgumentException("Invalid axis: " + axis);
}
}
@Override
public float getAlignment(int axis) {
switch(axis) {
case 1:
return this.getVerticalAlignment();
default:
return super.getAlignment(axis);
}
}
@Override
public Shape modelToView(int pos, Shape a, Bias b) throws BadLocationException {
int p0 = this.getStartOffset();
int p1 = this.getEndOffset();
if (pos >= p0 && pos <= p1) {
Rectangle r = a.getBounds();
if (pos == p1) {
r.x += r.width;
}
r.width = 0;
return r;
} else {
return null;
}
}
@Override
public int viewToModel(float x, float y, Shape a, Bias[] bias) {
Rectangle alloc = (Rectangle)a;
if (x < (float)(alloc.x + alloc.width)) {
bias[0] = Bias.Forward;
return this.getStartOffset();
} else {
bias[0] = Bias.Backward;
return this.getEndOffset();
}
}
@Override
public void setSize(float width, float height) {
}
protected void resize(int width, int height) {
if (width != this.fWidth || height != this.fHeight) {
this.fWidth = width;
this.fHeight = height;
MutableAttributeSet attr = new SimpleAttributeSet();
attr.addAttribute(Attribute.WIDTH, Integer.toString(width));
attr.addAttribute(Attribute.HEIGHT, Integer.toString(height));
((StyledDocument)this.getDocument()).setCharacterAttributes(this.fElement.getStartOffset(), this.fElement.getEndOffset(), attr, false);
}
}
@Override
public void mousePressed(MouseEvent e) {
Dimension size = this.fComponent.getSize();
if (e.getX() >= size.width - 7 && e.getY() >= size.height - 7 && this.getSelectionState() == 2) {
Point loc = this.fComponent.getLocationOnScreen();
this.fGrowBase = new Point(loc.x + e.getX() - this.fWidth, loc.y + e.getY() - this.fHeight);
this.fGrowProportionally = e.isShiftDown();
} else {
this.fGrowBase = null;
JTextComponent comp = (JTextComponent)this.fContainer;
int start = this.fElement.getStartOffset();
int end = this.fElement.getEndOffset();
int mark = comp.getCaret().getMark();
int dot = comp.getCaret().getDot();
if (e.isShiftDown()) {
if (mark <= start) {
comp.moveCaretPosition(end);
} else {
comp.moveCaretPosition(start);
}
} else {
if (mark != start) {
comp.setCaretPosition(start);
}
if (dot != end) {
comp.moveCaretPosition(end);
}
}
}
}
@Override
public void mouseDragged(MouseEvent e) {
if (this.fGrowBase != null) {
Point loc = this.fComponent.getLocationOnScreen();
int width = Math.max(2, loc.x + e.getX() - this.fGrowBase.x);
int height = Math.max(2, loc.y + e.getY() - this.fGrowBase.y);
if (e.isShiftDown() && this.fImage != null) {
float imgWidth = (float)this.fImage.getWidth(this);
float imgHeight = (float)this.fImage.getHeight(this);
if (imgWidth > 0.0F && imgHeight > 0.0F) {
float prop = imgHeight / imgWidth;
float pwidth = (float)height / prop;
float pheight = (float)width * prop;
if (pwidth > (float)width) {
width = (int)pwidth;
} else {
height = (int)pheight;
}
}
}
this.resize(width, height);
}
}
@Override
public void mouseReleased(MouseEvent e) {
this.fGrowBase = null;
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
}
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
private Icon makeIcon(String gifFile) throws IOException {
InputStream resource = MyImageView.class.getResourceAsStream(gifFile);
if (resource == null) {
BatchUtils.showDialogBox("Image Not Found", MyImageView.class.getName() + "/" + gifFile + " not found.");
return null;
} else {
BufferedInputStream in = new BufferedInputStream(resource);
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int n;
while((n = in.read(buffer)) > 0) {
out.write(buffer, 0, n);
}
in.close();
out.flush();
buffer = out.toByteArray();
if (buffer.length == 0) {
System.err.println("warning: " + gifFile + " is zero-length");
return null;
} else {
return new ImageIcon(buffer);
}
}
}
private void loadIcons() {
try {
if (sPendingImageIcon == null) {
sPendingImageIcon = this.makeIcon("icons/image-delayed.gif");
}
if (sMissingImageIcon == null) {
sMissingImageIcon = this.makeIcon("icons/image-failed.gif");
}
} catch (Exception var2) {
BatchUtils.showDialogBox("ImageView", "Couldn't load image icons");
}
}
protected StyleSheet getStyleSheet() {
HTMLDocument doc = (HTMLDocument)this.getDocument();
return doc.getStyleSheet();
}
}