package com.izforge.izpack.installer.container.provider;

import java.io.InputStream;
import java.net.URL;
import java.util.logging.Logger;

import javax.swing.ImageIcon;
import javax.swing.UIManager;

import org.picocontainer.injectors.Provider;

import com.izforge.izpack.api.adaptator.IXMLElement;
import com.izforge.izpack.api.adaptator.IXMLParser;
import com.izforge.izpack.api.adaptator.impl.XMLParser;
import com.izforge.izpack.api.resource.Resources;
import com.izforge.izpack.gui.IconsDatabase;
import com.izforge.izpack.installer.gui.InstallerFrame;

/**
 * Provide icons database
 */
public class IconsProvider implements Provider
{
    private static final Logger logger = Logger.getLogger(IconsProvider.class.getName());

    /**
     * Resource name for custom icons
     */
    private static final String CUSTOM_ICONS_RESOURCEFILE = "customicons.xml";

    public IconsDatabase provide(Resources resources) throws Exception
    {
        IconsDatabase icons = new IconsDatabase();
        loadIcons(icons);
        loadCustomIcons(icons, resources);
        return icons;
    }

    /**
     * Loads the icons.
     *
     * @param iconsDatabase
     * @throws Exception Description of the Exception
     */
    private void loadIcons(IconsDatabase iconsDatabase) throws Exception
    {
        // Initialisations
        InputStream inXML = getClass().
                getResourceAsStream("icons.xml");

        parseXML(inXML, iconsDatabase);
    }

    /**
     * Loads custom icons into the installer.
     *
     * @param icons     the icons database
     * @param resources used to load the icons
     * @throws Exception
     */
    private void loadCustomIcons(IconsDatabase icons, Resources resources) throws Exception
    {
        // We try to load and add a custom langpack.
        InputStream inXML = null;
        try
        {
            inXML = resources.getInputStream(CUSTOM_ICONS_RESOURCEFILE);
        }
        catch (Throwable exception)
        {
            logger.warning("Resource " + CUSTOM_ICONS_RESOURCEFILE
                                   + " not defined. No custom icons available");
            return;
        }
        logger.fine("Custom icons available");

        parseXML(inXML, icons);
    }

    /**
     * parse the xml and fill in the db
     *
     * @param inXML
     * @param icons
     */
    private void parseXML(InputStream inXML, IconsDatabase icons)
    {
        URL url;
        ImageIcon img;// Initialises the parser
        IXMLParser parser = new XMLParser();

        // We get the data
        IXMLElement data = parser.parse(inXML);

        // We load the icons
        for (IXMLElement icon : data.getChildrenNamed("icon"))
        {
            url = InstallerFrame.class.getResource(icon.getAttribute("res"));
            img = new ImageIcon(url);
            logger.fine("Icon with id found: " + icon.getAttribute("id"));
            icons.put(icon.getAttribute("id"), img);
        }

        // We load the Swing-specific icons
        for (IXMLElement icon : data.getChildrenNamed("sysicon"))
        {
            url = InstallerFrame.class.getResource(icon.getAttribute("res"));
            img = new ImageIcon(url);
            UIManager.put(icon.getAttribute("id"), img);
        }
    }

}

@@ -2425,25 +2425,8 @@
   %7B%0A
-        URL url;%0A
     
@@ -2443,16 +2443,25 @@
 con img;
+%0A        
 // Initi
@@ -2718,46 +2718,98 @@
     
-url = InstallerFrame.class.getResource
+img = loadIcon(icon);%0A            if (img != null)%0A            %7B%0A                icons.put
 (ico
@@ -2816,37 +2816,41 @@
 n.getAttribute(%22
-res%22)
+id%22), img
 );%0A            i
@@ -2852,112 +2852,141 @@
     
-img = new ImageIcon(url);%0A            logger.fine(%22Icon with id found: %22 + icon.getAttribute(%22id
+%7D%0A        %7D%0A%0A        // We load the Swing-specific icons%0A        for (IXMLElement icon : data.getChildrenNamed(%22sysicon
 %22))
-;
 %0A   
+     %7B%0A
     
@@ -2982,37 +2982,125 @@
      %7B%0A         
-icons
+   img = loadIcon(icon);%0A            if (img != null)%0A            %7B%0A                UIManager
 .put(icon.getAtt
@@ -3131,120 +3131,372 @@
     
+    %7D%0A        
 %7D
-%0A
 %0A    
+%7D%0A%0A
     /
-/ We load the Swing-specific icons%0A        for (IXMLElement icon : data.getChildrenNamed(%22sysicon%22))
+**%0A     * Loads an icon declared in an XML file.%0A     * %0A     * @param icon%0A     *            the XML element that declares the icon%0A     * @return the icon or %3Ccode%3Enull%3C/icon%3E if it does not exist%0A     */%0A    private ImageIcon loadIcon(IXMLElement icon)%0A    %7B%0A        ImageIcon img = null;%0A        String id = icon.getAttribute(%22id%22);
 %0A   
@@ -3500,29 +3500,64 @@
         
-%7B%0A   
+String path = icon.getAttribute(%22res%22);%0A
         
  url = I
@@ -3548,16 +3548,19 @@
         
+URL
  url = I
@@ -3595,145 +3595,303 @@
 rce(
-icon.getAttribute(%22res%22));%0A            img = new ImageIcon(url);%0A            UIManager.put(icon.getAttribute(%22id%22), img);%0A        %7D%0A    %7D%0A
+path);%0A        if (url == null)%0A        %7B%0A            logger.warning(%22Icon with id '%22 + id + %22': file '%22 + path + %22' not found%22);%0A        %7D%0A        else%0A        %7B%0A            img = new ImageIcon(url);%0A            logger.fine(%22Icon with id '%22 + id + %22' found%22);%0A        %7D%0A        return img;%0A    %7D
 %0A%7D%0A

Fix for IZPACK-943