package de.javasoft.synthetica.democenter.examples.jycombobox;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document;

import de.javasoft.swing.JYComboBox;
import de.javasoft.swing.jycombobox.IPopupComponentInitializer;

/**
 * Demonstrates how to create and install a custom 
 * component popup for a JYComboBox.  
 */
@SuppressWarnings("serial")
public class SimpleCustomComponentPopup extends JFrame
{
  
  public SimpleCustomComponentPopup()
  {
    super("SimpleCustomComponentPopup Demo");
    setLayout(new FlowLayout());
    
    JLabel label = new JLabel("JYComboBox - custom popup");
    add(label);

    JYComboBox combo = new JYComboBox();
//@highlight
    combo.setItem(createDocument());
    combo.setPopupComponent(new TextAreaPopupPanel(combo));
    combo.setPopupResizable(true);
    //install a renderer for the document
    combo.setRenderer(new ComboBoxDocumentRenderer(combo.getRenderer()));
//@/highlight
    add(combo);
    
    ((JComponent)getContentPane()).setBorder(new EmptyBorder(10,10,10,10));
    
    //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setSize(new Dimension(400, 300));
    setLocationRelativeTo(null);        //center
    setVisible(true);
  }
  
  private Document createDocument()
  {
    DefaultEditorKit editorKit = new DefaultEditorKit();
    Document doc = editorKit.createDefaultDocument();
    try
    {
      String s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt " +
      "ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris " +
      "nisi ut aliquip ex ea commodo consequat.\n\nDuis aute irure dolor in reprehenderit in voluptate velit esse " +
      "cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa " + 
      "qui officia deserunt mollit anim id est laborum.";
      doc.insertString(0, s, null);
    }
    catch (BadLocationException e)
    {
      throw new RuntimeException(e);
    }
    return doc;    
  }
  
  //
  // Popup Component Class
  //  
  private static class TextAreaPopupPanel extends JPanel implements IPopupComponentInitializer
  {
    private JYComboBox comboBox;
    private JTextArea textArea;
    
    public TextAreaPopupPanel(JYComboBox comboBox)
    {
      this.comboBox = comboBox;      
      setLayout(new GridBagLayout());
      
      textArea = new JTextArea();
      textArea.setLineWrap(true);
      textArea.setWrapStyleWord(true);
      JScrollPane scroller = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
      add(scroller, new GridBagConstraints(0, 0, 2, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,0,10,0), 0, 0));
      
      JButton okButton = new JButton(createOKAction());
      add(okButton, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0,0,0,10), 0, 0));
      
      JButton cancelButton = new JButton(createCancelAction());
      add(cancelButton, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0, 0));
      
      setBorder(new EmptyBorder(10,10,10,10));
      setPreferredSize(new Dimension(450,250));
    }
    
    //IPopupComponentInitializer implementation
    public void initializePopupComponent(JYComboBox comboBox)
    {
      //pass comboBox item to popup, we use a document copy
      //so the edited text can be revoked 
//@highlight
      Document doc = (Document)comboBox.getItem();
//@/highlight
      try
      {
        String text = doc.getText(0, doc.getLength());
        Document docCopy = new DefaultEditorKit().createDefaultDocument();
        docCopy.insertString(0, text, null);
//@highlight
        textArea.setDocument(docCopy);
//@/highlight
      }
      catch (BadLocationException e)
      {
        throw new RuntimeException(e);
      }      
    }
    
    private Action createOKAction()
    {
      Action a = new AbstractAction("OK"){
        public void actionPerformed(ActionEvent evt)
        {
//@highlight
          //set item in comboBox
          comboBox.setItem(textArea.getDocument());
          comboBox.closePopup();
//@/highlight
        }        
      };
      return a;
    }
    
    private Action createCancelAction()
    {
      Action a = new AbstractAction("Cancel"){
        public void actionPerformed(ActionEvent evt)
        {
//@highlight
          comboBox.cancelPopup();
//@/highlight
        }        
      };
      return a;
    }    
  }
  
  //
  // ComboBox Renderer Class
  //  
  private static class ComboBoxDocumentRenderer implements ListCellRenderer 
  {
    private ListCellRenderer defaultRenderer;

    public ComboBoxDocumentRenderer(ListCellRenderer defaultRenderer)
    {
      this.defaultRenderer = defaultRenderer;
    }
    
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
    {
      JLabel l = (JLabel)defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
      Document doc = (Document)value;
      try
      {
        String s = doc.getText(0, Math.min(doc.getLength(), 20));
        l.setText(s + "...");
      }
      catch (BadLocationException e)
      {
        throw new RuntimeException(e);
      }
      return l;
    }
  }
    
  /**
   * Static main method for application startup. 
   */
  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      public void run()
      {
        try
        {
          UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaStandardLookAndFeel");
          new SimpleCustomComponentPopup();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    });
  }  
}
