package org.eclipse.cdt.internal.corext.textmanipulation;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
 
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ILineTracker;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.util.Assert;

import org.eclipse.cdt.internal.ui.CStatusConstants;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;


/**
 * An implementation of a <code>TextBuffer</code> that is based on <code>ITextSelection</code>
 * and <code>IDocument</code>.
 */
public class TextBuffer {

	private static class DocumentRegion extends TextRegion {
		IRegion fRegion;
		public DocumentRegion(IRegion region) {
			fRegion= region;
		}
		public int getOffset() {
			return fRegion.getOffset();
		}
		public int getLength() {
			return fRegion.getLength();
		}
	}
	
	private IDocument fDocument;
	
	private static final TextBufferFactory fgFactory= new TextBufferFactory();
	
	TextBuffer(IDocument document) {
		fDocument= document;
		Assert.isNotNull(fDocument);
	}
	
	/**
	 * Returns the number of characters in this text buffer.
	 *
	 * @return the number of characters in this text buffer
	 */
	public int getLength() {
		return fDocument.getLength();
	}
	
	/**
	 * Returns the number of lines in this text buffer.
	 * 
	 * @return the number of lines in this text buffer
	 */
	public int getNumberOfLines() {
		return fDocument.getNumberOfLines();
	}
	
	/**
	 * Returns the character at the given offset in this text buffer.
	 *
	 * @param offset a text buffer offset
	 * @return the character at the offset
	 * @exception  IndexOutOfBoundsException  if the <code>offset</code> 
	 *  argument is negative or not less than the length of this text buffer.
	 */
	public char getChar(int offset) {
		try {
			return fDocument.getChar(offset);
		} catch (BadLocationException e) {
			throw new ArrayIndexOutOfBoundsException(e.getMessage());
		}
	}
	
	/**
	 * Returns the whole content of the text buffer.
	 *
	 * @return the whole content of the text buffer
	 */
	public String getContent() {
		return fDocument.get();
	}
	
	/**
	 * Returns length characters starting from the specified position.
	 *
	 * @return the characters specified by the given text region. Returns <code>
	 *  null</code> if text range is illegal
	 */
	public String getContent(int start, int length) {
		try {
			return fDocument.get(start, length);
		} catch (BadLocationException e) {
			return null;
		}
	}
	
	/**
	 * Returns the preferred line delimiter to be used for this text buffer.
	 * 
	 * @return the preferred line delimiter
	 */
	public String getLineDelimiter() {
		String lineDelimiter= getLineDelimiter(0);
		if (lineDelimiter == null)
			lineDelimiter= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
		return lineDelimiter;
	}
	
	/**
	 * Returns the line delimiter used for the given line number. Returns <code>
	 * null</code> if the line number is out of range.
	 *
	 * @return the line delimiter used by the given line number or <code>null</code>
	 */
	public String getLineDelimiter(int line) {
		try {
			return fDocument.getLineDelimiter(line);
		} catch (BadLocationException e) {
			return null;
		}	
	}
	
	/**
	 * Returns the line for the given line number. If there isn't any line for
	 * the given line number, <code>null</code> is returned.
	 *
	 * @return the line for the given line number or <code>null</code>
	 */
	public String getLineContent(int line) {
		try {
			IRegion region= fDocument.getLineInformation(line);
			return fDocument.get(region.getOffset(), region.getLength());
		} catch (BadLocationException e) {
			return null;
		}
	}
	
	/**
	 * Returns the line indent for the given line. If there isn't any line for the
	 * given line number, <code>-1</code> is returned.
	 * 
	 * @return the line indent for the given line number of <code>-1</code>
	 */
	public int getLineIndent(int lineNumber, int tabWidth) {
		return getIndent(getLineContent(lineNumber), tabWidth);
	}
	
	/**
	 * Returns a region of the specified line. The region contains  the offset and the 
	 * length of the line excluding the line's delimiter. Returns <code>null</code> 
	 * if the line doesn't exist.
	 *
	 * @param line the line of interest
	 * @return a line description or <code>null</code> if the given line doesn't
	 *  exist
	 */
	public TextRegion getLineInformation(int line) {
		try {
			return new DocumentRegion(fDocument.getLineInformation(line));
		} catch (BadLocationException e) {
			return null;
		}	
	}
	
