/*******************************************************************************
 * Copyright (c) 2003, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.server.ui.internal.editor;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.wst.server.core.*;
import org.eclipse.wst.server.core.internal.Server;
import org.eclipse.wst.server.ui.editor.IServerEditorPartInput;
import org.eclipse.wst.server.ui.internal.Messages;
import org.eclipse.wst.server.ui.internal.ServerUIPlugin;
import org.eclipse.wst.server.ui.internal.Trace;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
 * 
 */
public class GlobalCommandManager {
	// maximum number of commands in the history
	private static final int MAX_HISTORY = 200;

	class ServerResourceCommand {
		IUndoableOperation command;
		String id;
	}

	// commands in the undo history
	protected List undoList = new ArrayList();

	// size of the undo stack on last save
	protected int undoSaveIndex = 0;

	// commands in the redo history
	protected List redoList = new ArrayList();

	class CommandManagerInfo {
		// number of open editors on this resource
		int count;
		
		// true if the resource has not been saved since
		// the last change
		boolean isDirty;
		
		// true if the resource is read-only
		boolean isReadOnly;
		
		// the element id
		String id;
		
		// the working copy
		IServerWorkingCopy wc;
		
		// files and timestamps
		Map fileMap;
		
		int timestamp;
	}

	protected Map commandManagers = new HashMap();

	// property change listeners
	protected List propertyListeners;
	public static final String PROP_DIRTY = "dirtyState";
	public static final String PROP_UNDO = "undoAction";
	public static final String PROP_REDO = "redoAction";
	public static final String PROP_RELOAD = "reload";

	protected static GlobalCommandManager instance;

	public static GlobalCommandManager getInstance() {
		if (instance == null)
			instance = new GlobalCommandManager();
		return instance;
	}

	/**
	 * Add a property change listener to this instance.
	 *
	 * @param listener java.beans.PropertyChangeListener
	 */
	public void addPropertyChangeListener(PropertyChangeListener listener) {
		if (propertyListeners == null)
			propertyListeners = new ArrayList();
		propertyListeners.add(listener);
	}

	/**
	 * Remove a property change listener from this instance.
	 *
	 * @param listener java.beans.PropertyChangeListener
	 */
	public void removePropertyChangeListener(PropertyChangeListener listener) {
		if (propertyListeners != null)
			propertyListeners.remove(listener);
	}

	/**
	 * Fire a property change event.
	 */
	protected void firePropertyChangeEvent(String propertyName, Object oldValue, Object newValue) {
		if (propertyListeners == null)
			return;

		PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
		//Trace.trace("Firing: " + event + " " + oldValue);
		try {
			int size = propertyListeners.size();
			PropertyChangeListener[] pcl = new PropertyChangeListener[size];
			propertyListeners.toArray(pcl);
			
			for (int i = 0; i < size; i++)
				try {
					pcl[i].propertyChange(event);
				} catch (Exception e) {
					// ignore
				}
		} catch (Exception e) {
			// ignore
		}
	}

	/**
	 * Get the command manager for a given id.
	 * 
	 * @param id an id
	 */
	public void getCommandManager(String id) {
		Trace.trace(Trace.FINEST, "Getting command manager for " + id);
		try {
			CommandManagerInfo info = (CommandManagerInfo) commandManagers.get(id);
			if (info != null) {
				info.count ++;
				return;
			}
		} catch (Exception e) {
			Trace.trace(Trace.WARNING, "Could not find existing command manager", e);
		}
		Trace.trace(Trace.FINEST, "Creating new command manager for " + id);
		try {
			CommandManagerInfo info = new CommandManagerInfo();
			info.count = 1;
			info.id = id;
			IServer server = null;
			if (id != null)
				server = ServerCore.findServer(id);
			if (server != null)
				info.wc = server.createWorkingCopy();
			info.isDirty = false;
			info.isReadOnly = false;
			commandManagers.put(id, info);
			updateTimestamps(id);
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not obtain command manager", e);
		}
		return;
	}

