[309606] Develop Script Editor
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/build.properties b/plugins/org.eclipse.actf.examples.scripteditor/build.properties
index 3ba46d6..06928ed 100644
--- a/plugins/org.eclipse.actf.examples.scripteditor/build.properties
+++ b/plugins/org.eclipse.actf.examples.scripteditor/build.properties
@@ -17,6 +17,7 @@
                plugin_customization.ini,\
                about.bmp,\
                about.html,\
-               favorites.pref
+               favorites.pref,\
+               resources/
 output.. = bin/
 source.. = src/
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/plugin.xml b/plugins/org.eclipse.actf.examples.scripteditor/plugin.xml
index 810a697..e1c20e0 100644
--- a/plugins/org.eclipse.actf.examples.scripteditor/plugin.xml
+++ b/plugins/org.eclipse.actf.examples.scripteditor/plugin.xml
@@ -71,6 +71,13 @@
                style="push">
          </action>
          <action
+               class="org.eclipse.actf.examples.scripteditor.actions.ExportHTMLAction"
+               id="org.eclipse.actf.examples.scripteditor.ExportHTMLAction"
+               label="Export HTML"
+               menubarPath="file/impExportGroup"
+               style="push">
+         </action>
+         <action
                class="org.eclipse.actf.examples.scripteditor.actions.FileCSVExportAction"
                id="org.eclipse.actf.examples.scripteditor.FileCSVExporttAction"
                label="%scripteditor.action.csv.export"
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/resources/css/vd-player-ie.css b/plugins/org.eclipse.actf.examples.scripteditor/resources/css/vd-player-ie.css
new file mode 100644
index 0000000..cffa4f6
--- /dev/null
+++ b/plugins/org.eclipse.actf.examples.scripteditor/resources/css/vd-player-ie.css
@@ -0,0 +1,19 @@
+.vd-container {
+/*	display: inline !important;*/
+	zoom: 1 !important;
+}
+
+.vd-container .vd-captions span {
+	background: black !important;
+}
+
+.vd-container, .vd-container .vd-controls, .vd-container .vd-descriptions, .vd-container .vd-descriptions-config {
+	zoom: 1 !important;
+	width: 480px !important;
+}
+
+.vd-prefetcher {
+	position: absolute !important;
+	left: -65535px !important;
+}
+
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/resources/css/vd-player.css b/plugins/org.eclipse.actf.examples.scripteditor/resources/css/vd-player.css
new file mode 100644
index 0000000..d89efb2
--- /dev/null
+++ b/plugins/org.eclipse.actf.examples.scripteditor/resources/css/vd-player.css
@@ -0,0 +1,69 @@
+.vd-container {
+	position: relative;
+	display: inline-block;
+	text-align: center;
+	background: #808080;
+	min-width: 480px;
+}
+
+.vd-container {
+	position: relative;
+	display: inline-block;
+	text-align: center;
+}
+
+.vd-container .vd-descriptions {
+	position: relative;
+	height: 1px;
+	padding: 0;
+	margin: 0;
+	text-align: left;
+	border-bottom: solid 1px #404040;
+	background: #ffffff;
+	min-width: 480px;
+	overflow: hidden;
+}
+
+.vd-container .vd-descriptions.vd-show {
+	height: 4em;
+	padding: 0.25ex 0;
+}
+
+.vd-container .vd-descriptions-config {
+	text-align: right;
+	background: #ffffff;
+	min-width: 480px;
+}
+
+.vd-container .vd-captions {
+	position: absolute;
+	width: 96%;
+	margin: 2%;
+	padding: 0;
+	color: white;
+	font-size: 150%;
+	font-family: sans-serif;
+	text-align: center;
+	left: 0;
+	bottom: 1em;
+	text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
+}
+
+.vd-container .vd-controls {
+	position: relative;
+	background: #404040;
+	margin: 0;
+	padding: 0;
+	color: white;
+	font-family: sans-serif;
+	text-align: right;
+}
+
+.vd-container .vd-controls button {
+	float: left;
+}
+
+.vd-container .vd-controls span {
+	line-height: 1.5;
+}
+
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player.js b/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-ja.js
similarity index 100%
rename from plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player.js
rename to plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-ja.js
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/ai/scripteditor/util/TTMLUtil.java b/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/ai/scripteditor/util/TTMLUtil.java
new file mode 100644
index 0000000..190f179
--- /dev/null
+++ b/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/ai/scripteditor/util/TTMLUtil.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation and Others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Kentarou FUKUDA - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.ai.scripteditor.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+
+import org.eclipse.actf.ai.internal.ui.scripteditor.XMLFileMessageBox;
+import org.eclipse.actf.ai.scripteditor.data.ScriptData;
+import org.eclipse.actf.ai.ui.scripteditor.views.IUNIT;
+import org.eclipse.actf.util.FileUtils;
+import org.eclipse.swt.SWT;
+
+public class TTMLUtil {
+
+	private static ScriptData instScriptData = ScriptData.getInstance();
+
+	/**
+	 * Export AudioDescription data in TTML format
+	 */
+	public static void exportTTML(String ttmlPathname, boolean warnOverwrite) {
+		exportTTML(ttmlPathname, false, null, null, null, warnOverwrite);
+	}
+
+	/**
+	 * Export AudioDescription data in TTML format and pre-recorded
+	 * AudioDescription(AD) WAV files
+	 */
+	public static void exportTTMLandWAV(String ttmlPathname,
+			String adWavDirpath, String adWavFilename, String adUrlBase,
+			boolean warnOverwrite) {
+		exportTTML(ttmlPathname, true, adWavDirpath, adWavFilename, adUrlBase,
+				warnOverwrite);
+	}
+
+	/**
+	 * Export AudioDescription data in TTML format and pre-recorded
+	 * AudioDescription(AD) WAV files
+	 */
+	private static void exportTTML(String ttmlPathname, boolean isPrerecorded,
+			String adWavDirpath, String adWavFilename, String adUrlBase,
+			boolean warnOverwrite) {
+		PrintWriter writer = null;
+
+		VoicePlayerFactory voice = VoicePlayerFactory.getInstance();
+
+		try {
+			File file = new File(ttmlPathname);
+
+			if (warnOverwrite && file.exists()) {
+				XMLFileMessageBox warningExistFile = new XMLFileMessageBox(
+						IUNIT.MB_STYLE_OVERWR, ttmlPathname);
+				int ret = warningExistFile.open();
+				if (ret != SWT.YES)
+					return;
+			}
+
+			writer = new PrintWriter(new OutputStreamWriter(
+					new FileOutputStream(ttmlPathname), "UTF-8"));
+
+			String LINE_SEP = FileUtils.LINE_SEP;
+
+			writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+			writer.println("<?xml-stylesheet href=\"ttml.css\" type=\"text/css\"?>");
+			writer.println("<?access-control allow=\"*\"?>");
+			writer.println("<tt ttp:profile='http://www.w3.org/ns/ttml/profile/dfxp-full'"
+					+ LINE_SEP
+					+ "    xmlns='http://www.w3.org/ns/ttml'"
+					+ LINE_SEP
+					+ "    xmlns:ttm='http://www.w3.org/ns/ttml#metadata'"
+					+ LINE_SEP
+					+ "    xmlns:tts='http://www.w3.org/ns/ttml#styling'"
+					+ LINE_SEP
+					+ "    xmlns:ttp='http://www.w3.org/ns/ttml#parameter'"
+					+ LINE_SEP
+					+ "    xmlns:tvd='http://www.eclipse.org/actf/ai/tvd'>");
+			writer.println(" <head>");
+			writer.println("  <metadata>");
+			writer.println("   <ttm:title>TextTrack (Audio Description)</ttm:title>");// TODO
+			writer.println("  </metadata>");
+
+			writer.println("  <styling>" + LINE_SEP
+					+ "   <style xml:id=\"style1\"/>" + LINE_SEP
+					+ "  </styling>" + LINE_SEP + "  <layout>" + LINE_SEP
+					+ "   <region xml:id=\"region1\" style=\"style1\"/>"
+					+ LINE_SEP + "  </layout>" + LINE_SEP
+					+
+					//
+					" </head>" + LINE_SEP + " <body>" + LINE_SEP
+					+ "  <div role=\"narration\" region=\"region1\">");
+
+			if (isPrerecorded) {
+				File readmeFile = new File(adWavDirpath + "1st_Readme.txt");
+				try {
+					PrintWriter pw = new PrintWriter(readmeFile, "UTF-8");
+					if (voice.canSpeakToFile()) {
+						pw.println("Please convert wav files into wma/oga/m4a formats.");
+						pw.println(" wma: for IE8 or older");
+						pw.println(" oga: for Chrome, Firefox, Opera");
+						pw.println(" m4a: for IE9 or later, Safari");
+						pw.println();
+						pw.println("After converting files, please deploy these files to your Web server,");
+						pw.println("and adjust URLs of \"tvd:external\" attribute in "
+								+ file.getName());
+						pw.flush();
+						pw.close();
+					} else {
+						pw.println("This TTS engine can't create wav files.");
+						pw.println("Please prepare audio descriptions in wma/oga/m4a formats.");
+						pw.println(" wma: for IE8 or older");
+						pw.println(" oga: for Chrome, Firefox, Opera");
+						pw.println(" m4a: for IE9 or later, Safari");
+						pw.println();
+						pw.println("After preparing files, please deploy these files to your Web server,");
+						pw.println("and adjust URLs of \"tvd:external\" attribute in "
+								+ file.getName());
+						pw.flush();
+						pw.close();
+					}
+				} catch (Exception e) {
+				}
+			}
+
+			// Write all ScriptData
+			for (int i = 0; i < instScriptData.getLengthScriptList(); i++) {
+				int startTime = instScriptData.getScriptStartTime(i);
+				int frame = (startTime % 1000) / (1000 / 30);
+				String frameS = (frame > 9) ? Integer.toString(frame) : "0"
+						+ frame;
+
+				String strStartTime = instScriptData
+						.makeFormatHHMMSS(startTime / 1000) + ":" + frameS;
+				int endTime = instScriptData.getScriptEndTime(i);
+
+				int duration = endTime - startTime;
+				frame = (endTime % 1000) / (1000 / 30);
+				frameS = (frame > 9) ? Integer.toString(frame) : "0" + frame;
+
+				String StrEndTime = instScriptData
+						.makeFormatHHMMSS(endTime / 1000) + ":" + frameS;
+
+				frame = (duration % 1000) / (1000 / 30);
+				frameS = (frame > 9) ? Integer.toString(frame) : "0" + frame;
+
+				String strDuration = instScriptData
+						.makeFormatHHMMSS(duration / 1000) + ":" + frameS;
+
+				String strDesc = instScriptData.getScriptData(i);
+
+				// TODO diff duration with next item				
+				writer.print("    <p xml:id=\"description" + i + "\" begin=\""
+						+ strStartTime);
+				if (instScriptData.getExtendExtended(i)) {
+					writer.print("\" tvd:extended=\"true\" dur=\""
+							+ strDuration + "\"");
+				} else {
+					writer.print("\" tvd:extended=\"false\" end=\""
+							+ StrEndTime + "\"");
+				}
+
+				if (isPrerecorded) {
+					int number = i + 1;
+					String ad_file;
+					if (number < 10) {
+						ad_file = adWavFilename + "_0000" + number;
+					} else if (number < 100) {
+						ad_file = adWavFilename + "_000" + number;
+					} else if (number < 1000) {
+						ad_file = adWavFilename + "_00" + number;
+					} else if (number < 10000) {
+						ad_file = adWavFilename + "_0" + number;
+					} else {
+						ad_file = adWavFilename + number;
+					}
+					if (adUrlBase == null || adUrlBase.isEmpty()) {
+						writer.print(" tvd:external=\"file://" + adWavDirpath
+								+ ad_file + ".*\"");
+					} else {
+						writer.print(" tvd:external=\"" + adUrlBase + ad_file
+								+ ".*\"");
+					}
+					if (voice.canSpeakToFile()) {
+						String strGender = instScriptData.getExtendGender(i) ? "male"
+								: "female";
+						voice.setGender(strGender);
+						voice.setSpeed(instScriptData.getExtendSpeed(i));
+						voice.speakToFile(instScriptData.getScriptData(i),
+								new File(adWavDirpath + ad_file + ".wav"));
+					}
+				}
+				writer.println(">" + canonicalize(strDesc) + "</p>");
+			}
+
+			writer.println("  </div>" + LINE_SEP + " </body>" + LINE_SEP
+					+ "</tt>");
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (writer != null) {
+				try {
+					writer.flush();
+					writer.close();
+				} catch (Exception e) {
+				}
+			}
+		}
+	}
+
+	private static String canonicalize(String targetS) {
+		return (targetS.replaceAll("\\p{Cntrl}", "").replaceAll("&", "&amp;")
+				.replaceAll("<", "&lt;").replaceAll(">", "&gt;")
+				.replaceAll("\"", "&quot;").replaceAll("\'", "&apos;"));
+	}
+
+}
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/examples/scripteditor/actions/ExportHTMLAction.java b/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/examples/scripteditor/actions/ExportHTMLAction.java
new file mode 100644
index 0000000..260c4a1
--- /dev/null
+++ b/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/examples/scripteditor/actions/ExportHTMLAction.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 IBM Corporation and Others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.examples.scripteditor.actions;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+
+import org.eclipse.actf.ai.internal.ui.scripteditor.XMLFileMessageBox;
+import org.eclipse.actf.ai.scripteditor.util.ResourceUtil;
+import org.eclipse.actf.ai.scripteditor.util.TTMLUtil;
+import org.eclipse.actf.ai.scripteditor.util.WebBrowserFactory;
+import org.eclipse.actf.ai.ui.scripteditor.views.IUNIT;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+public class ExportHTMLAction implements IWorkbenchWindowActionDelegate {
+
+	// parameters
+	private static final String[] NAMES = { "HTML (*.HTML)" };
+	private static final String[] EXTENSIONS = { "*.html" };
+
+	/**
+	 * Export HTML template
+	 */
+	private void exportHTML(String filepath, String adFilename,
+			boolean warnOverwrite) {
+		PrintWriter writer = null;
+		try {
+			File file = new File(filepath);
+
+			if (warnOverwrite && file.exists()) {
+				XMLFileMessageBox warningExistFile = new XMLFileMessageBox(
+						IUNIT.MB_STYLE_OVERWR, filepath);
+				int ret = warningExistFile.open();
+				if (ret != SWT.YES)
+					return;
+			}
+
+			writer = new PrintWriter(new OutputStreamWriter(
+					new FileOutputStream(filepath), "UTF-8"));
+
+			String url = WebBrowserFactory.getInstance().getVideoURL();
+
+			if (url == null) {
+				return;
+			}
+
+			int index1 = url.lastIndexOf(".");
+			int index2 = url.lastIndexOf("/");
+			int index3 = url.lastIndexOf("\\");
+
+			if (index1 > 0 && (index2 > 0 && index2 < index1)
+					|| (index3 > 0 && index3 < index1)) {
+				url = url.substring(0, index1);
+			}
+			if (url.startsWith("http")) {
+				if (index1 > 0 && (index2 > 7 && index2 < index1)) {
+					url = url.substring(0, index1);
+				}
+			} else {
+				if (index1 > 0 && (index2 > 0 && index2 < index1)
+						|| (index3 > 0 && index3 < index1)) {
+					url = url.substring(0, index1);
+				}
+				url = "file://" + url;
+			}
+
+			writer.println("<!DOCTYPE html>");
+			writer.println("<html lang=\"en\">");
+			writer.println("<head>");
+			writer.println("<meta content=\"text/html; charset=utf-8\" http-equiv=content-type>");
+			writer.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
+			writer.println("");
+			writer.println("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7; IE=EmulateIE9\">");
+			writer.println("");
+			writer.println("<title>Audio Description Template</title>");
+			writer.println("");
+			writer.println("<!-- HTML5 movie header start -->");
+			writer.println("    <!--[if lt IE 9]>");
+			writer.println("    <link rel=\"stylesheet\" href=\"resource/vd-player-ie.css\">");
+			writer.println("    <script src=\"resource/vd-compat-ie.js\" defer></script>");
+			writer.println("    <![endif]-->");
+			writer.println("    <link rel=\"stylesheet\" href=\"resource/vd-player.css\">");
+			writer.println("    <script src=\"resource/vd-compat.js\" defer></script>");
+			writer.println("    <script src=\"resource/vd-player-en.js\" defer></script>");
+			writer.println("<!-- HTML5 movie header end -->");
+			writer.println("");
+			writer.println("</head>");
+			writer.println("<body>");
+			writer.println("<div>");
+			writer.println("");
+			writer.println("<!-- HTML5 movie main start-->");
+			writer.println("    <video width=\"320\" height=\"240\">");
+			writer.println("        <source type=\"video/ogg\" src=\"" + url
+					+ ".ogv\">");
+			writer.println("        <source type=\"video/mp4\" src=\"" + url
+					+ ".mp4\">");
+			writer.println("        <source type=\"video/x-ms-wmv\" src=\""
+					+ url + ".wmv\">");
+			writer.println("        <track kind=\"metadata\" data-kind=\"descriptions\" src=\""
+					+ adFilename
+					+ "\" srclang=\"en\" label=\"Audio Description\" default>"); // TODO
+																					// lang
+			writer.println("    </video>");
+			writer.println("<!-- HTML5 movie main end-->");
+			writer.println("");
+			writer.println("</div>");
+			writer.println("</body>");
+			writer.println("</html>");
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (writer != null) {
+				try {
+					writer.flush();
+					writer.close();
+				} catch (Exception e) {
+				}
+			}
+		}
+	}
+
+	public void run(IAction action) {
+		// Request FileDialog (Choice open file name)
+		FileDialog saveDialog = new FileDialog(Display.getCurrent()
+				.getActiveShell(), SWT.SAVE);
+		saveDialog.setFilterNames(NAMES);
+		saveDialog.setFilterExtensions(EXTENSIONS);
+		saveDialog.setFileName("audio_description_template.html");
+		String saveFilepath = saveDialog.open();
+
+		if (saveFilepath != null) {
+
+			int last = saveFilepath.lastIndexOf(".html");
+			String preRecordedFilepath;
+			if (last > 0) {
+				preRecordedFilepath = saveFilepath.substring(0, last)
+						+ "_p.html";
+			} else {
+				preRecordedFilepath = saveFilepath + "_p.html";
+			}
+
+			// TODO
+			int index = saveFilepath.lastIndexOf(File.separator);
+			String dirName = saveFilepath.substring(0, index + 1);
+			String fileName;
+			if (last > 0) {
+				fileName = saveFilepath.substring(index+1, last);
+			} else {
+				fileName = saveFilepath.substring(index+1);
+			}
+
+			exportHTML(saveFilepath, fileName + "_ad.xml", true);
+			exportHTML(preRecordedFilepath, fileName + "_ad_p.xml", false);
+
+			File resourceDir = new File(dirName + "resource");
+			resourceDir.mkdir();
+			ResourceUtil.saveResources(dirName + "resource" + File.separator);
+
+			File adFilesDir = new File(dirName + "ad_files");
+			adFilesDir.mkdir();
+
+			String adFilepath = dirName + fileName + "_ad.xml";
+			TTMLUtil.exportTTML(adFilepath, false);
+
+			adFilepath = dirName + fileName + "_ad_p.xml";
+			TTMLUtil.exportTTMLandWAV(adFilepath, dirName + "ad_files" + File.separator,
+					fileName, null, false);
+		}
+	}
+
+	public void dispose() {
+	}
+
+	public void init(IWorkbenchWindow window) {
+	}
+
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+}
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/examples/scripteditor/actions/ExportTTMLAction.java b/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/examples/scripteditor/actions/ExportTTMLAction.java
index 7e4872f..d507121 100644
--- a/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/examples/scripteditor/actions/ExportTTMLAction.java
+++ b/plugins/org.eclipse.actf.examples.scripteditor/src/org/eclipse/actf/examples/scripteditor/actions/ExportTTMLAction.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and Others
+ * Copyright (c) 2010, 2012 IBM Corporation and Others
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -10,17 +10,7 @@
  *******************************************************************************/
 package org.eclipse.actf.examples.scripteditor.actions;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-
