/*
   Source code by David Eck
                  Department of Mathematics and Computer Science
                  Hobart and William Smith Colleges
                  Geneva, NY 14456
                  eck@hws.edu
                  
   This Java source code file can be used IN UNMODIFIED FORM for
   any purpose.  You can also make and distribute modified versions,
   as long as you include an acknowledgement of the original
   author in the modified version.
*/

package xca;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ColorDialog extends JDialog implements ActionListener {

   private static class ColorPatch extends JPanel {
      int index;
      ColorPatch(int index, Color color) {
         this.index = index;
         setBackground(color);
         enableEvents(AWTEvent.MOUSE_EVENT_MASK);
         setPreferredSize(new Dimension(40,40));
      }
      public void paintComponent(Graphics g) {
         super.paintComponent(g);
         
         Color bg = getBackground();
         if (bg.getRed() < 180 && bg.getBlue() < 200 && bg.getGreen() < 170)
            g.setColor(Color.white);
         else
            g.setColor(Color.black);
         g.drawString(""+index,6,18);
         g.drawRect(0,0,getWidth()-1,getHeight()-1);
      }
      protected void processMouseEvent(MouseEvent evt) {
         if (evt.getID() == MouseEvent.MOUSE_PRESSED) {
            Color c = JColorChooser.showDialog(this, 
                            "Select Color " + index, getBackground());
            if (c != null)
               setBackground(c);
         }
      }
   }

   private int colorCt;
   private ColorPatch[] colorPatch;
   private boolean canceled;

   public JButton grayscaleButton, whiteBrightButton, whiteDullButton, whitePaleButton,
                     blackBrightButton, blackDullButton, blackPaleButton;
            
   public JButton cancelButton, okButton, defaultsButton;
   
   public ColorDialog(Frame parent, int[] colorPalette) {
      super(parent,"Select State Colors",true);
      setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
      colorCt = colorPalette.length;
      
      JPanel bottom = new JPanel();
      JPanel middle = new JPanel();
      if (colorCt <= 3)
         middle.setLayout(new GridLayout(1,colorCt,3,3));
      else
         middle.setLayout(new GridLayout(0,8,3,3));
      middle.setBackground(Color.gray);
      JPanel p = new JPanel();
      p.setLayout(new BorderLayout(5,5));
      p.add(middle,BorderLayout.CENTER);
      p.add(new JLabel("Click on a color to change it", JLabel.CENTER), BorderLayout.SOUTH);
      p.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
      p.setBackground(Color.gray);
      getContentPane().add(p,BorderLayout.CENTER);
      getContentPane().add(bottom,BorderLayout.SOUTH);
      
      cancelButton = new JButton("Cancel");
      okButton = new JButton("OK");
      defaultsButton = new JButton("Defaults");
      okButton.addActionListener(this);
      cancelButton.addActionListener(this);
      defaultsButton.addActionListener(this);
      if (colorCt <= 3)
         bottom.add(defaultsButton);
      bottom.add(cancelButton);
      bottom.add(okButton);

      if (colorCt > 3) {
         JPanel top = new JPanel();
         top.setLayout(new GridLayout(4,2));
         getContentPane().add(top,BorderLayout.NORTH);
         grayscaleButton = new JButton("Grayscale");
         whiteBrightButton = new JButton("White / Bright Spectrum");
         blackBrightButton = new JButton("Black / Bright Spectrum");
         whiteDullButton = new JButton("White / Dull Spectrum");
         blackDullButton = new JButton("Black / Dull Spectrum");
         whitePaleButton = new JButton("White / Pale Spectrum");
         blackPaleButton = new JButton("Black / Pale Spectrum");
         grayscaleButton.addActionListener(this);
         whiteBrightButton.addActionListener(this);
         whiteDullButton.addActionListener(this);
         whitePaleButton.addActionListener(this);
         blackBrightButton.addActionListener(this);
         blackDullButton.addActionListener(this);
         blackPaleButton.addActionListener(this);
         top.add(defaultsButton);
         top.add(grayscaleButton);
         top.add(whiteBrightButton);
         top.add(blackBrightButton);
         top.add(whiteDullButton);
         top.add(blackDullButton);
         top.add(whitePaleButton);
         top.add(blackPaleButton);
      }
      
      colorPatch = new ColorPatch[colorCt];
      for (int i = 0; i < colorCt; i++) {
         colorPatch[i] = new ColorPatch(i, new Color(colorPalette[i]));
         middle.add(colorPatch[i]);
      }
      
      pack();
      if (parent != null)
         setLocation(parent.getLocation().x + 80, parent.getLocation().y + 50);      
      show();
   }
   
   public void show() {
      canceled = true;
      super.show();
   }
   
   public int[] getPalette() {
      if (canceled)
         return null;
      else {
         int[] palette = new int[colorCt];
         for (int i = 0; i < colorCt; i++)
            palette[i] = colorPatch[i].getBackground().getRGB();
         return palette;
      }
   }
   
   public void actionPerformed(ActionEvent evt) {
      Object src = evt.getSource();
      if (src == defaultsButton)
          makeDefaultPalette();
      else if (src == grayscaleButton)
          makeGrayscalePalette();
      else if (src == whiteBrightButton)
          makeSpectrumPalette(true,1,1.0F);
      else if (src == blackBrightButton)
          makeSpectrumPalette(false,1,1.0F);
      else if (src == whiteDullButton)
          makeSpectrumPalette(true,1,0.65F);
      else if (src == blackDullButton)
         makeSpectrumPalette(false,1,0.65F);
      else if (src == whitePaleButton)
         makeSpectrumPalette(true,0.5F,1);
      else if (src == blackPaleButton)
         makeSpectrumPalette(false,0.5F,1);
      else if (src == cancelButton)
         dispose();
      else if (src == okButton) {
         canceled = false;
         hide();
      }
   }
   
   public void makeDefaultPalette() {
      int[] palette = WorldPane.makeStandardPalette(colorCt);
      for (int i = 0; i < colorCt; i++)
         colorPatch[i].setBackground(new Color(palette[i]));
   }
   
   public void makeGrayscalePalette() {
      for (int i = 0; i < colorCt; i++) {
         int g = (int)( 255 * ((double)i)/colorCt );
         int c = (g << 16) | (g << 8) | g;
         colorPatch[i].setBackground(new Color(c));
      }
   }
   
   public void makeSpectrumPalette(boolean whiteBackground, float saturation, float brightness) {
      colorPatch[0].setBackground( whiteBackground? Color.white : Color.black );
      for (int i = 1; i < colorCt; i++) {
         float h = ((float)(i-1)) / (colorCt - 1);
         colorPatch[i].setBackground(Color.getHSBColor(h,saturation,brightness));
      }
   }

}

