/*******************************************************************************
 * Copyright (c) 2004, 2013 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ant.internal.ui.editor.text;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.ant.internal.ui.editor.AntEditor;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.IAntElement;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;

public class AntFoldingStructureProvider {

	private AntEditor fEditor;
	private IDocument fDocument;

	/**
	 * A mapping of the foldable position to the <code>AntElementNode<code> that represent that region
	 */
	private Map<Position, IAntElement> fPositionToElement = new HashMap<>();

	public AntFoldingStructureProvider(AntEditor editor) {
		fEditor = editor;
	}

	private void updateFoldingRegions(ProjectionAnnotationModel model, Set<Position> currentRegions) {
		Annotation[] deletions = computeDifferences(model, currentRegions);

		Map<Annotation, Position> additionsMap = new HashMap<>();
		for (Iterator<Position> iter = currentRegions.iterator(); iter.hasNext();) {
			Position position = iter.next();
			IAntElement node = fPositionToElement.get(position);
			additionsMap.put(new ProjectionAnnotation(node.collapseProjection()), position);
		}

		if ((deletions.length != 0 || additionsMap.size() != 0)) {
			model.modifyAnnotations(deletions, additionsMap, new Annotation[] {});
		}
	}

	private Annotation[] computeDifferences(ProjectionAnnotationModel model, Set<Position> additions) {
		List<Annotation> deletions = new ArrayList<>();
		for (Iterator<Annotation> iter = model.getAnnotationIterator(); iter.hasNext();) {
			Object annotation = iter.next();
			if (annotation instanceof ProjectionAnnotation) {
				Annotation annot = (Annotation) annotation;
				Position position = model.getPosition(annot);
				if (additions.contains(position)) {
					additions.remove(position);
				} else {
					deletions.add(annot);
				}
			}
		}
		return deletions.toArray(new Annotation[deletions.size()]);
	}

	public void updateFoldingRegions(AntModel antModel) {
		fPositionToElement = new HashMap<>();
		try {
			ProjectionAnnotationModel model = fEditor.getAdapter(ProjectionAnnotationModel.class);
			if (model == null) {
				return;
			}

			Set<Position> currentRegions = new HashSet<>();
			List<IAntElement> root = new ArrayList<>();
			AntProjectNode node = antModel.getProjectNode();
			if (node != null && node.getOffset() != -1) {
				root.add(node);
				List<AntElementNode> nodes = antModel.getNonStructuralNodes();
				root.addAll(nodes);
			}
			addFoldingRegions(currentRegions, root);
			updateFoldingRegions(model, currentRegions);
		}
		catch (BadLocationException be) {
			// ignore as document has changed
		}
	}

	private void addFoldingRegions(Set<Position> regions, List<IAntElement> children) throws BadLocationException {
		// add a Position to 'regions' for each foldable region
		for (IAntElement element : children) {
			if (element.getImportNode() != null || element.isExternal()) {
				continue; // elements are not really in this document and therefore are not foldable
			}
			int startLine = fDocument.getLineOfOffset(element.getOffset());
			int endLine = fDocument.getLineOfOffset(element.getOffset() + element.getLength());
			if (startLine < endLine) {
				int start = fDocument.getLineOffset(startLine);
				int end = fDocument.getLineOffset(endLine) + fDocument.getLineLength(endLine);
				Position position = new Position(start, end - start);
				regions.add(position);
				fPositionToElement.put(position, element);
			}

			List<IAntElement> childNodes = element.getChildNodes();
			if (childNodes != null) {
				addFoldingRegions(regions, childNodes);
			}
		}
	}

	public void setDocument(IDocument document) {
		fDocument = document;
	}
}
