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

import java.awt.Component;
import java.util.EventObject;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

import jp.co.nri.rid.xml.*;
import jp.co.nri.rid.table.*;
import	jp.co.iti.fagot.util.*;

/**
 * RTable用のセルエディタ／レンダラ
 */
public class RCellEditor implements TableCellEditor,TableCellRenderer{
	
	protected	EventListenerList		listenerList;
	protected	ChangeEvent				changeEvent;
	protected	iCellEditorComponent	myComponent;
	private		boolean					myEditable = true;
	
	/**
	 * @param	type		エディタタイプ記述文字列。
	 * @param	editable	編集可否。
	 * @since	1.00
	 */
	public RCellEditor(String type ,boolean editable){
		myEditable = editable;
		init(type ,true ,new StopEditingListener(this));
	}
	
	/**
	 * @param	type		エディタタイプ記述文字列。
	 * @param	editable	編集可否。
	 * @param	listener	アクションリスナー。
	 * @since	1.00
	 */
	public RCellEditor(String type ,boolean editable ,ActionListener listener){ init(type ,editable ,listener); }
	
	/**
	 * コンストラクタから使用される。
	 * @param	type		エディタタイプ記述文字列。
	 * @param	editable	編集可否。
	 * @param	listener	アクションリスナー。
	 * @since	1.00
	 */
	public void init(String type ,boolean editable ,ActionListener listener){
		String[] params = ZString.tokenize(type);
		
		if("+text".equals(params[0])){
			if(1 < params.length)	myComponent = new REditableComboCEC(params ,editable ,listener);
			else	myComponent = new TextCEC(editable ,listener);
		}
		else if("+seq".equals(params[0]))	myComponent = new SeqCEC();
		else if("+bool".equals(params[0]))	myComponent = new BoolCEC(editable ,listener);
		else if("+color".equals(params[0]))	myComponent = new ColorCEC(editable ,listener);
		else if("-site".equals(params[0]))	myComponent = new RSiteChooseCEC(params ,editable ,listener);
		else if("-child".equals(params[0]))	myComponent = new RChildChooseCEC(params ,editable ,listener);
		else if("-template".equals(params[0]))	myComponent = new RFileChooseCEC(editable ,listener);
		else if("+font".equals(params[0]))	myComponent = new RFontFamilyChooseCEC(editable ,listener);
		else								myComponent = new ChooseCEC(params ,editable ,listener);
		
		listenerList	= new EventListenerList();
		changeEvent		= new ChangeEvent(this);
    }
	
	/**
	 * TableCellEditor実装
	 * @since	1.00
	 */
	public void addCellEditorListener(CellEditorListener listener){
		listenerList.add(CellEditorListener.class, listener);
	}
	
	/**
	 * TableCellEditor実装
	 * @since	1.00
	 */
	public void removeCellEditorListener(CellEditorListener listener){
		listenerList.remove(CellEditorListener.class, listener);
	}
	
	protected void fireEditingStopped(){
		CellEditorListener[] listeners = (CellEditorListener[])listenerList.getListeners(CellEditorListener.class);
		int mx=listeners.length;
		for (int i=0;i<mx;i++)	listeners[i].editingStopped(changeEvent);
	}
	
	protected void fireEditingCanceled(){
		CellEditorListener[] listeners = (CellEditorListener[])listenerList.getListeners(CellEditorListener.class);
		int mx=listeners.length;
		for (int i=0;i<mx;i++)	listeners[i].editingCanceled(changeEvent);
	}
	
	/**
	 * TableCellEditor実装
	 * @since	1.00
	 */
	public void cancelCellEditing(){	fireEditingCanceled();	}
	
	/**
	 * TableCellEditor実装
	 * @since	1.00
	 */
	public boolean stopCellEditing(){
		fireEditingStopped();
		return true;
	}
	
	/**
	 * TableCellEditor実装
	 * @since	1.00
	 */
	public boolean isCellEditable(EventObject event){	return myEditable;	}
	
	/**
	 * TableCellEditor実装
	 * @since	1.00
	 */
	public boolean shouldSelectCell(EventObject event){	return true;	}
	
	/**
	 * TableCellEditor実装
	 * @since	1.00
	 */
    public Object getCellEditorValue(){	return myComponent.text(); }
	
	/**
	 * TableCellEditor実装
	 * @since	1.00
	 */
	public Component getTableCellEditorComponent(JTable table ,Object value ,boolean isSelected ,int row ,int column){
		if(myComponent instanceof iChildReloadable){
			return ChildRelodableComponent(((RXMLTableModel)table.getModel()).element(row) ,value);
		}
		if(myComponent instanceof iReloadable)	return RelodableComponent(value);
		if(myComponent instanceof BoolCEC){
			elementBooster elem = ((RXMLTableModel)table.getModel()).element(row ,column);
			if(null==elem)	return component("false");
		}
		return component(value);
	}
	
	/**
	 * TableCellRenderer実装
	 * @since	1.00
	 */
	public Component getTableCellRendererComponent(JTable table ,Object value ,boolean isSelected ,boolean hasFocus ,int row ,int column){
		myComponent.focus(hasFocus ,table);
		if(myComponent instanceof iChildReloadable){
			return ChildRelodableComponent(((RXMLTableModel)table.getModel()).element(row) ,value);
		}
		if(myComponent instanceof iReloadable)	return RelodableComponent(value);
//		myComponent.focus(hasFocus ,table);
		if(myComponent instanceof BoolCEC){
			elementBooster elem = ((RXMLTableModel)table.getModel()).element(row ,column);
			if(null==elem)	return component("false");
		}
		return component(value);
	}
	
	public JComponent ChildRelodableComponent(elementBooster element ,Object value){
		((iChildReloadable)myComponent).reload(element);
		return component(value);
	}
	
	public JComponent RelodableComponent(Object value){
		((iReloadable)myComponent).reload();
		return component(value);
	}
	
	public JComponent component(Object value){
		if(value instanceof String)	myComponent.text((String)value);
		else						myComponent.text(null);
		
		return myComponent.component();
	}
	
	public iCellEditorComponent CEC(){ return myComponent; }
}
