package org.openslx.dozmod.gui.control;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
import org.openslx.thrifthelper.TransferStatusWrapper;
@SuppressWarnings("serial")
public class BlockProgressBar extends JPanel {
private final Color[] blockColors = new Color[5];
private final TransferStatusWrapper blocks = new TransferStatusWrapper(null);
private boolean simpleMode = true;
public BlockProgressBar(byte[] blocks) {
super();
setupListeners();
// 0 = complete, 1 = missing, 2 = uploading, 3 = queued for copying, 4 = copying
blockColors[0] = Color.BLACK;
blockColors[1] = Color.RED;
blockColors[2] = Color.YELLOW;
blockColors[3] = Color.BLUE;
blockColors[4] = Color.GREEN;
this.blocks.setBlocks(blocks);
}
public void setStatus(byte[] blocks) {
this.blocks.setBlocks(blocks);
this.repaint(100);
}
private void setupListeners() {
final BlockProgressBar me = this;
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
me.toggleMode();
}
}
});
}
private void toggleMode() {
simpleMode = !simpleMode;
this.repaint(100);
}
@Override
public void paintComponent(Graphics g) {
if (blocks.isEmpty()) {
// No valid block data, draw white window
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
} else if (simpleMode) {
drawSimple(g);
} else {
drawDetailed(g);
}
}
private void drawSimple(Graphics g) {
final float width = getWidth();
final int height = getHeight();
final float complete = blocks.getComplete();
final float doneWidth = width * complete;
final Rectangle doneRect = new Rectangle(0, 0, (int) doneWidth, height);
final Rectangle remainingRect = new Rectangle((int) doneWidth, 0, (int) (width - doneWidth), height);
g.setColor(Color.BLUE);
g.fillRect(doneRect.x, doneRect.y, doneRect.width, doneRect.height);
g.setColor(Color.WHITE);
g.fillRect(remainingRect.x, remainingRect.y, remainingRect.width, remainingRect.height);
final String progress = (int) (complete * 100) + "%";
Rectangle2D textExtent = g.getFontMetrics().getStringBounds(progress, g);
final int textX = (int) ((width - textExtent.getWidth()) / 2);
final int textY = (int) ((height - textExtent.getHeight()) / 2);
g.setColor(Color.WHITE);
g.setClip(doneRect.x, doneRect.y, doneRect.width, doneRect.height);
g.drawString(progress, textX, textY);
g.setColor(Color.BLACK);
g.setClip(remainingRect.x, remainingRect.y, remainingRect.width, remainingRect.height);
g.drawString(progress, textX, textY);
}
private void drawDetailed(Graphics g) {
final int blockCount = blocks.getBlockCount();
// Calculate display mode
final int height = getHeight();
final float width = getWidth() - 2;
float blockWidth = width / blockCount;
int rows = 1;
while (blockWidth * rows < 6 && (float) height / rows > 7) {
rows++;
}
blockWidth *= rows;
final float blockHeight;
final float blockHeightVisible;
if (rows == 1) {
blockHeightVisible = blockHeight = height;
} else {
blockHeight = (height + 2) / rows;
blockHeightVisible = blockHeight - 2;
}
// Draw
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
float x = 0, y = 0;
for (byte block : blocks.getBlocks()) {
float toX = x + blockWidth;
if (block >= 0 && block < blockColors.length) {
g.setColor(blockColors[block]);
final int boxWidth = ((int) toX) - ((int) x) - 1;
final int boxHeight = (int) (y + blockHeightVisible) - (int) y;
g.fillRect((int) x, (int) y, boxWidth > 1 ? boxWidth : 1, boxHeight > 1 ? boxHeight : 1);
}
x = toX;
if (x + 0.5 > width) {
x = 0;
y += blockHeight;
}
}
}
}