//
//		Color Picker  Copyright(C)1996. Masakazu Fujimiya
//		m-fujimiya@nri.co.jp
//

import java.awt.*;
import java.awt.event.*;
import netscape.javascript.*;
import java.lang.Integer;
import java.net.URL;
import java.net.MalformedURLException;

public class colorpicker extends java.applet.Applet implements ItemListener, TextListener
{
//    Color	fColor;
    int	cx,cy,cw,ch;
    int	xsep,ysep;
    int	px,py,sy;
    int	satx,saty,satw,sath;
    int	mainx,mainy,mainw,mainh;

    public float hValue,sValue,bValue;

    public boolean bDrag;

    int	pox[],poy[];
   
    float aHSB[];

    Image	offs;		// Offscreen image
    Graphics	grf;	// Offscreen graph port
    public ImageButton  ButtonOk;
    public ImageButton  ButtonApply;
    public ImageButton  ButtonCancel;
    public Checkbox CheckboxWebSafe;
    public TextField TextFieldRed, TextFieldGreen, TextFieldBlue;

    public Panel oRGBPanel;
    public Panel oButtonPanel;
    public Panel oPreviewPanel;
    public Panel oPalettePanel;
   
    Image okImages[];
    Image applyImages[];
    Image cancelImages[];
   

    ImageColorPalette oPal;
    ImageBrightnessPalette oBri;
    ImagePalettePreview oPrev;

    GridBagLayout layout;

    boolean bWebSafe;
    boolean bUpdateText;
   
    JSObject win;

    public int getRed()
    {
       // First convert RGB to HSB
       Integer oR = new Integer(TextFieldRed.getText());
       
       int nR = oR.intValue();

        if (bWebSafe==true)
         nR = ((nR+25) / 51) * 51;
       
        return nR;   
    }

    public int getGreen()
    {
       // First convert RGB to HSB
       Integer oG = new Integer(TextFieldGreen.getText());

       int nG = oG.intValue();

        if (bWebSafe==true)
         nG = ((nG+25) / 51) * 51;
       
        return nG;
    }
   
    public int getBlue()
    {
       // First convert RGB to HSB
       Integer oB = new Integer(TextFieldBlue.getText());
       
       int nB = oB.intValue();

        if (bWebSafe==true)
         nB = ((nB+25) / 51) * 51;
       
        return nB;
    }
   
