/******************************************************************************* * Copyright 2012 Geoscience Australia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package au.gov.ga.earthsci.worldwind.common.layers.screenoverlay; import gov.nasa.worldwind.avlist.AVList; import java.awt.Color; import java.net.MalformedURLException; import java.net.URL; import java.util.zip.CRC32; import javax.imageio.ImageIO; import au.gov.ga.earthsci.worldwind.common.util.FileUtil; import au.gov.ga.earthsci.worldwind.common.util.Validate; /** * A default mutable implementation of the {@link ScreenOverlayAttributes} interface. * <p/> * Provides some sensible defaults that can be used with minimal configuration. * * @author James Navin (james.navin@ga.gov.au) */ public class MutableScreenOverlayAttributesImpl implements ScreenOverlayAttributes { private static final ScreenOverlayPosition DEFAULT_OVERLAY_POSITION = ScreenOverlayPosition.CENTER; private static final LengthExpression DEFAULT_LENGTH = new LengthExpression("80%"); private static final int DEFAULT_BORDER_WIDTH = 2; private static final int NO_BORDER_WIDTH = 0; private static final Color DEFAULT_BORDER_COLOR = Color.GRAY; private static final String ID_PREFIX = "ScreenOverlay"; private URL sourceUrl; private String sourceHtml; private String sourceId; private ScreenOverlayPosition position = DEFAULT_OVERLAY_POSITION; private LengthExpression minHeight = DEFAULT_LENGTH; private LengthExpression maxHeight = null; // Fixed height private LengthExpression minWidth = DEFAULT_LENGTH; private LengthExpression maxWidth = null; // Fixed width private boolean drawBorder = true; private Color borderColor = DEFAULT_BORDER_COLOR; private int borderWidth = DEFAULT_BORDER_WIDTH; // Constructor used for testing etc. MutableScreenOverlayAttributesImpl(){} public MutableScreenOverlayAttributesImpl(URL sourceUrl) { Validate.notNull(sourceUrl, "A source URL is required"); this.sourceUrl = sourceUrl; } public MutableScreenOverlayAttributesImpl(String sourceHtml) { Validate.notBlank(sourceHtml, "Source html is required"); this.sourceHtml = sourceHtml.trim(); } @Override public URL getSourceUrl() { return sourceUrl; } @Override public String getSourceHtml() { return sourceHtml; } @Override public String getSourceId() { if (sourceId == null) { CRC32 checksum = new CRC32(); if (sourceUrl != null) { checksum.update((sourceUrl.toExternalForm()).getBytes()); } else { checksum.update(sourceHtml.getBytes()); } sourceId = ID_PREFIX + checksum.getValue(); } return sourceId; } @Override public boolean isSourceHtml() { // Assume content is HTML if not an image... return !isSourceImage(); } @Override public boolean isSourceImage() { if (sourceUrl == null) { return false; } String urlSuffix = FileUtil.getExtension(sourceUrl.toExternalForm()); for (String suffix : ImageIO.getReaderFileSuffixes()) { if (suffix.equalsIgnoreCase(urlSuffix)) { return true; } } return false; } @Override public ScreenOverlayPosition getPosition() { return position; } public void setPosition(ScreenOverlayPosition position) { this.position = (position == null ? DEFAULT_OVERLAY_POSITION : position); } @Override public LengthExpression getMinHeight() { return minHeight; } public void setMinHeight(String expression) { setMinHeight(new LengthExpression(expression)); } public void setMinHeight(LengthExpression minHeight) { if (minHeight == null) { minHeight = maxHeight == null ? DEFAULT_LENGTH : maxHeight; } this.minHeight = minHeight; } @Override public LengthExpression getMaxHeight() { return maxHeight == null ? minHeight : maxHeight; } public void setMaxHeight(String expression) { setMaxHeight(new LengthExpression(expression)); } public void setMaxHeight(LengthExpression maxHeight) { this.maxHeight = maxHeight; } @Override public float getHeight(float screenHeight) { return clampDimension(screenHeight, getMinHeight().getLength(screenHeight), getMaxHeight().getLength(screenHeight)); } @Override public LengthExpression getMinWidth() { return minWidth; } public void setMinWidth(String expression) { setMinWidth(new LengthExpression(expression)); } public void setMinWidth(LengthExpression minWidth) { this.minWidth = minWidth; } @Override public LengthExpression getMaxWidth() { return maxWidth == null ? minWidth : maxWidth; } public void setMaxWidth(String expression) { setMaxWidth(new LengthExpression(expression)); } public void setMaxWidth(LengthExpression maxWidth) { this.maxWidth = maxWidth; } @Override public float getWidth(float screenWidth) { return clampDimension(screenWidth, getMinWidth().getLength(screenWidth), getMaxWidth().getLength(screenWidth)); } @Override public boolean isDrawBorder() { return drawBorder; } public void setDrawBorder(boolean drawBorder) { this.drawBorder = drawBorder; } @Override public Color getBorderColor() { return drawBorder ? borderColor : null; } public void setBorderColor(Color borderColor) { this.borderColor = (borderColor == null ? DEFAULT_BORDER_COLOR : borderColor); } @Override public int getBorderWidth() { return drawBorder ? borderWidth : NO_BORDER_WIDTH; } public void setBorderWidth(int borderWidth) { this.borderWidth = (borderWidth < 0 ? DEFAULT_BORDER_WIDTH : borderWidth); } private float clampDimension(float screenDimension, float min, float max) { screenDimension = Math.max(1, screenDimension); if (screenDimension < min) return min; if (screenDimension > max) return max; return screenDimension; } /** * Create a new {@link MutableScreenOverlayAttributesImpl} from the provided parameters */ public MutableScreenOverlayAttributesImpl(AVList params) { Validate.notNull(params, "Initialisation parameters are required"); if (params.hasKey(ScreenOverlayKeys.URL)) { Object urlEntry = params.getValue(ScreenOverlayKeys.URL); if (urlEntry instanceof URL) { // If its a URL, use it this.sourceUrl = (URL)urlEntry; } else { // If its a String, use it along with a context URL (if provided) URL context = (URL)params.getValue(ScreenOverlayKeys.CONTEXT_URL); try { this.sourceUrl = new URL(context, (String)urlEntry); } catch (MalformedURLException e) { throw new IllegalArgumentException("Unable to create source URL from params.", e); } } } else if (params.hasKey(ScreenOverlayKeys.OVERLAY_CONTENT)) { this.sourceHtml = params.getStringValue(ScreenOverlayKeys.OVERLAY_CONTENT).trim(); } else { throw new IllegalArgumentException("No overlay content or source URL found. At least one is required."); } if (params.hasKey(ScreenOverlayKeys.MIN_HEIGHT)) { Object minHeight = params.getValue(ScreenOverlayKeys.MIN_HEIGHT); if (minHeight instanceof LengthExpression) { this.minHeight = (LengthExpression)minHeight; } else if (minHeight instanceof String) { this.minHeight = new LengthExpression((String)minHeight); } else if (minHeight == null) { this.minHeight = null; } else { throw new IllegalArgumentException("Min height must be one of String or LengthExpression"); } } if (params.hasKey(ScreenOverlayKeys.MAX_HEIGHT)) { Object maxHeight = params.getValue(ScreenOverlayKeys.MAX_HEIGHT); if (maxHeight instanceof LengthExpression) { this.maxHeight = (LengthExpression)maxHeight; } else if (maxHeight instanceof String) { this.maxHeight = new LengthExpression((String)maxHeight); } else if (maxHeight == null) { this.maxHeight = null; } else { throw new IllegalArgumentException("Max height must be one of String or LengthExpression"); } } if (params.hasKey(ScreenOverlayKeys.MIN_WIDTH)) { Object minWidth = params.getValue(ScreenOverlayKeys.MIN_WIDTH); if (minWidth instanceof LengthExpression) { this.minWidth = (LengthExpression)minWidth; } else if (minWidth instanceof String) { this.minWidth = new LengthExpression((String)minWidth); } else if (minWidth == null) { this.minWidth = null; } else { throw new IllegalArgumentException("Min height must be one of String or LengthExpression"); } } if (params.hasKey(ScreenOverlayKeys.MAX_WIDTH)) { Object maxWidth = params.getValue(ScreenOverlayKeys.MAX_WIDTH); if (maxWidth instanceof LengthExpression) { this.maxWidth = (LengthExpression)maxWidth; } else if (maxWidth instanceof String) { this.maxWidth = new LengthExpression((String)maxWidth); } else if (maxWidth == null) { this.maxWidth = null; } else { throw new IllegalArgumentException("Max height must be one of String or LengthExpression"); } } if (params.hasKey(ScreenOverlayKeys.DRAW_BORDER)) { this.drawBorder = (Boolean)params.getValue(ScreenOverlayKeys.DRAW_BORDER); } if (params.hasKey(ScreenOverlayKeys.BORDER_WIDTH)) { this.borderWidth = (Integer)params.getValue(ScreenOverlayKeys.BORDER_WIDTH); } if (params.hasKey(ScreenOverlayKeys.BORDER_COLOR)) { this.borderColor = (Color)params.getValue(ScreenOverlayKeys.BORDER_COLOR); } if (params.hasKey(ScreenOverlayKeys.POSITION)) { Object position = params.getValue(ScreenOverlayKeys.POSITION); if (position instanceof ScreenOverlayPosition) { this.position = (ScreenOverlayPosition)position; } else if (position instanceof String) { this.position = ScreenOverlayPosition.valueOf(((String)position).toUpperCase()); } else { throw new IllegalArgumentException("Position must be one of String or ScreenOverlayPosition"); } } } }