/*
 * Galatea Dialog Manager:
 * (c)2004 Takuya NISHIMOTO (nishi@hil.t.u-tokyo.ac.jp)
 *
 * $Id: DialogManagerWindow.java,v 1.18 2008/02/14 03:35:54 nishi Exp $
 */

/*

 Linux で jdk1.5.0 の場合に日本語が文字化けする：

 Vine Linux 3.1 の場合：

 # cd /usr/java/jdk1.5.0_02/jre/lib/fonts
 # mkdir fallback
 # cd fallback
 # ln -s /usr/X11R6/lib/X11/fonts/TrueType/sazanami-gothic.ttf .
 # ln -s /usr/X11R6/lib/X11/fonts/TrueType/sazanami-mincho.ttf .
 # ln -s /usr/X11R6/lib/X11/fonts/TrueType/fonts.dir .

 */


package galatea.dialog.window;

import galatea.dialog.ISystemEventLogger;
import galatea.dialog.Tstamp;
import galatea.document.DocLoader;
import galatea.httpclient.INetUtilListener;
import galatea.httpclient.NetUtil;
import galatea.logger.ILoggerListener;
import galatea.util.Property;
import galatea.util.Util;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

public class DialogManagerWindow
	implements ISystemEventLogger, INetUtilListener, ILoggerListener
{
	private final class MenuExitActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
	}

	private final class MenuQuitActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (eventListener_ != null) {
				eventListener_.quitAction();
			} else {
				System.out.println(e);
			}
		}
	}

	private final class MainPanelButtonStopActionListener implements
			ActionListener {
		public void actionPerformed(ActionEvent e) {
			labelPauseMode_.setText("Mode: Pause");
			if (eventListener_ != null) {
				eventListener_.setPauseModeAction(true);
			} else {
				System.out.println(e);
			}
		}
	}

	private final class MainPanelButtonStartActionListener implements
			ActionListener {
		public void actionPerformed(ActionEvent e) {
			labelPauseMode_.setText("Mode: Run");
			if (eventListener_ != null) {
				eventListener_.setPauseModeAction(false);
			} else {
				System.out.println(e);
			}
		}
	}

	private final class MainPanelValidateActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			String uri = textFieldLocation_.getText();
			if (uri != null && uri.length() > 0) {
				String doc = DocLoader.convert(uri);
				if (doc != "") {
					System.err.println("[DM Validate OK] " + uri);
				} else {
					System.err.println("[DM Validate ERROR] " + uri);
				}
			}
		}
	}

	private final class MainPanelGoActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			String uri = textFieldLocation_.getText();
			if (eventListener_ != null) {
				labelPauseMode_.setText("Mode: Run");
				eventListener_.setPauseModeAction(false);
				eventListener_.setNextDocumentAction(uri);
				eventListener_.terminateDialogAction();
			} else {
				System.out.println(e);
				System.out.println(uri);
			}
		}
	}

//	private final class MenuViewGrammarActionListener implements ActionListener {
//		public void actionPerformed(ActionEvent e) {
//			if (viewGrammarFrame_ == null) {
//				viewGrammarFrame_ = new JFrame("View Grammar");
//				viewGrammarPane_ = new JEditorPane("text/plain", "");
//				viewGrammarPane_.setEditable(false);
//				viewGrammarPane_.setText(grammarFile_);
//				viewGrammarFrame_.getContentPane().add(new JScrollPane
//						(viewGrammarPane_,
//								ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
//								ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
//						));
//				viewGrammarFrame_.setSize(600, 400);
//				viewGrammarFrame_.setVisible(true);
//				viewGrammarFrame_.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
//			} else {
//				viewGrammarFrame_.setVisible(true);
//			}
//		}
//	}
//
//	private final class MenuViewTranslatedActionListener implements ActionListener {
//		public void actionPerformed(ActionEvent e) {
//			if (viewTranslatedFrame_ == null) {
//				viewTranslatedFrame_ = new JFrame("View Translated");
//				
//				viewTranslatedPane_ = new JEditorPane("text/plain", "");
//				viewTranslatedPane_.setEditable(false);
//				viewTranslatedPane_.setText(translatedFile_);
//				
//				viewTranslatedFrame_.getContentPane().add(new JScrollPane
//						(viewTranslatedPane_,
//								ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
//								ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
//						));
//				
//				viewTranslatedFrame_.setSize(600, 400);
//				viewTranslatedFrame_.setVisible(true);
//				viewTranslatedFrame_.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
//				
//			} else {
//				viewTranslatedFrame_.setVisible(true);
//			}
//		}
//	}