    public void init()
    {
//       setBackground(Color.white);       
       
       bWebSafe = true;
       bUpdateText = true;
       
       pox = new int[4];
       poy = new int[4];

       //oPanel.setSize(size().width, size().height);

       layout = new GridBagLayout();
       setLayout(layout);
       GridBagConstraints c = new GridBagConstraints();

       cx = cy = 10; // margins

       cw = 1    ; ch = 2; // Width an height of eah pixel drawn
       
       xsep = 256 ; ysep = 64; // Number of pixel (width, height) drawn
       
       hValue = 1; sValue = 1; bValue = 1;

       satx = xsep*cw + cx*2;
       satw = cx*2;
       saty = cy;
       sath = ysep*ch;
       sy = saty + sath;
       mainx = px = cx;
       mainy = py = cy;
       mainw = xsep*cw;
       mainh = ysep*ch;

       oRGBPanel = new Panel();
       oRGBPanel.setLayout(new FlowLayout(FlowLayout.CENTER));

       TextFieldRed = new TextField(3);
       TextFieldRed.setText("255");
       oRGBPanel.add(new Label("R:"));
       oRGBPanel.add(TextFieldRed);

       TextFieldGreen = new TextField(3);
       TextFieldGreen.setText("255");       
       oRGBPanel.add(new Label("G:"));
       oRGBPanel.add(TextFieldGreen);

       TextFieldBlue = new TextField(3);
       TextFieldBlue.setText("255");       
       oRGBPanel.add(new Label("B:"));
       oRGBPanel.add(TextFieldBlue);

       c.fill = GridBagConstraints.BOTH;
       c.weightx = 0.0;
       c.gridwidth = GridBagConstraints.REMAINDER;
       c.gridheight= 1;
       layout.setConstraints(oRGBPanel, c);
       add(oRGBPanel);


       oPalettePanel = new Panel();
       oPalettePanel.setLayout(new FlowLayout(FlowLayout.CENTER));

       oPal = new ImageColorPalette(this, xsep, ysep, cw, ch);
       oPalettePanel.add(oPal);

       oBri = new ImageBrightnessPalette(this, 20, ysep, cw, ch);
       oPalettePanel.add(oBri);

       c.fill = GridBagConstraints.BOTH;
       c.weightx = 0.0;
       c.gridwidth = GridBagConstraints.REMAINDER;
       c.gridheight= 1;
       layout.setConstraints(oPalettePanel, c);
       add(oPalettePanel);

       oPreviewPanel = new Panel();
       oPreviewPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
       
       oPrev = new ImagePalettePreview(this, 250, 20);

       oPreviewPanel.add(oPrev);
       
       c.fill = GridBagConstraints.BOTH;
       c.weightx = 0.0;
       c.gridwidth = GridBagConstraints.REMAINDER;
       c.gridheight= 1;
       layout.setConstraints(oPreviewPanel, c);
       add(oPreviewPanel);

       // Create the buttons layout
       oButtonPanel = new Panel();
       oButtonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));

       try
       {
          okImages = new Image[3];
          okImages[0] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_ok_0.gif"));
          okImages[1] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_ok_1.gif"));
          okImages[2] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_ok_2.gif"));

          applyImages = new Image[3];
          applyImages[0] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_apply_0.gif"));
          applyImages[1] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_apply_1.gif"));
          applyImages[2] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_apply_2.gif"));

          cancelImages = new Image[3];
          cancelImages[0] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_cancel_0.gif"));
          cancelImages[1] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_cancel_1.gif"));
          cancelImages[2] = getImage(new URL(getCodeBase().toString() + "/images/icon_txt_cancel_2.gif"));

          try
          {
             MediaTracker tracker = new MediaTracker(this);
             tracker.addImage(okImages[0], 0);
             tracker.addImage(okImages[1], 1);
             tracker.addImage(okImages[2], 2);
             
             tracker.addImage(applyImages[0], 3);
             tracker.addImage(applyImages[1], 4);
             tracker.addImage(applyImages[2], 5);
             
             tracker.addImage(cancelImages[0], 6);
             tracker.addImage(cancelImages[1], 7);
             tracker.addImage(cancelImages[2], 8);             
             
             tracker.waitForAll();
          }   
          catch(Exception e)
          {
          }
       }
       catch(MalformedURLException e)
       {
       }
       
       ButtonOk = new ImageButton(okImages);
       oButtonPanel.add(ButtonOk);
       
       ButtonApply = new ImageButton(applyImages);
       oButtonPanel.add(ButtonApply);
       
       ButtonCancel = new ImageButton(cancelImages);
       oButtonPanel.add(ButtonCancel);

       CheckboxWebSafe = new Checkbox("Web Safe");
       oButtonPanel.add(CheckboxWebSafe);
       CheckboxWebSafe.setState(true);

       c.fill = GridBagConstraints.BOTH;
       c.weightx = 0.0;
       c.gridwidth = GridBagConstraints.REMAINDER;
       c.gridheight= 1;
       layout.setConstraints(oButtonPanel, c);
       add(oButtonPanel);
       
       CheckboxWebSafe.addItemListener(this);
       
       ButtonOk.addMouseListener(new MyMouseAdapter(this));
       ButtonApply.addMouseListener(new MyMouseAdapter(this));
       ButtonCancel.addMouseListener(new MyMouseAdapter(this));

       TextFieldRed.addTextListener(this);
       TextFieldGreen.addTextListener(this);
       TextFieldBlue.addTextListener(this);

       if (getParameter("DefaultRed") != null && getParameter("DefaultGreen") != null && getParameter("DefaultBlue") != null)
       {
          // First convert RGB to HSB
          Integer oR = new Integer(getParameter("DefaultRed"));
          Integer oG = new Integer(getParameter("DefaultGreen"));
          Integer oB = new Integer(getParameter("DefaultBlue"));
	    
          float hsb[] = Color.RGBtoHSB(oR.intValue(), oG.intValue(), oB.intValue(), null);

          hValue = hsb[0];
          sValue = hsb[1];
          bValue = hsb[2];
       }
       
       setHSBValue(hValue, sValue, bValue);

    }

    public void setHSBValue(float h, float s, float b)
    {
	if(h<0) 
	    hValue=0;
	else
	if(h>1) // 0.999
	    hValue=1;
	else
	    hValue=h;

	if(s<0) 
	    sValue=0;
	else
	if(s>1) // 0.995 
	    sValue=1;
	else
	    sValue=s;

	if(b<0) 
	    bValue=0;
	else
	if(b>1) 
	    bValue=1;
	else
	    bValue=b;

	/*
	 * Set TextField vals
	 */
	Color oColor = new Color(Color.HSBtoRGB(hValue, sValue, bValue));
       
	int nR = oColor.getRed();
	int nG = oColor.getGreen();
	int nB = oColor.getBlue();
				 
	if (bWebSafe)
	{
	    nR = ((nR+25) / 51) * 51;
	    nG = ((nG+25) / 51) * 51;
	    nB = ((nB+25) / 51) * 51;
	}

	String sHR = Integer.toString(nR);
	String sHG = Integer.toString(nG);
	String sHB = Integer.toString(nB);
	
        bUpdateText = false;
	TextFieldRed.setText(sHR);
	TextFieldGreen.setText(sHG);
	TextFieldBlue.setText(sHB);
        bUpdateText = true;       
    }

    public void paintPreview()
    {
/*       float	h,s,b;
       
       h = (float)hValue;
       s = (float)sValue;
       b = (float)bValue;
       
       Graphics oPreGrf = CanvasPreview.getGraphics();

       Color oColor = Color.getHSBColor(h, s, b);
       
       nR = oColor.getRed();
       nG = oColor.getGreen();
       nB = oColor.getBlue();
       
       if (bWebSafe)
       {
          nR = (nR / 51) * 51;
          nG = (nG / 51) * 51;
          nB = (nB / 51) * 51;
          
          oColor = new  Color(nR, nG, nB);
       }

       oPreGrf.setColor(oColor);
       oPreGrf.fill3DRect(0, 0, CanvasPreview.size().width, CanvasPreview.size().height, true);
*/
       /*
       int wk = col/256/256/256;
       col = col - wk;
       red = col/256/256;
       green = (col-red*256*256)/256;
       blue = col-red*256*256-green*256;

       wks = Integer.toString(255+red,16);
       if (wks.length()==1) wks = "0" + wks;
       outs = wks;
       wks = Integer.toString(255+green,16);
       if (wks.length()==1) wks = "0" + wks;
       outs = outs + wks;
       wks = Integer.toString(255+blue,16);
       if (wks.length()==1) wks = "0" + wks;
       outs = outs + wks;
       */
       
       
       /*
        * Draw Hex value in text.
        */
       /*
       g.clearRect(0, mainy+mainh+cy*3, size().width, 35);
       g.setColor(Color.black);

       String sHR = Integer.toHexString(nR);
       String sHG = Integer.toHexString(nG);
       String sHB = Integer.toHexString(nB);

       if (sHR.length() < 2)
         sHR = "0" + sHR;
       if (sHG.length() < 2)
         sHG = "0" + sHG;
       if (sHB.length() < 2)
         sHB = "0" + sHB;
       
       g.drawString("Hex value = " + sHR.toUpperCase() + sHG.toUpperCase() + sHB.toUpperCase(), mainx+5, mainy+mainh+cy*3+25);
       

       //g.drawString("Hex value = " + sHR.toUpperCase() + sHG.toUpperCase() + sHB.toUpperCase(), mainx+5, mainy+mainh+cy*3+25);
       //g.drawString("Color value = " + outs.toUpperCase(), mainx+5, mainy+mainh+cy*3+25);
       //g.drawString("RGB Value = " + nR + ", " + nG + ", " + nB, mainx+5, mainy+mainh+cy*3+25);
       */
    }
   
    public void itemStateChanged(ItemEvent e)
    {
       if (e.getStateChange() == ItemEvent.SELECTED) 
       {
            bWebSafe = true;

	    TextFieldRed.setEditable(false);
	    TextFieldGreen.setEditable(false);
	    TextFieldBlue.setEditable(false);
       }
       else
       {
            bWebSafe = false;

	    TextFieldRed.setEditable(true);
	    TextFieldGreen.setEditable(true);
	    TextFieldBlue.setEditable(true);
       }

       oPal.repaint();
       oBri.repaint();
       oPrev.repaint();
    }
   
    class MyMouseAdapter extends MouseAdapter
    {
       colorpicker oParent;

       MyMouseAdapter(colorpicker oTmpParent)
       {
          oParent = oTmpParent;
       }
       public void mouseClicked(MouseEvent e)
       {
          //System.out.println(szCommand);
          int r, g, b;
          Color oColor;

          oColor = new Color(Color.HSBtoRGB(hValue, sValue, bValue));
          r = oColor.getRed();
          g = oColor.getGreen();
          b = oColor.getBlue();

          if (bWebSafe)
          {
             r = ((r+25) / 51) * 51;
             g = ((g+25) / 51) * 51; 
             b = ((b+25) / 51) * 51;
          }

          String sHR = Integer.toHexString(r);
          String sHG = Integer.toHexString(g);
          String sHB = Integer.toHexString(b);

          if (sHR.length() < 2)
            sHR = "0" + sHR;
          if (sHG.length() < 2)
            sHG = "0" + sHG;
          if (sHB.length() < 2)
            sHB = "0" + sHB;

          try
          {
             win = JSObject.getWindow(oParent);

             if (win != null)
             {
                if (e.getComponent() == ButtonOk)
                {
                   win.eval("CallBackFunc(0)");
                }
                else
                if (e.getComponent() == ButtonApply)
                {
                   win.eval("CallBackFunc(1)");
                }
                else
                {
                   win.eval("CallBackFunc(2)");
                }
             }
          }
          catch( java.lang.ClassCastException ex )
          {
             System.err.println( "A parameter is not found");
          }
       }
       
    }
    
    public void textValueChanged(TextEvent e)
    {
       // First convert RGB to HSB
       Integer oR = new Integer(TextFieldRed.getText());
       Integer oG = new Integer(TextFieldGreen.getText());
       Integer oB = new Integer(TextFieldBlue.getText());
	    
       float hsb[] = Color.RGBtoHSB(oR.intValue(), oG.intValue(), oB.intValue(), null);
       
       int nR = oR.intValue();
       int nG = oG.intValue();
       int nB = oB.intValue();

       hValue = hsb[0];
       sValue = hsb[1];
       bValue = hsb[2];
	    
       oPal.repaint();
       oBri.repaint();
       oPrev.repaint();       
    }
}

