/*
 * @(#)RidApplication.java
 *
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 *
 * RID-X : Application Super Class
 *
 * @author  Intelligent Technology Inc.
 * @version 1.01 2001/11/07
 */
package jp.co.nri.rid.doc;

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;

import java.awt.event.ActionEvent;

import java.io.File;
import java.io.FileOutputStream;

import java.util.Enumeration;
import java.util.Vector;

import javax.swing.Action;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;

import org.w3c.dom.Element;
import org.w3c.dom.Text;

import org.xml.sax.InputSource;

import org.apache.xerces.parsers.DOMParser;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.DOMSerializer;
import org.apache.xml.serialize.XMLSerializer;

import jp.co.iti.fagot.ZApp;
import jp.co.iti.fagot.IZApp;

import jp.co.iti.fagot.doc.IDocument;
import jp.co.iti.fagot.doc.DefaultApplication;
import jp.co.iti.fagot.doc.DocBar;
import jp.co.iti.fagot.doc.DocDocument;
import jp.co.iti.fagot.doc.DocElement;
import jp.co.iti.fagot.doc.DocManager;
import jp.co.iti.fagot.doc.DocPane;
import jp.co.iti.fagot.doc.DocManager;

import jp.co.iti.fagot.ui.UDialog;

import jp.co.iti.fagot.util.ZInstance;
import jp.co.iti.fagot.util.ZDebug;
import jp.co.iti.fagot.util.ZFile;
import jp.co.iti.fagot.util.ZMessage;
import jp.co.iti.fagot.util.ZString;
import jp.co.iti.fagot.util.ZResource;

import jp.co.nri.Rid;

import jp.co.nri.rid.RidPane;
import jp.co.nri.rid.RidZoneTitlePane;
import jp.co.nri.rid.RidMapTitlePane;
import jp.co.nri.rid.RUpdateManager;

import jp.co.nri.rid.snapshot.xcopy;

import jp.co.nri.rid.search.SearchPanel;

import jp.co.nri.rid.mapper.Mapper;

import jp.co.nri.rid.table.RTable;
import jp.co.nri.rid.table.LineNoRowHeader;

import jp.co.nri.rid.environment.MessageDialog;
import jp.co.nri.rid.error.RidMessage;
/**
 * Ridual Application メインプログラム
 */
public class RidApplication extends DefaultApplication {
	/**
	 * デフォルトコンストラクタ
	 */
	public RidApplication() {
	}

	//## IApplication #################################################
	/**
	 * 初期化
	 * @param frame アプリケーションフレーム
	 */
	public boolean initApplication(JFrame frame) {
	// アプリケーションをインスタンス一覧に登録
	ZInstance.map().put( Rid.APPLICATION, this );

	// フレームをインスタンス一覧に登録
	ZInstance.map().put( Rid.FRAME, frame );

	// ユニットバーの作成
	frame.getContentPane().add("West",createDocBar());

	// キャンバスの作成
	JTabbedPane tab = new JTabbedPane();
	ZInstance.map().put( Rid.PANEL_TAB, tab );

	// パネルの作成
	for ( int nIndex=0 ; nIndex<Rid.PANEL_COUNT ; nIndex++ ) {
		JComponent cmp = createPanel(nIndex);
		tab.add(getTabName(nIndex),cmp);
	}

	// タブ変更イベントの取得
	tab.addChangeListener( new TabAdapter() );

	frame.getContentPane().add("Center",tab);

	// アクティブパネルの設定
	int nIndex = tab.getSelectedIndex();
	DocBar bar = (DocBar)ZInstance.map().get(Rid.DOCBAR);
	bar.setPanel( nIndex );
	String szTitle = tab.getTitleAt( nIndex );
	ZInstance.prop().setProperty( Rid.PANEL_ACTIVE, szTitle );

	return true;
	}

	/**
	 * 終了
	 */
	public void exitApplication() {
	savePages();
	}

