/*******************************************************************************
 * 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.jface.text;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;

 
/**
 * Describes the presentation styles for a section of an indexed text 
 * such as a document or string. A text presentation defines a default style
 * for the whole section and in addition style differences for individual 
 * subsections. Text presentations can be narrowed down to a particular
 * result window. All methods are result window aware, i.e. ranges outside
 * the result window are always ignored.<p>
 * All iterators provided by a text presentation assume that they enumerate
 * non overlapping, consecutive ranges inside the default range. Thus, all
 * these iterators do not include the default range. The default style range
 * must be explicitly asked for using <code>getDefaultStyleRange</code>.
 */
public class TextPresentation {
	
	/**
	 * Applies the given presentation to the given text widget. Helper method.
	 *
	 * @param presentation the style information
	 * @param the widget to which to apply the style information
	 * @since 2.0
	 */
	public static void applyTextPresentation(TextPresentation presentation, StyledText text) {
		
		StyleRange[] ranges= new StyleRange[presentation.getDenumerableRanges()];				
		
		int i= 0;
		Iterator e= presentation.getAllStyleRangeIterator();
		while (e.hasNext())
			ranges[i++]= (StyleRange) e.next();
		
		text.setStyleRanges(ranges);
	}	
	
	
	
	
	/**
	 * Enumerates all the <code>StyleRange</code>s included in the presentation.
	 */
	class FilterIterator implements Iterator {
		
		/** The index of the next style range to be enumerated */
		protected int fIndex;
		/** The upper bound of the indices of style ranges to be enumerated */
		protected int fLength;
		/** Indicates whether ranges similar to the default range should be enumerated */
		protected boolean fSkipDefaults;
		/** The result window */
		protected IRegion fWindow;
		
		/**
		 * <code>skipDefaults</code> tells the enumeration to skip all those style ranges
		 * which define the same style as the presentation's default style range.
		 * 
		 * @param skipDefaults <code>false</code> if ranges similar to the default range should be enumerated
		 */
		protected FilterIterator(boolean skipDefaults) {
			
			fSkipDefaults= skipDefaults;
			
			fWindow= fResultWindow;
			fIndex= getFirstIndexInWindow(fWindow);
			fLength= getFirstIndexAfterWindow(fWindow);
			
			if (fSkipDefaults)
				computeIndex();
		}
		
		/*
		 * @see Iterator#next()
		 */
		public Object next() {
			try {
				StyleRange r= (StyleRange) fRanges.get(fIndex++);
				return createWindowRelativeRange(fWindow, r);
			} catch (ArrayIndexOutOfBoundsException x) {
				throw new NoSuchElementException();
			} finally {
				if (fSkipDefaults)
					computeIndex();
			}
		}
		
		/*
		 * @see Iterator#hasNext()
		 */
		public boolean hasNext() {
			return fIndex < fLength;
		}
		
		/*
		 * @see Iterator#remove()
		 */
		public void remove() {
			throw new UnsupportedOperationException();
		}
		
		/**
		 * Returns whether the given object should be skipped.
		 * 
		 * @param o the object to be checked
		 * @return <code>true</code> if the object should be skipped by the iterator
		 */
		protected boolean skip(Object o) {
			StyleRange r= (StyleRange) o;
			return r.similarTo(fDefaultRange);
		}
		
		/**
		 * Computes the index of the styled range that is the next to be enumerated.
		 */
		protected void computeIndex() {
			while (fIndex < fLength && skip(fRanges.get(fIndex)))
				++ fIndex;
		}
	}
	
	/** The syle information for the range covered by the whole presentation */
	private StyleRange fDefaultRange;
	/** The member ranges of the presentation */
	private ArrayList fRanges;
	/** A clipping region against which the presentation can be clipped when asked for results */
	private IRegion fResultWindow;
	/**
	 * The optional extent for this presentation.
	 * @since 3.0
	 */
	private IRegion fExtent;
	
	
	/**
	 * Creates a new empty text presentation.
	 */
	public TextPresentation() {
		fRanges= new ArrayList(50);
	}
	
