/*******************************************************************************
 * Copyright (c) 2004 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.jst.jsp.ui.tests.other;

import java.io.IOException;
import java.io.InputStream;

import org.eclipse.jst.jsp.ui.tests.Logger;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.sse.core.internal.util.StringUtils;
import org.eclipse.wst.xml.core.internal.document.DOMModelImpl;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class StructuredDocumentToDOMUnitTests implements IStructuredDocumentListener {
	public StructuredDocumentToDOMUnitTests() {
		super();
	}

	String getTestString1() {
		return "<a>a<b />b</a>"; // -> <a>ab</a>;
	}

	String getTestString2() {
		return "<menu>\n<rname>\nLiam's Chowder House and Grill\n</rname>\n</menu>";
	}

	String getTestString3() {
		// return " <?xml version=\"1.0\" ?>\n
		// <testTopSibling><p>text</p></testTopSibling>";
		return "<test/>\n\n <html>\n</html>";
	}

	String getTestString4() {
		return "<?xml version=\"1.0\" ?>";
	}

	/**
	 * 
	 * @param args
	 *            java.lang.String[]
	 */
	public static void main(String[] args) {

		try {
			StructuredDocumentToDOMUnitTests instance = new StructuredDocumentToDOMUnitTests();
			instance.testNodeDeletion4();
		}
		catch (Exception t) {
			t.printStackTrace();
		}
	}

	void makeChange1(IDOMModel tree) {

		//	
		// pick a parent and ones of its children to delete
		// (note: validity of this code is highly dependent on input string)
		org.w3c.dom.Document dom = tree.getDocument();
		NodeList nodes = dom.getChildNodes();
		//
		/*
		 * for "first" test case Node testParentNode = nodes.item(0); Node
		 * testChildNode = testParentNode.getFirstChild();
		 */
		// for "second" test case
		Node testParentNode = nodes.item(0);
		Node testChildNode = testParentNode.getFirstChild();
		testChildNode = testChildNode.getNextSibling();

		testParentNode.removeChild(testChildNode);

	}

	void makeChange2(IStructuredDocument structuredDocument) {

		// delete the apostrope in test string // 4, 4?
		structuredDocument.replaceText(this, 19, 1, null);
	}

	void makeChange3(IDOMModel tree) {

		//	
		// pick a parent and ones of its children to delete
		// (note: validity of this code is highly dependent on input string)
		org.w3c.dom.Document dom = tree.getDocument();
		// NodeList nodes = dom.getChildNodes();
		//
		Node testChildNode = dom.getLastChild();

		dom.removeChild(testChildNode);

	}

	/**
	 * newModel method comment.
	 */
	public void newModel(NewDocumentEvent structuredDocumentEvent) {
		System.out.println("newModel:");
	}

	/**
	 * noChange method comment.
	 */
	public void noChange(NoChangeEvent structuredDocumentEvent) {
		// log for now, unless we find reason not to
		Logger.log(Logger.INFO, "StructuredDocumentToDOMUnitTests::noChange needs to be implemented");
	}

	/**
	 * nodesReplaced method comment.
	 */
	public void nodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {
		System.out.println("nodesReplaced:");
		System.out.println("\tNewFlatNodes:");
		IStructuredDocumentRegionList flatNodeList = structuredDocumentEvent.getNewStructuredDocumentRegions();
		int len = flatNodeList.getLength();
		for (int i = 0; i < len; i++) {
			String outString = flatNodeList.item(i).toString();
			outString = StringUtils.escape(outString);
			System.out.println("\t\t" + outString);
		}
		System.out.println("\tOldFlatNodes:");
		flatNodeList = structuredDocumentEvent.getOldStructuredDocumentRegions();
		len = flatNodeList.getLength();
		for (int i = 0; i < len; i++) {
			String outString = flatNodeList.item(i).toString();
			outString = StringUtils.escape(outString);
			System.out.println("\t\t" + outString);
		}
	}

	/**
	 * regionChanged method comment.
	 */
	public void regionChanged(RegionChangedEvent structuredDocumentEvent) {
		System.out.println("regionChanged:");
	}

	/**
	 * regionsReplaced method comment.
	 */
	public void regionsReplaced(RegionsReplacedEvent structuredDocumentEvent) {
		System.out.println("regionsReplaced:");
	}

	/**
	 * Unit test -- tests basic parsing results of inserting a test string
	 * into an initial string.
	 */
	void testNodeDeletion() {
		// String initialString =
		// "<par><x>\ntextx\n</x>\n<y>\ntexty\n</y></par>";
		// String initialString = "<par><x>textx</x><y>texty</y></par>";
		// test cases for two text nodes left together (remove <b/>):
		// first case works, second doesn't
		// String initialString = "<a>a<b /></a>"; // -> <a>a</a>
		// String initialString = "<a>a<b />b</a>"; // -> <a>ab</a>
		// String initialString = getTestString1();
		String initialString = getTestString2();

		// print out what we always can
		System.out.println();
		System.out.println("----------------");
		System.out.println("Test Node Deletion");
		String outString = StringUtils.escape(initialString);
		System.out.println("Initial String: " + outString);
		// always start with fresh model
		IStructuredDocument f = null;

		IModelManager mm = StructuredModelManager.getModelManager();
		try {
			f = mm.createStructuredDocumentFor("dummy.xml", (InputStream) null, null);
		}
		catch (IOException e) {
			// do nothing, since dummy
		}


		//
		// we'll listen to structuredDocument events to print out diagnostics
		f.addDocumentChangedListener(this);
		//

		IDOMModel tree = new DOMModelImpl();
		f.addDocumentChangingListener((IStructuredDocumentListener) tree);

		// set text to structuredDocument (which updates tree)
		f.setText(null, initialString);

		// dump initial structuredDocument
		Debug.dump(f);
		// dump initial dom
		DebugDocument.dump(tree.getDocument());
		//
		//
		// makeChange1(tree);
		makeChange2(f);

		// display resulting text
		System.out.println("resultString (from structuredDocument): ");
		System.out.println(StringUtils.escape(f.getText()));
		//
		//
		// dump post change structuredDocument
		Debug.dump(f);
		// dump post change DOM
		DebugDocument.dump(tree.getDocument());

		//

	}

	/**
	 * Unit test -- tests basic parsing results of inserting a test string
	 * into an initial string.
	 */
	void testNodeDeletion3() {
		String initialString = getTestString3();

		// print out what we always can
		System.out.println();
		System.out.println("----------------");
		System.out.println("Test Node Deletion");
		String outString = StringUtils.escape(initialString);
		System.out.println("Initial String: " + outString);
		// always start with fresh model
		IStructuredDocument f = null;

		IModelManager mm = StructuredModelManager.getModelManager();
		try {
			f = mm.createStructuredDocumentFor("dummy.xml", (InputStream) null, null);
		}
		catch (IOException e) {
			// do nothing, since dummy
		}
		//
		// we'll listen to structuredDocument events to print out diagnostics
		f.addDocumentChangedListener(this);
		//

		IDOMModel tree = new DOMModelImpl();
		f.addDocumentChangingListener((IStructuredDocumentListener) tree);

		// set text to structuredDocument (which updates tree)
		f.setText(null, initialString);

		// dump initial structuredDocument
		Debug.dump(f);
		// dump initial dom
		DebugDocument.dump(tree.getDocument());
		//
		//
		// makeChange1(tree);
		makeChange3(tree);

		// display resulting text
		System.out.println("resultString (from structuredDocument): ");
		System.out.println(StringUtils.escape(f.getText()));
		//
		//
		// dump post change structuredDocument
		Debug.dump(f);
		// dump post change DOM
		DebugDocument.dump(tree.getDocument());

		//

	}

	/**
	 * Unit test -- test insert followed by delete at beginning of string.
	 */
	void testNodeDeletion4() {
		String initialString = getTestString4();

		// print out what we always can
		System.out.println();
		System.out.println("----------------");
		System.out.println("Test Node Insert and Delete");
		String outString = StringUtils.escape(initialString);
		System.out.println("Initial String: " + outString);
		// always start with fresh model
		IStructuredDocument f = null;

		IModelManager mm = StructuredModelManager.getModelManager();
		try {
			f = mm.createStructuredDocumentFor("dummy.xml", (InputStream) null, null);
		}
		catch (IOException e) {
			// do nothing, since dummy
		}
		//
		// we'll listen to structuredDocument events to print out diagnostics
		f.addDocumentChangedListener(this);
		//

		IDOMModel tree = new DOMModelImpl();
		f.addDocumentChangingListener((IStructuredDocumentListener) tree);

		// set text to structuredDocument (which updates tree)
		f.setText(null, initialString);

		// dump initial structuredDocument
		Debug.dump(f);
		// dump initial dom
		DebugDocument.dump(tree.getDocument());
		//
		//
		f.replaceText(null, 0, 0, "a");

		System.out.println(" ==== Results after insert");
		// display resulting text
		System.out.println("resultString (from structuredDocument): ");
		System.out.println(StringUtils.escape(f.getText()));
		//
		//
		// dump post change structuredDocument
		Debug.dump(f);
		// dump post change DOM
		DebugDocument.dump(tree.getDocument());

		//

		f.replaceText(null, 0, 1, "");

		System.out.println(" ==== Results after delete");
		// display resulting text
		System.out.println("resultString (from structuredDocument): ");
		System.out.println(StringUtils.escape(f.getText()));
		//
		//
		// dump post change structuredDocument
		Debug.dump(f);
		// dump post change DOM
		DebugDocument.dump(tree.getDocument());

		//

	}
}