class ImageColorPalette extends Canvas implements MouseMotionListener
{
    int nPixelWidth, nPixelHeight;
    int nWidth, nHeight;

    int nPosX, nPosY;

    int	pox[],poy[];

    Dimension oMinSize;

    colorpicker oParent;

    Image oImageColorPalette;

    ImageColorPalette(colorpicker oTmpParent, int nTmpWidth, int nTmpHeight, int nTmpPixelWidth, int nTmpPixelHeight)
    {
        pox = new int[4];
        poy = new int[4];

       oParent = oTmpParent;

       nWidth = nTmpWidth;
       nHeight = nTmpHeight;
	
       nPixelWidth = nTmpPixelWidth;
       nPixelHeight = nTmpPixelHeight;

       oMinSize = new Dimension(nWidth*nPixelWidth, nHeight*nPixelHeight);

       nPosX = 0;
       nPosY = 0;

       addMouseMotionListener(this);
       addMouseListener(new MyMouseAdapter());
    }

    public Dimension preferredSize()
    {
       return minimumSize();
    }

    public synchronized Dimension minimumSize()
    {
       return oMinSize;
    }

    public void update(Graphics g)
    {
       paint(g);
    }
   

    public void paint(Graphics g)
    {
       int	i,j;
       int	ix,iy;
       int	col;
       float	h,s,b;

       oImageColorPalette = createImage(size().width, size().height);
       Graphics oImgGrf = oImageColorPalette.getGraphics();

       for (i=0 ; i<nWidth ; i++) 
       {
          for (j=0 ; j<nHeight ; j++) 
	      {
             ix = i * nPixelWidth;
             iy = j * nPixelHeight;
             h = (float)i/(float)nWidth;
             s = (float)j/(float)nHeight;
             b = oParent.bValue;
             
             Color oColor = new Color(Color.HSBtoRGB(h, s, b));
       
             int nR = oColor.getRed();
             int nG = oColor.getGreen();
             int nB = oColor.getBlue();
       
             if (oParent.bWebSafe)
             {
                nR = ((nR+25) / 51) * 51;
                nG = ((nG+25) / 51) * 51;
                nB = ((nB+25) / 51) * 51;
          
                oColor = new  Color(nR, nG, nB);
             }
           
             oImgGrf.setColor(oColor);
             oImgGrf.fillRect(ix,iy,nPixelWidth,nPixelHeight);
          }
       }
	
       g.drawImage(oImageColorPalette, 0, 0, this);


       g.setColor(Color.yellow);
       g.drawRect(nPosX-1,nPosY-1,2,2);
       g.setColor(Color.blue);
       g.drawRect(nPosX-2,nPosY-2,4,4);

       oParent.paintPreview();
    }

