/**
 * @(#)ColorCEC.java
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 * RID-3 : Color Cell Editor Component
 * @author  Intelligent Technology Inc.
 * @version 1.00 2001/10/01-2002/03/26
 * @see iCellEditorComponent
 */
package	jp.co.nri.rid.table.editor;

import	java.awt.*;
import	java.awt.event.*;
import	javax.swing.*;
import	javax.swing.text.*;
import	javax.swing.event.*;
import	jp.co.iti.fagot.util.*;

/**
 * 色を選択するためのセルエディタ/レンダラコンポーネント
 */
public class ColorCEC extends JPanel implements iCellEditorComponent,FocusListener{
	private JButton		myButton;
	private JTextField	myTextField;
	
	/**
	 * @param	editable	編集可否。
	 * @param	listener	アクションリスナー。
	 * @since	1.00
	 */
	public ColorCEC(boolean editable ,ActionListener listener){
		super(new BorderLayout());
		myButton = new JButton("...");
		myButton.addActionListener(listener);
		myButton.addActionListener(new actionChoose(this));
		myTextField = new JTextField();
		myTextField.setBorder(null);
//		myTextField.getDocument().addDocumentListener(new ColorDocumentAdapter(listener));
		myTextField.addActionListener(listener);
		if(listener instanceof CECAdapter)	((CECAdapter)listener).editor(this);
		editable(editable);
		
		add(myTextField ,BorderLayout.CENTER);
		add(myButton ,BorderLayout.EAST);
		
		addFocusListener(this);
	}
	
	/**
	 * セル値(String)を取得する。
	 * @return	セル値。
	 * @since	1.00
	 */
	public String	text(){ return myTextField.getText(); }
	
	/**
	 * セル値を設定する。
	 * @param	text	セル値。
	 * @since	1.00
	 */
	public void		text(String text){
		int	color = 0;
		try{ color = hex(text); }
		catch(java.lang.NumberFormatException e){ text = null; }
		ButtonColor(color);
		
		if(null==text)	myTextField.setText(null);
		else			myTextField.setText(text);
//		else			myTextField.setText(text(color(color)));
	}
	
	/**
	 * エディタコンポーネントを取得する。
	 * @return	エディタコンポーネント。
	 * @since	1.00
	 */
	public JComponent	component(){		return this; }
	
	/**
	 * テキストフィールドコンポーネントを取得する。
	 * @return	テキストフィールドコンポーネント。
	 * @since	1.00
	 */
	public JTextField	getTextField(){		return myTextField; }
	public void			ButtonColor(int color){
		myButton.setBackground(color(color));
		myButton.setForeground(color(0xffffff - color));
	};
	
	/**
	 * int色情報をColorクラスに変換する。
	 * @param	color	int型色情報。
	 * @return	Colorオブジェクト。
	 * @since	1.00
	 */
	public Color color(int color){
		int red   = 0xff & (color >>> 16);
		int green = 0xff & (color >>>  8);
		int brue  = 0xff & color;
		return new Color(red,green,brue);
	}
	
	private Color color(String text){
		int color = 0;
		try{ color = hex(text); }
		catch(java.lang.NumberFormatException e){}
		return color(color);
	}
	
	/**
	 * Colorクラスを文字列に変換する。
	 * @param	color	Colorオブジェクト。
	 * @return	色文字列。
	 * @since	1.00
	 */
	public String text(Color color){
		if(null==color)	return null;
		int red		=  (0xff & color.getRed())		<< 16;
		int green	=  (0xff & color.getGreen())	<<  8;
		int blue	=  0xff & color.getBlue();
		
		int value = red | green | blue;
		
		return "#" + hex(value ,6);
	}
	
