package com.kreative.paint.material.pattern;
import java.util.regex.Matcher;
public class Pattern {
public static final Pattern BACKGROUND = new Pattern(0L, "Background");
public static final Pattern BG_75_FG_25 = new Pattern(0xAA005500AA005500L, null);
public static final Pattern BG_50_FG_50 = new Pattern(0xAA55AA55AA55AA55L, null);
public static final Pattern BG_25_FG_75 = new Pattern(0xAAFF55FFAAFF55FFL, null);
public static final Pattern FOREGROUND = new Pattern(-1L, "Foreground");
public final int width;
public final int height;
public final int denominator;
public final int[] values;
public final String name;
public Pattern(long pattern, String name) {
this.width = 8;
this.height = 8;
this.denominator = 1;
this.values = new int[64];
this.name = name;
for (int i = 0; i < 64; i++) {
this.values[i] = (pattern < 0) ? 1 : 0;
pattern <<= 1;
}
}
public Pattern(int width, int height, int denominator, String name) {
this.width = (width < 1) ? 1 : width;
this.height = (height < 1) ? 1 : height;
this.denominator = (denominator < 1) ? 1 : denominator;
this.values = new int[this.width * this.height];
this.name = name;
}
private static final java.util.regex.Pattern VALUE_PATTERN =
java.util.regex.Pattern.compile("([._@#$%&*]|[0-9]+)");
public Pattern(int width, int height, int denominator, String text, String name) {
this(width, height, denominator, name);
int i = 0, n = this.values.length;
Matcher m = VALUE_PATTERN.matcher(text);
while (i < n && m.find()) {
String valueText = m.group();
switch (valueText.charAt(0)) {
case '.': case '_':
this.values[i++] = 0;
break;
case '@': case '#': case '$':
case '%': case '&': case '*':
this.values[i++] = this.denominator;
break;
default:
try {
int value = Integer.parseInt(valueText);
this.values[i++] = value;
} catch (NumberFormatException nfe) {
// ignored
}
break;
}
}
}
public int getIndex(int x, int y) {
y %= height;
if (y < 0) y += height;
x %= width;
if (x < 0) x += width;
return (y * width) + x;
}
public int getRGB(int x, int y, int bg, int fg) {
int value = values[getIndex(x, y)];
if (value <= 0) return bg;
if (value >= denominator) return fg;
int bgA = (bg >> 24) & 0xFF;
int bgR = (bg >> 16) & 0xFF;
int bgG = (bg >> 8) & 0xFF;
int bgB = (bg >> 0) & 0xFF;
int fgA = (fg >> 24) & 0xFF;
int fgR = (fg >> 16) & 0xFF;
int fgG = (fg >> 8) & 0xFF;
int fgB = (fg >> 0) & 0xFF;
int a = bgA + (fgA - bgA) * value / denominator;
int r = bgR + (fgR - bgR) * value / denominator;
int g = bgG + (fgG - bgG) * value / denominator;
int b = bgB + (fgB - bgB) * value / denominator;
return (a << 24) | (r << 16) | (g << 8) | b;
}
public boolean isBackground() {
for (int value : values) {
if (value > 0) {
return false;
}
}
return true;
}
public boolean isForeground() {
for (int value : values) {
if (value < denominator) {
return false;
}
}
return true;
}
@Override
public boolean equals(Object that) {
if (that instanceof Pattern) {
return this.equals((Pattern)that, false);
} else {
return false;
}
}
public boolean equals(Pattern that, boolean withName) {
if (this.width != that.width) return false;
if (this.height != that.height) return false;
if (this.denominator != that.denominator) return false;
if (this.values.length != that.values.length) return false;
for (int i = 0; i < this.values.length; i++) {
if (this.values[i] != that.values[i]) return false;
}
if (!withName) return true;
if (this.name != null) return this.name.equals(that.name);
if (that.name != null) return that.name.equals(this.name);
return true;
}
@Override
public int hashCode() {
int hashCode = width + height + denominator;
for (int value : values) hashCode += value;
return hashCode;
}
}