    public void mouseDragged(MouseEvent e)
    {
       oParent.setHSBValue((float)e.getX()/(float)(nWidth*nPixelWidth), (float)e.getY()/(float)(nHeight*nPixelHeight), oParent.bValue);

       nPosX = e.getX();
       nPosY = e.getY();

       if (nPosX < 0)
         nPosX = 0;
       if (nPosX > (nWidth*nPixelWidth))
         nPosX = (nWidth*nPixelWidth);

       if (nPosY < 0)
         nPosY = 0;
       if (nPosY > (nHeight*nPixelHeight))
         nPosY = (nHeight*nPixelHeight);

       //	paintValue(getGraphics());
    }

    public void mouseMoved(MouseEvent e)
    {
       // do nothiung
    }

    class MyMouseAdapter extends MouseAdapter
    {
       public void mouseClicked(MouseEvent e)
       {
          mouseDragged(e);
       }
    }
}

class ImageBrightnessPalette extends Canvas implements MouseMotionListener
{
    int nPixelWidth, nPixelHeight;
    int nWidth, nHeight;
    int nPosX, nPosY;

    int	pox[],poy[];

    Dimension oMinSize;

    colorpicker oParent;

    Image oImageBrightnessPalette;

    ImageBrightnessPalette(colorpicker oTmpParent, int nTmpWidth, int nTmpHeight, int nTmpPixelWidth, int nTmpPixelHeight)
    {
        pox = new int[4];
        poy = new int[4];
 
       oParent = oTmpParent;

       nWidth = nTmpWidth;
       nHeight = nTmpHeight;
	
       nPixelWidth = nTmpPixelWidth;
       nPixelHeight = nTmpPixelHeight;

       oMinSize = new Dimension(nWidth*nPixelWidth+5, nHeight*nPixelHeight);

       nPosY = nHeight*nPixelHeight;

       addMouseMotionListener(this);
       addMouseListener(new MyMouseAdapter());
    }