	/**
	 * Release the command manager for a given id.
	 * 
	 * @param id an id
	 */
	public void releaseCommandManager(String id) {
		Trace.trace(Trace.FINEST, "Releasing command manager for " + id);
		try {
			CommandManagerInfo info = (CommandManagerInfo) commandManagers.get(id);
			if (info != null) {
				info.count --;
				if (info.count == 0) {
					commandManagers.remove(id);
					clearUndoList(id);
					clearRedoList(id);
				}
			}
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not release command manager", e);
		}
	}

	/**
	 * Reload the command manager for a given id.
	 * 
	 * @param id an id
	 */
	public void reload(String id) {
		try {
			CommandManagerInfo info = getExistingCommandManagerInfo(id);
			if (info != null) {
				IServer server = null;
				if (id != null)
					server = ServerCore.findServer(id);
				if (server != null)
					info.wc = server.createWorkingCopy();
				firePropertyChangeEvent(PROP_RELOAD, id, null);
			}
			clearUndoList(id);
			clearRedoList(id);
			undoSaveIndex = undoList.size();
			setDirtyState(id, false);
			updateTimestamps(id);
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not release command manager", e);
		}
	}

	/**
	 * 
	 */
	protected CommandManagerInfo getExistingCommandManagerInfo(String id) {
		try {
			return (CommandManagerInfo) commandManagers.get(id);
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Could not find existing command manager info");
		}
		return null;
	}

