/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.compare.examples.xml;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;

import org.eclipse.core.runtime.IProgressMonitor;

public class OrderedMatching extends AbstractMatching {

	public OrderedMatching() {
		super();
	}

	protected int orderedMath(XMLNode x, XMLNode y) {
		//assumes x and y have children
		Object[] xc= x.getChildren();
		Object[] yc= y.getChildren();

		ArrayList xc_elementsAL= new ArrayList();
		ArrayList xc_attrsAL= new ArrayList();

		ArrayList yc_elementsAL= new ArrayList();
		ArrayList yc_attrsAL= new ArrayList();

		//find attributes and elements and put them in xc_elementsAL and xc_attrsAL, respectively
		for (int i= 0; i < xc.length; i++) {
			XMLNode x_i= (XMLNode) xc[i];
			if (x_i.getXMLType().equals(XMLStructureCreator.TYPE_ELEMENT)) {
				xc_elementsAL.add(x_i);
			} else if (
				x_i.getXMLType().equals(XMLStructureCreator.TYPE_ATTRIBUTE)) {
				xc_attrsAL.add(x_i);
			}
		}

		//do the same for yc				
		for (int i= 0; i < yc.length; i++) {
			XMLNode y_i= (XMLNode) yc[i];
			if (y_i.getXMLType().equals(XMLStructureCreator.TYPE_ELEMENT)) {
				yc_elementsAL.add(y_i);
			} else if (
				y_i.getXMLType().equals(XMLStructureCreator.TYPE_ATTRIBUTE)) {
				yc_attrsAL.add(y_i);
			}
		}

		Object[] xc_elements= xc_elementsAL.toArray();
		Object[] yc_elements= yc_elementsAL.toArray();

		ArrayList DTMatching= new ArrayList();
		// Matching to be added to Entry in fDT_Matchings
		int distance= 0; //distance to be added to entry in fDT

		// perform unordered matching on attributes
		// this updates fDT and fDT_Matchings
		if (xc_attrsAL.size() > 0 || yc_attrsAL.size() > 0) {
			if (xc_attrsAL.size() == 0)
				distance += yc_attrsAL.size();
			else if (yc_attrsAL.size() == 0)
				distance += xc_attrsAL.size();
			else {
				//unorderedMatch(x, y, xc_attrs, yc_attrs);
				//				distance += fDT[indexOfLN(x)][indexOfRN(y)];
				//				DTMatching= fDT_Matchings[indexOfLN(x)][indexOfRN(y)];
				distance= handleAttributes(xc_attrsAL, yc_attrsAL, DTMatching);
			}
		}

		//perform ordered matching on element children, i.e. number them in order of appearance

		/* start new */
		distance=
			handleRangeDifferencer(
				xc_elements,
				yc_elements,
				DTMatching,
				distance);
		/* end new */

		/* start: Naive ordered compare /*
		//			int minlength= (xc_elements.length > yc_elements.length)?yc_elements.length:xc_elements.length;
		//			for (int i= 0; i < minlength; i++) {
		//				distance += dist((XMLNode) xc_elements[i], (XMLNode) yc_elements[i]);
		//				DTMatching.add(new Match( (XMLNode)xc_elements[i], (XMLNode)yc_elements[i]));
		//			}
		//			if (xc_elements.length > yc_elements.length) {
		//				for (int i= minlength; i < xc_elements.length; i++) {
		//					distance += countNodes((XMLNode) xc_elements[i]);
		//				}
		//			} else if (xc_elements.length < yc_elements.length) {
		//				for (int i= minlength; i < yc_elements.length; i++) {
		//					distance += countNodes((XMLNode) yc_elements[i]);
		//				}
		//			}
		/* end: Naive ordered compare */

		fDT[indexOfLN(x)][indexOfRN(y)]= distance;
		fDT_Matchings[indexOfLN(x)][indexOfRN(y)]= DTMatching;
		return distance;

	}

