/*******************************************************************************
 * 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;



/**
 * A child document is one particular example of a slave document. Child documents
 * are created by the <code>ChildDocumentManager</code>, an implementation of
 * <code>ISlaveDocumentManager</code>.<p>
 * 
 * A child document represents one consequetive range of its master document.
 * The master document is called parent document. The child document is always in sync 
 * with its parent document by utilizing the parent document as its <code>ITextStore</code>.<p>
 * 
 * This class is for internal use only.
 *
 * @see ITextStore
 */
public final class ChildDocument extends AbstractDocument {
	
	
	/**
	 * Implements <code>ITextStore</code> based on <code>IDocument</code>.
	 */
	class TextStore implements ITextStore {
		
		/*
		 * @see ITextStore#set(String)
		 */
		public void set(String txt) {
			try {
				fParentDocument.replace(fRange.getOffset(), fRange.getLength(), txt);
			} catch (BadLocationException x) {
				// cannot happen
			}
		}
		
		/*
		 * @see ITextStore#replace(int, int, String)
		 */
		public void replace(int offset, int length, String txt) {
			try {
				fParentDocument.replace(fRange.getOffset() + offset, length, txt);
			} catch (BadLocationException x) {
				// ignored as surrounding document should have handled this
			}
		}
		
		/*
		 * @see ITextStore#getLength()
		 */
		public int getLength() {
			return fRange.getLength();
		}
		
		/*
		 * @see ITextStore#get(int, int)
		 */
		public String get(int offset, int length) {
			try {
				return fParentDocument.get(fRange.getOffset() + offset, length);
			} catch (BadLocationException x) {
			}
			
			return null;
		}
		
		/*
		 * @see ITextStore#get(int)
		 */
		public char get(int offset) {
			try {
				return fParentDocument.getChar(fRange.getOffset() + offset);
			} catch (BadLocationException x) {
			}
			
			return (char) 0;
		}
	};
	
	
	
	/** The parent document */
	private IDocument fParentDocument;
	/** 
	 * The parent document as <code>IDocumentExtension</code>
	 * @since 2.0
	 */
	private IDocumentExtension fExtension;
	/**
	 * The parent document as <code>IDocumentExtension2</code>
	 * @since 2.1
	 */
	private IDocumentExtension2 fExtension2;
	/** The section inside the parent document */
	private Position fRange;
	/** The document event issued by the parent document */
	private DocumentEvent fParentEvent;
	/** The document event issued and to be issued by the child document */
	private DocumentEvent fEvent;
	/** Indicates whether the child document initiated a parent document update or not */
	private boolean fIsUpdating= false;
	/** 
	 * The expected document content after the parent document changed.
	 * @since 2.1
	 */
	private String fExpectedContent;
	/** 
	 * The length of this child document prior to the change of the parent document
	 * @since 2.1
	 */
	private int fRememberedLength;
	/** 
	 * Indicates whether this document is in auto expand mode.
	 * @since 2.1
	 */
	private boolean fIsAutoExpanding= false;
	
	
	/**
	 * Creates a child document for the given range of the given parent document.
	 *
	 * @param parentDocument the parent Document
	 * @param range the parent document range covered by the child document
	 */
	public ChildDocument(IDocument parentDocument, Position range) {
		super();
		
		fParentDocument= parentDocument;
		if (fParentDocument instanceof IDocumentExtension) 
			fExtension= (IDocumentExtension) fParentDocument;
		if (fParentDocument instanceof IDocumentExtension2)
			fExtension2= (IDocumentExtension2) fParentDocument;
			
		fRange= range;
		
		ITextStore s= new TextStore();
		ILineTracker tracker= new DefaultLineTracker();
		tracker.set(s.get(0, fRange.getLength()));
		
		setTextStore(s);
		setLineTracker(tracker);
		
		completeInitialization();
	}
	
	/**
	 * Sets the child document's parent document range.
	 *
	 * @param offset the offset of the parent document range
	 * @param length the length of the parent document range
	 */
	public void setParentDocumentRange(int offset, int length) throws BadLocationException {
		
		if (offset < 0 || length < 0 || offset + length > fParentDocument.getLength())
			throw new BadLocationException();
								
		fRange.setOffset(offset);
		fRange.setLength(length);
		
		getTracker().set(fParentDocument.get(offset, length));
	}
	