    public Dimension preferredSize()
    {
       return minimumSize();
    }

    public synchronized Dimension minimumSize()
    {
       return oMinSize;
    }

    public void update(Graphics g)
    {
       paint(g);
    }
   
    public void paint(Graphics g)
    {
       float	h,s,b;
       int	ix,iy,i,j;

       oImageBrightnessPalette = createImage(size().width, size().height);
       Graphics oImgGrf = oImageBrightnessPalette.getGraphics();

       /*
        * Draw Right palette
        */
       for (j=0 ; j<nHeight; j++) 
       {
          iy = j * nPixelHeight;
          h = oParent.hValue;
          s = oParent.sValue;
          b = (float)j/(float)nHeight;
       
          Color oColor = new Color(Color.HSBtoRGB(h, s, b));
       
          int nR = oColor.getRed();
          int nG = oColor.getGreen();
          int nB = oColor.getBlue();
          
          if (oParent.bWebSafe)
	      {
             nR = ((nR+25) / 51) * 51;
             nG = ((nG+25) / 51) * 51;
             nB = ((nB+25) / 51) * 51;
             
             oColor = new  Color(nR, nG, nB);
          }       
       
          oImgGrf.setColor(oColor);
          oImgGrf.fillRect(0,iy,20,nPixelHeight);
       }

       g.drawImage(oImageBrightnessPalette, 0, 0, this);

       pox[0] = pox[3] = nWidth*nPixelWidth;
       poy[0] = poy[3] = nPosY;
       pox[1] = pox[2] = pox[0] + 4;
       poy[1] = poy[0] + 4;
       poy[2] = poy[0] - 4;
       g.setColor(Color.yellow);
       g.fillPolygon(pox, poy, 3);
       g.setColor(Color.blue);
       g.drawPolygon(pox, poy, 4);
       
       oParent.paintPreview();
    }
    