-import org.eclipse.actf.ai.internal.ui.scripteditor.PreviewPanel;
-import org.eclipse.actf.ai.internal.ui.scripteditor.XMLFileMessageBox;
-import org.eclipse.actf.ai.scripteditor.data.ScriptData;
-import org.eclipse.actf.ai.ui.scripteditor.views.IUNIT;
-import org.eclipse.actf.util.FileUtils;
+import org.eclipse.actf.ai.scripteditor.util.TTMLUtil;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.swt.SWT;
@@ -29,182 +19,21 @@
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.IWorkbenchWindowActionDelegate;
 
-public class ExportTTMLAction implements IWorkbenchWindowActionDelegate, IUNIT {
-
-	/**
-	 * Local data
-	 */
-	// instance of each ViewPart class
-	private ScriptData instScriptData = null;
-	private PreviewPanel instPreviewPanel = null;
-
-	// private Shell instParentShell = null;
+public class ExportTTMLAction implements IWorkbenchWindowActionDelegate {
 
 	// parameters
 	private static final String[] NAMES = { "TTML format (*.xml)" };
 	private static final String[] EXTENSIONS = { "*.xml" };
-	private String saveFileName = "";
 
-	/**
-	 * Local method : PickUP instance of each ViewPart class
-	 */
-	private void pickupInstViewPart() {
-		if (instScriptData == null) {
-			instScriptData = ScriptData.getInstance();
-		}
-		if (instPreviewPanel == null) {
-			instPreviewPanel = PreviewPanel.getInstance();
-		}
-	}
-
-	/**
-	 * Local method : Save data to target file(CSV)
-	 */
-	private void saveFile(String fname, boolean warnOverwrite) {
-		PrintWriter writer = null;
-		try {
-			File file = new File(fname);
-
-			// already file exist
-			if (warnOverwrite && file.exists()) {
-				// Warning : No Script data
-				XMLFileMessageBox warningExistFile = new XMLFileMessageBox(
-						MB_STYLE_OVERWR, fname);
-				// Check answer
-				int ret = warningExistFile.open();
-				if (ret != SWT.YES)
-					return;
-			}
-
-			// Open file
-			writer = new PrintWriter(new OutputStreamWriter(
-					new FileOutputStream(fname), "UTF-8"));
-
-			String LINE_SEP = FileUtils.LINE_SEP;
-
-			// Write Header & Comments
-			writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-			writer.println("<?xml-stylesheet href=\"ttml.css\" type=\"text/css\"?>");
-			writer.println("<?access-control allow=\"*\"?>");
-			writer.println("<tt ttp:profile='http://www.w3.org/ns/ttml/profile/dfxp-full'"
-					+ LINE_SEP
-					+ "    xmlns='http://www.w3.org/ns/ttml'"
-					+ LINE_SEP
-					+ "    xmlns:ttm='http://www.w3.org/ns/ttml#metadata'"
-					+ LINE_SEP
-					+ "    xmlns:tts='http://www.w3.org/ns/ttml#styling'"
-					+ LINE_SEP
-					+ "    xmlns:ttp='http://www.w3.org/ns/ttml#parameter'"
-					+ LINE_SEP
-					+ "    xmlns:actftvd='http://www.eclipse.org/actf/ai/tvd'>");
-			writer.println(" <head>");
-			writer.println("  <ttm:title>" + instPreviewPanel.getURLMovie()
-					+ "</ttm:title>");// TODO
-
-			writer.println(
-			/*
-			 * "  <styling>" + LINE_SEP +
-			 * "    <style xml:id='ad1' tts:color='yellow' tts:fontFamily='proportionalSansSerif' tts:fontSize='16px' tts:textAlign='left'/>"
-			 * + LINE_SEP + "  </styling>" + LINE_SEP + "  <layout>" + LINE_SEP
-			 * + "   <region xml:id='descriptionArea'" + LINE_SEP +
-			 * "           style='ad1'" + LINE_SEP +
-			 * "           tts:origin='0% -15%'" + LINE_SEP +
-			 * "           tts:extent='100% 20%'" + LINE_SEP +
-			 * "           tts:padding='0px 0px'" + LINE_SEP +
-			 * "           tts:backgroundColor='black'" + LINE_SEP +
-			 * "           tts:opacity='0.75'" + LINE_SEP +
-			 * "           tts:displayAlign='before'" + LINE_SEP +
-			 * "           tts:showBackground='whenActive' />" + LINE_SEP +
-			 * "  </layout>" + LINE_SEP +
-			 */
-			" </head>" + LINE_SEP + " <body>" + LINE_SEP
-					+ "  <div role=\"narration\" region=\"descriptionArea\">");
-
-			// Write all ScriptData
-			for (int i = 0; i < instScriptData.getLengthScriptList(); i++) {
-				int startTime = instScriptData.getScriptStartTime(i);
-				int frame = (startTime % 1000) / (1000 / 30);
-				String frameS = (frame > 9) ? Integer.toString(frame) : "0"
-						+ frame;
-
-				String strStartTime = instScriptData
-						.makeFormatHHMMSS(startTime / 1000) + ":" + frameS;
-				int endTime = instScriptData.getScriptEndTime(i) + 250; // TBD
-				if (i < instScriptData.getLengthScriptList() - 1) {
-					if (endTime > instScriptData.getScriptStartTime(i + 1)) {
-						endTime = instScriptData.getScriptStartTime(i + 1) - 100;
-					}
-				}
-
-				int duration = endTime - startTime;
-				frame = (endTime % 1000) / (1000 / 30);
-				frameS = (frame > 9) ? Integer.toString(frame) : "0" + frame;
-
-				String StrEndTime = instScriptData
-						.makeFormatHHMMSS(endTime / 1000) + ":" + frameS;
-
-				frame = (duration % 1000) / (1000 / 30);
-				frameS = (frame > 9) ? Integer.toString(frame) : "0" + frame;
-
-				String strDuration = instScriptData
-						.makeFormatHHMMSS(duration / 1000) + ":" + frameS;
-
-				String strDesc = instScriptData.getScriptData(i);
-
-				// TODO diff duration with next item
-				/*
-				 * writer.println("    <p xml:id=\"description"+i+
-				 * "\" ttm:role=\"narration\" begin=\"" +
-				 * strStartTime+"\" dur=\""
-				 * +strDuration+"s\">"+canonicalize(strDesc )+"</p>");
-				 */
-				writer.print("    <p xml:id=\"description" + i
-						+ "\" ttm:role=\"narration\" begin=\"" + strStartTime);
-				if (instScriptData.getExtendExtended(i)) {
-					writer.println("\" actftvd:extended='true' dur=\""
-							+ strDuration + "\" >" + canonicalize(strDesc)
-							+ "</p>");
-				} else {
-					writer.println("\" end=\"" + StrEndTime + "\">"
-							+ canonicalize(strDesc) + "</p>");
-				}
-			}
-
-			writer.println("  </div>" + LINE_SEP + " </body>" + LINE_SEP
-					+ "</tt>");
-
-		} catch (IOException e) {
-			e.printStackTrace();
-		} finally {
-			if (writer != null) {
-				try {
-					writer.flush();
-					writer.close();
-				} catch (Exception e) {
-				}
-			}
-		}
-	}
-
-	/**
-	 * run() method
-	 */
 	public void run(IAction action) {
-		// Request FileDialog (Choice open file name)
 		FileDialog saveDialog = new FileDialog(Display.getCurrent()
 				.getActiveShell(), SWT.SAVE);
 		saveDialog.setFilterNames(NAMES);
 		saveDialog.setFilterExtensions(EXTENSIONS);
-		saveFileName = saveDialog.open();
+		String filepath = saveDialog.open();
 
-		// Check null (file name)
-		if (saveFileName != null) {
-			// Store instance of each ViewPart class
-			pickupInstViewPart();
-			// instParentShell = instSelWavTab.getParentShell();
-
-			// Save file
-			saveFile(saveFileName, true);
+		if (filepath != null) {
+			TTMLUtil.exportTTML(filepath, true);
 		}
 	}
 
@@ -216,10 +45,4 @@
 
 	public void selectionChanged(IAction action, ISelection selection) {
 	}
-
-	private String canonicalize(String targetS) {
-		return (targetS.replaceAll("\\p{Cntrl}", "").replaceAll("&", "&amp;")
-				.replaceAll("<", "&lt;").replaceAll(">", "&gt;")
-				.replaceAll("\"", "&quot;").replaceAll("\'", "&apos;"));
-	}
 }