001    package org.openstreetmap.gui.jmapviewer;
002    
003    //License: GPL.
004    
005    import static org.openstreetmap.gui.jmapviewer.FeatureAdapter.tr;
006    
007    import java.awt.Color;
008    import java.awt.Font;
009    import java.awt.Graphics;
010    import java.awt.Image;
011    import java.awt.Point;
012    import java.awt.Rectangle;
013    import java.awt.font.TextAttribute;
014    import java.awt.geom.Rectangle2D;
015    import java.awt.image.ImageObserver;
016    import java.util.HashMap;
017    
018    import org.openstreetmap.gui.jmapviewer.interfaces.Attributed;
019    
020    public class AttributionSupport {
021    
022        private Attributed source;
023    
024        private Image attrImage;
025        private String attrTermsText;
026        private String attrTermsUrl;
027        public static final Font ATTR_FONT = new Font("Arial", Font.PLAIN, 10);
028        public static final Font ATTR_LINK_FONT;
029        
030        protected Rectangle attrTextBounds = null;
031        protected Rectangle attrToUBounds = null;
032        protected Rectangle attrImageBounds = null;
033    
034        static {
035            HashMap<TextAttribute, Integer> aUnderline = new HashMap<TextAttribute, Integer>();
036            aUnderline.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
037            ATTR_LINK_FONT = ATTR_FONT.deriveFont(aUnderline);
038        }
039    
040        public void initialize(Attributed source) {
041            this.source = source;
042            boolean requireAttr = source.requiresAttribution();
043            if (requireAttr) {
044                attrImage = source.getAttributionImage();
045                attrTermsText = source.getTermsOfUseText();
046                attrTermsUrl = source.getTermsOfUseURL();
047                if (attrTermsUrl != null && attrTermsText == null) {
048                    attrTermsText = tr("Background Terms of Use");
049                }
050            } else {
051                attrImage = null;
052                attrTermsUrl = null;
053            }
054        }
055    
056        public void paintAttribution(Graphics g, int width, int height, Coordinate topLeft, Coordinate bottomRight, int zoom, ImageObserver observer) {
057            if (source == null || !source.requiresAttribution())
058                return;
059            // Draw attribution
060            Font font = g.getFont();
061            g.setFont(ATTR_LINK_FONT);
062    
063            // Draw terms of use text
064            int termsTextHeight = 0;
065            int termsTextY = height;
066    
067            if (attrTermsText != null) {
068                Rectangle2D termsStringBounds = g.getFontMetrics().getStringBounds(attrTermsText, g);
069                int textRealHeight = (int) termsStringBounds.getHeight();
070                termsTextHeight = textRealHeight - 5;
071                int termsTextWidth = (int) termsStringBounds.getWidth();
072                termsTextY = height - termsTextHeight;
073                int x = 2;
074                int y = height - termsTextHeight;
075                attrToUBounds = new Rectangle(x, y-termsTextHeight, termsTextWidth, textRealHeight);
076                g.setColor(Color.black);
077                g.drawString(attrTermsText, x + 1, y + 1);
078                g.setColor(Color.white);
079                g.drawString(attrTermsText, x, y);
080            }
081    
082            // Draw attribution logo
083            if (attrImage != null) {
084                int x = 2;
085                int imgWidth = attrImage.getWidth(observer);
086                int imgHeight = attrImage.getHeight(observer);
087                int y = termsTextY - imgHeight - termsTextHeight - 5;
088                attrImageBounds = new Rectangle(x, y, imgWidth, imgHeight);
089                g.drawImage(attrImage, x, y, null);
090            }
091    
092            g.setFont(ATTR_FONT);
093            String attributionText = source.getAttributionText(zoom, topLeft, bottomRight);
094            if (attributionText != null) {
095                Rectangle2D stringBounds = g.getFontMetrics().getStringBounds(attributionText, g);
096                int textHeight = (int) stringBounds.getHeight() - 5;
097                int x = width - (int) stringBounds.getWidth();
098                int y = height - textHeight;
099                g.setColor(Color.black);
100                g.drawString(attributionText, x + 1, y + 1);
101                g.setColor(Color.white);
102                g.drawString(attributionText, x, y);
103                attrTextBounds = new Rectangle(x, y-textHeight, (int) stringBounds.getWidth(), (int) stringBounds.getHeight());
104            }
105    
106            g.setFont(font);
107        }
108    
109        public boolean handleAttribution(Point p, boolean click) {
110            if (source == null || !source.requiresAttribution())
111                return false;
112    
113            /* TODO: Somehow indicate the link is clickable state to user */
114    
115            if (attrTextBounds != null && attrTextBounds.contains(p)) {
116                String attributionURL = source.getAttributionLinkURL();
117                if (attributionURL != null) {
118                    if (click) {
119                        FeatureAdapter.openLink(attributionURL);
120                    }
121                    return true;
122                }
123            } else if (attrImageBounds != null && attrImageBounds.contains(p)) {
124                String attributionImageURL = source.getAttributionImageURL();
125                if (attributionImageURL != null) {
126                    if (click) {
127                        FeatureAdapter.openLink(source.getAttributionImageURL());
128                    }
129                    return true;
130                }
131            } else if (attrToUBounds != null && attrToUBounds.contains(p)) {
132                String termsOfUseURL = source.getTermsOfUseURL();
133                if (termsOfUseURL != null) {
134                    if (click) {
135                        FeatureAdapter.openLink(termsOfUseURL);
136                    }
137                    return true;
138                }
139            }
140            return false;
141        }
142    
143    }
144