	/**
	 * Creates a new empty text presentation. <code>sizeHint</code>  tells the 
	 * expected size of this presentation.
	 * 
	 * @param sizeHint the expected size of this presentation
	 */
	public TextPresentation(int sizeHint) {
		Assert.isTrue(sizeHint > 0);
		fRanges= new ArrayList(sizeHint);
	}

	/**
	 * Creates a new empty text presentation with the given extent.
	 * <code>sizeHint</code>  tells the expected size of this presentation.
	 * 
	 * @param sizeHint the expected size of this presentation
	 * @since 3.0
	 */
	public TextPresentation(IRegion extent, int sizeHint) {
		this(sizeHint);
		Assert.isNotNull(extent);
		fExtent= extent;
	}
	
	/**
	 * Sets the result window for this presentation. When dealing with
	 * this presentation all ranges which are outside the result window 
	 * are ignored. For example, the size of the presentation is 0
	 * when there is no range inside the window even if there are ranges
	 * outside the window. All methods are aware of the result window. 
	 *
	 * @param resultWindow the result window
	 */
	public void setResultWindow(IRegion resultWindow) {
		fResultWindow= resultWindow;
	}
	
	/**
	 * Set the default style range of this presentation. 
	 * The default style range defines the overall area covered
	 * by this presentation and its style information.
	 *
	 * @param range the range decribing the default region
	 */
	public void setDefaultStyleRange(StyleRange range) {
		fDefaultRange= range;
	}
	
	/**
	 * Returns this presentation's default style range. The returned <code>StyleRange</code>
	 * is relative to the start of the result window.
	 *
	 * @return this presentation's default style range
	 */
	public StyleRange getDefaultStyleRange() {
		return createWindowRelativeRange(fResultWindow, fDefaultRange);
	}

	/**
	 * Add the given range to the presentation. The range must be a 
	 * subrange of the presentation's default range.
	 *
	 * @param range the range to be added
	 */
	public void addStyleRange(StyleRange range) {
		checkConsistency(range);
		fRanges.add(range);
	}
		
	/**
	 * Merges the given range into this presentation. The range must be a 
	 * subrange of the presentation's default range.
	 *
	 * @param range the range to be added
	 * @since 3.0
	 */
	public void mergeStyleRange(StyleRange range) {
		if (range.length == 0)
			return;

		checkConsistency(range);

		int start= range.start;
		int length= range.length;
		int end= start + length;
		
		if (fRanges.size() == 0) {
			StyleRange defaultRange= getDefaultStyleRange();
			if (defaultRange == null)
				defaultRange= range;
			
			defaultRange.start= start;
			defaultRange.length= length;
			applyStyle(range, defaultRange);
			fRanges.add(defaultRange);
		} else {
			IRegion rangeRegion= new Region(start, length);
			int first= getFirstIndexInWindow(rangeRegion);
			
			if (first == fRanges.size()) {
				StyleRange defaultRange= getDefaultStyleRange();
				if (defaultRange == null)
					defaultRange= range;
				defaultRange.start= start;
				defaultRange.length= length;
				applyStyle(range, defaultRange);
				fRanges.add(defaultRange);
				return;
			}
			
			int last= getFirstIndexAfterWindow(rangeRegion);
			ArrayList rangesCopy= new ArrayList(fRanges);
			int insertOffset= 0;
			for (int i= first; i < last && length > 0; i++) {
			
				StyleRange current= (StyleRange)rangesCopy.get(i);
				int currentStart= current.start;
				int currentEnd= currentStart + current.length;

				if (end <= currentStart) {
					fRanges.add(i + insertOffset, range);
					return;
				}
				
				if (start >= currentEnd)
					continue;
				
				StyleRange currentCopy= null;
				if (end < currentEnd)
					currentCopy= (StyleRange)current.clone();
				
				if (start < currentStart) {
					// Apply background to new default range and add it
					StyleRange defaultRange= getDefaultStyleRange();
					if (defaultRange == null)
						defaultRange= new StyleRange();
					
					defaultRange.start= start;
					defaultRange.length= currentStart - start;
					applyStyle(range, defaultRange);
					fRanges.add(i + insertOffset, defaultRange);
					insertOffset++;
					
					
					// Apply background to first part of current range
					current.length= Math.min(end, currentEnd) - currentStart;
					applyStyle(range, current);
				}
				
				if (start >= currentStart) {
					// Shorten the current range
					current.length= start - currentStart;
						
					// Apply the background to the rest of the current range and add it
					if (current.length > 0) {
						current= (StyleRange)current.clone();
						insertOffset++;
						fRanges.add(i + insertOffset, current);
					}
					applyStyle(range, current);
					current.start= start;
					current.length= Math.min(end, currentEnd) - start;
				}

				if (end < currentEnd) {
					// Add rest of current range
					currentCopy.start= end;
					currentCopy.length= currentEnd - end;
					insertOffset++;
					fRanges.add(i + insertOffset,  currentCopy);
				}

				// Update range
				range.start=  currentEnd;
				range.length= Math.max(end - currentEnd, 0);
				start= range.start;
				length= range.length;
			}
			if (length > 0) {
				// Apply background to new default range and add it
				StyleRange defaultRange= getDefaultStyleRange();
				if (defaultRange == null)
					defaultRange= range;
				defaultRange.start= start;
				defaultRange.length= end - start;
				defaultRange.background= range.background;
				fRanges.add(last + insertOffset, defaultRange);
			}
		}
	}
	
