001package jmri.jmrit.consisttool;
002
003import java.awt.*;
004import java.awt.image.BufferedImage;
005
006import javax.swing.*;
007
008import jmri.*;
009import jmri.jmrit.roster.*;
010import jmri.util.gui.GuiLafPreferencesManager;
011
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014
015/**
016 * 
017 * A ListCellRenderer for the ConsistComboBox
018 *
019 * @author Lionel Jeanson Copyright (c) 2023
020 * 
021 */
022public class ConsistListCellRenderer extends JLabel implements ListCellRenderer<Object> {
023    
024    @Override
025    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {        
026        if (value == null) {
027            return null;
028        }
029        
030        if (value instanceof String) {
031            setText((String) value);
032            setIcon(null);
033            return this;            
034        }
035        
036        if (value instanceof LocoAddress) {            
037            LocoAddress consistAddress = (LocoAddress) value;
038            setText(consistAddress.toString());
039            setIcon(getConsistIcon(consistAddress));
040        }
041        return this;        
042    }
043    
044    public static ImageIcon getConsistIcon(LocoAddress consistAddress) {
045        return getConsistIcon(consistAddress, InstanceManager.getDefault(RosterIconFactory.class));
046    }
047    
048    public static ImageIcon getConsistIcon(LocoAddress consistAddress, RosterIconFactory iconFact ) {
049        if (iconFact == null) {
050            iconFact = InstanceManager.getDefault(RosterIconFactory.class);
051        }
052        int iconHeight =  iconFact.getIconFactoryHeight();
053        BufferedImage bi = new BufferedImage( 1, iconHeight, BufferedImage.TYPE_INT_ARGB);            
054        Consist consist =  InstanceManager.getDefault(jmri.ConsistManager.class).getConsist(consistAddress);
055        Font f = new Font("Monospaced", Font.PLAIN, InstanceManager.getDefault(GuiLafPreferencesManager.class).getFontSize());
056
057        for (DccLocoAddress loco : consist.getConsistList()) {
058            log.debug("Loco : {} - Position : {}", loco, consist.getPosition(loco));
059            String reName = consist.getRosterId(loco);
060            String label = null;
061            if (reName != null) {
062                ImageIcon icon;
063                Boolean dir = consist.getLocoDirection(loco);
064                if (dir) {
065                    icon = iconFact.getIcon(reName);
066                } else {
067                    icon = iconFact.getReversedIcon(reName);
068                }
069                if ( (icon != null) && (bi.getWidth() + icon.getIconWidth() > 0) ) {                        
070                    BufferedImage ti = new BufferedImage(bi.getWidth() + icon.getIconWidth(),  iconHeight, BufferedImage.TYPE_INT_ARGB);
071                    Graphics g = ti.createGraphics();
072                    g.drawImage(icon.getImage(), ti.getHeight()/2-icon.getIconHeight()/2, 0, null);
073                    g.drawImage(bi, icon.getIconWidth(), 0, null);           
074                    g.dispose(); 
075                    bi = ti;
076                } else {
077                    label = "["+reName+"]";
078                }
079            } else {
080                 label = "["+loco.toString()+"]";
081            }
082            if (label != null) {
083                // write label for that locomotive in a buffered image                    
084                BufferedImage li =  new BufferedImage( label.length()*f.getSize(),   iconHeight, BufferedImage.TYPE_INT_ARGB);
085                Graphics gli = li.createGraphics();
086                gli.setFont(f);
087                //gli.setColor(this.getForeground());
088                gli.drawString(label, 0,  iconHeight/2 + gli.getFontMetrics().getMaxAscent()/2);                    
089                // expand existing buffered image
090                BufferedImage ti = new BufferedImage( gli.getFontMetrics().stringWidth(label) + bi.getWidth() +2, iconHeight, BufferedImage.TYPE_INT_ARGB);
091                Graphics gti = ti.createGraphics(); 
092                gti.drawImage(li, 0, 0, null);
093                gti.drawImage(bi, gli.getFontMetrics().stringWidth(label)+2, 0, null);
094                // update and free ressources
095                bi = ti;
096                gli.dispose();
097                gti.dispose();                     
098            }
099        }
100        return (new ImageIcon(bi));        
101    }
102    
103    private static final Logger log = LoggerFactory.getLogger(ConsistListCellRenderer.class);
104}