//	private final class MenuViewSrcActionListener implements ActionListener {
//		public void actionPerformed(ActionEvent e) {
//			if (viewSrcFrame_ == null) {
//				viewSrcFrame_ = new JFrame("View Source");
//				
//				viewSrcPane_ = new JEditorPane("text/plain", "");
//				viewSrcPane_.setEditable(false);
//				viewSrcPane_.setText(srcFile_);
//				
//				viewSrcFrame_.getContentPane().add(new JScrollPane
//						(viewSrcPane_,
//								ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
//								ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
//						));
//				
//				viewSrcFrame_.setSize(600, 400);
//				viewSrcFrame_.setVisible(true);
//				viewSrcFrame_.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
//				
//			} else {
//				viewSrcFrame_.setVisible(true);
//			}
//		}
//	}

	private final class MenuOpenActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			// currDirPath_ = "file:C:/workspace/galatea/../"
			String org = currLocalDirPath_.replaceFirst("file:", "");
			JFileChooser chooser = new JFileChooser(org); 
			chooser.showOpenDialog(null);
			File file = chooser.getSelectedFile();
			if ( file == null ) return;
			String uri = file.getAbsolutePath();
			uri = Util.replaceAll(uri, "\\", "/");
			uri = "file:" + uri;
			if (eventListener_ != null) {
				labelPauseMode_.setText("Mode: Run");
				eventListener_.setPauseModeAction(false);
				eventListener_.setNextDocumentAction(uri);
				eventListener_.terminateDialogAction();
			} else {
				System.out.println(e);
				System.out.println(uri);
			}
			//
			currLocalDirPath_ = Util.getUriDirectory(uri);
		}
	}

	private JEditorPane  applogPane_ = null;
	private StringBuffer applogContent_ = null;
	
	private JEditorPane  recogPane_ = null;
	private StringBuffer recogContent_ = null;
	
	private JEditorPane  statePane_ = null;
	private StringBuffer stateContent_ = null;
	
	private IDMWindowActionListener eventListener_ = null;
	
	private JLabel labelPauseMode_ = null;
	private JTextField textFieldLocation_ = null;
	private JTextArea textFieldSpeaking_ = null;
	
	private String currLocalDirPath_ = "";
	
	//
	//private JFrame viewSrcFrame_ = null;
	//private JEditorPane viewSrcPane_ = null;
	//private String srcFile_ = "";
	
	//
	//private JFrame viewTranslatedFrame_ = null;
	//private JEditorPane viewTranslatedPane_ = null;
	//private String translatedFile_ = "";
	
	//
	//private JFrame viewGrammarFrame_ = null;
	//private JEditorPane viewGrammarPane_ = null;
	//private String grammarFile_ = "";
	
	private String test1Label_;
	private String test1Command_;
	private String test2Label_;
	private String test2Command_;
	private String test3Label_;
	private String test3Command_;
	
	private String demo1Label_;
	private String demo1File_ ;
	private String demo2Label_;
	private String demo2File_ ;
	private String demo3Label_;
	private String demo3File_ ;
	private String demo4Label_;
	private String demo4File_ ;
	
	private JTextField textFieldDebuggerEval_;
	private JTextArea textFieldDebuggerResult_;
	private StringBuffer debugEvalResultContent_;

	private JTextArea textFieldHttpLog_;
	private String httpLogText_ = "";
	private JTextArea textFieldViewSrc_;
	private JTextArea textFieldViewGram_;
	private JTextArea textFieldViewTrans_;
	private JTextArea textFieldLogger_;
	private String loggerText_ = "";
	private JTextArea textFieldConfig_;
	
	private void _send(String str) {
		System.out.println(str);
		System.out.flush();
	}
	
	private void _makeWindow(int width, int height) throws Exception {
		JFrame frame = new JFrame(galatea.dialog.Tstamp.TSTAMP);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JMenuBar menuBar = _makeMenuBar();
		frame.setJMenuBar(menuBar);
		
		JTabbedPane tab = new JTabbedPane();
		tab.addTab("Main", _makeMainPanel());
		tab.addTab("Config", _makeConfigPanel());
		tab.addTab("Script", _makeDebuggerPanel());
		tab.addTab("Logger", _makeLoggerPanel());
		tab.addTab("Http", _makeHttpPanel());
		tab.addTab("Source", _makeViewSrcPanel());
		tab.addTab("Translated", _makeViewTransPanel());
		tab.addTab("Grammar", _makeViewGramPanel());
		tab.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		tab.setTabPlacement(SwingConstants.TOP);
		frame.getContentPane().add(tab);
		
		frame.setSize(width, height);
		frame.setVisible(true);
	}

	private JMenuBar _makeMenuBar() {
		// menu bar
		JMenuBar menuBar = new JMenuBar();
		JMenu menuFile = new JMenu("File");
		menuBar.add(menuFile);
		
		// File
		JMenuItem itemOpen = new JMenuItem("Open Local File...");
		menuFile.add(itemOpen);
		itemOpen.addActionListener( new MenuOpenActionListener());
		
		//
//		JMenuItem itemViewSrc = new JMenuItem("View Source");
//		menuFile.add(itemViewSrc);
//		itemViewSrc.addActionListener( new MenuViewSrcActionListener());
		
		//
//		JMenuItem itemViewTranslated = new JMenuItem("View Translated");
//		menuFile.add(itemViewTranslated);
//		itemViewTranslated.addActionListener( new MenuViewTranslatedActionListener());
		
		//
//		JMenuItem itemViewGrammar = new JMenuItem("View Grammar");
//		menuFile.add(itemViewGrammar);
//		itemViewGrammar.addActionListener( new MenuViewGrammarActionListener());
		
		//
		JMenuItem itemQuit = new JMenuItem("Quit Current Dialog");
		menuFile.add(itemQuit);
		itemQuit.addActionListener( new MenuQuitActionListener());
		
		//
		JMenuItem itemExit = new JMenuItem("Exit");
		menuFile.add(itemExit);
		itemExit.addActionListener( new MenuExitActionListener());
		
		// Face
		JMenu menuFace = new JMenu("Face");
		menuBar.add(menuFace);
		//
		JMenuItem itemAgentEnable = new JMenuItem("AgentEnable");
		menuFace.add(itemAgentEnable);
		itemAgentEnable.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set AgentEnable = ENABLE");
			}
		});
		JMenuItem itemAgentDisable = new JMenuItem("AgentDisable");
		menuFace.add(itemAgentDisable);
		itemAgentDisable.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set AgentEnable = DISABLE");
			}
		});
		//
		JMenuItem itemAgentAlpha10 = new JMenuItem("Alpha 1.0");
		menuFace.add(itemAgentAlpha10);
		itemAgentAlpha10.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set AgentAlpha = 1.0");
			}
		});
		JMenuItem itemAgentAlpha08 = new JMenuItem("Alpha 0.8");
		menuFace.add(itemAgentAlpha08);
		itemAgentAlpha08.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set AgentAlpha = 0.8");
			}
		});
		JMenuItem itemAgentAlpha05 = new JMenuItem("Alpha 0.5");
		menuFace.add(itemAgentAlpha05);
		itemAgentAlpha05.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set AgentAlpha = 0.5");
			}
		});
		JMenuItem itemAgentAlpha03 = new JMenuItem("Alpha 0.3");
		menuFace.add(itemAgentAlpha03);
		itemAgentAlpha03.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set AgentAlpha = 0.3");
			}
		});
		//
		JMenuItem itemViewMode1 = new JMenuItem("Texture");
		menuFace.add(itemViewMode1);
		itemViewMode1.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set ViewMode = TEXTURE");
			}
		});
		//
		JMenuItem itemViewMode2 = new JMenuItem("Texture with Wireframe");
		menuFace.add(itemViewMode2);
		itemViewMode2.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set ViewMode = TEXTURE_WITH_WIREFRAME");
			}
		});
		//
		JMenuItem itemViewMode3 = new JMenuItem("Wireframe");
		menuFace.add(itemViewMode3);
		itemViewMode3.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FSM set ViewMode = WIREFRAME");
			}
		});
		//
		
		// Mask
		JMenu menuMask = new JMenu("Mask");
		menuBar.add(menuMask);
		//
		JMenuItem itemMask1 = new JMenuItem("man01");
		menuMask.add(itemMask1);
		itemMask1.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set Mask = man01");
			}
		});
		//
		JMenuItem itemMask2 = new JMenuItem("man02");
		menuMask.add(itemMask2);
		itemMask2.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set Mask = man02");
			}
		});
		//
		JMenuItem itemMask3 = new JMenuItem("woman01");
		menuMask.add(itemMask3);
		itemMask3.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set Mask = woman01");
			}
		});
		//
		
		// Auto
		JMenu menuAuto = new JMenu("Auto");
		menuBar.add(menuAuto);
		//
		JMenuItem itemAutoMoveOn = new JMenuItem("AutoMove ON");
		menuAuto.add(itemAutoMoveOn);
		itemAutoMoveOn.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set AutoMove = 1");
			}
		});
		//
		JMenuItem itemAutoMoveOff = new JMenuItem("AutoMove OFF");
		menuAuto.add(itemAutoMoveOff);
		itemAutoMoveOff.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set AutoMove = 0");
			}
		});
		//
		JMenuItem itemAutoGazeOn = new JMenuItem("AutoGaze ON");
		menuAuto.add(itemAutoGazeOn);
		itemAutoGazeOn.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set AutoGaze = 1");
			}
		});
		//
		JMenuItem itemAutoGazeOff = new JMenuItem("AutoGaze OFF");
		menuAuto.add(itemAutoGazeOff);
		itemAutoGazeOff.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set AutoGaze = 0");
			}
		});
		//
		JMenuItem itemEmotionSpeakOn = new JMenuItem("EmotionSpeak ON");
		menuAuto.add(itemEmotionSpeakOn);
		itemEmotionSpeakOn.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set AutoEmotionSpeak = 1");
			}
		});
		//
		JMenuItem itemEmotionSpeakOff = new JMenuItem("EmotionSpeak OFF");
		menuAuto.add(itemEmotionSpeakOff);
		itemEmotionSpeakOff.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @AM-MCL set AutoEmotionSpeak = 0");
			}
		});
		//
		
		// Expression
		JMenu menuExp = new JMenu("Expression");
		menuBar.add(menuExp);
		//
		JMenuItem itemEmo1 = new JMenuItem("Neutral");
		menuExp.add(itemEmo1);
		itemEmo1.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FS-MCL set Emotion = NEUTRAL");
			}
		});
		//
		JMenuItem itemEmo2 = new JMenuItem("Happy");
		menuExp.add(itemEmo2);
		itemEmo2.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FS-MCL set Emotion = HAPPY 90");
			}
		});
		//
		JMenuItem itemEmo3 = new JMenuItem("Disgusted");
		menuExp.add(itemEmo3);
		itemEmo3.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FS-MCL set Emotion = DISGUSTED 90");
			}
		});
		//
		JMenuItem itemEmo4 = new JMenuItem("Sad");
		menuExp.add(itemEmo4);
		itemEmo4.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FS-MCL set Emotion = SAD 90");
			}
		});
		//
		JMenuItem itemEmo5 = new JMenuItem("Angry");
		menuExp.add(itemEmo5);
		itemEmo5.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FS-MCL set Emotion = ANGRY 90");
			}
		});
		//
		JMenuItem itemEmo6 = new JMenuItem("Surprised");
		menuExp.add(itemEmo6);
		itemEmo6.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FS-MCL set Emotion = SURPRISED 30");
			}
		});
		//
		JMenuItem itemEmo7 = new JMenuItem("Feared");
		menuExp.add(itemEmo7);
		itemEmo7.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				_send("to @FS-MCL set Emotion = FEARED 90");
			}
		});
		//
		
		// Demo
		JMenu menuDemo = new JMenu("Demo");
		menuBar.add(menuDemo);
		//
		
		test1Label_   = Property.getAsStr("DM.Window.Test.1.Label", null);
		test1Command_ = Property.getAsStr("DM.Window.Test.1.Command",  null);
		if (test1Label_ != null && test1Command_ != null) {
			JMenuItem itemTest1 = new JMenuItem(test1Label_);
			menuDemo.add(itemTest1);
			itemTest1.addActionListener( new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					_send(test1Command_);
				}
			});
		}
		
		test2Label_   = Property.getAsStr("DM.Window.Test.2.Label", null);
		test2Command_ = Property.getAsStr("DM.Window.Test.2.Command",  null);
		if (test2Label_ != null && test2Command_ != null) {
			JMenuItem itemTest2 = new JMenuItem(test2Label_);
			menuDemo.add(itemTest2);
			itemTest2.addActionListener( new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					_send(test2Command_);
				}
			});
		}
		
		test3Label_   = Property.getAsStr("DM.Window.Test.3.Label", null);
		test3Command_ = Property.getAsStr("DM.Window.Test.3.Command",  null);
		if (test3Label_ != null && test3Command_ != null) {
			JMenuItem itemTest3 = new JMenuItem(test3Label_);
			menuDemo.add(itemTest3);
			itemTest3.addActionListener( new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					_send(test3Command_);
				}
			});
		}
		
		
		demo1Label_ = Property.getAsStr("DM.Window.Demo.1.Label", null);
		demo1File_  = Property.getAsStr("DM.Window.Demo.1.File",  null);
		if (demo1Label_ != null && demo1File_ != null)  {
			JMenuItem itemDemo1 = new JMenuItem(demo1Label_);
			menuDemo.add(itemDemo1);
			itemDemo1.addActionListener( new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					String adrs = Util.resolveAdrs(currLocalDirPath_, demo1File_);
					if (eventListener_ != null) {
						labelPauseMode_.setText("Mode: Run");
						eventListener_.setPauseModeAction(false);
						eventListener_.setNextDocumentAction(adrs);
						eventListener_.terminateDialogAction();
					} else {
						System.err.println("adrs:" + adrs);
					}
				}
			});
		}
		
		demo2Label_ = Property.getAsStr("DM.Window.Demo.2.Label", null);
		demo2File_  = Property.getAsStr("DM.Window.Demo.2.File",  null);
		if (demo2Label_ != null && demo2File_ != null)  {
			JMenuItem itemDemo2 = new JMenuItem(demo2Label_);
			menuDemo.add(itemDemo2);
			itemDemo2.addActionListener( new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					String adrs = Util.resolveAdrs(currLocalDirPath_, demo2File_);
					if (eventListener_ != null) {
						labelPauseMode_.setText("Mode: Run");
						eventListener_.setPauseModeAction(false);
						eventListener_.setNextDocumentAction(adrs);
						eventListener_.terminateDialogAction();
					} else {
						System.err.println("adrs:" + adrs);
					}
				}
			});
		}
		
		demo3Label_ = Property.getAsStr("DM.Window.Demo.3.Label", null);
		demo3File_  = Property.getAsStr("DM.Window.Demo.3.File",  null);
		if (demo3Label_ != null && demo3File_ != null)  {
			JMenuItem itemDemo3 = new JMenuItem(demo3Label_);
			menuDemo.add(itemDemo3);
			itemDemo3.addActionListener( new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					String adrs = Util.resolveAdrs(currLocalDirPath_, demo3File_);
					if (eventListener_ != null) {
						labelPauseMode_.setText("Mode: Run");
						eventListener_.setPauseModeAction(false);
						eventListener_.setNextDocumentAction(adrs);
						eventListener_.terminateDialogAction();
					} else {
						System.err.println("adrs:" + adrs);
					}
				}
			});
		}
		
		demo4Label_ = Property.getAsStr("DM.Window.Demo.4.Label", null);
		demo4File_  = Property.getAsStr("DM.Window.Demo.4.File",  null);
		if (demo4Label_ != null && demo4File_ != null)  {
			JMenuItem itemDemo4 = new JMenuItem(demo4Label_);
			menuDemo.add(itemDemo4);
			itemDemo4.addActionListener( new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					String adrs = Util.resolveAdrs(currLocalDirPath_, demo4File_);
					if (eventListener_ != null) {
						labelPauseMode_.setText("Mode: Run");
						eventListener_.setPauseModeAction(false);
						eventListener_.setNextDocumentAction(adrs);
						eventListener_.terminateDialogAction();
					} else {
						System.err.println("adrs:" + adrs);
					}
				}
			});
		}
		return menuBar;
	}
	
	
	private GridBagConstraints _initPos() {
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.anchor = GridBagConstraints.NORTH;
		constraints.fill = GridBagConstraints.BOTH;
		constraints.insets = new Insets(3, 3, 3, 3);
		constraints.gridy = 0;
		constraints.gridheight = 1;
		return constraints;
	}
	

	// 延びない
	private void _setPos(GridBagConstraints c, int x, int width) {
		_setPos(c, x, width, 0, 0);
	}

	// 横方向に伸びる
	private void _setPos(GridBagConstraints c, int x, int width, int wx) {
		_setPos(c, x, width, wx, 0);
	}
	
	// 横方向にも縦方向にも伸びる
	private void _setPos(GridBagConstraints c, int x, int width, int wx, int wy) {
		c.gridx = x;
		c.gridwidth = width;
		c.weightx = wx;
		c.weighty = wy;
	}
	
	private void _nextRow(GridBagConstraints c) { 
		c.gridy++;
	}
	
	private JPanel _makeMainPanel() {
		// panel
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c = _initPos();
		
		// **-- location bar
		_setPos(c, 0, 2, 1);
		textFieldLocation_ = new JTextField();
		panel.add(textFieldLocation_, c);
		
		// --*- button 
		_setPos(c, 2, 1);
		JButton buttonGo = new JButton("Go"); 
		panel.add(buttonGo, c);
		buttonGo.addActionListener( new MainPanelGoActionListener());
		
		// ---* button 
		_setPos(c, 3, 1);
		JButton buttonValidate = new JButton("Validate"); 
		panel.add(buttonValidate, c);
		buttonValidate.addActionListener( new MainPanelValidateActionListener());
		
		// *--- run/pause mode
		_nextRow(c);
		_setPos(c, 0, 1, 1);
		JButton buttonStart = new JButton("Run"); 
		panel.add(buttonStart, c);
		buttonStart.addActionListener( new MainPanelButtonStartActionListener());
		
		// -*--
		_setPos(c, 1, 1, 1);
		JButton buttonStop = new JButton("Pause"); 
		panel.add(buttonStop, c);
		buttonStop.addActionListener( new MainPanelButtonStopActionListener());
		
		// --**
		_setPos(c, 2, 2);
		labelPauseMode_ = new JLabel("Mode: Run");
		panel.add(labelPauseMode_, c);
		
		
		// speaking
		_nextRow(c);
		_setPos(c, 0, 4);
		panel.add(new JLabel("Speak"), c);
		
		_nextRow(c);
		_setPos(c, 0, 4, 1, 1);
		textFieldSpeaking_ = new JTextArea();
		textFieldSpeaking_.setEditable(false);
		textFieldSpeaking_.setRows(3);
		textFieldSpeaking_.setLineWrap(true);
		panel.add(new JScrollPane(textFieldSpeaking_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		
		// applog
		_nextRow(c);
		_setPos(c, 0, 4);
		panel.add(new JLabel("Log"), c);
		
		_nextRow(c);
		_setPos(c, 0, 4, 1, 1);
		applogPane_ = new JEditorPane("text/plain", "");
		applogPane_.setEditable(false);
		panel.add(new JScrollPane(applogPane_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		
		_nextRow(c);
		_setPos(c, 0, 4);
		panel.add(new JLabel("Input"), c);
		
		_nextRow(c);
		_setPos(c, 0, 4, 1, 1);
		recogPane_ = new JEditorPane("text/plain", "");
		recogPane_.setEditable(false);
		panel.add(new JScrollPane(recogPane_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		
		_nextRow(c);
		_setPos(c, 0, 4);
		panel.add(new JLabel("State"), c);
		
		_nextRow(c);
		_setPos(c, 0, 4, 1, 1);
		statePane_ = new JEditorPane("text/plain", "");
		statePane_.setEditable(false);
		panel.add(new JScrollPane(statePane_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		return panel;
	}
	
	private JPanel _makeDebuggerPanel() {
		// panel
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c = _initPos();
		
		// ***-- textfield
		_setPos(c, 0, 3, 1);
		textFieldDebuggerEval_ = new JTextField();
		panel.add(textFieldDebuggerEval_, c);
		
		// ---*- button 
		_setPos(c, 3, 1);
		JButton buttonGo = new JButton("Eval"); 
		panel.add(buttonGo, c);
		buttonGo.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String str = textFieldDebuggerEval_.getText();
				if (eventListener_ != null) {
					debugEvalResultContent_.append(">" + str + "\n");
					textFieldDebuggerResult_.setText(
							debugEvalResultContent_.toString());
					eventListener_.setDebuggerEvalAction(str);
				} else {
					System.out.println(e);
					System.out.println(str);
				}
			}
		});
		
		// ----* button 
		_setPos(c, 4, 1);
		JButton buttonSrc = new JButton("To Source"); 
		panel.add(buttonSrc, c);
		buttonSrc.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String str = textFieldDebuggerEval_.getText();
				str += ".toSource()";
				if (eventListener_ != null) {
					debugEvalResultContent_.append(">" + str + "\n");
					textFieldDebuggerResult_.setText(
							debugEvalResultContent_.toString());
					eventListener_.setDebuggerEvalAction(str);
				} else {
					System.out.println(e);
					System.out.println(str);
				}
			}
		});
		

		_nextRow(c);
		_setPos(c, 0, 5);
		panel.add(new JLabel("Result"), c);
		
		_nextRow(c);
		_setPos(c, 0, 5, 1, 1);
		textFieldDebuggerResult_ = new JTextArea();
		textFieldDebuggerResult_.setEditable(false);
		textFieldDebuggerResult_.setRows(3);
		textFieldDebuggerResult_.setLineWrap(true);
		panel.add(new JScrollPane(textFieldDebuggerResult_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		return panel;
	}
		
	public void dispDebuggerEvalResult(String result) {
		debugEvalResultContent_.append(result + "\n");
		if (textFieldDebuggerResult_ != null) {
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					textFieldDebuggerResult_.setText(
							debugEvalResultContent_.toString());
				}
			});
		}
	}

	private JPanel _makeLoggerPanel() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c = _initPos();
		_setPos(c, 0, 0, 1, 1);
		textFieldLogger_ = new JTextArea();
		textFieldLogger_.setEditable(false);
		textFieldLogger_.setRows(1);
		textFieldLogger_.setLineWrap(true);
		panel.add(new JScrollPane(textFieldLogger_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		return panel;
	}

	private JPanel _makeHttpPanel() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c = _initPos();
		_setPos(c, 0, 0, 1, 1);
		textFieldHttpLog_ = new JTextArea();
		textFieldHttpLog_.setEditable(false);
		textFieldHttpLog_.setRows(1);
		textFieldHttpLog_.setLineWrap(true);
		panel.add(new JScrollPane(textFieldHttpLog_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		return panel;
	}
	
	private JPanel _makeViewSrcPanel() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c = _initPos();
		_setPos(c, 0, 0, 1, 1);
		textFieldViewSrc_ = new JTextArea();
		textFieldViewSrc_.setEditable(false);
		textFieldViewSrc_.setRows(1);
		textFieldViewSrc_.setLineWrap(true);
		panel.add(new JScrollPane(textFieldViewSrc_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		return panel;
	}
	
	private JPanel _makeViewGramPanel() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c = _initPos();
		_setPos(c, 0, 0, 1, 1);
		textFieldViewGram_ = new JTextArea();
		textFieldViewGram_.setEditable(false);
		textFieldViewGram_.setRows(1);
		textFieldViewGram_.setLineWrap(true);
		panel.add(new JScrollPane(textFieldViewGram_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		return panel;
	}
	
	private JPanel _makeViewTransPanel() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c = _initPos();
		_setPos(c, 0, 0, 1, 1);
		textFieldViewTrans_ = new JTextArea();
		textFieldViewTrans_.setEditable(false);
		textFieldViewTrans_.setRows(1);
		textFieldViewTrans_.setLineWrap(true);
		panel.add(new JScrollPane(textFieldViewTrans_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		return panel;
	}
	
	private JPanel _makeConfigPanel() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c = _initPos();
		_setPos(c, 0, 0, 1, 1);
		textFieldConfig_ = new JTextArea();
		textFieldConfig_.setEditable(false);
		textFieldConfig_.setRows(1);
		textFieldConfig_.setLineWrap(true);
		panel.add(new JScrollPane(textFieldConfig_,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
		), c
		);
		
		String config = Property.getConfigStrings();
		textFieldConfig_.setText(config);
		
		return panel;
	}
	
	public DialogManagerWindow() {
		applogContent_ = new StringBuffer();
		recogContent_  = new StringBuffer();
		stateContent_ = new StringBuffer();
		debugEvalResultContent_ = new StringBuffer();
		currLocalDirPath_ = Property.getAsStr("user.dir", "/");
		currLocalDirPath_ += Property.getAsStr("user.dir.suffix", "/files/");
		currLocalDirPath_ = "file:" + Util.replaceAll(currLocalDirPath_, "\\", "/");
		
		if ( Property.getAsBoolean("ShowWindow", true)) {
			try {
				_setLookAndFeel();
				int w = Property.getAsInt("DM.WindowWidth", 640);
				int h = Property.getAsInt("DM.WindowHeight", 480);
				_makeWindow(w, h);
			} catch(Exception e) { 
				System.out.println(e); 
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private void _setLookAndFeel() {
		final String metal   = "javax.swing.plaf.metal.MetalLookAndFeel";
		final String mac     = "com.sun.java.swing.plaf.mac.MacLookAndFeel";
		final String motif   = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
		final String windows = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
		final String gtk     = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
		String lafname = metal;
		if (Util.isWindows()) {
			lafname = windows;
		}
		try {
			Class lnfClass = Class.forName(windows);
			LookAndFeel newLAF = (LookAndFeel) (lnfClass.newInstance());
			if (newLAF.isSupportedLookAndFeel()) {
				try {
					UIManager.setLookAndFeel(newLAF);
					//SwingUtilities.updateComponentTreeUI(this);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void documentLocationChanged(String text) {
		if (textFieldLocation_ != null) {
			textFieldLocation_.setText(text);
		}
	}
	
	public void outputVoiceStarted(String text) {
		if (textFieldSpeaking_ != null) {
			textFieldSpeaking_.setText(Util.removeTags(text));
		}
	}
	
	public void dispApplog(String text) {
		if (applogContent_ != null) {
			applogContent_.insert(0, text + "\n");
		}
		if (applogPane_ != null) {
			applogPane_.setText(applogContent_.toString());
		}
	}
	
	public void inputEventReceived(String text) {
		if (recogContent_ != null) {
			recogContent_.insert(0, text + "\n");
		}
		if (recogPane_ != null) {
			recogPane_.setText(recogContent_.toString());
		}
	}
	
	public void dialogStateChanged(String text) {
		if (stateContent_ != null) {
			stateContent_.insert(0, text + "\n");
		}
		if (statePane_ != null) {
			statePane_.setText(stateContent_.toString());
		}
	}
	
	public void fatalError(String error) {
		if (stateContent_ != null) {
			stateContent_.insert(0, error + "\n");
		}
		if (statePane_ != null) {
			statePane_.setText(stateContent_.toString());
		}
	}

	public void setDialogManagerWindowActionListener(
			IDMWindowActionListener listener) {
		eventListener_ = listener;
	}
	
	public void srcFileUpdated(String text) {
//		srcFile_ = text;
//		if (viewSrcPane_ != null) {
//			viewSrcPane_.setText(srcFile_);
//		}
		if (textFieldViewSrc_ != null) {
			textFieldViewSrc_.setText(text);
		}
	}
	
	public void translatedFileUpdated(String text) {
//		translatedFile_ = text;
//		if (viewTranslatedPane_ != null) {
//			viewTranslatedPane_.setText(translatedFile_);
//		}
		if (textFieldViewTrans_ != null) {
			textFieldViewTrans_.setText(text);
		}
	}
	
	public void grammarFileUpdated(String text) {
//		grammarFile_ = text;
//		if (viewGrammarPane_ != null) {
//			viewGrammarPane_.setText(grammarFile_);
//		}
		if (textFieldViewGram_ != null) {
			textFieldViewGram_.setText(text);
		}
	}
	
	@Override
	public void addNetUtilEvent(String msg) {
		if (textFieldHttpLog_ != null) {
			httpLogText_ += msg + "\n";
			textFieldHttpLog_.setText(httpLogText_);
		}
	}

	@Override
	public void addLoggerEvent(String msg) {
		if (textFieldLogger_ != null) {
			loggerText_ = msg + "\n" + loggerText_;
			textFieldLogger_.setText(loggerText_);
		}
	}

	public static void main(String args[]) throws Exception {
		DialogManagerWindow w = new DialogManagerWindow();
		w.dispApplog("abc日本語です。");
		w.dispApplog("java.io.tmpdir=" + System.getProperty("java.io.tmpdir"));
		w.dispApplog("os.arch=" + System.getProperty("os.arch"));
		w.dispApplog("os.name=" + System.getProperty("os.name"));
		w.dispApplog("user.dir=" + System.getProperty("user.dir"));
		
		for (int i = 0; ; i++) {
			String s = "test" + i;
			w.dispApplog(s);
			try { 
				Thread.sleep(3000);
			} catch (Exception e) {e.printStackTrace();}
		}
	}

}

