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

/* JAVA */
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

/* W3C */
import	org.w3c.dom.Document;

/* rid */
import	jp.co.nri.rid.table.editor.*;
import	jp.co.iti.fagot.doc.*;
import	jp.co.iti.fagot.ZApp;
import	jp.co.iti.fagot.util.*;
import jp.co.nri.rid.RMenu;
import jp.co.nri.rid.xml.*;

/**
 * ユニットを表示するためのテーブル。
 */
public class RTable extends JTable{
//	protected RClmDefs			myClmDefs;
//	private TableColumnModel	myColumnModel;
	private TableColumnModel	dmyColumnModel;
	public	Columns				columns;
//	private Vector			myColumns;
	
	public int SortedModelIndex = -1;
	
	/**
	 * @param	name	テーブル名
	 * @since	1.00
	 */
	public RTable(String name){
		columns		= new Columns(name);
/*
		myColumns		= columns();
		myColumnModel	= ColumnModel(myColumns);
*/
		dmyColumnModel	= new DefaultTableColumnModel();
		setAutoResizeMode(AUTO_RESIZE_OFF);
//		Dimension sz = myComboBox.getPreferredSize();
		setRowHeight(24);
		JTableHeader header = getTableHeader();
		header.setDefaultRenderer(new SortedHeaderRenderer());
		header.addMouseListener(new SortAdapter());
		
		addMouseListener(new RMouseAdapter());
	}
	
	/**
	 * データを読み直す
	 * @param	document	ドキュメント
	 * @since	1.00
	 */
	public void reload(Document document){
		// Table Model
		setColumnModel(dmyColumnModel);
		setModel(new RXMLTableModel(document ,columns.defs));
		setColumnModel(columns.model());
		SortedModelIndex = -1;
	}
	
	/**
	 * カラムデータを読み直す
	 * @since	1.00
	 */
	public void reloadColumn(){
		removeEditor();
		setColumnModel(columns.model());
	}
	
/*
	private Vector columns(){
		Vector columns = new Vector();
		
		ClmDef[] clmdefs = myClmDefs.ClmDefs();
		int mx = clmdefs.length;
		for(int i=0;i<mx;i++){
			ClmDef clmdef = clmdefs[i];
			TableColumn column = new TableColumn(i ,clmdef.width ,new RCellEditor(clmdef.type ,clmdef.editable) ,new RCellEditor(clmdef.type ,clmdef.editable));
//			column.setModelIndex(i);
			column.setHeaderValue(clmdef.title);
//			column.setCellEditor(new RCellEditor(clmdefs[i].type));
//			column.setCellRenderer(new RCellEditor(clmdefs[i].type));
			clmdef.column = column;
			columns.add(column);
		}
		
		return columns;
	}
	
	private TableColumnModel ColumnModel(Vector columns){
		TableColumnModel model = new DefaultTableColumnModel();
		for(Enumeration enum = columns.elements(); enum.hasMoreElements();){
			model.addColumn((TableColumn)enum.nextElement());
		}
		model.addColumnModelListener(new ColumnAdapter(myClmDefs));
		return model;
	}
*/
	
/**
 * RID-3 : RTable内のカラムを司るクラス
 * @version 1.00 2002/01/09-2002/03/26
 */
	public class Columns{
		public	RClmDefs	defs;
		private HashMap		myColumns;
		private String		myTableName;
		private	String		myColumnOrderKey;
		
		/**
		 * @param	name	テーブル名
		 * @since	1.00
		 */
		public Columns(String name){
			myTableName		= name;
			myColumnOrderKey= ZApp.getTheApp().getResource().getString(myTableName+".columnorder");
			if(null==myColumnOrderKey)	myColumnOrderKey = DocManager.loadProperty(DocManager.ELEMENT).getProperty(myTableName+".columnsorder.defaultkey");
			defs			= new RClmDefs(myTableName);
			myColumns		= new HashMap();
			
			ClmDef[] clmdefs = defs.ClmDefs();
			
			int mx = clmdefs.length;
			for(int i=0;i<mx;i++){
				ClmDef clmdef = clmdefs[i];
				TableColumn column = new TableColumn(i ,clmdef.width ,new RCellEditor(clmdef.type ,clmdef.editable) ,new RCellEditor(clmdef.type ,clmdef.editable));
				// ***fuku:20020919(start)***
				// 数値型の場合は右寄せ表示
				if ( clmdef.sorttype != null && clmdef.sorttype.equals("int") ) {
					// レンダラーの設定
					RCellEditor renderer = (RCellEditor)column.getCellRenderer();
					if ( renderer.CEC() instanceof JTextField ) {
						((JTextField)renderer.CEC()).setHorizontalAlignment(JTextField.RIGHT);
					}
					// エディタの設定
					RCellEditor editor = (RCellEditor)column.getCellEditor();
					if ( editor.CEC() instanceof JTextField ) {
						((JTextField)editor.CEC()).setHorizontalAlignment(JTextField.RIGHT);
					}
				}
				// ***fuku:20020919(end)***
				column.setHeaderValue(clmdef.title);
				clmdef.column = column;
				myColumns.put(clmdef.name ,column);
			}
		}
		