	/**
	 * Returns a line region of the specified offset.  The region contains the offset and 
	 * the length of the line excluding the line's delimiter. Returns <code>null</code> 
	 * if the line doesn't exist.
	 *
	 * @param offset an offset into a line
	 * @return a line description or <code>null</code> if the given line doesn't
	 *  exist
	 */ 
	public TextRegion getLineInformationOfOffset(int offset) {
		try {
			return new DocumentRegion(fDocument.getLineInformationOfOffset(offset));
		} catch (BadLocationException e) {
			return null;
		}	
	}
	
	/**
	 * Returns the line number that contains the given position. If there isn't any
	 * line that contains the position, <code>null</code> is returned. The returned 
	 * string is a copy and doesn't contain the line delimiter.
	 *
	 * @return the line that contains the given offset or <code>null</code> if line
	 *  doesn't exist
	 */ 
	public int getLineOfOffset(int offset) {
		try {
			return fDocument.getLineOfOffset(offset);
		} catch (BadLocationException e) {
			return -1;
		}
	}

	/**
	 * Returns the line that contains the given position. If there isn't any
	 * line that contains the position, <code>null</code> is returned. The returned 
	 * string is a copy and doesn't contain the line delimiter.
	 *
	 * @return the line that contains the given offset or <code>null</code> if line
	 *  doesn't exist
	 */ 
	public String getLineContentOfOffset(int offset) {
		try {
			IRegion region= fDocument.getLineInformationOfOffset(offset);
			return fDocument.get(region.getOffset(), region.getLength());
		} catch (BadLocationException e) {
			return null;
		}
	}

	/**
	 * Converts the text determined by the region [offset, length] into an array of lines. 
	 * The lines are copies of the original lines and don't contain any line delimiter 
	 * characters.
	 *
	 * @return the text converted into an array of strings. Returns <code>null</code> if the 
	 *  region lies outside the source. 
	 */
	public String[] convertIntoLines(int offset, int length) {
		try {
			String text= fDocument.get(offset, length);
			ILineTracker tracker= new DefaultLineTracker();
			tracker.set(text);
			int size= tracker.getNumberOfLines();
			String result[]= new String[size];
			for (int i= 0; i < size; i++) {
				IRegion region= tracker.getLineInformation(i);
				result[i]= getContent(offset + region.getOffset(), region.getLength());
			}
			return result;
		} catch (BadLocationException e) {
			return null;
		}
	}
	
