/*
 Javier Kohen's Java Framework Classes.
 Copyright (C) 2000-2001  Javier Kohen <jkohen at tough.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 package ar.com.jkohen.awt;
 
 import java.awt.*;
 import java.awt.event.*;
 import java.io.IOException;
 import java.util.Vector;
 
 import ar.com.jkohen.awt.TextFieldHistory;
 import ar.com.jkohen.irc.MircMessage;
 import ar.com.jkohen.util.Resources;
 import com.splendid.awtchat.SmileyTextArea;
 
 public class TextAttributePicker extends Dialog implements KeyListener, MouseListener, MouseMotionListener
 {
 	private TextField tf;
 
 	private int current_foreground = 0;
 
 	private static Vector items;
 	private static int order[];
 	private String action_command;
 
 	private Dimension item_size;
 	private Dimension disposition;
 	private Dimension gap;
 
 	private Image image;
 	private Graphics img_gfx;
 
 	public TextAttributePicker(Frame f, TextField tf, Dimension disposition, Dimension item_size, Dimension gap)
 	{
 		super(f);
 		this.tf = tf;
 		
 		Color colors[] = SmileyTextArea.getColorPalette();
 /*
 		GridBagLayout gb = new GridBagLayout();
 		GridBagConstraints gbc = new GridBagConstraints();
 
 		setLayout(gb);
 
 		reset = new ImageButton(false);
 		reset.setIcon(Resources.getImage("picker.regular"));
 	 	add(reset);
 
 		bold = new ImageButton(false);
 		bold.setIcon(Resources.getImage("picker.bold"));
 		add(bold);
 
 		under = new ImageButton(false);
 		under.setIcon(Resources.getImage("picker.under"));
 		add(under);
 
 		italic = new ImageButton(false);
 		italic.setIcon(Resources.getImage("picker.italic"));
 		add(italic);
 
 		reverse = new ImageButton(false);
 		reverse.setIcon(Resources.getImage("picker.reverse"));
 		add(reverse);
 		
 		gbc.weightx = 1.0;
 		gb.setConstraints((Component) color_picker, gbc);
 		add((Component) color_picker);
 */
 		this.disposition = disposition;
 		this.item_size = item_size;
 		this.gap = gap;
 		this.action_command = "";
 
 //		this.items = new Vector(colors.length);

 //		setColors(colors);

 
 		/* Event listeners.
 		 */
 /*
 		reset.addActionListener(this);
 		bold.addActionListener(this);
 		under.addActionListener(this);
 		italic.addActionListener(this);
 		reverse.addActionListener(this);
 		color_picker.addActionListener(this);
 */
 		addMouseListener(this);
 		addMouseMotionListener(this);
 		addKeyListener(this);
 		
 		setBackground(f.getBackground());
 		
 		pack();
 		setResizable(false);
 		setVisible(true);
 		requestFocus();
 	}
 
 	public void setTextField(TextField tf)
 	{
 		this.tf = tf;
 	}
 	
 	public Color [] getColors()
 	{
 		Color [] colors = new Color [items.size()];
 		items.copyInto(colors);
 
 		return(colors);
 	}
 
 	public static void setColors(Color [] colors)
 	{
 		items = new Vector(colors.length);
 		items.removeAllElements();
 
 		for (int i = 0; i < colors.length; i++)
 			items.addElement(colors[i]);
 	}
 
 	public static void setOrder(int o[])
 	{
 		order = o;
 		Vector v = new Vector(o.length);
 		for (int i = 0; i < o.length; i++)
 			v.addElement(items.elementAt(i));
 
 		for (int i = 0; i < o.length; i++)
 			items.setElementAt(v.elementAt(i), o[i]);
 	}
 /*	
 	public void actionPerformed(ActionEvent ev)
 	{
 		Object source = ev.getSource();
 		String text_attr = "";
 
 		System.out.println(source.toString());
 		
 		if (source.equals(this))
 		{
 			Color c = getSelected();
 			int ci = getSelectedIndex();
 //			int ci = c.getRGB();
 			int modifiers = ev.getModifiers();
 
 			if ((MouseEvent.BUTTON1_MASK & modifiers) != 0 || modifiers == 0)
 			{
 				// WORKAROUND: #32 Netscape Navigator doesn't set it right for BUTTON1.
 				text_attr = String.valueOf(ci);
 				current_foreground = ci;
 			}
 			else if ((MouseEvent.BUTTON3_MASK & modifiers) != 0)
 			{
 				text_attr = current_foreground + "," + ci;
 			}
 		}
 		else if (source.equals(bold))
 		{
 		   	text_attr = MircMessage.attrEncode(MircMessage.BOLD);
 		}
 		else if (source.equals(under))
 		{
 		   	text_attr = MircMessage.attrEncode(MircMessage.UNDERLINE);
 		}
 		else if	(source.equals(italic))
 		{
 	 	   text_attr = MircMessage.attrEncode(MircMessage.ITALIC);
 		}
 		else if (source.equals(reset))
 		{
 			text_attr = MircMessage.attrEncode(MircMessage.RESET);
 		}
 		else if (source.equals(reverse))
 		{
 			text_attr = MircMessage.attrEncode(MircMessage.REVERSE);
 		}
 		
 		processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, text_attr, ev.getModifiers()));
 	}
 */	
 	public void setBackground(Color c)
 	{
 		super.setBackground(c);
 /*
 		reset.repaint();
 		bold.repaint();
 		under.repaint();
 		italic.repaint();
 		reverse.repaint();
 */
 		repaint();
 	}
 
 	public Dimension getItemSize()
 	{
 		return(item_size);
 	}
 
 	public void setItemSize(Dimension d)
 	{
 		item_size.setSize(d.width, d.height);
 	}
 
 	public Dimension getDisposition()
 	{
 		return disposition;
 	}
 
 	protected Dimension getRealDisposition()
 	{
 		Dimension r = disposition;
 
 		if (r.width == 0 && r.height == 0)
 		{
 			r.width = r.height = (int) Math.sqrt(items.size() - 1) + 1;
 		}
 		else if (r.width == 0)
 		{
 			r.width = (items.size() - 1) / r.height + 1;
 		}
 		else if (r.height == 0)
 		{
 			r.height = (items.size() - 1) / r.width + 1;
 		}
 
 		return(r);
 	}
 
 	public void setDisposition(Dimension d)
 	{
 		disposition.setSize(d.width, d.height);
 	}
 
 	public Dimension getGap()
 	{
 		return(gap);
 	}
 
 	public void setGap(Dimension d)
 	{
 		gap.setSize(d.width, d.height);
 	}
 
 	/**
 	 * If <code>gap</code> is big enough, user will notice this method is not exact.
 	 */
 	private int getItemAt(Point p)
 	{
 		Dimension real = getRealDisposition();
 
 		int i = p.x / (item_size.width + gap.width);
 		int j = p.y / (item_size.height + gap.height);
 
 		int index = ((i * real.height + j) - 1);
 		
 		for (int k = 0; k < order.length; k++)
 			if (index == order[k])
 				return(k);
 				
 		return(-1);
 	}
 /*
 	public int getSelectedIndex()
 	{
 		return last_selected;
 	}
 
 	public void setSelectedIndex(int i)
 	{
 		this.last_selected = i;
 	}
 
 	public Color getSelected()
 	{
 		return (Color) items.elementAt(last_selected);
 	}
 
 	public void setSelected(Color c)
 	{
 		this.last_selected = items.indexOf(c);
 	}
 */
 
 
 	private void createImageBuffer(Dimension size)
 	{
 		image = createImage(size.width, size.height);
 		if (img_gfx != null)
 			img_gfx.dispose();
 
 		img_gfx = image.getGraphics();
    	}
 
 	public void update(Graphics g)
 	{
 		paint(g);
 	}
 
 	public void paint(Graphics g)
 	{
 		Dimension size = getSize();
 
 		if (img_gfx == null || image.getWidth(this) != size.width || image.getHeight(this) != size.height)
 			createImageBuffer(size);
 
 		Dimension real_disposition = getRealDisposition();
 		int x = 0, y = 0;
 /*
 		for (int i = 0; i < real_disposition.width; i++)
 		{
 			y = 0;
 			
 			for (int j = 0; j < real_disposition.height; j++)
 			{
 				int index = i * real_disposition.height + j;
 				if (index >= 5)
 					break;
 			
 				img_gfx.setColor(Color.black);
 				img_gfx.fillRect(x + 2, y + 2, item_size.width - 2, item_size.height - 2);
 				img_gfx.setColor(Color.white);
 				img_gfx.fillRect(x, y, item_size.width - 1, item_size.height - 1);
 				img_gfx.setColor(Color.black);
 				img_gfx.drawString("A", x + 2, y + getFont().getSize());
 				
 				y += gap.height + item_size.height;
 			}
 			x += gap.width + item_size.width;
 		}
 
 		x = 0;
 */
 		for (int i = 0; i < real_disposition.width; i++)
 		{
 //			y = gap.height + item_size.height;

 			y = 0;
 
 			for (int j = 0; j < real_disposition.height; j++)
 			{
 				int index = i * real_disposition.height + j;
 				if (index >= items.size())
 					break;
 
 				img_gfx.setColor(Color.black);
 				img_gfx.fillRect(x + 2, y + 2, item_size.width - 2, item_size.height - 2);
 				
 				img_gfx.setColor((Color) items.elementAt(index));
 				img_gfx.fillRect(x, y, item_size.width - 1, item_size.height - 1);
 				
 				if (index <= 9)
 					index += 0x30;
 				else
 					index += 0x37;
 				img_gfx.setColor(new Color(0xCC, 0xCC, 0xCC));
 				img_gfx.drawString(String.valueOf((char)index), x + 2, y + getFont().getSize());
 
 				y += gap.height + item_size.height;
 			}
 	   		x += gap.width + item_size.width;
 		}
 		
 	   	g.drawImage(image, getInsets().left, getInsets().top, this);
 	}
 
 	public String getActionCommand()
 	{
 		return action_command;
 	}
 
 	public void setActionCommand(String action)
 	{
 		this.action_command = action;
 	}
 	
 	public void keyPressed(KeyEvent ev)
 	{
 		char ch = Character.toUpperCase(ev.getKeyChar());
    		if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F'))
 		{
 			if (ch <= '9')
 				ch -= 0x30;
 			else
 				ch -= 0x37;
 				
 			int index = 1;
 			for (int k = 0; k < order.length; k++)
 				if (ch == order[k])
 					index = k;
 				
 			setActionCommand(String.valueOf(index));
 			TextFieldHistory tfh = (TextFieldHistory)tf;
 			if (tfh != null)
 				tfh.insert(MircMessage.COLOR + action_command);
 				
 			return;
 		}
 		
 		dispose();
 	}
 	
 	public void keyReleased(KeyEvent e)
 	{
 	}
 
 	public void keyTyped(KeyEvent e)
 	{
 	}
 
 	public void mouseDragged(MouseEvent ev)
 	{
 	}
 	
 	public void mouseMoved(MouseEvent ev)
 	{
 		if(getItemAt(ev.getPoint()) >= 0)
 			setCursor(new Cursor(Cursor.HAND_CURSOR));
 		else
 			setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 	}
 	
 	public void mouseClicked(MouseEvent ev)
 	{
 	}
 
 	public void mousePressed(MouseEvent ev)
 	{
 	}
 
 	public void mouseReleased(MouseEvent ev)
 	{
 		int index = getItemAt(ev.getPoint());
 		if (index == -1)
 			return;
 			
 		if ((ev.getModifiers() & MouseEvent.BUTTON3_MASK) == 0)
 			setActionCommand(String.valueOf(index));
 			
 		if ((ev.getModifiers() & MouseEvent.BUTTON3_MASK) != 0)
 			setActionCommand(0 + "," + index);
 
 		TextFieldHistory tfh = (TextFieldHistory)tf;
 		if (tfh != null)
 			tfh.insert(MircMessage.COLOR + action_command);
 		
 //		processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, action_command, ev.getModifiers()));

 
 		// Avoid taking mouse focus.

 		ev.consume();
    }
 
 	public void mouseEntered(MouseEvent ev)
 	{
 	}
 
 	public void mouseExited(MouseEvent ev)
 	{
 		setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 	}
 
 	public void setVisible(boolean b)
 	{
 		if (b)
 			setLocation(new Point(tf.getLocationOnScreen().x, tf.getLocationOnScreen().y + tf.getSize().height));
 			
 		super.setVisible(b);
 	}
 	
 	public Insets getInsets()
 	{
 		Insets i = super.getInsets();
 		return (new Insets(i.top + 2, i.left + 2, i.bottom + 2, i.right + 2));
 	}
 	
 	public Dimension getMinimumSize()
 	{
 		return getPreferredSize();
 	}
 
 	public Dimension getPreferredSize()
 	{
 		Dimension real = getRealDisposition();
 		Insets insets = getInsets();
 		int attributes_height = item_size.height + gap.height;
 
 		return(new Dimension(insets.left + insets.right + (item_size.width * real.width) + gap.width * (real.width - 1), insets.top + insets.bottom + (item_size.height * real.height) + gap.height * (real.height - 1)));
 	}
 }