package org.jcon.df.edit.control;

import org.jcon.df.edit.EditEvent;
import org.jcon.ui.ImageLib;
import org.jcon.ui.VisualLib;
import org.jcon.ui.comp.DoClickable;
import org.jcon.param.Param;
import org.jcon.param.StringVector;
import org.jcon.util.msg.Message;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JButton;

/**
 * A Control representing a JButton. We support InfoText
 * and alternate InfoText for different button text.
 *
 * @author Jack Harich
 */
public class JButtonControl extends Control
    implements ActionListener, MouseListener, DoClickable {

//---------- Private Fields ------------------------------
// Internal
private JButton    button = 
    VisualLib.createCompactButton(null, null, null);
private boolean    isEditable;
private String     actionCommand;
private String     infoText; // null if none

// Key = ButtonText, Object = String, InfoText
private Hashtable  alternateInfoTexts = new Hashtable();

//---------- Initialization ------------------------------
public JButtonControl() {
    button.addActionListener(this);
}
//---------- Abstract Implementation ---------------------
public Component getComponent() {
    return (Component)button;
}
//---------- Superclass Overrides ------------------------
public void init() { // Called after above
    button.setText(myParam.getString("Text"));
    actionCommand = myParam.getString("Command");
    
    // This will be no tool tip text if not supplied
    button.setToolTipText(myParam.getString("ToolTipText"));
    
    String mnemonic = myParam.getString("HotCharacter");
    if (mnemonic != null) {
        button.setMnemonic(mnemonic.charAt(0));
    }
    // For uniform width buttons in button bar
    if (myParam.hasProperty("PreferredWidth")) {
        int prefWidth = myParam.getInt("PreferredWidth");
        int prefHeight = button.getPreferredSize().height;
        button.setPreferredSize(new Dimension(prefWidth, prefHeight));
    }
    if (myParam.hasProperty("ImageResourceClass")) {
        initImage();
    }
    button.setEnabled(myParam.isTrueDefaultTrue("Enabled"));
    
    // Mouse events and InfoText
    infoText = myParam.getLinesVectorString("InfoText", " ");
    if (infoText != null) {
        button.addMouseListener(this);
    } else {
        button.removeMouseListener(this);
    }
    // Fill alternateInfoTexts or return
    alternateInfoTexts.clear();
    if (! myParam.hasProperty("AlternateInfoText")) return;
    
    Vector altParams = myParam.getParamVector("AlternateInfoText");
    for (int i = 0; i < altParams.size(); i++) {
        Param altParam = (Param)altParams.elementAt(i);
        String altButtonText = altParam.getString("ButtonText");
        String altInfoText = altParam.getLinesVectorString("InfoText", " ");
        alternateInfoTexts.put(altButtonText, altInfoText);
    }
}
public void setEditable(boolean editable) {
    // Not supported
}
public void setValue(Object value) {
    button.setText((String)value);
}
public Object getValue() {
    return button.getText();
}
//---------- ActionListener Implementation ---------------
public void actionPerformed(ActionEvent evt) {
    if (actionCommand != null && editListener != null) {
        // Fire event
        EditEvent editEvent = new EditEvent(
            EditEvent.COMMAND, null); // null for no DataSourceID
        editEvent.setCommand(actionCommand);
        editListener.processEditEvent(editEvent);       
    }
}
//---------- MouseListener Implementation ----------------
public void mouseClicked(MouseEvent evt) { }
public void mousePressed(MouseEvent evt) { }
public void mouseReleased(MouseEvent evt) { }

public void mouseEntered(MouseEvent evt) { 
    fireShowInfoTextEvent(true);
}
public void mouseExited(MouseEvent evt) { 
    fireShowInfoTextEvent(false);
}
//---------- DoClickable Implementation ------------------
public void doClick(int pressTime) {
    button.doClick(pressTime);
}
//---------- Private Methods -----------------------------
private void fireShowInfoTextEvent(boolean isShowText) {
    //print(".fireShowInfoTextEvent() - isShowText = " + isShowText);
    if (! button.isEnabled()) return;
    
    EditEvent editEvent = new EditEvent(
        EditEvent.MESSAGE, null); // null for no DataSourceID
    Message message = new Message("EditEvent");
    message.set("EventType", "CommandParam");
    
    // Set text using alternative InfoText
    String text = null;
    if (isShowText) {
        String buttonText = button.getText();
        String altInfoText = (String)
            alternateInfoTexts.get(buttonText);
        
        if (altInfoText != null) {
            text = altInfoText;
        } else {
            text = infoText;
        }
    }
    // Create command Param, put in message
    StringVector lines = new StringVector();
    if (text != null) lines.addElement(text);
    
    Param cmdParam = new Param();
    cmdParam.put("CommandName", "SetInfoText");
    if (! lines.isEmpty()) cmdParam.put("InfoText", lines);
    message.set("Param", cmdParam);
    
    // Send message
    editEvent.setMessage(message);
    editListener.processEditEvent(editEvent); 
}
private void initImage() {
    String className = myParam.getString("ImageResourceClass");
    String resourceName = myParam.getString("ImageResourceName");

    Image image = ImageLib.loadClassResourceImage(
        className, resourceName);
    ImageIcon icon = new ImageIcon(image);
    button.setIcon(icon);
    //print(".initImage() - set icon for " + resourceName);
}
//--- Std
private static void print(String text) {
    System.out.println("JButtonControl" + text);
}

} // End class
