/*
 * Cay S. Horstmann & Gary Cornell, Core Java
 * Published By Sun Microsystems Press/Prentice-Hall
 * Copyright (C) 1997 Sun Microsystems Inc.
 * All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this 
 * software and its documentation for NON-COMMERCIAL purposes
 * and without fee is hereby granted provided that this 
 * copyright notice appears in all copies. 
 * 
 * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR 
 * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS
 * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED 
 * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING 
 * THIS SOFTWARE OR ITS DERIVATIVES.
 */
 
/**
 * @version 1.10 27 Oct 1997
 * @author Cay Horstmann
 */

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import java.text.*;
import java.util.*;

public class ChartBeanCustomizer extends Panel
   implements Customizer
{  public ChartBeanCustomizer()
   {  Panel p;
      setLayout(new BorderLayout());

      final Panel cardPanel = new Panel();
      final CardLayout cardLayout = new CardLayout();
      cardPanel.setLayout(cardLayout);

      Panel card = new Panel();
      card.setLayout(new BorderLayout());

      TextArea fileInfo = new TextArea(
         "You can read data values for the chart\n"
         + "from a text file. The file must contain one\n"
         + "data value in each line.",
         3, 50, TextArea.SCROLLBARS_NONE);
      fileInfo.setEditable(false);
      card.add(fileInfo, "Center");

      Button loadButton = new Button("Load");
      loadButton.addActionListener(new ActionListener()
         {  public void actionPerformed(ActionEvent evt)
            {  loadFile();
            }
         });
      p = new Panel();
      p.add(loadButton);
      card.add(p, "South");
      cardPanel.add(card, "0");

      add(cardPanel, "Center");

      card = new Panel();
      card.setLayout(new GridBagLayout());

      CheckboxGroup g = new CheckboxGroup();
      normal = new Checkbox("Normal", g, true);
      inverse = new Checkbox("Inverse", g, false);
      
      p = new Panel();
      p.add(normal);
      p.add(inverse);
      normal.addItemListener(new ItemListener()
         {  public void itemStateChanged(ItemEvent evt)
            {  if (evt.getStateChange() == ItemEvent.SELECTED)
                  setInverse(false);
            }
         });
         
      inverse.addItemListener(new ItemListener()
         {  public void itemStateChanged(ItemEvent evt)
            {  if (evt.getStateChange() == ItemEvent.SELECTED)
                  setInverse(true);
            }
         });

      colorEditor 
         = PropertyEditorManager.findEditor(Color.class);
      colorEditor.addPropertyChangeListener
         (new PropertyChangeListener()
         {  public void propertyChange(PropertyChangeEvent 
               evt)
            {  setGraphColor((Color)colorEditor.getValue());
            }
         });

      GridBagConstraints gbc = new GridBagConstraints();
      gbc.weightx = 100;
      gbc.weighty = 100;
      gbc.fill = GridBagConstraints.NONE;
      gbc.anchor = GridBagConstraints.WEST;

      add(card, new Label("Set Color"), gbc, 0, 0, 1, 1);
      add(card, p, gbc, 0, 1, 1, 1);
      add(card, colorEditor.getCustomEditor(), 
         gbc, 0, 2, 1, 1);
      cardPanel.add(card, "1");

      card = new Panel();
      card.setLayout(new GridBagLayout());

      positionGroup = new CheckboxGroup();
      position = new Checkbox[3];
      position[0] = new Checkbox("Left", g, false);
      position[1] = new Checkbox("Center", g, true);
      position[2] = new Checkbox("Right", g, false);

      p = new Panel();
      for (int i = 0; i < position.length; i++)
      {  final int value = i;
         p.add(position[i]);
         position[i].addItemListener(new ItemListener()
            {  public void itemStateChanged(ItemEvent evt)
               {  if (evt.getStateChange() 
                     == ItemEvent.SELECTED)
                     setTitlePosition(value);
               }
            });
      }

      titleField = new TextField();
      titleField.addTextListener(new TextListener() 
         {  public void textValueChanged(TextEvent evt)
            {  setTitle(titleField.getText());
            }
         });
      
      add(card, new Label("Set Title"), gbc, 0, 0, 1, 1);
      add(card, p, gbc, 0, 1, 1, 1);
      gbc.fill = GridBagConstraints.HORIZONTAL;
      add(card, titleField, gbc, 0, 2, 1, 1);
      cardPanel.add(card, "2");

      p = new Panel();
      Button nextButton = new Button("Next");
      Button previousButton = new Button("Previous");
      nextButton.addActionListener(new ActionListener()
         {  public void actionPerformed(ActionEvent evt)
            {  cardLayout.next(cardPanel);
            }
         });
      previousButton.addActionListener(new ActionListener()
         {  public void actionPerformed(ActionEvent evt)
            {  cardLayout.previous(cardPanel);
            }
         });
      p.add(previousButton);
      p.add(nextButton);
      add(p, "South");
   }

   public static void add(Container t, 
      Component c, GridBagConstraints gbc,
      int x, int y, int w, int h)
   {  gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = w;
      gbc.gridheight = h;
      t.add(c, gbc);
   }

   public void loadFile()
   {  Container c = getParent();
      while (c != null && !(c instanceof Frame)) 
         c = c.getParent();
      FileDialog dlg = new FileDialog((Frame)c,
            "Open data file", FileDialog.LOAD);
      dlg.show();
      String filename = dlg.getFile();
      if (filename != null)
      {  filename = dlg.getDirectory() + filename;
         NumberFormat fmt = NumberFormat.getNumberInstance();
         try
         {  Vector v = new Vector();
            BufferedReader in 
               = new BufferedReader(new FileReader(filename));
            String line;
            while ((line = in.readLine()) != null)
               v.addElement(fmt.parse(line));
            double[] d = new double[v.size()];
            for (int i = 0; i < d.length; i++)
               d[i] = ((Number)v.elementAt(i)).doubleValue();
            setValues(d);
         }
         catch(IOException e) {}
         catch(ParseException e) {}
      }
   }

   public void setTitle(String newValue)
   {  String oldValue = bean.getTitle();
      bean.setTitle(newValue);
      pcs.firePropertyChange("title", oldValue, newValue);
   }

   public void setTitlePosition(int i)
   {  Integer oldValue = new Integer(bean.getTitlePosition());
      Integer newValue = new Integer(i);
      bean.setTitlePosition(i);
      pcs.firePropertyChange("title", oldValue, newValue);
   }

   public void setInverse(boolean b)
   {  Boolean oldValue = new Boolean(bean.isInverse());
      Boolean newValue = new Boolean(b);
      bean.setInverse(b);
      pcs.firePropertyChange("inverse", oldValue, newValue);
   }

   public void setValues(double[] newValue)
   {  double[] oldValue = bean.getValues();
      bean.setValues(newValue);
      pcs.firePropertyChange("inverse", oldValue, newValue);
   }

   public void setGraphColor(Color newValue)
   {  Color oldValue = bean.getGraphColor();
      bean.setGraphColor(newValue);
      pcs.firePropertyChange("inverse", oldValue, newValue);
   }

   public Dimension getPreferredSize()
   {  return new Dimension(300, 200);
   }

   public void setObject(Object obj)
   {  bean = (ChartBean)obj;
      
      normal.setState(!bean.isInverse());
      inverse.setState(bean.isInverse());

      titleField.setText(bean.getTitle());
      
      positionGroup.setSelectedCheckbox
         (position[bean.getTitlePosition()]);      
      
      colorEditor.setValue(bean.getGraphColor());
   }

   public void addPropertyChangeListener
      (PropertyChangeListener l)
   {  pcs.addPropertyChangeListener(l);
   }

   public void removePropertyChangeListener
      (PropertyChangeListener l)
   {  pcs.removePropertyChangeListener(l);
   }

   ChartBean bean;
   PropertyChangeSupport pcs = new PropertyChangeSupport(this);
   PropertyEditor colorEditor;

   Checkbox normal;
   Checkbox inverse;
   Checkbox[] position;
   CheckboxGroup positionGroup;
   TextField titleField;
}
