1 package org.molwind.chemical.view;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import java.awt.Color;
21 import java.awt.Graphics;
22 import java.awt.image.BufferedImage;
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.OutputStream;
26 import java.util.Iterator;
27
28 import javax.imageio.ImageIO;
29
30 import org.molwind.chemical.model.ChemicalEntity;
31 import org.molwind.io.ImageFileCache;
32 import org.molwind.model.LayeredPosition;
33 import org.molwind.view.AbstractTile;
34
35
36
37
38
39
40
41 public class ChemicalTile extends AbstractTile {
42
43 private String worldName;
44 private File tempDir;
45
46
47
48
49
50
51
52 public ChemicalTile(final LayeredPosition position) {
53 super(position);
54 tempDir = null;
55 }
56
57
58
59
60
61
62
63 public String getWorldName() {
64 return worldName;
65 }
66
67
68
69
70
71
72
73 public void setWorldName(final String newWorldName) {
74 this.worldName = newWorldName;
75 }
76
77
78
79
80
81
82
83
84
85 public File getTempDir()
86 throws IOException {
87 if (tempDir != null) {
88 return tempDir;
89 }
90 File file = File.createTempFile("xxx", null);
91 File td = file.getParentFile();
92 String worldName = getWorldName();
93
94 if (worldName == null) {
95 worldName = "world" + System.currentTimeMillis();
96 }
97
98 File tmpDir = null;
99
100 if (td == null) {
101 tmpDir = new File(worldName);
102 } else {
103 tmpDir = new File(td, worldName);
104 }
105
106 if (!tmpDir.exists() && !tmpDir.mkdirs()) {
107 throw new IOException("Cannot create directory " + tmpDir);
108 }
109
110 setTempDir(tmpDir);
111 return tmpDir;
112 }
113
114
115
116
117
118
119
120 public void setTempDir(final File newTempDir) {
121 this.tempDir = newTempDir;
122 }
123
124
125 private File getImageFile()
126 throws IOException {
127 File tmpDir = getTempDir();
128 return new File(tmpDir, toFileName());
129 }
130
131 private String toFileName() {
132 StringBuilder builder = new StringBuilder();
133
134 builder.append(getPosition());
135 builder.append(".");
136 builder.append(getImageType());
137
138 return builder.toString();
139 }
140
141 private BufferedImage getImageFromFile()
142 throws IOException {
143 File tmpImageFile = getImageFile();
144 if (!tmpImageFile.exists()) {
145 return null;
146 }
147 return ImageIO.read(tmpImageFile);
148 }
149
150 private void updateCache(final BufferedImage image)
151 throws IOException {
152 ImageFileCache imageCache = ImageFileCache.getInstance();
153 File imageFile = getImageFile();
154 imageCache.update(imageFile, imageCache);
155 }
156
157 private BufferedImage createImage(final int width, final int height) {
158 BufferedImage image = new BufferedImage(width, height,
159 BufferedImage.TYPE_INT_RGB);
160 Graphics graphic = image.getGraphics();
161 graphic.setColor(Color.white);
162 graphic.fillRect(0, 0, width, height);
163 return image;
164 }
165
166 private BufferedImage composeImage(final Iterator it) {
167 BufferedImage image = createImage(420, 420);
168
169 LayeredPosition position = getPosition();
170
171 double levelFactor = 30 / Math.pow(2, position.getLayer());
172 double xTile = levelFactor * position.getX();
173 double yTile = levelFactor * position.getY();
174
175 Graphics graphic = image.getGraphics();
176
177 while (it.hasNext()) {
178 ChemicalEntity chemicalEntity = (ChemicalEntity) it.next();
179
180 BufferedImage moleculeImage = chemicalEntity.getDrawing();
181 int height = moleculeImage.getHeight(null);
182
183 double xTemp = 420 / levelFactor * (chemicalEntity.getX() - xTile);
184 double yTemp = 420 / levelFactor * (chemicalEntity.getY() - yTile);
185
186 graphic.drawImage(moleculeImage,
187 (int) xTemp, 420 - (int) yTemp - height, null);
188 }
189 return image;
190 }
191
192
193
194
195
196
197
198
199
200 public void writeTo(final OutputStream output)
201 throws IOException {
202
203 BufferedImage image = getImageFromCache();
204 if (image == null) {
205 image = getImageFromFile();
206 if (image == null) {
207 if (getEntityCount() <= 0) {
208 image = getEmptyImage();
209 } else {
210 image = composeImage(getEntityIterator());
211 }
212 updateCache(image);
213 }
214 }
215 if (!ImageIO.write(image, getImageType(), output)) {
216 throw new IOException("Cannot write image");
217 }
218 }
219
220 private BufferedImage getImageFromCache()
221 throws IOException {
222 ImageFileCache imageCache = ImageFileCache.getInstance();
223 return imageCache.getImage(getImageFile());
224 }
225
226 }