	/* matches two trees according to paper "X-Diff", p. 16 */
	public void match(
		XMLNode LeftTree,
		XMLNode RightTree,
		boolean rightTreeIsAncestor,
		IProgressMonitor monitor)
		throws InterruptedException {

		fNLeft= new Vector();
		//numbering LeftTree: Mapping nodes in LeftTree to numbers to be used as array indexes
		fNRight= new Vector();
		//numbering RightTree: Mapping nodes in RightTree to numbers to be used as array indexes
		numberNodes(LeftTree, fNLeft);
		numberNodes(RightTree, fNRight);
		fDT= new int[fNLeft.size()][fNRight.size()];
		fDT_Matchings= new ArrayList[fNLeft.size()][fNRight.size()];
		for (int i= 0; i < fDT.length; i++) {
			fDT[i]= new int[fNRight.size()];
			for (int j= 0; j < fDT[0].length; j++) {
				fDT[i][j]= NO_ENTRY;
			}
		}

		dist(LeftTree, RightTree);
		//		/* mark matchings on LeftTree and RightTree */
		fMatches= new Vector();
		if (!LeftTree.getSignature().equals(RightTree.getSignature())) {
			//matching is empty	
		} else {
			fMatches.add(new Match(LeftTree, RightTree));
			for (int i_M= 0; i_M < fMatches.size(); i_M++) {
				Match m= (Match) fMatches.elementAt(i_M);
				if (!isLeaf(m.fx) && !isLeaf(m.fy)) {
					//					if (fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ] == null)
					//						System.out.println("Error: ID not unique for " + m.fx.getId());
					//					else
					//						fMatches.addAll(fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ]);
					if (fDT_Matchings[indexOfLN(m.fx)][indexOfRN(m.fy)]
						!= null)
						fMatches.addAll(
							fDT_Matchings[indexOfLN(m.fx)][indexOfRN(m.fy)]);
				}
			}
		}
		//end of Step2
		/* Renumber Id of Nodes to follow Matches. Or for ancestor, copy over Id to ancestor */
		if (rightTreeIsAncestor) {
			for (ListIterator it_M= fMatches.listIterator(); it_M.hasNext();) {
				Match m= (Match) it_M.next();
				if (m.fx != null && m.fy != null)
					m.fy.setId(m.fx.getId());
			}
		} else {
			int newId= 0;
			for (ListIterator it_M= fMatches.listIterator();
				it_M.hasNext();
				newId++) {
				Match m= (Match) it_M.next();
				if (m.fx != null)
					m.fx.setId(Integer.toString(newId));
				if (m.fy != null)
					m.fy.setId(Integer.toString(newId));
				//				System.out.println("Matching: "+ ((m.fx != null)?m.fx.getOrigId():"null")+" -> "+((m.fx != null)?m.fx.getId():"null")+" , "+((m.fy != null)?m.fy.getOrigId():"null")+" -> "+((m.fy != null)?m.fy.getId():"null")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			}
		}
		//if (monitor != null) monitor.done();
	}

	public int handleAttributes(
		ArrayList xc_attrs,
		ArrayList yc_attrs,
		ArrayList DTMatching) {
		int distance= 0;
		x_for : for (
			Iterator iter_xc= xc_attrs.iterator(); iter_xc.hasNext();) {
			XMLNode x_attr= (XMLNode) iter_xc.next();
			String x_attr_name= x_attr.getName();
			for (Iterator iter_yc= yc_attrs.iterator(); iter_yc.hasNext();) {
				XMLNode y_attr= (XMLNode) iter_yc.next();
				if (y_attr.getName().equals(x_attr_name)) {
					if (!y_attr.getValue().equals(x_attr.getValue()))
						distance += 1;
					DTMatching.add(new Match(x_attr, y_attr));
					yc_attrs.remove(y_attr);
					continue x_for;
				}
			}
			DTMatching.add(new Match(x_attr, null));
			distance += 1;
		}

		for (Iterator iter_yc= yc_attrs.iterator(); iter_yc.hasNext();) {
			DTMatching.add(new Match(null, (XMLNode) iter_yc.next()));
			distance += 1;
		}

		return distance;
	}

	protected int handleXandYnotLeaves(XMLNode x, XMLNode y) {
		/* handle entries as ordered*/
		return orderedMath(x, y);
	}
}
