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

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
 
import org.eclipse.cdt.internal.ui.CStatusConstants;
import org.eclipse.cdt.ui.CUIPlugin;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.util.Assert;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.IDocumentProvider;


/* package */ class TextBufferFactory {

	protected IDocumentProvider fDocumentProvider;
	private Map fFileValueMap;
	private Map fBufferValueMap;
	
	private static class Value {
		TextBuffer buffer;
		FileEditorInput input;
		IDocument document;
		IAnnotationModel annotationModel;
		int references;
		public Value(TextBuffer b, FileEditorInput i, IDocument d, IAnnotationModel m) {
			buffer= b;
			input= i;
			document= d;
			annotationModel= m;
		}
	}

	public TextBufferFactory() {
		// XXX http://dev.eclipse.org/bugs/show_bug.cgi?id=5170
		// Need way to map a file to a document without knowing any kind of document provider.
		this(CUIPlugin.getDefault().getDocumentProvider());
	}
	
	public TextBufferFactory(IDocumentProvider provider) {
		fDocumentProvider= provider;
		Assert.isNotNull(fDocumentProvider);
		fFileValueMap= new HashMap(5);
		fBufferValueMap= new HashMap(5);
	}

	public TextBuffer acquire(IFile file) throws CoreException {
		FileEditorInput input= new FileEditorInput(file);	
		
		Value value= (Value)fFileValueMap.get(input);
		if (value != null) {
			value.references++;
			return value.buffer;
		}
		
		fDocumentProvider.connect(input);
		IDocument document= fDocumentProvider.getDocument(input);
		IAnnotationModel annotationModel= fDocumentProvider.getAnnotationModel(input);
		annotationModel.connect(document);
		value= new Value(new TextBuffer(document), input, document, annotationModel);
		fFileValueMap.put(input, value);
		fBufferValueMap.put(value.buffer, value);
		value.references++;
		return value.buffer;
	}
	
	public void release(TextBuffer buffer) {
		final Value value= (Value)fBufferValueMap.get(buffer);
		if (value == null)
			return;
						
		value.references--;
		if (value.references == 0) {
			buffer.release();	
			value.annotationModel.disconnect(value.document);
			fDocumentProvider.disconnect(value.input);
			fFileValueMap.remove(value.input);
			fBufferValueMap.remove(buffer);
		}
	}
	
	public void commitChanges(TextBuffer buffer, boolean force, IProgressMonitor pm) throws CoreException {
		final Value value= (Value)fBufferValueMap.get(buffer);
		if (value == null)
			return;
		
		boolean save= force || fDocumentProvider.mustSaveDocument(value.input);
		if (save) {
			IWorkspaceRunnable action= new IWorkspaceRunnable() {
				public void run(IProgressMonitor pm) throws CoreException {
					fDocumentProvider.aboutToChange(value.input);
					fDocumentProvider.saveDocument(pm, value.input, value.document, true);
				}
			};
			try {
				ResourcesPlugin.getWorkspace().run(action, pm);
			} finally {
				fDocumentProvider.changed(value.input);
			}
		}
	}
	
	public TextBuffer create(IFile file) throws CoreException {
		FileEditorInput input= new FileEditorInput(file);	
		IDocument document= fDocumentProvider.getDocument(input);
		if (document != null) {
			return new TextBuffer(new Document(document.get()));
		} else {
			return createFromFile(file);
		}
	}

	private TextBuffer createFromFile(IFile file) throws CoreException {
		IDocument document;
		InputStreamReader in= null;
		try {		
			document= new Document();
			in= new InputStreamReader(new BufferedInputStream(file.getContents()));
			StringBuffer buffer= new StringBuffer();
			char[] readBuffer= new char[2048];
			int n= in.read(readBuffer);
			while (n > 0) {
				buffer.append(readBuffer, 0, n);
				n= in.read(readBuffer);
			}
			document.set(buffer.toString());
			return new TextBuffer(document);
		} catch (IOException x) {
			IStatus s= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, CStatusConstants.INTERNAL_ERROR, x.getMessage(), x);
			throw new CoreException(s);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException x) {
				}
			}
		}
	}
	
	public TextBuffer create(String content) throws CoreException {
		return new TextBuffer(new Document(content));
	}
	
	public void save(TextBuffer buffer, IProgressMonitor pm) throws CoreException {
		Value value= (Value)fBufferValueMap.get(buffer);
		if (value == null)
			throwNotManaged();
		fDocumentProvider.saveDocument(pm, value.input, value.document, true);
	}

	public void aboutToChange(TextBuffer buffer) throws CoreException {
		Value value= (Value)fBufferValueMap.get(buffer);
		if (value == null)
			throwNotManaged();
		fDocumentProvider.aboutToChange(value.input);
	}
		
	public void changed(TextBuffer buffer) throws CoreException {
		Value value= (Value)fBufferValueMap.get(buffer);
		if (value == null)
			throwNotManaged();
		fDocumentProvider.changed(value.input);
	}
	
	private void throwNotManaged() throws CoreException {
		IStatus s= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, 
			CStatusConstants.INTERNAL_ERROR, "TextBufferFactory.bufferNotManaged", null); //$NON-NLS-1$
		throw new CoreException(s);
	}
}

