/*
* Created on Mar 28, 2006
*/
package org.seqcode.projects.seqview.paintable;
import java.awt.*;
import java.text.*;
import org.seqcode.genome.location.Region;
/**
* @author tdanford
*/
public class HashMarkPaintable extends RegionPaintable {
private static NumberFormat nf;
private PaintableProperties props;
private boolean labelAbove;
static {
nf = NumberFormat.getInstance();
}
public HashMarkPaintable () {
super();
props = new PaintableProperties();
labelAbove = true;
}
public PaintableProperties getProperties() {
return props;
}
public void setLabelAbove (boolean b) {labelAbove = b;}
public boolean canPaint() {
return true;
}
public void setRegion(Region r) {
super.setRegion(r);
setCanPaint(true);
setWantsPaint(true);
notifyListeners();
}
public int getMaxVertSpace() {return 25;}
public int getMinVertSpace() {return 25;}
/* (non-Javadoc)
* @see org.seqcode.viz.paintable.Paintable#paintItem(java.awt.Graphics, int, int, int, int)
*/
public void paintItem(Graphics2D g, int x1, int y1, int x2, int y2) {
int rs = getRegion().getStart(), re = getRegion().getEnd();
int rw = re - rs + 1;
int h = y2 - y1;
int w = x2 - x1;
double log10 = Math.log(10.0);
double logScale = Math.log((double)rw) / log10;
Font oldFont = g.getFont();
g.setFont(new Font("Arial",Font.PLAIN,(int)(h * .4)));
FontMetrics fontmetrics = g.getFontMetrics();
char[] nines = {'9','9','9','9','9','9','9','9','9','9','9','9','9'};
int tickSize = Math.max(1, pow10((int)Math.floor(logScale) - 2));
int tickDigits = (int)Math.ceil(Math.log(re / tickSize) / log10) + 1;
int spaceUsed = fontmetrics.charsWidth(nines,0,tickDigits);
int spaceAvail = (int) (.5 * w / (rw / ((double)tickSize)));
while(spaceUsed > spaceAvail) {
tickSize *= 10;
tickDigits = (int)Math.ceil(Math.log(re / tickSize) / log10) + 1;
spaceUsed = fontmetrics.charsWidth(nines,0,tickDigits);
spaceAvail = (int) (.7 * w / (rw / ((double)tickSize)));
}
tickSize = Math.max(tickSize, 1);
int hh = h/2;
int my, ly;
if (labelAbove) {
my = y1 + hh;
ly = my - 2;
} else {
my = y1;
ly = y2;
}
g.setColor(Color.white);
g.fillRect(x1, my, w, hh);
g.setColor(Color.DARK_GRAY);
g.drawRect(x1, my, w, hh);
int bpStart = tickSize * (int)Math.ceil((double)rs / (double)tickSize);
double scale = (double)w / (double)rw;
int tickPixWidth = (int)Math.round((double)tickSize * scale);
boolean paintBlack = true;
String axisLabel = getRegion().getChrom() + " x " + String.valueOf(nf.format(tickSize));
if (!axisLabel.matches("^chr.*")) {
axisLabel = "chr" + axisLabel;
}
g.drawString(axisLabel, x1 + 2, ly);
for(int bp = bpStart; bp <= re; bp += tickSize) {
int xOffset = x1 + (int)Math.round((double)(bp-rs) * scale);
if(paintBlack) {
g.setColor(Color.black);
g.fillRect(xOffset, my, tickPixWidth, hh);
}
g.setColor(paintBlack ? Color.white : Color.black);
g.drawString(String.valueOf(bp / tickSize), xOffset, my + hh - 1);
paintBlack = !paintBlack;
}
g.setFont(oldFont);
}
private int pow10(int exp) {
int value = 1;
for(int i = 0; i < exp; i++) {
value *= 10;
}
return value;
}
}