    public void mouseDragged(MouseEvent e)
    {
       oParent.setHSBValue(oParent.hValue, oParent.sValue, (float)e.getY()/(float)(nHeight*nPixelHeight));

       nPosY = e.getY();

       if (nPosY < 0)
         nPosY = 0;
       if (nPosY > (nHeight*nPixelHeight))
         nPosY = (nHeight*nPixelHeight);
    }

    public void mouseMoved(MouseEvent e)
    {
       // Do nothing
    }

    class MyMouseAdapter extends MouseAdapter
    {
       public void mouseClicked(MouseEvent e)
       {
          mouseDragged(e);
       }
    }
}

class ImagePalettePreview extends Canvas
{
    int nWidth, nHeight;

    Dimension oMinSize;

    colorpicker oParent;

    Image oImagePalettePreview;

    ImagePalettePreview(colorpicker oTmpParent, int nTmpWidth, int nTmpHeight)
    {
       oParent = oTmpParent;

       nWidth = nTmpWidth;
       nHeight = nTmpHeight;
	
       oMinSize = new Dimension(nWidth, nHeight);
    }

    public Dimension preferredSize()
    {
       return minimumSize();
    }

    public synchronized Dimension minimumSize()
    {
       return oMinSize;
    }

    public void update(Graphics g)
    {
       paint(g);
    }
   
    public void paint(Graphics g)
    {
       float	h,s,b;

       h = oParent.hValue;
       s = oParent.sValue;
       b = oParent.bValue;

       oImagePalettePreview = createImage(nWidth, nHeight);
       Graphics oPreGrf = oImagePalettePreview.getGraphics();

       Color oColor = new Color(Color.HSBtoRGB(h, s, b));
       
       int nR = oColor.getRed();
       int nG = oColor.getGreen();
       int nB = oColor.getBlue();
       
       if (oParent.bWebSafe)
       {
          nR = ((nR+25) / 51) * 51;
          nG = ((nG+25) / 51) * 51;
          nB = ((nB+25) / 51) * 51;

          oColor = new  Color(nR, nG, nB);
       }

       g.setColor(oColor);
       g.fill3DRect(0, 0, nWidth, nHeight, true);
    }
}
