package org.eclipse.cdt.internal.core.model;

/*
 * (c) Copyright QNX Software Systems Ltd. 2002.
 * All Rights Reserved.
 */
 
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.cdt.core.model.BufferChangedEvent;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IBuffer;
import org.eclipse.cdt.core.model.IBufferChangedListener;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICModelStatusConstants;
import org.eclipse.cdt.core.model.IOpenable;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;

public abstract class Openable extends Parent implements IOpenable, IBufferChangedListener {

	protected IResource resource;	

	public Openable (ICElement parent, IPath path, int type) {
		// Check if the file is under the workspace.
		this (parent, ResourcesPlugin.getWorkspace().getRoot().getFileForLocation (path),
			path.lastSegment(), type);
	}

	public Openable (ICElement parent, IResource resource, int type) {
		this (parent, resource, resource.getName(), type);
	}
	
	public Openable (ICElement parent, IResource res, String name, int type) {
		super (parent, name, type);
		resource = res;
	}

	public IResource getResource()  {
		return resource;
	}

	/**
	 * The buffer associated with this element has changed. Registers
	 * this element as being out of synch with its buffer's contents.
	 * If the buffer has been closed, this element is set as NOT out of
	 * synch with the contents.
	 *
	 * @see IBufferChangedListener
	 */
	public void bufferChanged(BufferChangedEvent event) {
		if (event.getBuffer().isClosed()) {
			CModelManager.getDefault().getElementsOutOfSynchWithBuffers().remove(this);
			getBufferManager().removeBuffer(event.getBuffer());
		} else {
			CModelManager.getDefault().getElementsOutOfSynchWithBuffers().put(this, this);
		}
	}	
	/**
	 * Updates the info objects for this element and all of its children by
	 * removing the current infos, generating new infos, and then placing
	 * the new infos into the C Model cache tables.
	 */
	protected void buildStructure(OpenableInfo info, IProgressMonitor monitor) throws CModelException {

		if (monitor != null && monitor.isCanceled()) return;
	
		// remove existing (old) infos
		removeInfo();
		HashMap newElements = new HashMap(11);
		info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
		CModelManager.getDefault().getElementsOutOfSynchWithBuffers().remove(this);
		for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
			ICElement key = (ICElement) iter.next();
			Object value = newElements.get(key);
			CModelManager.getDefault().putInfo(key, value);
		}
		