	//## IZFilable ####################################################
	/**
	 * 開く
	 * @param szFile ファイル名
	 */
	public boolean open(String szFile) {
	// 新規作成の場合、ディレクトリ群の作成
	if ( szFile == null ) {
		szFile = createProject();
		if ( szFile == null ) {
			RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
			return false;
		}
	} else {
		// ディレクトリ指定の場合は、data.dir,site.xmlを付与
		ZResource res = ZApp.getTheApp().getResource();
		File fFile = new File( szFile );
		if ( fFile.isDirectory() ) {
			String szDataDir = res.getString("rid.data.dir");
			String szSiteXml = res.getString("rid.site.xml");
			szFile += File.separator+szDataDir+File.separator+szSiteXml;
		}
	}


	// site.xmlの読み込み
	File fName = new File( szFile );
	if ( !fName.exists() ) {
		String szMsg = "site.xml not exists:"+szFile;
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}
	DocDocument siteDoc = loadDocument(Rid.DOCUMENT_SITE,szFile);
	if ( siteDoc == null ) {
		String szMsg = "site.xml load failed:"+szFile;
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}

	// 付属するドキュメントを開く
	String szParent = ZFile.getParent(szFile);

	// リソース
	String szName = ((DocElement)siteDoc.getDocumentElement()).getChildElementAttribute(".ReferenceUnit.FileUnit","Type=resource","Name");
	if ( szName.length() == 0 ) {
		String szMsg = "Empty RidProject.ReferenceUnit.FileUnit(resource)";
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1101",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}

	String szLoadFile = szParent+File.separator+szName;
	fName = new File( szLoadFile );
	if ( !fName.exists() ) {
		String szMsg = "resource.xml not exists:"+szLoadFile;
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}
	DocDocument resDoc = loadDocument(Rid.DOCUMENT_RESOURCE,szLoadFile);
	if ( resDoc == null ) {
		String szMsg = "resource.xml load failed:"+szLoadFile;
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}

	// ドキュメント
	szName = ((DocElement)siteDoc.getDocumentElement()).getChildElementAttribute(".ReferenceUnit.FileUnit","Type=document","Name");
	if ( szName.length() == 0 ) {
		String szMsg = "Empty RidProject.ReferenceUnit.FileUnit(document)";
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1101",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}

	szLoadFile = szParent+File.separator+szName;
	fName = new File( szLoadFile );
	if ( !fName.exists() ) {
		String szMsg = "document.xml not exists:"+szLoadFile;
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}
	DocDocument docDoc = loadDocument(Rid.DOCUMENT_DOCUMENT,szLoadFile);
	if ( docDoc == null ) {
		String szMsg = "document.xml load failed:"+szLoadFile;
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}

	// スナップショット
	szName = ((DocElement)siteDoc.getDocumentElement()).getChildElementAttribute(".ReferenceUnit.FileUnit","Type=snapshot","Name");
	if ( szName.length() == 0 ) {
		String szMsg = "Empty RidProject.ReferenceUnit.FileUnit(snapshot)";
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1101",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}

	szLoadFile = szParent+File.separator+szName;
	fName = new File( szLoadFile );
	if ( !fName.exists() ) {
		String szMsg = "snapshot.xml not exists:"+szLoadFile;
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}
	DocDocument snpDoc = loadDocument(Rid.DOCUMENT_SNAPSHOT,szLoadFile);
	if ( snpDoc == null ) {
		String szMsg = "snapshot.xml load failed:"+szLoadFile;
		ZDebug.err(szMsg);
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szMsg));
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
		return false;
	}

	// 全て読み込み完了したので、ZInstanceに登録
	ZInstance.map().put( Rid.DOCUMENT_SITE, siteDoc );
	ZInstance.map().put( Rid.DOCUMENT_RESOURCE, resDoc );
	ZInstance.map().put( Rid.DOCUMENT_DOCUMENT, docDoc );
	ZInstance.map().put( Rid.DOCUMENT_SNAPSHOT, snpDoc );

	super.open(szFile);

	JTabbedPane tab = (JTabbedPane)ZInstance.map().get(Rid.PANEL_TAB);
	if ( tab != null ) {
		tab.setSelectedIndex(0);
		JComponent cmp = (JComponent)ZInstance.map().get( Rid.PANEL_ZONE );
		cmp.requestFocus();
	}

	// ドキュメントの更新
	updateDocument();
	return true;
	}

	/**
	 * 保存
	 */
	public boolean save() {
	if ( !canSave() ) {
		return false;
	}
	// タイムスタンプの取得
	String szDateTime = ZString.getDateTime();
	ZDebug.trace("Save:"+szDateTime);

	DocDocument siteDoc = (DocDocument)ZInstance.map().get( Rid.DOCUMENT_SITE );
	siteDoc.beginTransaction();
	DocElement  root    = (DocElement)siteDoc.getDocumentElement();
	root.setAttribute("Update",szDateTime);
	siteDoc.commit();
	siteDoc = saveDocument(siteDoc,getFileName());
	// 正常に保存できた場合は付属するドキュメントも保存
	if ( siteDoc != null ) {
		// 付属するドキュメントを保存
		String szParent = ZFile.getParent(getFileName());
		// リソース
		String szName = ((DocElement)siteDoc.getDocumentElement()).getChildElementAttribute(".ReferenceUnit.FileUnit","Type=resource","Name");
		if ( szName.length() == 0 ) {
			String szMsg = "Empty RidProject.ReferenceUnit.FileUnit(resource)";
			ZDebug.err(szMsg);
			RidMessage ridMsg = new RidMessage();
			MessageDialog.showError(ridMsg.Error("E1101",szMsg));
			return false;
		}
		DocDocument relDoc = (DocDocument)ZInstance.map().get( Rid.DOCUMENT_RESOURCE );
		relDoc.beginTransaction();
		root = (DocElement)relDoc.getDocumentElement();
		root.setAttribute("Update",szDateTime);
		relDoc.commit();
		saveDocument(relDoc,szParent+File.separator+szName);

		// ドキュメント
		szName = ((DocElement)siteDoc.getDocumentElement()).getChildElementAttribute(".ReferenceUnit.FileUnit","Type=document","Name");
		if ( szName.length() == 0 ) {
			String szMsg = "Empty RidProject.ReferenceUnit.FileUnit(document)";
			ZDebug.err(szMsg);
			RidMessage ridMsg = new RidMessage();
			MessageDialog.showError(ridMsg.Error("E1101",szMsg));
			return false;
		}
		relDoc = (DocDocument)ZInstance.map().get( Rid.DOCUMENT_DOCUMENT );
		relDoc.beginTransaction();
		root = (DocElement)relDoc.getDocumentElement();
		root.setAttribute("Update",szDateTime);
		relDoc.commit();
		saveDocument(relDoc,szParent+File.separator+szName);

		// ドキュメント
		szName = ((DocElement)siteDoc.getDocumentElement()).getChildElementAttribute(".ReferenceUnit.FileUnit","Type=snapshot","Name");
		if ( szName.length() == 0 ) {
			String szMsg = "Empty RidProject.ReferenceUnit.FileUnit(snapshot)";
			ZDebug.err(szMsg);
			RidMessage ridMsg = new RidMessage();
			MessageDialog.showError(ridMsg.Error("E1101",szMsg));
			return false;
		}
		relDoc = (DocDocument)ZInstance.map().get( Rid.DOCUMENT_SNAPSHOT );
		relDoc.beginTransaction();
		root = (DocElement)relDoc.getDocumentElement();
		root.setAttribute("Update",szDateTime);
		relDoc.commit();
		saveDocument(relDoc,szParent+File.separator+szName);

		// ページSVGの保存
		savePages();
	}

	return true;
	}

	/**
	 * 名前を付けて保存
	 * @param szFile ファイル名
	 */
	public boolean saveAs(String szFile) {
	if ( !szFile.endsWith(".xml") ) {
		szFile += ".xml";
	}
	return super.saveAs( szFile );
	}

	/**
	 * ファイルが更新されたか問い合わせ
	 */
	public boolean isModified(){
	boolean isModify = false;
	// サイト
	DocDocument doc = (DocDocument)ZInstance.map().get( Rid.DOCUMENT_SITE );
	isModify = doc.isModified();

	// リソース
	if ( !isModify ) {
		doc = (DocDocument)ZInstance.map().get( Rid.DOCUMENT_RESOURCE );
		isModify = doc.isModified();
	}

	// ドキュメント
	if ( !isModify ) {
		doc = (DocDocument)ZInstance.map().get( Rid.DOCUMENT_DOCUMENT );
		isModify = doc.isModified();
	}

	// ドキュメント
	if ( !isModify ) {
		doc = (DocDocument)ZInstance.map().get( Rid.DOCUMENT_SNAPSHOT );
		isModify = doc.isModified();
	}

	return isModify;
	}

	//## 初期化 #######################################################
	/**
	 * DocBarの構築
	 */
	protected JComponent createDocBar() {
	// ツールバーの作成
	DocBar bar = new DocBar();
	bar.setOrientation(SwingConstants.VERTICAL);
	bar.setFloatable( false );
	ZInstance.map().put( Rid.DOCBAR, bar );
	return bar;
	}

	/**
	 * パネルの作成
	 * @param nIndex パネル番号
	 */
	protected JComponent createPanel(int nIndex) {
	// 基本パネル
	JPanel panel = new JPanel();
	panel.setLayout(new BorderLayout());
	// 上部コンポーネント
	JComponent cmp = createNorthComponent(nIndex);
	if ( cmp != null ) {
		panel.add("North",cmp);
	}
	// 中央コンポーネント
	JScrollPane scroll = new JScrollPane();
	cmp = createCenterComponent(nIndex);
	scroll.setViewportView(cmp);
	if ( cmp instanceof DocPane ) {
		scroll.getViewport().addChangeListener( new ScrollAdapter() ) ;
	} else if ( cmp instanceof RTable ) {
		JTable rowHeader = new LineNoRowHeader((RTable)cmp);
		scroll.setRowHeaderView(rowHeader);
		scroll.getRowHeader().setPreferredSize(rowHeader.getPreferredSize());
		switch ( nIndex ) {
		  case Rid.PANEL_PAGES_INDEX:	// ページリスト
			ZInstance.map().put( Rid.PANEL_PAGES_HEADER, rowHeader );
			break;
		  case Rid.PANEL_RESOURCES_INDEX:	// リソース
			ZInstance.map().put( Rid.PANEL_RESOURCES_HEADER, rowHeader );
			break;
		  case Rid.PANEL_DOCUMENTS_INDEX:	// ドキュメント
			ZInstance.map().put( Rid.PANEL_DOCUMENTS_HEADER, rowHeader );
			break;
		  case Rid.PANEL_PAGERES_INDEX:	// ページリソース対応表
			ZInstance.map().put( Rid.PANEL_PAGERES_HEADER, rowHeader );
			break;
		  case Rid.PANEL_LINKS_INDEX:	// リンク表
			ZInstance.map().put( Rid.PANEL_LINKS_HEADER, rowHeader );
			break;
		}
	}
	panel.add("Center",scroll);
	return panel;
	}

	/**
	 * 上部コンポーネントの作成
	 * @param nIndex パネル番号
	 */
	protected JComponent createNorthComponent(int nIndex) {
	JComponent cmp = null;
	switch(nIndex) {
	  case Rid.PANEL_ZONE_INDEX:	// ゾーン
		cmp = new RidZoneTitlePane();
		ZInstance.map().put( Rid.PANEL_ZONE_TITLE, cmp );
		break;
	  case Rid.PANEL_MAP_INDEX:	// マップ
		cmp = new RidMapTitlePane();
		ZInstance.map().put( Rid.PANEL_MAP_TITLE, cmp );
		break;
	}
	return cmp;
	}

	/**
	 * 中央コンポーネントの作成
	 * @param nIndex パネル番号
	 */
	protected JComponent createCenterComponent(int nIndex) {
	JComponent cmp = null;
	switch(nIndex) {
	  case Rid.PANEL_ZONE_INDEX:	// ゾーン
		cmp = new RidPane(Rid.PANEL_ZONE);
		((RidPane)cmp).setKeyMap( ((RidPane)cmp).createDefaultKeyMap(ZApp.getTheApp()) );
		ZInstance.map().put( Rid.PANEL_ZONE, cmp );
		break;
	  case Rid.PANEL_MAP_INDEX:	// マップ
		cmp = new RidPane(Rid.PANEL_MAP);
		((RidPane)cmp).setKeyMap( ((RidPane)cmp).createDefaultKeyMap(ZApp.getTheApp()) );
		ZInstance.map().put( Rid.PANEL_MAP, cmp );
		break;
	  case Rid.PANEL_PAGES_INDEX:	// ページリスト
		cmp = new RTable("table.pages");
		ZInstance.map().put( Rid.PANEL_PAGES, cmp );
		break;
	  case Rid.PANEL_RESOURCES_INDEX:	// リソース
		cmp = new RTable("table.resources");
		ZInstance.map().put( Rid.PANEL_RESOURCES, cmp );
		break;
	  case Rid.PANEL_DOCUMENTS_INDEX:	// ドキュメント
		cmp = new RTable("table.documents");
		ZInstance.map().put( Rid.PANEL_DOCUMENTS, cmp );
		break;
	  case Rid.PANEL_PAGERES_INDEX:	// ページリソース対応表
		cmp = new RTable("table.linkedpages");
		ZInstance.map().put( Rid.PANEL_PAGERES, cmp );
		break;
	  case Rid.PANEL_LINKS_INDEX:	// リンク表
		cmp = new RTable("table.links");
		ZInstance.map().put( Rid.PANEL_LINKS, cmp );
		break;
	  case Rid.PANEL_SEARCH_INDEX:	// 検索パネル
		cmp = new SearchPanel();
		ZInstance.map().put( Rid.PANEL_SEARCH, cmp );
		break;
	}
	return cmp;
	}

	/**
	 * タブ名の取得
	 * @param nIndex パネル番号
	 */
	protected String getTabName(int nIndex) {
	String szTab = null;
	switch(nIndex) {
	  case Rid.PANEL_ZONE_INDEX:		szTab=Rid.PANEL_ZONE		;break;  	// ゾーン
	  case Rid.PANEL_MAP_INDEX:			szTab=Rid.PANEL_MAP			;break;  	// マップ
	  case Rid.PANEL_PAGES_INDEX:		szTab=Rid.PANEL_PAGES		;break;  	// ページリスト
	  case Rid.PANEL_RESOURCES_INDEX:	szTab=Rid.PANEL_RESOURCES	;break;  	// リソース
	  case Rid.PANEL_DOCUMENTS_INDEX:	szTab=Rid.PANEL_DOCUMENTS	;break;  	// ドキュメント
	  case Rid.PANEL_PAGERES_INDEX:		szTab=Rid.PANEL_PAGERES		;break;  	// ページリソース対応表
	  case Rid.PANEL_LINKS_INDEX:		szTab=Rid.PANEL_LINKS		;break;  	// リンク
	  case Rid.PANEL_SEARCH_INDEX:		szTab=Rid.PANEL_SEARCH		;break;  	// 検索パネル
	}
	return szTab;
	}

	
	
	
	static final private String[] label_keys = { "msg.newproject.name",
		"msg.newproject.abbreviation",
		"msg.newproject.formal",
		"msg.newproject.purpose",
		"msg.newproject.comment",
		"msg.newproject.start",
		"msg.newproject.cutover",
		"msg.newproject.leader",
		"msg.newproject.member"
	};
	static final private int[] panelIndexs = { 0,1,1,1,1,2,2,3,3 };

//## ドキュメント #################################################
	/**
	 * プロジェクトの新規作成
	 * @return 作成したsite.xmlファイル名
	 */




	protected String createProject() {
	IZApp app = ZApp.getTheApp();
	ZResource res = app.getResource();

	// 親フレームの取得
//	JFrame frame = (JFrame)ZInstance.map().get( Rid.FRAME );
//	if ( frame.isDisplayable() || !frame.isShowing() ) {
//		frame = null;
//		app   = null;
//	}

	// 新規作成ダイアログの表示
	mDialog = new UDialog(app,"newproject");
	JTextField[] text = new JTextField[9];

	// パネル内レイアウトの作成
	GridBagLayout gridbag = new GridBagLayout();
	GridBagConstraints cns = new GridBagConstraints();
	cns.fill = GridBagConstraints.BOTH;

//	JPanel panel = new JPanel(new BorderLayout());
//	panel.setLayout( gridbag );
	
	JPanel[] panels = new JPanel[4];
	
	JPanel root_panel = new JPanel(new BorderLayout(8,8));
	root_panel.setBorder(new EmptyBorder(4, 4, 0, 4));

	JPanel opt_panel = new JPanel(new BorderLayout());
	opt_panel.add(new JLabel("Option:"), BorderLayout.NORTH);
	
	JTabbedPane tab = new JTabbedPane();
	opt_panel.add(tab, BorderLayout.CENTER);
	
	root_panel.add(opt_panel ,BorderLayout.CENTER);
	
	panels[0] = new JPanel();
	panels[0].setLayout( gridbag );
	root_panel.add(panels[0], BorderLayout.NORTH);
	
	panels[1] = new JPanel();
	panels[1].setLayout( gridbag );
	tab.add(res.getString("msg.newproject.project"), panels[1]);
	
	panels[2] = new JPanel();
	panels[2].setLayout( gridbag );
	tab.add(res.getString("msg.newproject.schedule"), panels[2]);
	
	panels[3] = new JPanel();
	panels[3].setLayout( gridbag );
	tab.add(res.getString("msg.newproject.member"), panels[3]);
	
	int nInputCount = 9;
	for ( int nAt=0 ; nAt<nInputCount ; nAt++ ) {
//		cns.gridwidth = GridBagConstraints.RELATIVE;
		cns.gridwidth = 1;
		cns.fill = GridBagConstraints.BOTH;
		cns.weightx = 0.0;
//		panel.add(new JLabel(szTexts[0]),cns);
		panels[panelIndexs[nAt]].add(new JLabel(res.getString(label_keys[nAt])),cns);

		cns.gridwidth = GridBagConstraints.REMAINDER;
		cns.weightx = 10.0;

		text[nAt] = new JTextField() {
		/**
		 * コンポーネント最小のサイズを返します
		 * 幅が300以下にならないように最小サイズを確保します。
		 */
		public Dimension getPreferredSize() {
			Dimension dim = super.getPreferredSize();
			if ( dim.width < 300 ) {
				dim.width = 300;
			}
			return dim;
			}
		};
		panels[panelIndexs[nAt]].add(text[nAt],cns);
	}

	//-----------------------------------------------------------------
	// 10行目
	JPanel btnPanel = new JPanel();
	Action act  = null ;

	// OKボタン
	act = new AbstractAction("OK") {
	    public void actionPerformed(ActionEvent e) { mDialog.onOK(); }
	};
	JButton okBtn = new JButton(act);
	okBtn.setText("OK");
	btnPanel.add( okBtn );

	// Cancelボタン
	act = new AbstractAction("Cancel") {
	    public void actionPerformed(ActionEvent e) { mDialog.onCancel(); }
	};
	JButton cancelBtn = new JButton(act);
	cancelBtn.setText("Cancel");
	btnPanel.add( cancelBtn );

	root_panel.add(btnPanel, BorderLayout.SOUTH);

	// デフォルトボタンの設定
	mDialog.getRootPane().setDefaultButton( okBtn );

	// ダイアログの表示
	mDialog.setComponent( root_panel,false );

	String szFile = null;
	RidMessage ridMsg = new RidMessage();
	while ( mDialog.doModal() ) {
		String szName = text[0].getText();
		if ( szName != null && szName.length()>0 ) {
			szFile = res.getString("app.install.path")+File.separator
				   +res.getString("app.project.dir") +File.separator
				   +szName;
			File fFile = new File(szFile);
			if ( fFile.exists() ) {
				// ディレクトリが存在します
				MessageDialog.showError(ridMsg.Error("E1020",szName));
				szFile = null;
			} else if ( !fFile.mkdirs() ) {
				// プロジェクトの作成に失敗しました
				MessageDialog.showError(ridMsg.Error("E1021",szName));
				szFile = null;
			} else {
				break;
			}
		} else {
			// プロジェクト名が設定されていません
			MessageDialog.showError(ridMsg.Error("E1022",""));
			szFile = null;
		}
	}

	// ファイルが選択されたなら
	if ( szFile != null ) {
		// テンプレートディレクトリの一括コピー
		try {
			// コピー元
			String szSrc = res.getString("app.install.path")
						  +File.separator
						  +res.getString("app.template.dir");
			xcopy xc = new xcopy();
			xc.copy(szSrc,szFile);
		} catch (Exception e) {
			ZDebug.err("Directory copy failed:"+szFile);
			e.printStackTrace();
			return null;
		}

		// プロジェクトポータルの作成
		String szPropKey = "mapper";
		DocDocument doc = (DocDocument)DocManager.createDocument(szPropKey);
		doc.setDocumentId(szPropKey);
		doc.initDocument();
		Element root = doc.getDocumentElement();

		for ( int nAt=1 ; nAt<nInputCount ; nAt++ ) {
			String szTag = null;
			switch ( nAt ) {
			  case 1:	szTag = "Abbreviation";		break;
			  case 2:	szTag = "Formal";			break;
			  case 3:	szTag = "Purpose";			break;
			  case 4:	szTag = "Comment";			break;
			  case 5:	szTag = "Start";			break;
			  case 6:	szTag = "CutOver";			break;
			  case 7:	szTag = "Leader";			break;
			  case 8:	szTag = "Member";			break;
			}
			
			Element tag = doc.createElement(szTag);
			String szData = text[nAt].getText();
			if ( szData == null || szData.length() == 0 ) {
				szData = "<!-- no data -->";
			}
			Text textNode = doc.createTextNode(szData);
			
			root.appendChild( tag );
			tag.appendChild( textNode );
		}

		boolean bRet = false;
		String szTmpl = szFile+File.separator+
						res.getString("rid.template.dir")+File.separator+"_project.html";
		String szHtml = szFile+File.separator+
						res.getString("rid.plan.dir")+File.separator+"project.html";
		try {
			Mapper mapper = new Mapper();
			bRet = mapper.Type2(szTmpl, doc, szHtml);
		} catch ( Exception e ) {
			;
		}

		if ( bRet ) {
			// DW起動
			String szCmd  = res.getString("command.html.editor");
			if ( res.getBoolean("newproject.edit.html",true) && (szCmd != null) ) {
				if ( !RidExecAction.exec( szCmd, szHtml ) ) {
					MessageDialog.showError(ridMsg.Error("E1901",szCmd+" "+szHtml));
				}
			}
		} else {
			MessageDialog.showError(ridMsg.Error("E1021",szHtml));
		}

		// site.xmlの作成
		String szDataDir = res.getString("rid.data.dir");
		String szSiteXml = res.getString("rid.site.xml");
		return szFile+File.separator+szDataDir+File.separator+szSiteXml;
	}
	return null;
	}

	/**
	 * ドキュメントの作成
	 * @param szKey ドキュメント識別子
	 */
	protected DocDocument createDocument(String szKey) {
	// 先頭の "document." をのぞく
	String szPropKey = szKey.substring(9);
	DocDocument doc = (DocDocument)DocManager.createDocument(szPropKey);
	doc.setDocumentId(szPropKey);
	doc.initDocument();
	ZInstance.map().put( szKey, doc );
	return doc;
	}

	/**
	 * ドキュメントのロード
	 * @param szKey  ドキュメント識別子
	 * @param szFile ファイル名
	 */
	protected DocDocument loadDocument(String szKey,String szFile) {
	// 先頭の "document." をのぞく
	String szPropKey = szKey.substring(9);
	String szClass = DocManager.getClassName(DocManager.DOCUMENT,szPropKey);
	try {
		// パース
		DOMParser parser = new DOMParser();
		parser.setProperty("http://apache.org/xml/properties/dom/document-class-name",szClass);
		parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);
		InputSource in = DocManager.createInputSource(szFile);
		parser.parse(in);
		DocDocument doc = (DocDocument)parser.getDocument();
		doc.setDocumentId(szPropKey);
		return doc;
	} catch ( Throwable t ) {
		ZDebug.err("FileOpen failed:"+szFile);
		ZDebug.err("    "+t.toString());
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1100",szFile));
	}
	return createDocument(szKey);
	}