	/**
	 * Applies the template's style to the target.
	 * 
	 * @since 3.0
	 */
	private void applyStyle(StyleRange template, StyleRange target) {
		if (template.foreground != null)
			target.foreground= template.foreground;
		if (template.background != null)
			target.background= template.background;
		if (template.fontStyle != SWT.NORMAL)
			target.fontStyle= template.fontStyle;
	}

	/**
	 * Checks whether the given range is a subrange of the presentation's
	 * default style range.
	 *
	 * @param range the range to be checked
	 * @exception IllegalArgumentAxception if range is not a subrange of the presentation's default range
	 */
	private void checkConsistency(StyleRange range) {
		
		if (range == null)
			throw new IllegalArgumentException();
		
		if (fDefaultRange != null) {
			
			if (range.start < fDefaultRange.start)
				range.start= fDefaultRange.start;
				
			int defaultEnd= fDefaultRange.start + fDefaultRange.length;
			int end= range.start + range.length;
			if (end > defaultEnd)
				range.length -= (end - defaultEnd);
		}
	}
	
	/**
	 * Returns the index of the first range which overlaps with the 
	 * specified window.
	 *
	 * @param window the window to be used for searching
	 * @return the index of the first range overlapping with the window
	 */
	private int getFirstIndexInWindow(IRegion window) {
		int i= 0;
		if (window != null) {
			int start= window.getOffset();	
			while (i < fRanges.size()) {
				StyleRange r= (StyleRange) fRanges.get(i++);
				if (r.start + r.length > start) {
					-- i;
					break;
				}
			}
		}
		return i;
	}
	
	/**
	 * Returns the index of the first range which comes after the specified window and does
	 * not overlap with this window.
	 *
	 * @param window the window to be used for searching
	 * @return the index of the first range behind the window and not overlapping with the window
	 */
	private int getFirstIndexAfterWindow(IRegion window) {
		int i= fRanges.size();
		if (window != null) {
			int end= window.getOffset() + window.getLength();	
			while (i > 0) {
				StyleRange r= (StyleRange) fRanges.get(--i);
				if (r.start < end) {
					++ i;
					break;
				}
			}
		}
		return i;
	}
	
	/**
	 * Returns a style range which is relative to the specified window and
	 * appropriately clipped if necessary. The original style range is not
	 * modified.
	 *
	 * @param window the reference window 
	 * @param range the absolute range
	 * @return the window relative range based on the absolute range
	 */
	private StyleRange createWindowRelativeRange(IRegion window, StyleRange range) {
		if (range == null)
			return null;
		
		if (window == null) 
			return (StyleRange)range.clone();
		
		int start= range.start - window.getOffset();
		if (start < 0)
			start= 0;
		
		int rangeEnd= range.start + range.length;
		int windowEnd= window.getOffset() + window.getLength();
		int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd);
		end -= window.getOffset();
		