	/**
	 * Returns true if there is only one command manager.
	 * 
	 * @param id an id
	 * @return <code>true</code> if the only command manager
	 */
	public boolean isOnlyCommandManager(String id) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		return (info != null && info.count == 1);
	}
	
	protected IServerEditorPartInput getPartInput(String serverId, ServerResourceCommandManager serverCommandManager) {
		CommandManagerInfo serverInfo = null;
		IServerWorkingCopy server = null;
		boolean serverReadOnly = false;
		if (serverId != null) {
			serverInfo = getExistingCommandManagerInfo(serverId);
			if (serverInfo == null)
				return null;
			
			server = serverInfo.wc;
			serverReadOnly = serverInfo.isReadOnly;
		}

		return new ServerEditorPartInput(serverCommandManager, server, serverReadOnly);
	}
	
	/**
	 * 
	 */
	protected IServerWorkingCopy getServerResource(String id) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return null;
			
		return info.wc;
	}

	/**
	 * Execute the given command and place it in the undo stack.
	 * If the command cannot be undone, the user will be notifed
	 * before it is executed.
	 *
	 * @param id an id
	 * @param command a task
	 */
	public void executeCommand(String id, IUndoableOperation command) {
		if (!command.canUndo() && !undoList.isEmpty() && ServerUIPlugin.getPreferences().getPromptBeforeIrreversibleChange()) {
			try {
				Display d = Display.getCurrent();
				if (d == null)
					d = Display.getDefault();
		
				Shell shell = d.getActiveShell();
				if (!MessageDialog.openConfirm(shell, Messages.editorServerEditor, Messages.editorPromptIrreversible))
					return;
			} catch (Exception e) {
				// ignore
			}
		}
		
		ServerResourceCommand src = new ServerResourceCommand();
		src.id = id;
		src.command = command;

		try {
			command.execute(new NullProgressMonitor(), null);
		} catch (ExecutionException ce) {
			return;
		}

		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return;

		if (command.canUndo())
			addToUndoList(src);
		else {
			undoSaveIndex = -1;
			clearUndoList(id);
		}

		// clear redo list since a new command has been executed.
		clearRedoList(id);

		setDirtyState(id, true);
	}

	/**
	 * Add a command to the history.
	 */
	private void addToUndoList(ServerResourceCommand src) {
		undoList.add(src);

		// limit history growth
		if (undoList.size() > MAX_HISTORY)
			undoList.remove(0);

		firePropertyChangeEvent(PROP_UNDO, src.id, null);
	}

	/**
	 * Clears the undo of a particular resource.
	 */
	private void clearUndoList(String id) {
		int i = 0;
		boolean modified = false;
		while (i < undoList.size()) {
			ServerResourceCommand src = (ServerResourceCommand) undoList.get(i);
			if (src.id.equals(id)) {
				modified = true;
				undoList.remove(i);
			} else
				i++;
		}
		if (modified)
			firePropertyChangeEvent(PROP_UNDO, id, null);
	}

	/**
	 * Clears the redo of a particular resource.
	 */
	private void clearRedoList(String id) {
		int i = 0;
		boolean modified = false;
		while (i < redoList.size()) {
			ServerResourceCommand src = (ServerResourceCommand) redoList.get(i);
			if (src.id.equals(id)) {
				redoList.remove(i);
				modified = true;
			} else
				i++;
		}
		if (modified)
			firePropertyChangeEvent(PROP_REDO, id, null);
	}

	/**
	 * Returns true if there is a command that can be undone.
	 * @return boolean
	 */
	protected boolean canUndo(String a, String b) {
		Iterator iterator = undoList.iterator();
		while (iterator.hasNext()) {
			ServerResourceCommand src = (ServerResourceCommand) iterator.next();
			if (src.id == a || src.id == b)
				return true;
		}
		return false;
	}
	
	/**
	 * Returns true if there is a command that can be redone.
	 * @return boolean
	 */
	protected boolean canRedo(String a, String b) {
		Iterator iterator = redoList.iterator();
		while (iterator.hasNext()) {
			ServerResourceCommand src = (ServerResourceCommand) iterator.next();
			if (src.id == a || src.id == b)
				return true;
		}
		return false;
	}
	
	/**
	 * Returns the command that would be undone next.
	 * 
	 * @param a an id
	 * @return a task
	 */
	public IUndoableOperation getUndoCommand(String a) {
		int size = undoList.size();
		for (int i = size - 1; i >= 0; i--) {
			ServerResourceCommand src = (ServerResourceCommand) undoList.get(i);
			if (src.id == a)
				return src.command;
		}
		return null;
	}

	/**
	 * Returns the command that would be redone next.
	 * 
	 * @param a an id
	 * @return a task
	 */
	public IUndoableOperation getRedoCommand(String a) {
		int size = redoList.size();
		for (int i = size - 1; i >= 0; i--) {
			ServerResourceCommand src = (ServerResourceCommand) redoList.get(i);
			if (src.id == a)
				return src.command;
		}
		return null;
	}

	/**
	 * Returns true if the server resource is "dirty".
	 *
	 * @param id an id
	 * @return a task
	 */
	public boolean isDirty(String id) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return false;
		
		return info.isDirty;
	}
	
	/**
	 * Returns true if the server resource is read-only.
	 *
	 * @param id an id
	 * @return boolean
	 */
	public boolean isReadOnly(String id) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return false;
		return info.isReadOnly;
	}
	
	/**
	 * Sets the server resource read-only flag.
	 * 
	 * @param id an id
	 * @param readOnly <code>true</code> to set read-only, <code>false</code> otherwise
	 */
	public void setReadOnly(String id, boolean readOnly) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return;
		
		if (info.isReadOnly == readOnly)
			return;
		info.isReadOnly = readOnly;
		firePropertyChangeEvent(PROP_RELOAD, id, null);
	}

	/**
	 * Returns true if the server resource files are read-only.
	 *
	 * @param id an id
	 * @return <code>true</code> if the files are read-only
	 */
	public boolean areFilesReadOnly(String id) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return false;
		return (getReadOnlyFiles(id).length > 0);
	}
	
	/**
	 * Sets the dirty state and fires an event if needed.
	 * @param dirty boolean
	 */
	private void setDirtyState(String id, boolean dirty) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info.isDirty == dirty)
			return;
		
		info.isDirty = dirty;
		firePropertyChangeEvent(PROP_DIRTY, id, null);
	}

	/**
	 * Undo the last command.
	 */
	protected void undo(String a) {
		ServerResourceCommand src = null;
		Iterator iterator = undoList.iterator();
		while (iterator.hasNext()) {
			ServerResourceCommand src2 = (ServerResourceCommand) iterator.next();
			if (src2.id == a)
				src = src2;
		}
		if (src == null)
			return;
		
		try {
			src.command.undo(null, null);
		} catch (ExecutionException ee) {
			// do something
		}
		
		undoList.remove(src);
		firePropertyChangeEvent(PROP_UNDO, src.id, null);
		redoList.add(src);
		firePropertyChangeEvent(PROP_REDO, src.id, null);
		
		if (undoSaveIndex == undoList.size())
			setDirtyState(src.id, false);
		else
			setDirtyState(src.id, true);
	}

	/**
	 * Redo the last command.
	 */
	protected void redo(String a) {
		ServerResourceCommand src = null;
		Iterator iterator = redoList.iterator();
		while (iterator.hasNext()) {
			ServerResourceCommand src2 = (ServerResourceCommand) iterator.next();
			if (src2.id == a)
				src = src2;
		}
		if (src == null)
			return;

		try {
			src.command.execute(new NullProgressMonitor(), null);
		} catch (ExecutionException ce) {
			return;
		}
		redoList.remove(src);
		firePropertyChangeEvent(PROP_REDO, src.id, null);
		undoList.add(src);
		firePropertyChangeEvent(PROP_UNDO, src.id, null);
		
		if (undoSaveIndex == undoList.size())
			setDirtyState(src.id, false);
		else
			setDirtyState(src.id, true);
	}

	/**
	 * Clears the history list.
	 * 
	 * @param id an id
	 */
	public void resourceSaved(String id) {
		undoSaveIndex = undoList.size();
		setDirtyState(id, false);
	}

	/**
	 * Return an array of read-only files.
	 * 
	 * @param server a server
	 * @return a possibly empty array of files
	 */
	public static IFile[] getReadOnlyFiles(IServerAttributes server) {
		try {
			List list = new ArrayList();
			IFile file = ((Server)server).getFile();
			
			if (file != null)
				list.add(file);
			
			IFile[] files = new IFile[list.size()];
			list.toArray(files);
			return files;
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "getReadOnlyFiles", e);
		}
		return null;
	}

	/**
	 * 
	 */
	protected IFile[] getServerResourceFiles(String id) {
		if (id == null)
			return new IFile[0];
		
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return new IFile[0];
		
		return getReadOnlyFiles(info.wc);
	}

	protected IFile[] getReadOnlyFiles(String id) {
		List list = new ArrayList();
		IFile[] files = getServerResourceFiles(id);
		int size = files.length;
		for (int i = 0; i < size; i++) {
			if (files[i].isReadOnly())
				list.add(files[i]);
		}
		
		IFile[] fileList = new IFile[list.size()];
		list.toArray(fileList);
		return fileList;
	}

	/**
	 * Update the timestamps.
	 * 
	 * @param id an id
	 */
	public void updateTimestamps(String id) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return;
		
		info.fileMap = new HashMap();
		IFile[] files = getServerResourceFiles(id);
		if (files != null) {
			int size = files.length;
			
			for (int i = 0; i < size; i++) {
				if (files[i] != null) {
					File f = files[i].getLocation().toFile();
					if (f != null) {
						long time = f.lastModified();
						info.fileMap.put(files[i], new Long(time));
					}
				}
			}
		}
		info.timestamp = getTimestamp(info);
	}

	protected static int getTimestamp(CommandManagerInfo info) {
		IServer server = info.wc.getOriginal();
		
		if (server != null)
			return ((Server)server).getTimestamp();
		return -1;
	}

	/**
	 * 
	 */
	protected boolean hasChanged(String id) {
		CommandManagerInfo info = getExistingCommandManagerInfo(id);
		if (info == null)
			return false;
		IFile[] files = getServerResourceFiles(id);
		int size = files.length;
		
		int count = 0;
		for (int i = 0; i < size; i++) {
			count++;
			File f = files[i].getLocation().toFile();
			try {
				Long time = (Long) info.fileMap.get(files[i]);
				if (time.longValue() != f.lastModified())
					return true;
			} catch (Exception e) {
				return true;
			}
		}
		
		int timestamp = getTimestamp(info);
		if (info.timestamp != timestamp)
			return true;
		
		if (count != info.fileMap.size())
			return true;
		return false;
	}
}