package im.delight.android.identicons;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import java.security.MessageDigest;
public abstract class IdenticonBase {
private static final String HASH_ALGORITHM = "SHA-256";
private final int mRowCount;
private final int mColumnCount;
private final Paint mPaint;
private volatile int mCellWidth;
private volatile int mCellHeight;
private volatile byte[] mHash;
private volatile int[][] mColors;
private volatile boolean mReady;
public IdenticonBase() {
mRowCount = getRowCount();
mColumnCount = getColumnCount();
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
}
public static byte[] getHash(String input) {
byte[] mHash;
// if the input was null
if (input == null) {
// we can't create a hash value and have nothing to show (draw to the view)
mHash = null;
}
// if the input was a proper string (non-null)
else {
// generate a hash from the string to get unique but deterministic byte values
try {
final MessageDigest digest = java.security.MessageDigest.getInstance(HASH_ALGORITHM);
digest.update(input.getBytes());
mHash = digest.digest();
} catch (Exception e) {
mHash = null;
}
}
return mHash;
}
protected void setupColors() {
mColors = new int[mRowCount][mColumnCount];
int colorVisible = getIconColor();
int colorInvisible = getBackgroundColor();
for (int r = 0; r < mRowCount; r++) {
for (int c = 0; c < mColumnCount; c++) {
if (isCellVisible(r, c)) {
mColors[r][c] = colorVisible;
} else {
mColors[r][c] = colorInvisible;
}
}
}
}
public void show(String input) {
if (input != null) {
mHash = IdenticonBase.getHash(input);
} else {
mHash = null;
}
// set up the cell colors according to the input that was provided via show(...)
setupColors();
// this view may now be drawn (and thus must be re-drawn)
mReady = true;
}
public byte getByte(int index) {
if (mHash == null) {
return -128;
} else {
return mHash[index % mHash.length];
}
}
abstract protected int getRowCount();
abstract protected int getColumnCount();
abstract protected boolean isCellVisible(int row, int column);
abstract protected int getIconColor();
protected int getBackgroundColor() {
return Color.TRANSPARENT;
}
public void updateSize(int w, int h) {
mCellWidth = w / mColumnCount;
mCellHeight = h / mRowCount;
}
public void draw(Canvas canvas) {
if (mReady) {
int x, y;
for (int r = 0; r < mRowCount; r++) {
for (int c = 0; c < mColumnCount; c++) {
x = mCellWidth * c;
y = mCellHeight * r;
mPaint.setColor(mColors[r][c]);
canvas.drawRect(x, y + mCellHeight, x + mCellWidth, y, mPaint);
}
}
}
}
}