		/**
		 * 現在のカラム順キー
		 * @return	現在のカラム順キー
		 * @since	1.00
		 */
		public String	ColumnOrder(){ return myColumnOrderKey; }
		
		/**
		 * カラム順を変更する
		 * @param	現在のカラム順キー
		 * @since	1.00
		 */
		public void		ColumnOrder(String key){
			myColumnOrderKey = key;
			ZApp.getTheApp().getResource().putString(myTableName+".columnorder" ,key);
		}
		
		/**
		 * TableColumnModelを得る。
		 * @return	TableColumnModel
		 * @since	1.00
		 */
		public TableColumnModel model(){
			TableColumnModel model = new DefaultTableColumnModel();
			
			ZProperties	properties	= DocManager.loadProperty( DocManager.ELEMENT );
			String order = null;
			if(null!=myColumnOrderKey){
				String key = myTableName+".columnsorder."+myColumnOrderKey;
				order = ZApp.getTheApp().getResource().getString(key);
				if(null==order)	order = properties.getProperty(key);
			}
			if(null==order){
				order = DocManager.loadProperty(DocManager.ELEMENT).getProperty(myTableName+".colums.names");
			}
			StringTokenizer st = new StringTokenizer(order ," ");
			
			while(st.hasMoreTokens()){
				try{
					model.addColumn((TableColumn)myColumns.get(st.nextToken()));
				} catch(IllegalArgumentException e){}
			}
			model.addColumnModelListener(new ColumnAdapter(defs));
			return model;
		}
		
		/**
		 * テーブル名を得る。
		 * @return	テーブル名
		 * @since	1.00
		 */
		public String TableName(){ return myTableName; }
	}
	
	private class SortAdapter extends MouseAdapter{
		public void mouseClicked(MouseEvent e){
			JTableHeader	source	= (JTableHeader)e.getSource();
			Point			point	= e.getPoint();
			
			int column	= source.columnAtPoint(point);
			int index	= source.getColumnModel().getColumn(column).getModelIndex();
			
			((RTable)source.getTable()).SortedModelIndex = index;
			
			RXMLTableModel model = (RXMLTableModel)source.getTable().getModel();
			model.sort(index);
		}
	}
	
	private class ColumnAdapter implements TableColumnModelListener{
		private RClmDefs	myClmDefs;
		public ColumnAdapter(RClmDefs clmdefs){ myClmDefs=clmdefs; }
		
		public void columnAdded(TableColumnModelEvent e){
			//モデルに列が追加されたことをリスナーに通知します。
		}
		public void columnMarginChanged(ChangeEvent e){
			//マージンの変更のために列が移動されたことをリスナーに通知します。
			myClmDefs.save();
		}
		public void columnMoved(TableColumnModelEvent e){
			//列が再配置されたことをリスナーに通知します。
			
			String names = null;
			int mx = getColumnCount();
			for(int i=0;i<mx;i++){
				String name = getColumnName(i);
				if(null==names)	names = name;
				else			names = names + " " + name;
			}
			
			ZResource	res	= ZApp.getTheApp().getResource();
			res.putString(columns.TableName()+".columnsorder."+columns.ColumnOrder() ,names);
		}
		public void columnRemoved(TableColumnModelEvent e){
			//モデルから列が削除されたことをリスナーに通知します。
		}
		public void columnSelectionChanged(ListSelectionEvent e){
			//TableColumnModel の選択モデルが変更されたことをリスナーに通知します。
		}
	}
	
	private class RMouseAdapter implements MouseListener{
		public void mouseClicked(MouseEvent e){
		}
		public void mouseEntered(MouseEvent e){
		}
		public void mouseExited(MouseEvent e){
		}
		public void mousePressed(MouseEvent e){
		}
		public void mouseReleased(MouseEvent e){
			int row = rowAtPoint(e.getPoint());
			int col = columnAtPoint(e.getPoint());
			if((0<=row) && (0<=col) && e.isPopupTrigger()){
				elementBooster eb = ((RXMLTableModel)getModel()).element(row ,col);
				if(null!=eb){
					DocElement docelem = (DocElement)eb.element();
					if(null!=docelem)	RMenu.createContextMenu(e, docelem);
				}
			}
		}
	}

}
