package mobac.mapsources.custom;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.log4j.Logger;
import mobac.exceptions.TileException;
import mobac.gui.mapview.PreviewMap;
import mobac.mapsources.mapspace.MapSpaceFactory;
import mobac.program.interfaces.FileBasedMapSource;
import mobac.program.interfaces.MapSpace;
import mobac.program.interfaces.MapSpace.MapSpaceType;
import mobac.program.jaxb.ColorAdapter;
import mobac.program.model.MapSourceLoaderInfo;
import mobac.program.model.TileImageType;
import mobac.utilities.Utilities;
@XmlRootElement(name = "watermark")
public class CustomWatermarkMapSource implements FileBasedMapSource {
private static final Logger log = Logger.getLogger(CustomWatermarkMapSource.class);
private MapSpace mapSpace = MapSpaceFactory.getInstance(256, MapSpaceType.msMercatorSpherical);
private boolean initialized = false;
private TileImageType tileImageType = null;
private MapSourceLoaderInfo loaderInfo = null;
private byte[] mosaicMask = null;
@XmlElement(nillable = false, defaultValue = "Watermark")
private String name = "Watermark";
@XmlElement(defaultValue = "0")
private int minZoom = PreviewMap.MIN_ZOOM;
@XmlElement(defaultValue = "22")
private int maxZoom = PreviewMap.MAX_ZOOM;
@XmlElement(required = true)
private File watermarkFile = null;
@XmlElement(defaultValue = "#000000")
@XmlJavaTypeAdapter(ColorAdapter.class)
private Color backgroundColor = Color.BLACK;
@XmlElement(defaultValue = "100")
private int probability = 100;
@XmlElement
private String mosaic = null;
@XmlElement(defaultValue = "false")
private boolean hiddenDefault = false;
public CustomWatermarkMapSource() {
super();
}
@Override
public void initialize() {
if (initialized)
return;
reinitialize();
}
@Override
public int getMaxZoom() {
return maxZoom;
}
@Override
public int getMinZoom() {
return minZoom;
}
@Override
public String getName() {
return name;
}
@Override
public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod)
throws IOException, TileException, InterruptedException {
if (!initialized)
initialize();
if (mosaicMask != null) {
byte mask = mosaicMask[y % 8];
if ((mask & (1 << (x % 8))) == 0)
return null;
} else {
Random random = new Random();
if (random.nextInt(100) + 1 > probability)
return null;
}
try {
return Utilities.getFileBytes(watermarkFile);
} catch (FileNotFoundException e) {
log.debug("Map tile file not found: " + watermarkFile.getAbsolutePath());
return null;
}
}
@Override
public BufferedImage getTileImage(int zoom, int x, int y,
LoadMethod loadMethod) throws IOException, TileException,
InterruptedException {
byte[] data = getTileData(zoom, x, y, loadMethod);
if (data == null)
return null;
return ImageIO.read(new ByteArrayInputStream(data));
}
@Override
public TileImageType getTileImageType() {
return tileImageType;
}
@Override
public MapSpace getMapSpace() {
return mapSpace;
}
@Override
public Color getBackgroundColor() {
return backgroundColor;
}
@Override
@XmlTransient
public MapSourceLoaderInfo getLoaderInfo() {
return loaderInfo;
}
@Override
public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) {
this.loaderInfo = loaderInfo;
}
@Override
public void reinitialize() {
initialized = true;
if (!watermarkFile.exists())
throw new RuntimeException("watermarkFile file does not exist: " + watermarkFile.getAbsolutePath());
String fileName = watermarkFile.getName();
int indexPeriod = fileName.lastIndexOf(".");
String fileExt = (indexPeriod == -1 ? "" : fileName.substring(indexPeriod + 1).toLowerCase());
tileImageType = TileImageType.getTileImageType(fileExt);
if (mosaic != null) {
mosaicMask = new byte[8];
String[] masks = mosaic.split(",");
for (int i = 0; i < masks.length && i < mosaicMask.length; i++) {
char[] mask = masks[i].toCharArray();
mosaicMask[i] = 0;
for (int j = 0; j < mask.length && j < 8; j++)
if (mask[j] == '1')
mosaicMask[i] |= 1 << j;
}
}
}
@Override
public String toString() {
return name;
}
@Override
public boolean getHiddenDefault() {
return hiddenDefault;
}
}