/*******************************************************************************
 * 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.wst.sse.core.IModelManager;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.events.NoChangeEvent;
import org.eclipse.wst.sse.core.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.exceptions.SourceEditingException;
import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegionList;
import org.eclipse.wst.sse.core.util.Debug;
import org.eclipse.wst.sse.core.util.StringUtils;
import org.eclipse.wst.xml.core.document.XMLModel;
import org.eclipse.wst.xml.core.internal.document.XMLModelImpl;
import org.eclipse.wst.xml.core.internal.util.DebugDocument;
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(XMLModel 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(XMLModel 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) {
		throw new SourceEditingRuntimeException("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() throws SourceEditingException {
		//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; //new com.ibm.sed.structuredDocument.impl.IStructuredDocument(com.ibm.sed.model.IStructuredModel.XML);

		IModelManager mm = StructuredModelManager.getInstance().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);
		//

		XMLModel tree = new XMLModelImpl();
		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() throws SourceEditingException {
		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; //new com.ibm.sed.structuredDocument.impl.IStructuredDocument(com.ibm.sed.model.IStructuredModel.XML);

		IModelManager mm = StructuredModelManager.getInstance().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);
		//

		XMLModel tree = new XMLModelImpl();
		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() throws SourceEditingException {
		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; //new com.ibm.sed.structuredDocument.impl.IStructuredDocument(com.ibm.sed.model.IStructuredModel.XML);

		IModelManager mm = StructuredModelManager.getInstance().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);
		//

		XMLModel tree = new XMLModelImpl();
		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());

		//

	}
}