package com.kreative.paint.material.sprite; import java.util.regex.Matcher; import java.util.regex.Pattern; public enum ArrayOrdering { LTR_TTB (false, false, false, false, 0), LTR_TTB_BOUSTROPHEDON(false, false, false, true , 1), TTB_LTR (false, false, true , false, 2), TTB_LTR_BOUSTROPHEDON(false, false, true , true , 3), RTL_TTB (false, true , false, false, 4), RTL_TTB_BOUSTROPHEDON(false, true , false, true , 5), TTB_RTL (false, true , true , false, 6), TTB_RTL_BOUSTROPHEDON(false, true , true , true , 7), LTR_BTT (true , false, false, false, 8), LTR_BTT_BOUSTROPHEDON(true , false, false, true , 9), BTT_LTR (true , false, true , false, 10), BTT_LTR_BOUSTROPHEDON(true , false, true , true , 11), RTL_BTT (true , true , false, false, 12), RTL_BTT_BOUSTROPHEDON(true , true , false, true , 13), BTT_RTL (true , true , true , false, 14), BTT_RTL_BOUSTROPHEDON(true , true , true , true , 15); public final boolean bottomToTop; public final boolean rightToLeft; public final boolean vertical; public final boolean boustrophedon; public final int intValue; private ArrayOrdering( boolean bottomToTop, boolean rightToLeft, boolean vertical, boolean boustrophedon, int intValue ) { this.bottomToTop = bottomToTop; this.rightToLeft = rightToLeft; this.vertical = vertical; this.boustrophedon = boustrophedon; this.intValue = intValue; } public int[] getYX(int rows, int columns, int index, int[] yx) { int y, x; if (vertical) { x = (index / rows) % columns; y = (index % rows); if (boustrophedon && ((x & 1) != 0)) { y = (rows-1) - y; } } else { y = (index / columns) % rows; x = (index % columns); if (boustrophedon && ((y & 1) != 0)) { x = (columns-1) - x; } } if (bottomToTop) { y = (rows-1) - y; } if (rightToLeft) { x = (columns-1) - x; } if (yx == null) { return new int[]{y,x}; } else { yx[0] = y; yx[1] = x; return yx; } } public int getIndex(int rows, int columns, int y, int x) { y %= rows; x %= columns; if (bottomToTop) { y = (rows-1) - y; } if (rightToLeft) { x = (columns-1) - x; } if (vertical) { if (boustrophedon && ((x & 1) != 0)) { y = (rows-1) - y; } return x * rows + y; } else { if (boustrophedon && ((y & 1) != 0)) { x = (columns-1) - x; } return y * columns + x; } } @Override public String toString() { String verticalDirection = bottomToTop ? "Bottom to Top" : "Top to Bottom"; String horizontalDirection = rightToLeft ? "Right to Left" : "Left to Right"; String lineDirection = vertical ? verticalDirection : horizontalDirection; String pageDirection = vertical ? horizontalDirection : verticalDirection; String direction = lineDirection + ", " + pageDirection; if (boustrophedon) direction += ", Boustrophedon"; return direction; } public static ArrayOrdering fromIntValue(int intValue) { switch (intValue) { case 0: return LTR_TTB ; case 1: return LTR_TTB_BOUSTROPHEDON; case 2: return TTB_LTR ; case 3: return TTB_LTR_BOUSTROPHEDON; case 4: return RTL_TTB ; case 5: return RTL_TTB_BOUSTROPHEDON; case 6: return TTB_RTL ; case 7: return TTB_RTL_BOUSTROPHEDON; case 8: return LTR_BTT ; case 9: return LTR_BTT_BOUSTROPHEDON; case 10: return BTT_LTR ; case 11: return BTT_LTR_BOUSTROPHEDON; case 12: return RTL_BTT ; case 13: return RTL_BTT_BOUSTROPHEDON; case 14: return BTT_RTL ; case 15: return BTT_RTL_BOUSTROPHEDON; default: return null; } } public static ArrayOrdering fromBooleans( boolean bottomToTop, boolean rightToLeft, boolean vertical, boolean boustrophedon ) { if (bottomToTop) { if (rightToLeft) { if (vertical) { return boustrophedon ? BTT_RTL_BOUSTROPHEDON : BTT_RTL; } else { return boustrophedon ? RTL_BTT_BOUSTROPHEDON : RTL_BTT; } } else { if (vertical) { return boustrophedon ? BTT_LTR_BOUSTROPHEDON : BTT_LTR; } else { return boustrophedon ? LTR_BTT_BOUSTROPHEDON : LTR_BTT; } } } else { if (rightToLeft) { if (vertical) { return boustrophedon ? TTB_RTL_BOUSTROPHEDON : TTB_RTL; } else { return boustrophedon ? RTL_TTB_BOUSTROPHEDON : RTL_TTB; } } else { if (vertical) { return boustrophedon ? TTB_LTR_BOUSTROPHEDON : TTB_LTR; } else { return boustrophedon ? LTR_TTB_BOUSTROPHEDON : LTR_TTB; } } } } private static final Pattern DECIMAL_PATTERN = Pattern.compile("([0-9]+)"); private static final Pattern HEXADECIMAL_PATTERN = Pattern.compile("0[Xx]([0-9A-Fa-f]+)"); private static final String SPP = "(\\s|[!-~&&[^0-9A-Za-z]])?"; private static final Pattern VERTICAL_DIRECTION_PATTERN = Pattern.compile( "[Tt](op)?" + SPP + "[Tt]o?" + SPP + "[Bb](ottom)?" + "|" + "[Bb](ottom)?" + SPP + "[Tt]o?" + SPP + "[Tt](op)?" ); private static final Pattern HORIZONTAL_DIRECTION_PATTERN = Pattern.compile( "[Ll](eft)?" + SPP + "[Tt]o?" + SPP + "[Rr](ight)?" + "|" + "[Rr](ight)?" + SPP + "[Tt]o?" + SPP + "[Ll](eft)?" ); private static final Pattern BOUSTROPHEDON_PATTERN = Pattern.compile( "[Bb]oust(rophedon)?" ); public static ArrayOrdering fromString(String s) { Matcher m; s = s.trim().toLowerCase(); m = DECIMAL_PATTERN.matcher(s); if (m.matches()) { try { int i = Integer.parseInt(m.group(1), 10); return fromIntValue(i); } catch (NumberFormatException e) { return null; } } m = HEXADECIMAL_PATTERN.matcher(s); if (m.matches()) { try { int i = Integer.parseInt(m.group(1), 16); return fromIntValue(i); } catch (NumberFormatException e) { return null; } } m = VERTICAL_DIRECTION_PATTERN.matcher(s); if (!m.find()) return null; boolean bottomToTop = m.group().startsWith("b"); int verticalIndex = m.start(); m = HORIZONTAL_DIRECTION_PATTERN.matcher(s); if (!m.find()) return null; boolean rightToLeft = m.group().startsWith("r"); int horizontalIndex = m.start(); boolean vertical = verticalIndex < horizontalIndex; m = BOUSTROPHEDON_PATTERN.matcher(s); boolean boustrophedon = m.find(); return fromBooleans(bottomToTop, rightToLeft, vertical, boustrophedon); } }