1 package org.kite9.diagram.adl;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Set;
10
11 import org.kite9.diagram.adl.Symbol.SymbolShape;
12
13 /***
14 * Helps in the creation of keys by making sure that symbols don't reuse the
15 * same code
16 *
17 * @author robmoffat
18 *
19 */
20 public class KeyHelper {
21
22 static class UsedKey {
23
24 SymbolShape shape;
25
26 char theChar;
27
28 @Override
29 public boolean equals(Object arg0) {
30 if (arg0 instanceof UsedKey) {
31 UsedKey uk = (UsedKey) arg0;
32 return this.shape.equals(uk.shape) && this.theChar == uk.theChar;
33 } else {
34 return false;
35 }
36
37 }
38
39 public String toString() {
40 return shape.name() + ":" + theChar;
41 }
42
43 @Override
44 public int hashCode() {
45 return theChar + shape.hashCode();
46 }
47
48 }
49
50 public List<Symbol> getUsedSymbols() {
51 List<Symbol> out = new ArrayList<Symbol>(declared.values());
52 Collections.sort(out);
53 return out;
54 }
55
56 Set<UsedKey> used = new HashSet<UsedKey>();
57 Map<String, Symbol> declared = new HashMap<String, Symbol>();
58
59 public KeyHelper() {
60 }
61
62 public Symbol createSymbol(String text) {
63 return createSymbol(text, text);
64 }
65
66 public Symbol createSymbol(String text, String characterOptions) {
67 Symbol out = declared.get(text);
68 if (out != null)
69 return out;
70
71 if (characterOptions != null) {
72 for (int i = 0; i < characterOptions.length(); i++) {
73 char potential = Character.toUpperCase(characterOptions.charAt(i));
74 Symbol s = findAvailableShape(text, potential);
75 if (s != null)
76 return s;
77 }
78 }
79
80 for (int i = 0; i < text.length(); i++) {
81 char potential = Character.toUpperCase(text.charAt(i));
82 Symbol s = findAvailableShape(text, potential);
83 if (s != null)
84 return s;
85 }
86
87
88 for (char c = 'A'; c <= 'Z'; c++) {
89 Symbol s = findAvailableShape(text, c);
90 if (s != null)
91 return s;
92 }
93
94
95 throw new IllegalStateException("There are no more keys to allocate! " + used.size() + " used already.");
96 }
97
98 private Symbol findAvailableShape(String text, char potential) {
99 for (SymbolShape shape : SymbolShape.values()) {
100 Symbol out = findAvailableShape(text, potential, shape);
101
102 if (out != null) {
103 declared.put(text, out);
104 return out;
105 }
106 }
107 return null;
108 }
109
110 private Symbol findAvailableShape(String text, char potential, SymbolShape shape) {
111 UsedKey option = new UsedKey();
112 option.shape = shape;
113 option.theChar = potential;
114 if (!used.contains(option)) {
115 Symbol s = new Symbol(text, potential, shape);
116 used.add(option);
117 return s;
118 }
119
120 return null;
121 }
122
123 public Symbol createSymbol(String value, char key, SymbolShape shape) {
124 Symbol out = findAvailableShape(value, key, shape);
125 if (out != null) {
126 return out;
127 }
128 out = findAvailableShape(value, key);
129 if (out != null) {
130 return out;
131 }
132
133 return createSymbol(value, null);
134 }
135
136 }