/***********************************************************************
 * ColorBrowserApplet.java - Source Code (requires java 1.1)           *
 * Version release date : January 20, 2001                             *
 * Copyright (C) 2000-2001  Neural Semantics sprl, Belgium             *
 * Author : Michel Petre mpetre@neuralsemantics.com                    *
 *                                                                     *
 *     http://www.neuralsemantics.com/                                 *
 *                                                                     *
 * This code is released under GNU GPL license, version 2 or later.    *
 *                                                                     *
 *   This notice must remain intact in all copies of this code.        * 
 *   This code is distributed WITHOUT ANY WARRANTY OF ANY KIND.        *
 *   The GNU GPL license can be found at :                             *
 *           http://www.gnu.org/copyleft/gpl.html                      *
 *                                                                     *
 * Feel free to use any portion of this code for your best purposes.   *
 ***********************************************************************/

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.PixelGrabber;

public class ColorBrowserApplet extends Applet 
                                implements Runnable, MouseListener {

  // Line separator char
  final static String lsep = System.getProperty("line.separator");

  // Default background color
  Color bgcolor = Color.lightGray;
  // Currently selected pixel color
  Color pixColor;

  Dimension dim;
  Image img, image;
  Graphics graph;

  Canvas canvas;
  TextField fieldColor, fieldRGB, fieldHex;

  // Image display thread
  Thread runner;

//**********************************************************************
//                          Constructors
//**********************************************************************
  public ColorBrowserApplet() { }

//**********************************************************************
//                             Methods
//**********************************************************************
  public void init() {
    String s = getParameter("image");
    Image im = null;
    if (s != null)
      im = getImage(getDocumentBase(), getParameter("image"));
    if (im != null)
      this.loadImage(im);
    this.compose();
    repaint();
  }
//------------------------------------------------------------------------
  public void compose() {
    fieldColor = new TextField(4);
      fieldColor.setEditable(false);
      fieldColor.setBackground(Color.lightGray);
      fieldColor.setFont(new Font("Dialog", Font.PLAIN, 18));

    fieldRGB = new TextField(16);
      fieldRGB.setEditable(false);
      fieldRGB.setBackground(Color.lightGray);

    fieldHex = new TextField(10);
      fieldHex.setEditable(false);
      fieldHex.setBackground(Color.lightGray);

    Panel control = new Panel();
    control.setLayout(new FlowLayout(FlowLayout.CENTER, 30, 10));
    control.setBackground(Color.darkGray);
    control.add(fieldColor);
    control.add(fieldRGB);
    control.add(fieldHex);

    canvas = new Canvas();
    canvas.addMouseListener(this);

    setLayout(new BorderLayout());
    add("Center", canvas);
    add("South", control);
  }
//------------------------------------------------------------------------
  public boolean loadImage(Image im) {
    MediaTracker tracker = new MediaTracker(this);
    try {
      tracker.addImage(im, 0);
      tracker.waitForID(0);
      if ((im.getWidth(this) <= 0) || (im.getHeight(this) <= 0))
        return false;
      img = im;
      image = null;
      return true;
    }
    catch (Exception e) { }
    return false;
  }
//------------------------------------------------------------------------
  private Color getPixelColor(Image im, int x, int y) {
    // returns a Color object from pixel(x,y)
    int[] pix = new int[1];
    PixelGrabber pg = new PixelGrabber(im, x, y, 1, 1, pix, 0, 0);
    try { 
      pg.grabPixels(); 
    } 
    catch (InterruptedException e) { }
    return new Color((pix[0]>>16)&0xff, (pix[0]>>8)&0xff, (pix[0])&0xff);
  }

//**********************************************************************
//                               Thread
//**********************************************************************
  public void start() {
    // create thread
    if (runner == null) {
      runner = new Thread(this);
      runner.start();
    }
  }
//------------------------------------------------------------------------
  public void run() {
    // infinite loop
    while (true) {
      repaint();
      // let the computer breath
      try { Thread.sleep(200); }
      catch (InterruptedException e) { }
    }
  }
//------------------------------------------------------------------------
  public void stop() {
    this.cleanup();
  }
//------------------------------------------------------------------------
  public void destroy() {
    this.cleanup();
  }
//------------------------------------------------------------------------
  private synchronized void cleanup() {
    // kill the runner thread
    if (runner != null) {
      try {
        runner.stop();
        runner.join();
        runner = null;
      }
      catch(Exception e) { }
    }
  }

//**********************************************************************
//                     MouseListener Interface
//**********************************************************************
  public void mouseClicked(MouseEvent e) {
  }
//----------------------------------------------------------------------
  public void mouseEntered(MouseEvent e) {
  }
//----------------------------------------------------------------------
  public void mouseExited(MouseEvent e) {
  }
//----------------------------------------------------------------------
  public void mousePressed(MouseEvent e) {
    Object source = e.getSource();
    if (image != null) {
      pixColor = this.getPixelColor(image, (int)e.getX(), (int)e.getY());

      int r = pixColor.getRed();
      int g = pixColor.getGreen();
      int b = pixColor.getBlue();

      fieldColor.setBackground(pixColor);
      fieldRGB.setText("RGB = (" + r + ":" + g + ":" + b + ")");

      String sHex = Integer.toHexString(pixColor.getRGB()).toUpperCase();
      if (sHex.length() > 6)
        sHex = sHex.substring(sHex.length() - 6);
      if (sHex.length() < 6) {
        String sZero = "000000";
        sHex = sZero.substring(6 - sHex.length()) + sHex;
      }
      fieldHex.setText("#" + sHex);
    }
    repaint();
    e.consume();
  }
//----------------------------------------------------------------------
  public void mouseReleased(MouseEvent e) {
  }

//**********************************************************************
//                              Painting
//**********************************************************************
  public void paint(Graphics g) {
    Graphics canvasGraph = canvas.getGraphics();
    Dimension d = canvas.getSize();
    if ((d.width > 0) & (d.height > 0)) {
      if (img == null) {
        canvasGraph.setColor(bgcolor);
        canvasGraph.fillRect(0, 0, d.width, d.height);
        return;
      }
      if (image == null || d.width != dim.width || d.height != dim.height) {
        image = createImage(d.width, d.height);
        graph = image.getGraphics();
        graph.drawImage(img, 0, 0, d.width, d.height, bgcolor, null);
        dim = d;
      }
      // canvas painting
      if (canvasGraph != null) {
        canvasGraph.drawImage(image, 0, 0, d.width, d.height, bgcolor, this);
        canvasGraph.dispose();
      }
    }
  }

//**********************************************************************
//                             Applet info
//**********************************************************************
  public String getAppletInfo(){
    String s = "Quick Color Browser" + lsep + lsep +
               "A simple color viewer" + lsep +
               "Copyright (c) Neural Semantics, 2001" + lsep + lsep +
               "Home page : http://www.neuralsemantics.com/";
    return s;
  }
}