	/**
	 * ドキュメントの更新
	 * ファイルが開かれたときにパネルにドキュメントを初期設定する
	 * ここで更新している以外のパネルはパネルがアクティブになったときに更新する
	 */
	protected void updateDocument() {
	DocPane     panel = null;
	DocDocument doc   = (DocDocument)ZInstance.map().get(Rid.DOCUMENT_SITE);
	// Zone
	panel = (DocPane)ZInstance.map().get(Rid.PANEL_ZONE);
	if ( panel != null ) {
		panel.setDocument(doc);
	}

	// map
	panel = (DocPane)ZInstance.map().get(Rid.PANEL_MAP);
	if ( panel != null ) {
		panel.setDocument(doc);
	}

	// 画面の更新
	if ( panel != null ) {
		RUpdateManager.update(RUpdateManager.SET_DOCUMENT);
	}

	// Search パネルの初期化
	SearchPanel searchPanel = (SearchPanel)ZInstance.map().get(Rid.PANEL_SEARCH);
	if ( searchPanel != null ) {
	     searchPanel.init();
	}
	}

	/**
	 * ファイル名の更新（open,saveAs）時
	 */
	protected void fileChanged() {
	super.fileChanged();

	// プロジェクトディレクトリの設定
	ZResource res = ZApp.getTheApp().getResource();
	String szDataDir = res.getString("rid.data.dir");
	String szTitle = getFileName() ;
	if ( szTitle != null ) {
		String szParent = ZFile.getParent(getFileName());

		if ( szParent.endsWith(szDataDir) ) {
			String szPjDir = szParent.substring(0,szParent.length()-szDataDir.length()-1);
			ZInstance.prop().setProperty( Rid.PJ_DIR, szPjDir );
//			ZDebug.trace(szPjDir);
		} else {
			ZDebug.trace("invalid dir:"+szParent);
			ZInstance.prop().remove( Rid.PJ_DIR );
		}
	} else {
		ZDebug.trace("unsaved");
		ZInstance.prop().remove( Rid.PJ_DIR );
	}
	}