		StyleRange newRange= (StyleRange) range.clone();
		newRange.start= start;
		newRange.length= end - start;
		return newRange;
	}

	/**
	 * Returns the region which is relative to the specified window and
	 * appropriately clipped if necessary.
	 *
	 * @param region the absolute coverage
	 * @return the window relative region based on the absolute coverage
	 * @since 3.0
	 */
	private IRegion createWindowRelativeRegion(IRegion coverage) {
		if (fResultWindow == null || coverage == null)
			return coverage;
		
		int start= coverage.getOffset() - fResultWindow.getOffset();
		if (start < 0)
			start= 0;
		
		int rangeEnd= coverage.getOffset() + coverage.getLength();
		int windowEnd= fResultWindow.getOffset() + fResultWindow.getLength();
		int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd);
		end -= fResultWindow.getOffset();
		
		return new Region(start, end - start);
	}
	
	/**
	 * Returns an iterator which enumerates all style ranged which define a style 
	 * different from the presentation's default style range. The default style range
	 * is not enumerated.
	 *
	 * @return a style range interator
	 */
	public Iterator getNonDefaultStyleRangeIterator() {
		return new FilterIterator(fDefaultRange != null);
	}
	
	/**
	 * Returns an iterator which enumerates all style ranges of this presentation 
	 * except the default style range. The returned <code>StyleRange</code>s
	 * are relative to the start of the presentation's result window.
	 *
	 * @return a style range iterator
	 */
	public Iterator getAllStyleRangeIterator() {
		return new FilterIterator(false);
	}
	
	/**
	 * Returns whether this collection contains any style range including
	 * the default style range.
	 *
	 * @return <code>true</code> if there is no style range in this presentation
	 */
	public boolean isEmpty() {
		return (fDefaultRange == null && getDenumerableRanges() == 0);
	}
	
	/**
	 * Returns the number of style ranges in the presentation not counting the default
	 * style range.
	 *
	 * @return the number of style ranges in the presentation excluding the default style range
	 */
	public int getDenumerableRanges() {
		int size= getFirstIndexAfterWindow(fResultWindow) - getFirstIndexInWindow(fResultWindow);
		return (size < 0 ? 0 : size);
	}
		
	/**
	 * Returns the style range with the smallest offset ignoring the default style range or null
	 * if the presentation is empty.
	 *
	 * @return the style range with the smalled offset different from the default style range
	 */
	public StyleRange getFirstStyleRange() {
		try {
			
			StyleRange range= (StyleRange) fRanges.get(getFirstIndexInWindow(fResultWindow));
			return createWindowRelativeRange(fResultWindow, range);
			
		} catch (NoSuchElementException x) {
		}
		
		return null;
	}
	
	/**
	 * Returns the style range with the highest offset ignoring the default style range.
	 *
	 * @return the style range with the highest offset different from the default style range
	 */
	public StyleRange getLastStyleRange() {
		try {
			
			StyleRange range=  (StyleRange) fRanges.get(getFirstIndexAfterWindow(fResultWindow) - 1);
			return createWindowRelativeRange(fResultWindow, range);
			
		} catch (NoSuchElementException x) {
		}
		
		return null;
	}
	
	/**
	 * Returns the coverage of this presentation as clipped by the presentation's
	 * result window.
	 *
	 * @return the coverage of this presentation
	 */
	public IRegion getCoverage() {
		
		if (fDefaultRange != null) {
			StyleRange range= getDefaultStyleRange();
			return new Region(range.start, range.length);
		}
		
		StyleRange first= getFirstStyleRange();
		StyleRange last= getLastStyleRange();
		
		if (first == null || last == null)
			return null;
					
		return new Region(first.start, last.start - first. start + last.length);
	}
	
	/**
	 * Returns the extent of this presentation clipped by the
	 * presentation's result window.
	 *
	 * @return the clipped extent 
	 * @since 3.0
	 */
	public IRegion getExtent() {
		if (fExtent != null)
			return createWindowRelativeRegion(fExtent);
		else
			return getCoverage();
	}
	
	/**
	 * Clears this presentation by resetting all applied changes.
	 * @since 2.0
	 */
	public void clear() {
		fDefaultRange= null;
		fResultWindow= null;
		fRanges.clear();
	}


}
