/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/

package svt.gui;

import static org.openoffice.test.common.Testspace.*;
import static org.openoffice.test.vcl.Tester.*;
import static testlib.gui.AppTool.*;
import static testlib.gui.UIMap.*;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.openoffice.test.common.Condition;
import org.openoffice.test.common.FileUtil;
import org.openoffice.test.common.Logger;

import testlib.gui.SDTool;

@RunWith(Parameterized.class)
public class TestSample {

	public static String repos = "samples";

	public static String[][] params = {};

	@Parameters
	public static Collection<Object[]> data() {
		File dir = new File(repos);
		ArrayList<Object[]> list = new ArrayList<Object[]>();
		collect(dir, list);
		return list;
	}

	/**
	 * @see <a href="http://www.ibm.com">Manual Case</a>
	 * @param dir
	 * @param list
	 */
	public static void collect(File dir, ArrayList<Object[]> list) {
		File[] files = dir.listFiles();
		if (files == null)
			return;

		for (File file : files) {
			if (file.isDirectory()) {
				collect(file, list);
			} else {
				String fileName = file.getName().toLowerCase();
				for (String[] param : params) {
					String filter = param[0];
					if (filter != null && fileName.matches(filter)) {
						Object[] data = { file, param[1], param[2] };
						list.add(data);
						System.out.println(file + param[1] + param[2]);
						break;
					}
				}
			}
		}
	}

	private static final String writerFilter = ".*\\.((odt)|(ott)|(sxw)|(stw)|(doc)|(dot)|(docx)|(docm)|(dotx)|(dotm))$";
	private static final String calcFilter = ".*\\.((ods)|(ots)|(sxc)|(stc)|(xls)|(xlt)|(xlsx)|(xltx)|(xlsm)|(xltm))$";
	private static final String impressFilter = ".*\\.((odp)|(otp)|(sxi)|(sti)|(ppt)|(pot)|(pptx)|(pptm)|(potm)|(potx))$";
	private static final String drawFilter = ".*\\.((odg)|(otg)|(sxd)|(sxt))$";
	private static final String databaseFilter = ".*\\.(odb)$";

	@Rule
	public Logger log = Logger.getLogger(this);
	private File originalFile = null;
	private String saveas = null;
	private String editor = null;
	private File file = null;
	private String saveTo = null;
	private boolean passed = false;

	public TestSample(File file, String saveas, String editor) {
		this.originalFile = file;
		this.saveas = saveas;
		this.editor = editor;
	}

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() {
		app.start();

		FileUtil.deleteFile(getPath("temp"));
		File temp = new File(getPath("temp"));
		temp.mkdirs();
		log.info("Load sample file from \"" + originalFile.getAbsolutePath() + "\"");
		file = new File(temp + "/origin", "sample." + FileUtil.getFileExtName(originalFile.getName()) /*
																									 * file
																									 * .
																									 * getName
																									 * (
																									 * )
																									 */);
		FileUtil.copyFile(originalFile, file); // We use the copy to do test
		saveTo = getPath("temp/" + file.getName() + (saveas == null ? "" : "." + saveas));
	}

	@After
	public void tearDown() {
		if (!passed) {
			// Collect the failed sample files.
			File failedDir = new File(getPath("output/TestSample.Failed"));
			FileUtil.copyFile(originalFile, new File(failedDir, originalFile.getName()));
		}
	}

	@Test
	public void test() {
		if (editor == null) {
			String name = file.getName();
			if (name.matches(writerFilter)) {
				testWriter();
			} else if (name.matches(calcFilter)) {
				testCalc();
			} else if (name.matches(impressFilter)) {
				testImpress();
			} else if (name.matches(drawFilter)) {

			} else if (name.matches(databaseFilter)) {

			} else {
				Assert.assertTrue("It's supported", false);
			}
		} else {
			if (editor.equals("writer"))
				testWriter();
			if (editor.equals("calc"))
				testCalc();
			if (editor.equals("impress"))
				testImpress();
			if (editor.equals("draw"))
				testDraw();
			if (editor.equals("database"))
				testDatabase();
		}
	}

	private void testDatabase() {
		// TODO Auto-generated method stub

	}

	private void testDraw() {
		// TODO Auto-generated method stub

	}

	public void testWriter() {
		open(file.getAbsolutePath());
		handleBlocker(writer);
		sleep(10);

		// Assert.assertTrue("File Passed:" + file,
		// writer.getCaption().contains(file.getName()));
		saveAs(saveTo);
		if (alienFormatDlg.exists(3))
			alienFormatDlg.ok();
		sleep(2);
		writer.waitForEnabled(120, 2);
		close();
		
		open(saveTo);
		handleBlocker(writer);
		sleep(10);

		// Assert.assertTrue("File Passed:" + file,
		// writer.getCaption().contains(file.getName()));
		close();
		passed = true;
	}

	public void testCalc() {
		startcenter.menuItem("File->Open...").select();
		submitOpenDlg(file.getAbsolutePath());
		handleBlocker(calc);
		sleep(10); // Wait. Crash maybe occurs when the file is shown!

		// Assert.assertTrue("File Passed:" + file,
		// calc.getCaption().contains(file.getName()));

		calc.menuItem("File->Save As...").select();
		submitSaveDlg(saveTo);
		if (alienFormatDlg.exists(3))
			alienFormatDlg.ok();
		sleep(2);

		new Condition() {
			@Override
			public boolean value() {
				if (msgBox_AdditionalRowsNotSaved.exists()) {
					msgBox_AdditionalRowsNotSaved.ok();
				}
				return calc.isEnabled();
			}

		}.waitForTrue("Time out to wait the control to be enabled!", 120, 2);

		calc.menuItem("File->Close").select();
		openStartcenter();
		// Reopen the saved file
		startcenter.menuItem("File->Open...").select();
		submitOpenDlg(saveTo);
		handleBlocker(calc);
		sleep(10);

		// Assert.assertTrue("File Passed:" + file,
		// calc.getCaption().contains(file.getName()));
		calc.menuItem("File->Close").select();
		passed = true;
	}

	public void testImpress() {
		startcenter.menuItem("File->Open...").select();
		submitOpenDlg(file.getAbsolutePath());
		handleBlocker(impress, impressSlideSorter, impressOutline, impressHandout);
		sleep(10); // Wait. Crash maybe occurs when the file is shown!
		SDTool.getActiveView().menuItem("View->Normal").select();

		// Assert.assertTrue("File Passed:" + file,
		// impress.getCaption().contains(file.getName()));

		impress.menuItem("File->Save As...").select();
		submitSaveDlg(saveTo);
		if (alienFormatDlg.exists(3))
			alienFormatDlg.ok();
		sleep(2);
		impress.waitForEnabled(120, 2);
		impress.menuItem("File->Close").select();
		openStartcenter();
		// Reopen the saved file
		startcenter.menuItem("File->Open...").select();
		submitOpenDlg(saveTo);
		handleBlocker(impress);
		sleep(10); // Wait.

		// Assert.assertTrue("File Passed:" + file,
		// impress.getCaption().contains(file.getName()));
		impress.menuItem("File->Close").select();
		passed = true;
	}
}
