/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.rp181.datarender;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import org.rp181.dataview.CurrentDataTopComponent;
import org.rp181.dataview.SettingsTopComponent;
import org.rp181.logicdata.Logic8Set;
/**
*
* @author phani
*/
public class Renderer {
private static Renderer instance = null;
ColorSet defaultColorSet = new ColorSet();
//
public static final int LEFT_SIDE_MARGIN = 100;
private static final int TOP_MARGIN = 40;
private double zoom = 1;
/**
*
*/
private int xoff = 0;
private int width = -1;
private int height = -1;
private int[] chanMap = new int[8];
FontMetrics fm;
boolean color = true;
public boolean leftMargin = true;
boolean topMargin = true;
boolean coloredLines = true;
public int currentChannel = 1;
public int currentRow = 1;
BufferedImage image;
Graphics g = null;
int sampleStep;
int rowHeight;
int data[];
double time;
Logic8Set currentSet;
SettingsTopComponent settings;
//
BufferedImage background;
Graphics backgroundGraphics;
BufferedImage channels;
Graphics channelsGraphics;
BufferedImage highlight;
Graphics highlightGraphics;
BufferedImage datadisplay;
Graphics dataGraphics;
BufferedImage cursors;
Graphics cursorsGraphics;
int oldRowsActivated = -1;
boolean updateBackground = true;
boolean updateChannels = true;
boolean updateData = true;
public Renderer getInstance() {
if (instance == null) {
instance = new Renderer();
}
return instance;
}
public void setZoom(double z) {
zoom = z;
updateData = true;
}
public double getZoom() {
return zoom;
}
public void setOffset(int x) {
xoff = x;
updateData = true;
}
public int getOffset() {
return xoff;
}
Color darkBg = new Color(20, 20, 20);
int left;
int top;
int xP;
int yP;
public BufferedImage render(int w, int h, int xP, int yP, Logic8Set dat) {
this.xP = xP;
this.yP = yP;
currentSet = dat;
settings = SettingsTopComponent.getDefault();
if (settings.colorB.isSelected()) {
defaultColorSet.setColorMode(ColorSet.MODE_COLOR);
} else {
defaultColorSet.setColorMode(ColorSet.MODE_BLACK_AND_WHITE);
}
//if (upToDate == false)
{
try {
color = settings.colorB.isSelected();
leftMargin = settings.leftM.isSelected();
topMargin = settings.topM.isSelected();
coloredLines = settings.colorLines.isSelected();
if (!leftMargin) {
left = 0;
} else {
left = LEFT_SIDE_MARGIN;
}
if (!topMargin) {
top = 0;
} else {
top = TOP_MARGIN;
}
if (w != width || h != height) {
width = w;
height = h;
background = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
backgroundGraphics = background.createGraphics();
cursors = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
cursorsGraphics = background.createGraphics();
channels = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
channelsGraphics = background.createGraphics();
datadisplay = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
dataGraphics = background.createGraphics();
highlight = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
highlightGraphics = background.createGraphics();
updateBackground = true;
updateData = true;
}
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g = image.createGraphics();
fm = g.getFontMetrics();
sampleStep = (int) ((currentSet.getSampleLength() / (long) width) - left);
sampleStep = (int) ((double) sampleStep / zoom);
rowHeight = (height - top) / rowsActivated();
while ((xoff + width) * sampleStep > currentSet.getSampleLength()) {
xoff--;
}
xoff = Math.max(0, xoff);
currentRow = -1;
for (int d = 1; d <= 8; d++) {
if (isActivated(d)) {
currentRow++;
chanMap[d - 1] = currentRow;
} else {
chanMap[d - 1] = -1;
}
}
if (updateBackground) {
drawBackground();
}
if (oldRowsActivated != rowsActivated()) {
drawChannels();
}
if (settings.chanHigh.isSelected() && color && yP > 0) {
drawHighlight();
}
if (updateData) {
drawData();
}
updateCursors();
g.drawImage(background, 0, 0, null);
g.drawImage(channels, 0, 0, null);
if (settings.chanHigh.isSelected() && color && yP > 0) {
g.drawImage(highlight, 0, 0, null);
}
g.drawImage(datadisplay, 0, 0, null);
g.drawImage(cursors, 0, 0, null);
return image;
} catch (Exception e) {
e.printStackTrace();
g.drawImage(background, 0, 0, null);
g.drawImage(channels, 0, 0, null);
return image;
}
}
//return null;
}
public void drawInfo(Graphics g, int x, int y, int rowHeight, long sampleStep) {
int rowY = y;
if (topMargin) {
rowY -= TOP_MARGIN;
}
int row = 0;
while (rowY > rowHeight) {
rowY -= rowHeight;
row++;
}
int d = -1;
for (int i = 0; i < 8; i++) {
if (chanMap[i] == row) {
d = i + 1;
}
}
int xPos = x;
if (leftMargin) {
xPos -= LEFT_SIDE_MARGIN;
}
//xPos = xoff;
CurrentDataTopComponent.getDefault().channel.setText("Channel " + (row + 1));
Long[] cData = currentSet.getCompressedData(row);
CurrentDataTopComponent.getDefault().stateChanges.setText("State Changes: " + cData.length + "");
CurrentDataTopComponent.getDefault().totalTime.setText("Total Time: " + currentSet.getSampleLength() * currentSet.getTimeStep() + "");
CurrentDataTopComponent.getDefault().startSample.setText("Start Sample #: ");
CurrentDataTopComponent.getDefault().stopSample.setText("Stop Sample #: ");
CurrentDataTopComponent.getDefault().time.setText("Segment Time: ");
long cursor = getSampleNumber(xPos);
long sampleNum = 0;
long oldSampleNum = 0;
for (int i = 0; i < cData.length; i++) {
oldSampleNum = sampleNum;
sampleNum += cData[i];
if (cursor <= sampleNum) {
g.setColor(defaultColorSet.getInfoLineColor());
CurrentDataTopComponent.getDefault().startSample.setText("Start Sample #: " + oldSampleNum);
CurrentDataTopComponent.getDefault().stopSample.setText("Stop Sample #: " + sampleNum);
CurrentDataTopComponent.getDefault().time.setText("Segment Time: " + ((sampleNum - oldSampleNum) * currentSet.getTimeStep()) + " S");
if (!leftMargin) {
g.drawLine((int) (oldSampleNum / sampleStep) - xoff, y, (int) (sampleNum / sampleStep) - xoff, y);
} else {
g.drawLine(Math.max(LEFT_SIDE_MARGIN, (int) (oldSampleNum / sampleStep) - xoff + LEFT_SIDE_MARGIN), y, (int) (sampleNum / sampleStep) - xoff + LEFT_SIDE_MARGIN, y);
}
break;
}
}
}
public boolean intToBoolean(int i) {
if (i > 0) {
return true;
} else {
return false;
}
}
public int getCurrentChannel() {
return currentChannel;
}
Color bgColor = new Color(80, 80, 80);
private void highlight(int yP, int rowHeight, Graphics g, int left, int top, int sampleStep) {
int rowY = yP;
if (topMargin) {
rowY -= TOP_MARGIN;
}
int row = 0;
while (rowY > rowHeight) {
rowY -= rowHeight;
row++;
}
int d = -1;
for (int i = 0; i < 8; i++) {
if (chanMap[i] == row) {
d = i + 1;
}
}
if (color && d > 0) {
drawPlate(bgColor, g, left, (rowHeight) * row + top, width - left, rowHeight - 10);
g.setColor(Color.white);
if (coloredLines) {
g.setColor(defaultColorSet.getChannelColor(d));
if (d == 8) {
g.setColor(Color.white);
}
}
int prev = -1;
for (int i = 0; i < width; i++) {
data = currentSet.getSample((i + xoff) * sampleStep);
if (prev < 0) {
prev = data[d - 1];
} else {
if (data[d - 1] != prev) {
prev = data[d - 1];
g.drawLine(i - 1 + left, ((rowHeight / 5) + rowHeight * row) + top, i - 1 + left, ((rowHeight / 5) * 4 + rowHeight * row) + top);
}
}
boolean thick = false;
int y = ((rowHeight) / 5) * data[d - 1];
if (y == 0) {
y = ((rowHeight) / 5) * 4;
thick = true;
}
y += (rowHeight) * row;
y += top;
if (!thick) {
g.fillRect(i + left, y, 1, 1);
} else {
if (settings.thickBottom.isSelected()) {
g.fillRect(i + left, y - 1, 1, 1);
}
g.fillRect(i + left, y, 1, 1);
}
}
}
}
public long getSampleNumber(int x) {
long sampleNum = -1;
if (x > width || x < 0) {
return sampleNum;
} else {
int left;
if (!leftMargin) {
left = 0;
} else {
left = LEFT_SIDE_MARGIN;
}
int sampleStepC = (int) ((currentSet.getSampleLength() / (long) width) - left);
sampleStepC = (int) ((double) sampleStepC / zoom);
return (x + xoff) * sampleStepC;
}
}
Color co;
/**
*
* @param c
* @param g
* @param x
* @param y
* @param width
* @param height
*/
public void drawPlate(Color c, Graphics g, int x, int y, int width, int height) {
for (int i = 0; i <= 10; i++) {
co = new Color(Math.max(c.getRed() - (100 - i * 10), 0), Math.max(c.getGreen() - (100 - i * 10), 0), Math.max(c.getBlue() - (100 - i * 10), 0));
g.setColor(co);
g.fillRect(x, y + i, width, height);
}
g.setColor(c);
g.fillRect(x, y + 10, width, height - 10);
}
public void repaintNow() {
updateBackground = true;
updateData = true;
}
/**
*
* @param i
* @return
*/
public boolean isActivated(int i) {
return settings.chanField.getText().contains(i + "");
}
/**
*
* @return
*/
public int rowsActivated() {
String str = settings.chanField.getText();
int rows = 0;
if (str.contains("1")) {
rows++;
}
if (str.contains("2")) {
rows++;
}
if (str.contains("3")) {
rows++;
}
if (str.contains("4")) {
rows++;
}
if (str.contains("5")) {
rows++;
}
if (str.contains("6")) {
rows++;
}
if (str.contains("7")) {
rows++;
}
if (str.contains("8")) {
rows++;
}
return rows;
}
private void drawBackground() {
backgroundGraphics.setColor(defaultColorSet.getBackgroundColor());
backgroundGraphics.fillRect(0, 0, width, height);
}
private void drawChannels() {
//channels = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//channelsGraphics = channels.createGraphics();
channelsGraphics.setColor(clear);
channelsGraphics.fillRect(0, 0, width, height);
for (int d = 1; d <= 8; d++) {
currentRow = chanMap[d - 1];
if (isActivated(d)) {
if (color) {
drawPlate(defaultColorSet.getBackgroundColor(), channelsGraphics, left, (rowHeight) * currentRow + top, width - left, rowHeight);
}
if (leftMargin) {
if (color) {
channelsGraphics.setColor(defaultColorSet.getChannelColor(d));
drawPlate(defaultColorSet.getChannelColor(d), channelsGraphics, 0, (rowHeight) * currentRow + top, 20, rowHeight);
drawPlate(darkBg, channelsGraphics, 20, (rowHeight) * currentRow + top, left - 20, rowHeight);
}
if (settings.chanText.isSelected()) {
channelsGraphics.setColor(defaultColorSet.getTextColor());
channelsGraphics.drawString("Channel " + d, 30, (rowHeight) * (currentRow) + top + 25);
}
}
}
}
}
private void drawHighlight() {
// highlight = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// highlightGraphics = highlight.createGraphics();
highlightGraphics.setColor(clear);
highlightGraphics.fillRect(0, 0, width, height);
highlight(yP, rowHeight, highlightGraphics, left, top, sampleStep);
}
private void drawData() {
// datadisplay = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//dataGraphics = datadisplay.createGraphics();
dataGraphics.setColor(clear);
dataGraphics.fillRect(0, 0, width, height);
for (int d = 1; d <= 8; d++) {
if (isActivated(d)) {
currentRow = chanMap[d - 1];
int prev = -1;
for (int i = 0; i < width; i++) {
if (i % 200 == 0 && settings.timingMarkers.isSelected()) {
dataGraphics.setColor(defaultColorSet.getTextColor());
time = ((i + xoff) * sampleStep) * currentSet.getTimeStep();
String str = "";
String str2 = null;
if (time >= 1 || time == 0) {
str = time + "";
str = str.substring(0, 1);
str = str + " S";
str2 = ((time - Integer.parseInt(str.replaceAll(" S", ""))) * 1000) + "";
str2 = str2.substring(0, Math.min(6, str2.length()));
if (Double.parseDouble(str2) == 0) {
str2 = null;
} else {
str2 = str2.concat(" ms");
}
dataGraphics.drawString(str, i + left - (fm.stringWidth(str) / 2), top - 25);
if (str2 != null) {
dataGraphics.drawString(str2, i + left - (fm.stringWidth(str2) / 2), top - 12);
}
} else {
str = (time * 1000) + "";
str = str.substring(0, Math.min(5, str.length()));
str = str + " ms";
dataGraphics.drawString(str, i + left - (fm.stringWidth(str) / 2), top - 12);
}
dataGraphics.fillRect(i + left - 2, top - 5, 4, 4);
}
if (!color) {
dataGraphics.setColor(Color.black);
} else if (coloredLines) {
dataGraphics.setColor(defaultColorSet.getChannelColor(d));
if (d == 8) {
dataGraphics.setColor(Color.white);
}
}
data = currentSet.getSample((i + xoff) * sampleStep);
if (prev < 0) {
prev = data[d - 1];
} else {
if (data[d - 1] != prev) {
prev = data[d - 1];
dataGraphics.drawLine(i - 1 + left, ((rowHeight / 5) + rowHeight * currentRow) + top,
i - 1 + left, ((rowHeight / 5) * 4 + rowHeight * currentRow) + top);
}
}
boolean thick = false;
int y = ((rowHeight) / 5) * data[d - 1];
if (y == 0) {
y = ((rowHeight) / 5) * 4;
thick = true;
}
y += (rowHeight) * currentRow;
y += top;
if (!thick) {
dataGraphics.fillRect(i + left, y, 1, 1);
} else {
if (settings.thickBottom.isSelected()) {
dataGraphics.fillRect(i + left, y - 1, 1, 1);
}
dataGraphics.fillRect(i + left, y, 1, 1);
}
}
}
}
}
private void updateCursors() {
// cursors = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
//cursorsGraphics = cursors.createGraphics();
cursorsGraphics.setColor(clear);
cursorsGraphics.fillRect(0, 0, width, height);
if (settings.vertCursor.isSelected()) {
cursorsGraphics.setColor(defaultColorSet.getVerticalCursorColor());
if (leftMargin) {
cursorsGraphics.drawLine(Math.max(0, xP), top, xP, height);
} else {
cursorsGraphics.drawLine(xP, top, xP, height);
}
}
drawInfo(cursorsGraphics, xP, yP, rowHeight, sampleStep);
}
private Color clear = new Color(255, 255, 255, 0);
}