package org.jcon.df.edit.control.list;

import org.jcon.df.edit.control.element.Element;
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.border.EmptyBorder;

/**
* This class is a ListCellRenderer that displays an icon
* and/or text on each line by using a JLabel for the
* list elements. This is a nice, simple approach.
* It assumes that all list values are Elements.
*
* @author Jack Harich
*/
// Forced to extend JLabel to override paint()
public class ListControlCellRenderer extends JLabel
    implements ListCellRenderer {

//---------- Private Fields ------------------------------
// Internal
private Element element;
private boolean isSelected;

//---------- Initialization ------------------------------
public ListControlCellRenderer() {
    // Avoid cramming lines too tightly
    // We want to somewhat match the tree
    // This could become a property if tight is needed
    //   or it could be eliminated if icons give ok spacing
    
    // Insets - top, left, bottom, right
    EmptyBorder border = new EmptyBorder(
        new Insets(0, ListControl.X_INSET, 0, ListControl.X_INSET));
    this.setBorder(border);
}
//---------- SuperClass Overrides ------------------------
/**
 * paint is subclassed to draw the background correctly.  JLabel
 * currently does not allow backgrounds other than white, and it
 * will also fill behind the icon.  Something that isn't desirable.
 */
// See ba.tree.TreeViewCellRenderer for similar work
public void paint(Graphics g) {
    // Set background color
    Color backgroundColor;
    if(isSelected) {
        backgroundColor = Color.cyan;
    } else if(getParent() != null) {
        // Match container's background color
        backgroundColor = this.getParent().getBackground();
    } else {
        // This should never be called, but play it safe
        backgroundColor = this.getBackground();
    }
    g.setColor(backgroundColor);
       
    // Paint background
    FontMetrics metrics = g.getFontMetrics();
    
    Icon icon = element.getIcon();
    //this.setIcon(icon);
    
    String text = element.getText();
    //this.setText(text);
    
    int iconOffset = ListControl.X_INSET;
    if(icon != null && element.getText() != null) {
        iconOffset = (icon.getIconWidth() + this.getIconTextGap());
        g.fillRect(iconOffset, 0,
            getWidth() - 1 - iconOffset,
            this.getHeight() + 1 );        
        ((ImageIcon)icon).paintIcon(
            this, g, ListControl.X_INSET, 0);
    } else {
        g.fillRect(0, 0, getWidth() - 1, getHeight() + 1);
    } 
    // Paint text centered vertically
    int yAscent = metrics.getAscent();
    int lineHeight = getHeight() - 1;
    int textHeight = metrics.getHeight();
    int y = ((lineHeight - textHeight) / 2) + yAscent;    
    
    g.setColor(Color.black); // Foreground
    g.drawString(text, iconOffset + 1, y);
    
    // Note we do not call: super.paint(g); 
}
//---------- ListCellRenderer Implementation -------------
// This is the only method defined by ListCellRenderer.
// Configure the Jlabel superclass.
public Component getListCellRendererComponent(
    JList   list,
    Object  value,           // value to display
    int     index,           // cell index
    boolean isSelected,      // is the cell selected
    boolean cellHasFocus) {  // the list and the cell have the focus
    
    //print(" - value = " + value + ", valueClass = " + value.getClass());
    if (value instanceof Element) {
        // Save fields used in next paint() call
        this.isSelected = isSelected;    
        element = (Element)value;
        
        this.setText(element.getText());
        this.setIcon(element.getIcon());
    
    } else {
        // Call may be result of JList.setPrototypeCellValue()
        if (value instanceof String) {
            this.setText((String)value);
            this.setIcon(null);
            element = null; // To be safe and obvious

        } else {
            throw new IllegalArgumentException(
            "Unsupported PrototypeCellValue " + value);
        }
    }
    return this;
}
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("ListControlCellRenderer" + text);
}

} // End class