	/**
	 * Returns parent document
	 *
	 * @return the parent document
	 */
	public IDocument getParentDocument() {
		return fParentDocument;
	}
	
	/**
	 * Returns the range of the parent document covered by this child document.
	 *
	 * @return the child document's parent document range
	 */
	public Position getParentDocumentRange() {
		return fRange;
	}
		
	/**
	 * <p>Transforms a document event of the parent document into a child document
	 * based document event. This method considers whether the document is in 
	 * auto expand mode.</p>
	 * This method is public for test purposes only.
	 *
	 * @param e the parent document event
	 * @return the child document event
	 */
	public DocumentEvent normalize(DocumentEvent event) {
				
		int delta= event.getOffset() - fRange.getOffset();
		
		if (isAutoExpandEvent(event)) {
						
			if (delta < 0) {
				int eventEndOffset= event.getOffset() + event.getLength();
				
				if (eventEndOffset <= fRange.getOffset()) {
					
					// case 1
					StringBuffer buffer= new StringBuffer();
					if (event.getText() != null)
						buffer.append(event.getText());
					try {
						buffer.append(fParentDocument.get(eventEndOffset, -delta - event.getLength()));
					} catch (BadLocationException e) {
						// should not happen as the event is a valid parent document event
					}
					
					return new SlaveDocumentEvent(this, 0, 0, buffer.toString(), event);
				
				} else {
					
					// cases 2 and 3
					int length= Math.min(eventEndOffset - fRange.getOffset(), fRange.getLength());
					return new SlaveDocumentEvent(this, 0, length, event.getText(), event);
				}
				
			} else {
				int rangeEndOffset= fRange.getOffset() + fRange.getLength();
				
				if (event.getOffset() >= rangeEndOffset) {
					
					// case 5
					StringBuffer buffer= new StringBuffer();
					try {
						buffer.append(fParentDocument.get(rangeEndOffset, event.getOffset() - rangeEndOffset));
					} catch (BadLocationException e) {
						// should not happen as this event is a valid parent document event
					}
					if (event.getText() != null)
						buffer.append(event.getText());
						
					return new SlaveDocumentEvent(this, fRange.getLength(), 0, buffer.toString(), event);
				
				} else {
					
					// case 4 and 6
					int offset= event.getOffset() - fRange.getOffset();
					int length= Math.min(rangeEndOffset - event.getOffset(), event.getLength());
					return new SlaveDocumentEvent(this, offset, length, event.getText(), event);
				}
			}
		
		} else if (fRange.overlapsWith(event.fOffset, event.fLength)) {			
			
			int offset= delta < 0 ? 0 : delta;
			int length= delta < 0 ? event.fLength + delta : event.fLength;
			if (offset + length > fRange.getLength())
				length= fRange.getLength() - offset;
				
			return new SlaveDocumentEvent(this, offset, length, event.fText, event);
		}
		
		return null;
	}
	
	/**
	 * When called this child document is informed about a forthcoming change
	 * of its parent document. This child document checks whether the parent
	 * document change affects it and if so informs all document listeners.
	 *
	 * @param event the parent document event
	 */
	public void parentDocumentAboutToBeChanged(DocumentEvent event) {
		
		fParentEvent= event;
		
		fEvent= normalize(event);
		if (fEvent != null) {			
			
			StringBuffer buffer= new StringBuffer(get());
			fRememberedLength= buffer.length();
			buffer.replace(fEvent.fOffset, fEvent.fOffset+ fEvent.fLength, fEvent.fText == null ? "" : fEvent.fText);  //$NON-NLS-1$
			fExpectedContent= buffer.toString();
			
			delayedFireDocumentAboutToBeChanged();
		}
	}
		