		// add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
		// to be flushed. Might lead to performance issues.
		CModelManager.getDefault().putInfo(this, info);	
	}

	/**
	 * Close the buffer associated with this element, if any.
	 */
	protected void closeBuffer(OpenableInfo info) {
		if (!hasBuffer()) return; // nothing to do
		IBuffer buffer = null;
		buffer = getBufferManager().getBuffer(this);
		if (buffer != null) {
			buffer.close();
			buffer.removeBufferChangedListener(this);
		}
	}

	/**
	 * Builds this element's structure and properties in the given
	 * info object, based on this element's current contents (i.e. buffer
	 * contents if this element has an open buffer, or resource contents
	 * if this element does not have an open buffer). Children
	 * are placed in the given newElements table (note, this element
	 * has already been placed in the newElements table). Returns true
	 * if successful, or false if an error is encountered while determining
	 * the structure of this element.
	 */
	protected abstract boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException;
	//protected boolean generateInfos(OpenableInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws CModelException {
	//	return false;
	//}

	/**
	 * @see org.eclipse.cdt.core.model.IOpenable#getBuffer()
	 */
	public IBuffer getBuffer() throws CModelException {
		if (hasBuffer()) {
			// ensure element is open
			if (!isOpen()) {
				getElementInfo();
			}
			IBuffer buffer = getBufferManager().getBuffer(this);
			if (buffer == null) {
				// try to (re)open a buffer
				buffer = openBuffer(null);
			}
			return buffer;
		} else {
			return null;
		}
	}

	/**
	 * Answers the buffer factory to use for creating new buffers
	 */
	public IBufferFactory getBufferFactory(){
		return getBufferManager().getDefaultBufferFactory();
	}

	/**
	 * Returns the buffer manager for this element.
	 */
	protected BufferManager getBufferManager() {
		return BufferManager.getDefaultBufferManager();
	}
	
	/**
	 * Returns true if this element may have an associated source buffer,
	 * otherwise false. Subclasses must override as required.
	 */
	protected boolean hasBuffer() {
		return false;
	}
	/**
	 * @see org.eclipse.cdt.core.model.IOpenable#hasUnsavedChanges()
	 */
	public boolean hasUnsavedChanges() throws CModelException{
	
		if (isReadOnly() || !isOpen()) {
			return false;
		}
		IBuffer buf = this.getBuffer();
		if (buf != null && buf.hasUnsavedChanges()) {
			return true;
		}
		// for roots and projects must check open buffers
		// to see if they have an child with unsaved changes
		if (fType == C_MODEL ||
			fType == C_PROJECT) {
			Enumeration openBuffers= getBufferManager().getOpenBuffers();
			while (openBuffers.hasMoreElements()) {
				IBuffer buffer= (IBuffer)openBuffers.nextElement();
				if (buffer.hasUnsavedChanges()) {
					ICElement owner= (ICElement)buffer.getOwner();
					if (isAncestorOf(owner)) {
						return true;
					}
				}
			}
		}
	
		return false;
	}
	/**
	 * Subclasses must override as required.
	 * 
	 * @see org.eclipse.cdt.core.model.IOpenable#isConsistent()
	 */
	public boolean isConsistent() throws CModelException {
		return true;
	}

	/**
	 * @see org.eclipse.cdt.core.model.IOpenable#isOpen()
	 */	
	public boolean isOpen() {
		synchronized(CModelManager.getDefault()){
			return CModelManager.getDefault().getInfo(this) != null;
		}
	}

	/**
	 * Returns true if this represents a source element.
	 * Openable source elements have an associated buffer created
	 * when they are opened.
	 */
	protected boolean isSourceElement() {
		return false;
	}

	/**
	 * @see org.eclipse.cdt.core.model.IOpenable#makeConsistent(IProgressMonitor)
	 */
	public void makeConsistent(IProgressMonitor pm) throws CModelException {
		makeConsistent(pm, false);
	}
	
	public void makeConsistent(IProgressMonitor pm, boolean forced) throws CModelException {
		if (!isConsistent() || forced) {
			buildStructure((OpenableInfo)getElementInfo(), pm);
		}
	}

	/**
	 * @see org.eclipse.cdt.core.model.IOpenable#open(IProgressMonitor)
	 */
	public void open(IProgressMonitor pm) throws CModelException {
		if (!isOpen()) {
			this.openWhenClosed(pm);
		}
	}

	/**
	 * Opens a buffer on the contents of this element, and returns
	 * the buffer, or returns <code>null</code> if opening fails.
	 * By default, do nothing - subclasses that have buffers
	 * must override as required.
	 */
	protected IBuffer openBuffer(IProgressMonitor pm) throws CModelException {
		return null;
	}

	/**
	 * 	Open the parent element if necessary
	 * 
	 */
	protected void openParent(IProgressMonitor pm) throws CModelException {

		Openable openableParent = (Openable)getOpenableParent();
		if (openableParent != null) {
			if (!openableParent.isOpen()){
				openableParent.openWhenClosed(pm);
			}
		}
	}

	/**
	 * Open a <code>IOpenable</code> that is known to be closed (no check for
	 * <code>isOpen()</code>).
	 */
	protected void openWhenClosed(IProgressMonitor pm) throws CModelException {
		try {
			
			// 1) Parent must be open - open the parent if necessary
			openParent(pm);

			// 2) create the new element info and open a buffer if needed
			OpenableInfo info = (OpenableInfo) createElementInfo();
			IResource resource = getResource();
			if (resource != null && isSourceElement()) {
				this.openBuffer(pm);
			} 

			// 3) build the structure of the openable
			buildStructure(info, pm);
		
			// if any problems occuring openning the element, ensure that it's info
			// does not remain in the cache	(some elements, pre-cache their info
			// as they are being opened).
		} catch (CModelException e) {
			CModelManager.getDefault().removeInfo(this);
			throw e;
		}
	}

	/**
	 * @see org.eclipse.cdt.core.model.IOpenable#save(IProgressMonitor, boolean)
	 */
	public void save(IProgressMonitor pm, boolean force) throws CModelException {
		if (isReadOnly() || this.getResource().isReadOnly()) {
			throw new CModelException(new CModelStatus(ICModelStatusConstants.READ_ONLY, this));
		}
		IBuffer buf = getBuffer();
		if (buf != null) { 
			buf.save(pm, force);
			this.makeConsistent(pm); // update the element info of this element
		}
	}
		
}