	/**
	 * Subsitutes the given text for the specified text position
	 *
	 * @param offset the starting offset of the text to be replaced
	 * @param length the length of the text to be replaced
	 * @param text the substitution text
     * @exception  CoreException  if the text position [offset, length] is invalid.	 
	 */
	public void replace(int offset, int length, String text) throws CoreException {
		try {
			fDocument.replace(offset, length, text);
		} catch (BadLocationException e) {
			IStatus s= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, CStatusConstants.INTERNAL_ERROR, 
				TextManipulationMessages.getFormattedString(
					"TextBuffer.wrongRange",  //$NON-NLS-1$
					new Object[] {new Integer(offset), new Integer(length) } ), e);
			throw new CoreException(s);
		}	
	}
	
	public void replace(TextRange range, String text) throws CoreException {
		replace(range.fOffset, range.fLength, text);
	}

	//---- Special methods used by the <code>TextBufferEditor</code>
	
	/**
	 * Releases this text buffer.
	 */
	/* package */ void release() {
	}
	
	/* package */ void registerUpdater(IDocumentListener listener) {
		fDocument.addDocumentListener(listener);
	}
	
	/* package */ void unregisterUpdater(IDocumentListener listener) {
		fDocument.removeDocumentListener(listener);
	}
	
	//---- Utility methods
	
	/**
	 * Returns the indent for the given line.
	 * If line is <code>null</code>, <code>-1</code> is returned.
	 * 
	 * @param line the line for which the indent is determined
	 * @return the line indent for the given line number or <code>-1</code>
	 */
	public static int getIndent(String line, int tabWidth) {
		if (line == null)
			return -1;
		int indent= 0;
		int blanks= 0;
		int size= line.length();
		for (int i= 0; i < size; i++) {
			switch (line.charAt(i)) {
				case '\t':
					indent++;
					blanks= 0;
					continue;
				case ' ':
					blanks++;
					if (blanks == tabWidth) {
						indent++;
						blanks= 0;
					}
					continue;
				default:
					break;
			}
			break;
		}
		return indent;			
	}
	
	/**
	 * Returns a copy of the line with the given number of identations
	 * removed from the beginning.
	 * If the count is zero, the line is returned.
	 */
	public static String removeIndent(String line, int indentsToRemove, int tabWidth) {
		if (line != null) {
			int indent= 0;
			int blanks= 0;
			int size= line.length();
			for (int i= 0; i < size; i++) {
				
				if (indent >= indentsToRemove) {
					line= line.substring(i);
					break;
				}
				
				switch (line.charAt(i)) {
				case '\t':
					indent++;
					blanks= 0;
					continue;
				case ' ':
					blanks++;
					if (blanks == tabWidth) {
						indent++;
						blanks= 0;
					}
					continue;
				default:
					break;
				}
			}
		}
		return line;
	}
	
	//---- Factory methods ----------------------------------------------------------------
	
	/**
	 * Acquires a text buffer for the given file. If a text buffer for the given
	 * file already exists, then that one is returned.
	 * 
	 * @param file the file for which a text buffer is requested
	 * @return a managed text buffer for the given file
	 * @exception CoreException if it was not possible to acquire the
	 * 	text buffer
	 */
	public static TextBuffer acquire(IFile file) throws CoreException {
		return fgFactory.acquire(file);
	}
	
	/**
	 * Releases the given text buffer.
	 * 
	 * @param buffer the text buffer to be released
	 */
	public static void release(TextBuffer buffer) {
		fgFactory.release(buffer);
	}

	/**
	 * Commits the changes made to the given text buffer to the underlying
	 * storage system.
	 * 
	 * @param buffer the text buffer containing the changes to be committed.
	 * @param force if <code>true</code> the text buffer is committed in any case.
	 * 	If <code>false</code> the text buffer is <b>ONLY</b> committed if the client 
	 * 	is the last one that holds a reference to the text buffer. Clients of this
	 * 	method must make sure that they don't call this method from within an <code>
	 *  IWorkspaceRunnable</code>.
	 * @param pm the progress monitor used to report progress if committing is
	 * 	necessary
	 */
	public static void commitChanges(TextBuffer buffer, boolean force, IProgressMonitor pm) throws CoreException {
		fgFactory.commitChanges(buffer, force, pm);
	}
	
	/**
	 * Creates a new <code>TextBuffer</code> for the given file. The returned
	 * buffer will not be managed. Any subsequent call to <code>create</code>
	 * with the same file will return a different text buffer.
	 * <p>
	 * If the file is currently open in a text editor, the editors content is copied into
	 * the returned <code>TextBuffer</code>. Otherwise the content is read from
	 * disk.
	 * 
	 * @param file the file for which a text buffer is to be created
	 * @return a new unmanaged text buffer
	 * @exception CoreException if it was not possible to create the text buffer
	 */
	public static TextBuffer create(IFile file) throws CoreException {
		return fgFactory.create(file);
	}
	
	/**
	 * Creates a new <code>TextBuffer</code> for the string. The returned
	 * buffer will not be managed. Any subsequent call to <code>create</code>
	 * with the same string will return a different text buffer.
	 * 
	 * @param content the text buffer's content
	 * @return a new unmanaged text buffer
	 * @exception CoreException if it was not possible to create the text buffer
	 */
	public static TextBuffer create(String content) throws CoreException {
		return fgFactory.create(content);
	}
	
	// Unclear which methods are needed if we get the new save model. If optimal no
	// save is needed at all.
	
	public static void save(TextBuffer buffer, IProgressMonitor pm) throws CoreException {
		fgFactory.save(buffer, pm);
	}
	
	public static void aboutToChange(TextBuffer buffer) throws CoreException {
		fgFactory.aboutToChange(buffer);
	}
	
	public static void changed(TextBuffer buffer) throws CoreException {
		fgFactory.changed(buffer);
	}		
}