/*
 * Copyright 2015-2017 Andres Almiray
 *
 * 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 org.kordamp.ikonli.swing;

import org.kordamp.ikonli.Ikon;
import org.kordamp.ikonli.IkonHandler;

import javax.swing.Icon;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import static java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment;
import static java.util.Objects.requireNonNull;

/**
 * @author Andres Almiray
 */
public class FontIcon implements Icon {
    private static final Object LOCK = new Object[0];

    private Font font;
    private int width = 16;
    private int height = 16;
    private BufferedImage buffer;

    private int iconSize = 16;
    private Color iconColor = Color.BLACK;
    private Ikon ikon;

    public void paintIcon(Component c, Graphics g, int x, int y) {
        synchronized (LOCK) {
            if (buffer == null) {
                buffer = new BufferedImage(getIconWidth(), getIconHeight(),
                    BufferedImage.TYPE_INT_ARGB);

                Graphics2D g2 = (Graphics2D) buffer.getGraphics();
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

                g2.setFont(font);
                g2.setColor(iconColor);

                int sy = g2.getFontMetrics().getAscent();
                g2.drawString(String.valueOf(ikon.getCode()), 0, sy);

                g2.dispose();
            }

            g.drawImage(buffer, x, y, null);
        }
    }

    public Ikon getIkon() {
        return ikon;
    }

    public void setIkon(Ikon ikon) {
        requireNonNull(iconColor, "Argument 'iconFont' must not be null");
        this.ikon = ikon;
        synchronized (LOCK) {
            IkonHandler ikonHandler = IkonResolver.getInstance().resolve(ikon.getDescription());
            font = ((Font) ikonHandler.getFont()).deriveFont(Font.PLAIN, iconSize);
            buffer = null;
        }
    }

    public int getIconSize() {
        return iconSize;
    }

    public void setIconSize(int iconSize) {
        if (iconSize > 0) {
            this.iconSize = iconSize;
            font = font.deriveFont(Font.PLAIN, iconSize);

            BufferedImage tmp = new BufferedImage(iconSize, iconSize,
                BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = getLocalGraphicsEnvironment().createGraphics(tmp);
            g2.setFont(font);
            this.width = g2.getFontMetrics().charWidth(ikon.getCode());
            this.height = g2.getFontMetrics().getHeight();

            g2.dispose();

            synchronized (LOCK) {
                buffer = null;
            }
        }
    }

    public Color getIconColor() {
        return iconColor;
    }

    public void setIconColor(Color iconColor) {
        requireNonNull(iconColor, "Argument 'iconColor' must not be null");
        this.iconColor = iconColor;
        synchronized (LOCK) {
            buffer = null;
        }
    }

    public int getIconHeight() {
        return height;
    }

    public int getIconWidth() {
        return width;
    }
}

@@ -2562,37 +2562,39 @@
             
-buffer = null
+setProperties()
 ;%0A        %7D%0A
@@ -2769,24 +2769,60 @@
 = iconSize;%0A
+            if (null != font) %7B%0A    
             
@@ -2867,21 +2867,117 @@
 nSize);%0A
-%0A
     
+            setProperties();%0A            %7D%0A        %7D%0A    %7D%0A%0A    protected void setProperties() %7B%0A
         
@@ -3038,36 +3038,32 @@
 ze,%0A            
-  
-  
 BufferedImage.TY
@@ -3076,20 +3076,16 @@
 _ARGB);%0A
-    
         
@@ -3151,36 +3151,32 @@
 s(tmp);%0A        
-    
 g2.setFont(font)
@@ -3181,28 +3181,24 @@
 t);%0A        
- 
-   
 this.width =
@@ -3249,28 +3249,24 @@
 ));%0A        
-    
 this.height 
@@ -3297,28 +3297,24 @@
 tHeight();%0A%0A
-    
         g2.d
@@ -3328,28 +3328,24 @@
 );%0A%0A        
-    
 synchronized
@@ -3358,36 +3358,32 @@
 ) %7B%0A            
-    
 buffer = null;%0A 
@@ -3381,30 +3381,16 @@
 = null;%0A
-            %7D%0A
         

Fix NPE in Swing's FontIcon due to uninitialized Font. Fixes #16