/*******************************************************************************
 * 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.IProgressMonitor;
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
	 * @param monitor a progress monitor
	 */
	public void reload(String id, IProgressMonitor monitor) {
		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();
				//info.serverElement = ServerCore.getResourceManager().getServer()
				//info.serverElement = ServerCore.getEditManager().reloadEditModel(info.file, monitor);
				firePropertyChangeEvent(PROP_RELOAD, id, null);
			}
		} 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);
			
			//if ()
			//IServerConfiguration config = (IServerConfiguration) element;
			// TODO: get read-only files
			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;
	}
}