	/**
	 * ドキュメントの保存
	 * @param doc    ドキュメント
	 * @param szFile ファイル名
	 */
	protected DocDocument saveDocument(DocDocument doc,String szFile) {
	try {
		String  szEncoding = doc.getEncoding();
		boolean bIndenting = doc.getIndenting();
		// 出力
//		ZDebug.trace("save:"+szFile);
		OutputFormat fm = new OutputFormat(doc,szEncoding,bIndenting);
		FileOutputStream out = new FileOutputStream(szFile);
		DOMSerializer ser = new XMLSerializer(out,fm).asDOMSerializer();
		ser.serialize(doc);
		doc.setModified();
		return doc;
	} catch ( Throwable t ) {
		ZDebug.err("FileSave failed:"+szFile);
		t.printStackTrace();
		RidMessage ridMsg = new RidMessage();
		MessageDialog.showError(ridMsg.Error("E1110",szFile));
	}
	return null;
	}

	/**
	 * SVGの保存
	 */
	protected void savePages() {
	// SVGパネルを保存
//	RidSvgPane editor = (RidSvgPane)ZInstance.map().get( Rid.PANEL_PAGE );
//	if ( editor != null ) {
//		editor.save();
//	}
	}

	//## サブクラス：ChangeListener ###################################
	/**
	 * TabbedPaneの状態変更リスナー
	 */
	protected class TabAdapter implements ChangeListener {
	/**
	 * アクティブなタブシートの変更
	 * @param evt 変更イベント
	 */
	public void stateChanged(ChangeEvent evt) {
	if ( evt.getSource() instanceof JTabbedPane ) {
		// 今開かれたタブ番号を保存
		JTabbedPane tab = (JTabbedPane)evt.getSource();
		mPrevTab = tab.getSelectedIndex();

		// アクティブパネルの設定
		String szTitle = tab.getTitleAt( mPrevTab );
		ZInstance.prop().setProperty( Rid.PANEL_ACTIVE, szTitle );

		// ZoneパネルからMapパネルに移った場合に、ZoneUnitが選択状態のままだと
		// PageUnitが選択できなくなるので、パネル移動時にはZoneUnitの選択状態を
		// 解除する
		if ( mPrevTab == Rid.PANEL_MAP_INDEX ) {
//			ZDebug.trace();
			DocPane editor = (DocPane)ZInstance.map().get(szTitle);
			RidElementZone top = ((RidDocumentSite)editor.getDocument()).getTopZone();
			
			// ゾーンを収集
			Vector zones = top.getZones( true );
			Enumeration elm = zones.elements();
			while ( elm.hasMoreElements() ) {
				RidElementZone zone = (RidElementZone)elm.nextElement();
				if ( zone.isSelect() ) {
					zone.setSelect(null,false);
				}
			}
		}

		// アクティブパネルの再描画
		RUpdateManager.update(RUpdateManager.PANEL_ACTIVE);
	}
	}
	/**
	 * 以前表示されていたタブ
	 */
	protected int mPrevTab = -1;
	}

	//## サブクラス：ChangeListener ###################################
	/**
	 * DocPaneのスクロール状態変更リスナー
	 */
	protected class ScrollAdapter implements ChangeListener {
	/**
	 * DocPaneのスクロール
	 * @param evt 変更イベント
	 */
	public void stateChanged(ChangeEvent evt) {
	DocPane editor = (DocPane)((JViewport)evt.getSource()).getView();
	DocDocument doc = editor.getDocument();
	boolean isTran = doc.isTransaction();
	if ( !isTran ) {
		doc.beginTransaction();
	}
	editor.updateCenter();
	// コミット
	if ( !isTran ) {
		doc.commit();
	}

	// パンパネルの再描画
	RUpdateManager.update(RUpdateManager.PANEL_SCROLL);
	}
	}

	//## アトリビュート################################################
	/**
	 * 新規作成ダイアログ
	 */
	protected UDialog mDialog = null;
}