	/**
	 * 文字列を16進数としてint型に変換する。
	 * @param	text	文字列。
	 * @return	変換した数値。
	 * @since	1.00
	 */
	public int hex(String text) throws java.lang.NumberFormatException {
		if(null==text)	return 0;
/*
		String trimtext = text.trim();
		if(0>=trimtext.length())	return 0;
		if(7<trimtext.length())		return 0;
		StringBuffer buffer = new StringBuffer(trimtext);
		if('#' == buffer.charAt(0))	buffer.deleteCharAt(0);
//		else{ if(6<buffer.length())	return 0; }
		else	return 0;
*/
		if(0>=text.length())	return 0;
		StringBuffer buffer = new StringBuffer(text);
		if('#' != buffer.charAt(0))	return 0;
		buffer.deleteCharAt(0);
		for(int i=buffer.length()-1;0<=i;i--){
			char c = buffer.charAt(i);
			if(('0' <= c) && ('9' >= c))	continue;
			if(('A' <= c) && ('F' >= c))	continue;
			if(('a' <= c) && ('f' >= c))	continue;
//			buffer.deleteCharAt(i);
			return 0;
		}
		int hex = Integer.parseInt(new String(buffer) ,16);

		switch(text.length()){
			case 7:
				return hex;
			case 4:
				int r = hex >> 8;
				int g = (hex >> 4) & 0xf;
				int b = hex & 0xf;
				return (r << 20) | (g << 12) | (b << 4);
			default:
				return 0;
		}
	}
	
	private String hex(int hex ,int length){
		String zero = "00000000";
		
		if(zero.length() < length)	length = zero.length();
		String text = Integer.toHexString(hex);
		int zerolength = length - text.length();
		if(0 >= zerolength)	return text;
		return zero.substring(0,zerolength) + text;
	}
	
	/**
	 * 実装の都合上publicとなっているが、使用しないこと。
	 * @since	1.00
	 */
	public void	focus(boolean hasFocus ,JTable table){
		if(hasFocus){
//			myButton.setForeground(table.getSelectionForeground());
//			myButton.setBackground(table.getSelectionBackground());
			myTextField.setForeground(table.getSelectionForeground());
			myTextField.setBackground(table.getSelectionBackground());
		}
		
		else{
//			myButton.setBackground(color(color));
//			myButton.setForeground(color(0xffffff - color));
			myTextField.setBackground(table.getBackground());
			myTextField.setForeground(table.getForeground());
		}
	}
	
	/**
	 * 編集可否を設定する。
	 * @param	editable	true:編集可 false:編集不可。
	 * @since	1.00
	 */
	public void editable(boolean editable){ setEnabled(editable); }
	
	protected class actionChoose implements ActionListener{
		protected ColorCEC myCEC;
		public actionChoose(ColorCEC cec){ myCEC = cec; }
		public void actionPerformed(ActionEvent evt){
			exColorChooser	chooser	= new exColorChooser();
			Color color = chooser.exshow(myCEC ,"color" ,color(myCEC.text()));
//			Color color = JColorChooser.showDialog(myButton ,"color" ,color(myButton.getText()));
			if(null==color)	return;
			myCEC.text(text(color));
		}
	}
	
	protected class exColorChooser extends JColorChooser implements ActionListener{
		private	Color color;
		public Color exshow(Component c, String title ,Color col){
			JDialog dlg = JColorChooser.createDialog(c ,title ,true ,this ,this ,null);
			setColor(col);
			dlg.setLocationRelativeTo(null);
			color = null;
			dlg.show();
			return color;
		}
		public void actionPerformed(ActionEvent evt){	color = getColor();	}
	}
	
	/**
	 * 実装の都合上publicとなっているが、使用しないこと。
	 * @since	1.00
	 */
	public void focusGained(FocusEvent e){ myTextField.requestFocus(); }
	/**
	 * 実装の都合上publicとなっているが、使用しないこと。
	 * @since	1.00
	 */
	public void focusLost(FocusEvent e){}
	
/*
	private class ColorDocumentAdapter implements DocumentListener{
		protected ActionListener myAdapter;
		public ColorDocumentAdapter(ActionListener adapter){ myAdapter = adapter; }
		
		public void insertUpdate(DocumentEvent e){update(e.getDocument());}
		public void removeUpdate(DocumentEvent e){update(e.getDocument());}
		public void changedUpdate(DocumentEvent e){update(e.getDocument());}
		private void update(Document doc){
			String text = text();
			if(null==text)	return;
			int length = text.length();
			
			switch(length){
			case	7:
				if(!text.startsWith("#"))	return;
				break;
			case	6:
				if(text.startsWith("#"))	return;
				break;
			default:
				return;
			}
			
			myAdapter.actionPerformed(null);
		}
	}
*/
}