	/**
	 * When called this child document is informed about a change of its parent document.
	 * If this child document is affected it informs all of its document listeners.
	 *
	 * @param event the parent document event
	 */
	public void parentDocumentChanged(DocumentEvent event) {
		if ( !fIsUpdating && event == fParentEvent && fEvent != null) {
			try {
				
				if (!fExpectedContent.equals(get())) {
					// patch the event
					fEvent.fOffset= 0;
					fEvent.fLength= fRememberedLength;
					fEvent.fText= get();
				}
				
				fRememberedLength= 0;
				fExpectedContent= null;
				
				getTracker().replace(fEvent.fOffset, fEvent.fLength, fEvent.fText);
				fireDocumentChanged(fEvent);
				
			} catch (BadLocationException x) {
				Assert.isLegal(false);
			}
		}
	}
	
	/*
	 * @see AbstractDocument#fireDocumentAboutToBeChanged(DocumentEvent)
	 */
	protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
		// delay it until there is a notification from the parent document
		// otherwise there it is expensive to construct the parent document information
	}
	
	/**
	 * Fires the child document event as about-to-be-changed event to all
	 * registed listeners.
	 */
	private void delayedFireDocumentAboutToBeChanged() {
		super.fireDocumentAboutToBeChanged(fEvent);
	}
	
	/**
	 * Ignores the given event and sends the similar child document event instead.
	 *
	 * @param event the event to be ignored
	 */
	protected void fireDocumentChanged(DocumentEvent event) {
		super.fireDocumentChanged(fEvent);
	}
	
	/*
	 * @see IDocument#replace(int, int, String)
	 * @since 2.0
	 */
	public void replace(int offset, int length, String text) throws BadLocationException {
		try {
			fIsUpdating= true;
			if (fExtension != null)
				fExtension.stopPostNotificationProcessing();
				
			if ((0 > offset) || (0 > length) || (offset + length > getLength()))
				throw new BadLocationException();
			
			DocumentEvent event= new DocumentEvent(this, offset, length, text);
			fireDocumentAboutToBeChanged(event);
					
			try {
			
				if (fExtension2 != null)
					fExtension2.stopListenerNotification();
				
				getStore().replace(offset, length, text);
				getTracker().replace(offset, length, text);
				updateDocumentStructures(fEvent);
			
			} finally {
				if (fExtension2 != null)
					fExtension2.resumeListenerNotification();
			}
		 			
			doFireDocumentChanged(fEvent);
						
		} finally {
			fIsUpdating= false;
			if (fExtension != null)
				fExtension.resumePostNotificationProcessing();
		}
	}
	
	/*
	 * @see IDocument#set(String)
	 * @since 2.0
	 */
	public void set(String text) {
		try {
			fIsUpdating= true;
			if (fExtension != null)
				fExtension.stopPostNotificationProcessing();
			
			int length= getStore().getLength();
			DocumentEvent event= new DocumentEvent(this, 0, length, text);
			fireDocumentAboutToBeChanged(event);
		
			try {
				
				if (fExtension2 != null)
					fExtension2.stopListenerNotification();
					
				getStore().set(text);
				getTracker().set(text);
				updateDocumentStructures(fEvent);
				
			} finally {
				if (fExtension2 != null)
					fExtension2.resumeListenerNotification();
			}
			
			doFireDocumentChanged(fEvent);

		} finally {
			fIsUpdating= false;
			if (fExtension != null)
				fExtension.resumePostNotificationProcessing();
		}
	}
	
	/*
	 * @see IDocumentExtension#registerPostNotificationReplace(IDocumentListener, IDocumentExtension.IReplace)
	 * @since 2.0
	 */
	public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) {
		if (!fIsUpdating)
			throw new UnsupportedOperationException();
		super.registerPostNotificationReplace(owner, replace);
	}
	
	/**
	 * Sets the auto expand mode of this document.
	 * 
	 * @param autoExpand <code>true</code> if auto expanding, <code>false</code> otherwise
	 * @since 2.1
	 */
	public void setAutoExpandMode(boolean autoExpand) {
		fIsAutoExpanding= autoExpand;
	}
	
	/**
	 * Returns whether the given document might cause this document to auto expand.
	 * This default implementation always answers with its auto expand state.
	 * 
	 * @param event the document event
	 * @return <code>true</code> if the given event might cause this document to auto expand
	 */	
	public boolean isAutoExpandEvent(DocumentEvent event) {
		return fIsAutoExpanding;
	}
}
