/*******************************************************************************
 * Copyright (c) 2003, 2011 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.util.*;
import java.util.List;

import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.part.MultiPageEditorPart;

import org.eclipse.wst.server.core.*;
import org.eclipse.wst.server.core.internal.Server;
import org.eclipse.wst.server.core.internal.ServerWorkingCopy;
import org.eclipse.wst.server.ui.ServerUICore;
import org.eclipse.wst.server.ui.editor.*;
import org.eclipse.wst.server.ui.internal.*;
/**
 * A multi-page server resource editor.
 */
public class ServerEditor extends MultiPageEditorPart {
	/**
	 * Internal part and shell activation listener
	 */
	class ActivationListener extends ShellAdapter implements IPartListener {
		private IWorkbenchPart fActivePart;
		private boolean fIsHandlingActivation = false;
		
		public void partActivated(IWorkbenchPart part) {
			fActivePart = part;
			handleActivation();
		}

		public void partBroughtToTop(IWorkbenchPart part) {
			// do nothing
		}

		public void partClosed(IWorkbenchPart part) {
			// do nothing
		}

		public void partDeactivated(IWorkbenchPart part) {
			fActivePart = null;
		}

		public void partOpened(IWorkbenchPart part) {
			// do nothing
		}

		public void shellActivated(ShellEvent e) {
			handleActivation();
		}

		private void handleActivation() {
			if (fIsHandlingActivation)
				return;
			
			if (fActivePart == ServerEditor.this) {
				fIsHandlingActivation = true;
				try {
					checkResourceState();
				} finally {
					fIsHandlingActivation = false;
				}
			}
		}
	}

	class LifecycleListener implements IServerLifecycleListener {
		public void serverAdded(IServer oldServer) {
			// do nothing
		}
		public void serverChanged(IServer oldServer) {
			// do nothing
		}
		public void serverRemoved(IServer oldServer) {
			if (oldServer.equals(server.getOriginal())) {
				resourceDeleted = true;
				if (!isDirty()) {
					closeEditor();
				}
			}
		}
	}

	protected IServerWorkingCopy server;
	protected String serverId;
	protected String serverName;

	protected GlobalCommandManager commandManager;

	protected PropertyChangeListener listener;

	protected IAction undoAction;
	protected IAction redoAction;

	protected TextAction cutAction;
	protected TextAction copyAction;
	protected TextAction pasteAction;
	protected boolean updatingActions;

	protected IAction[] editorActions;

	protected java.util.List<IEditorPart> serverPages;

	// on focus change flag
	protected boolean resourceDeleted;

	// input given to the contained pages
	protected IServerEditorPartInput editorPartInput;

	// status line and status
	protected IStatusLineManager status;
	protected StatusLineContributionItem statusItem;

	private ActivationListener activationListener = new ActivationListener();
	protected LifecycleListener resourceListener;

	// used for disabling resource change check when saving through editor
	protected boolean isSaving = false;

	protected Map<IEditorPart, IServerEditorPartFactory> pageToFactory = new HashMap<IEditorPart, IServerEditorPartFactory>();

	/**
	 * ServerEditor constructor comment.
	 */
	public ServerEditor() {
		super();
		
		ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
		
		undoAction = new Action() {
			public void run() {
				getCommandManager().undo(serverId);
			}
		};
		undoAction.setEnabled(false);
		undoAction.setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
		//undoAction.setHoverImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO_HOVER));
		//undoAction.setDisabledImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_UNDO_DISABLED));
		
		redoAction = new Action() {
			public void run() {
				getCommandManager().redo(serverId);
			}
		};
		redoAction.setEnabled(false);
		redoAction.setImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
		//redoAction.setHoverImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO_HOVER));
		//redoAction.setDisabledImageDescriptor(sharedImages.getImageDescriptor(ISharedImages.IMG_TOOL_REDO_DISABLED));
	}

	/**
	 * Close the editor correctly.
	 */
	protected void closeEditor() {
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				getEditorSite().getPage().closeEditor(ServerEditor.this, false);
			}
		});
	}

	protected void createActions() {
		List<IAction> actionList = new ArrayList<IAction>();
		
		// add server actions
		if (server != null && server.getServerType() != null) {
			Iterator iterator = ServerEditorCore.getServerEditorActionFactories().iterator();
			String id = server.getServerType().getId();
			while (iterator.hasNext()) {
				ServerEditorActionFactory factory = (ServerEditorActionFactory) iterator.next();
				if (factory.supportsServerElementType(id) && factory.shouldDisplay(server))
					actionList.add(factory.createAction(getEditorSite(), editorPartInput));
			}
		}

		editorActions = new IAction[actionList.size()];
		actionList.toArray(editorActions);
	}

	public IServerEditorPartFactory getPageFactory(ServerEditorPart part) {
		try {
			return pageToFactory.get(part);
		} catch (Exception e) {
			// ignore
		}
		return null;
	}

	/**
	 * Creates the pages of this multi-page editor.
	 * <p>
	 * Subclasses of <code>MultiPageEditor</code> must implement this method.
	 * </p>
	 */
	protected void createPages() {
		try {
			int index = 0;
			serverPages = new ArrayList<IEditorPart>();
			
			// add editor pages
			int pageCount = 0;
			
			String serverTypeId = null;
			if (server != null && server.getServerType() != null)
				serverTypeId = server.getServerType().getId();
			
			Iterator iterator = ServerEditorCore.getServerEditorPageFactories().iterator();
			while (iterator.hasNext()) {
				IServerEditorPartFactory factory = (IServerEditorPartFactory) iterator.next();
				if (factory.supportsType(serverTypeId) && factory.shouldCreatePage(server)) {
					if (Trace.FINEST) {
						Trace.trace(Trace.STRING_FINEST, "Adding page: " + factory.getId() + " " + editorPartInput);
					}
					try {
						IEditorPart page = factory.createPage();
						if (page != null) {
							pageToFactory.put(page, factory);
							index = addPage(page, editorPartInput);
							setPageText(index, factory.getName());
							
							serverPages.add(page);
					
							pageCount ++;
						}
					} catch (Exception e) {
						if (Trace.SEVERE) {
							Trace.trace(Trace.STRING_SEVERE, "Could not display editor page " + factory.getId(), e);
						}
					}
				}
			}
			
			if (pageCount > 0)
				setActivePage(0);
			
			// register for events that might change the cut/copy/paste actions
			int count = getPageCount();
			for (int i = 0; i < count; i++) {
				Control control = getControl(i);
				registerEvents(control);
			}
			updateActions();
		} catch (Exception e) {
			if (Trace.SEVERE) {
				Trace.trace(Trace.STRING_SEVERE, "Error creating server editor pages", e);
			}
		}
	}

	public void dispose() {
		if (activationListener != null) {
			IWorkbenchWindow window = getSite().getWorkbenchWindow();
			window.getPartService().removePartListener(activationListener);
			Shell shell = window.getShell();
			if (shell != null && !shell.isDisposed())
				shell.removeShellListener(activationListener);
			activationListener = null;
		}
		
		if (resourceListener != null)
			ServerCore.removeServerLifecycleListener(resourceListener);
		
		if (serverName != null && !server.getName().equals(serverName)) {
			// only prompt if the server is in the workspace or there is a configuration
			if (server.getServerConfiguration() != null || ((Server)server).getFile() != null) {
				String title = Messages.editorServerEditor;
				String message = Messages.editorRenameFiles;
				if (MessageDialog.openQuestion(getEditorSite().getShell(), title,  message))
					try {
						((ServerWorkingCopy)server).renameFiles(null);
					} catch (Exception e) {
						if (Trace.SEVERE) {
							Trace.trace(Trace.STRING_SEVERE, "Error renaming server", e);
						}
					}
			}
		}
		
		super.dispose();
		if (commandManager != null) {
			commandManager.removePropertyChangeListener(listener);
			
			if (serverId != null)
				commandManager.releaseCommandManager(serverId);
			
			commandManager = null;
		}
	}

	/* (non-Javadoc)
	 * Saves the contents of this editor.
	 * <p>
	 * Subclasses must override this method to implement the open-save-close lifecycle
	 * for an editor.  For greater details, see <code>IEditorPart</code>
	 * </p>
	 *
	 * @see IEditorPart
	 */
	public void doSave(IProgressMonitor monitor) {
		// set the isSaving flag to true
		isSaving = true;
		
		// check pages for errors first
		java.util.List<String> errors = new ArrayList<String>();
		Iterator iterator = serverPages.iterator();
		int count = 0;
		int maxSeverity = -1;
		while (iterator.hasNext()) {
			IEditorPart part = (IEditorPart) iterator.next();
			if (part instanceof ServerEditorPart) {
				IStatus[] status2 = ((ServerEditorPart) part).getSaveStatus();
				if (status2 != null) {
					int size = status2.length;
					for (int i = 0; i < size; i++) {
						errors.add("[" + getPageText(count) + "] " + status2[i].getMessage());
						maxSeverity = Math.max(maxSeverity, status2[i].getSeverity());
					}
				}
			}
			count ++;
		}
		if (!errors.isEmpty() && maxSeverity > IStatus.OK) {
			StringBuffer sb = new StringBuffer();
			sb.append(Messages.errorEditorCantSave + "\n");
			iterator = errors.iterator();
			while (iterator.hasNext())
				sb.append("\t" + ((String) iterator.next()) + "\n");
			
			if (maxSeverity == IStatus.ERROR) {
				MessageDialog.openError(getEditorSite().getShell(), getPartName(), sb.toString());
				monitor.setCanceled(true);
				// reset the isSaving flag
				isSaving = false;
				return;
			} else if (maxSeverity == IStatus.WARNING)
				MessageDialog.openWarning(getEditorSite().getShell(), getPartName(), sb.toString());
			else // if (maxSeverity == IStatus.INFO)
				MessageDialog.openInformation(getEditorSite().getShell(), getPartName(), sb.toString());
		}
		
		try {
			monitor = ProgressUtil.getMonitorFor(monitor);
			int ticks = 2000;
			int pages = serverPages == null ? 0 : serverPages.size(); 
			int pagesTicks = ( pages * 100);
			String name = "";
			if (server != null)
				name = server.getName();
			monitor.beginTask(NLS.bind(Messages.savingTask, name), ticks + pagesTicks);
			if (server != null)
				ticks /= 2;
			
			if (server != null)  {
				iterator = serverPages.iterator();
				while(iterator.hasNext()) {
					IEditorPart part = (IEditorPart) iterator.next();
					part.doSave(ProgressUtil.getSubMonitorFor(monitor, 100));
				}

				server.save(false, ProgressUtil.getSubMonitorFor(monitor, ticks));
				getCommandManager().resourceSaved(serverId);
				commandManager.updateTimestamps(serverId);
			}
			
			ILabelProvider labelProvider = ServerUICore.getLabelProvider();
			if (server != null)
				setPartName(labelProvider.getText(server));
			labelProvider.dispose();
		} catch (Exception e) {
			if (Trace.SEVERE) {
				Trace.trace(Trace.STRING_SEVERE, "Error saving server editor", e);
			}
			
			monitor.setCanceled(true);
			
			String title = Messages.editorSaveErrorDialog;
			String message = NLS.bind(Messages.editorSaveErrorMessage, e.getLocalizedMessage());
			MessageDialog.openError(getEditorSite().getShell(), title,  message);
		} finally {
			monitor.done();
		}
		// reset the isSaving flag
		isSaving = false;
	}

	/* (non-Javadoc)
	 * Saves the contents of this editor to another object.
	 * <p>
	 * Subclasses must override this method to implement the open-save-close lifecycle
	 * for an editor.  For greater details, see <code>IEditorPart</code>
	 * </p>
	 *
	 * @see IEditorPart
	 */
	public void doSaveAs() {
		// do nothing
	}

	/**
	 * Fire a property change event.
	 *
	 * @param i a property change value
	 */
	protected void firePropertyChange(int i) {
		if (i == ServerEditorPart.PROP_ERROR)
			updateStatusError();
		super.firePropertyChange(i);
	}

	/**
	 * Return the global command manager.
	 * 
	 * @return the global command manager
	 */
	public GlobalCommandManager getCommandManager() {
		return commandManager;
	}

	/**
	 * Return the redo action.
	 *
	 * @return org.eclipse.jface.action.Action
	 */
	public IAction getRedoAction() {
		return redoAction;
	}

	/**
	 * Return the undo action.
	 *
	 * @return org.eclipse.jface.action.Action
	 */
	public IAction getUndoAction() {
		return undoAction;
	}

	/* (non-Javadoc)
	 * Sets the cursor and selection state for this editor to the passage defined
	 * by the given marker.
	 * <p>
	 * Subclasses may override.  For greater details, see <code>IEditorPart</code>
	 * </p>
	 *
	 * @see IEditorPart
	 */
	public void gotoMarker(IMarker marker) {
		// do nothing
	}

	/**
	 * Update the cut, copy, and paste actions.
	 */
	public void updateActionsImpl() {
		if (updatingActions)
			return;
		
		updatingActions = true;
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				updatingActions = false;
				updateActions();
			}
		});
	}

	/**
	 * Update the cut, copy, and paste actions.
	 */
	public void updateActions() {
		cutAction.update();
		copyAction.update();
		pasteAction.update();
	}
	
	/**
	 * Update the cut, copy, and paste actions.
	 */
	protected void updateStatusLine() {
		if (statusItem != null) {
			boolean readOnly = false;
			if (server != null && commandManager.isReadOnly(serverId))
				readOnly = true;
			
			if (readOnly)
				statusItem.setText(Messages.editorReadOnly);
			else
				statusItem.setText(Messages.editorWritable);
		}

		if (status != null) {
			StringBuffer sb = new StringBuffer();
			boolean first = true;
			if (server != null) {
				IFile[] files = commandManager.getReadOnlyFiles(serverId);
				for (int i = 0; i < files.length; i++) {
					if (!first)
						sb.append(", ");
					sb.append(files[i].getName());
					first = false;
				}
			}
			/*if (serverConfiguration != null) {
				IFile[] files = commandManager.getReadOnlyFiles(serverConfigurationId);
				for (int i = 0; i < files.length; i++) {
					if (!first)
						sb.append(", ");
					sb.append(files[i].getName());
					first = false;
				}
			}*/
			if (sb.length() > 1)
				status.setMessage(NLS.bind(Messages.editorReadOnlyFiles, sb.toString()));
			else
				status.setMessage("");
		}
	}

	/**
	 * 
	 */
	public void updateStatusError() {
		if (status == null)
			return;
		
		String error = null;
		IEditorPart part = getActiveEditor();
		if (part instanceof ServerEditorPart)
			error = ((ServerEditorPart) part).getErrorMessage();
		
		Iterator iterator = serverPages.iterator();
		int count = 0;
		while (error == null && iterator.hasNext()) {
			part = (IEditorPart) iterator.next();
			if (part instanceof ServerEditorPart) {
				error = ((ServerEditorPart) part).getErrorMessage();
				if (error != null)
					error = "[" + getPageText(count) + "] " + error;
			}
			count ++;
		}
		status.setErrorMessage(error);
	}

	/**
	 * 
	 */
	protected void pageChange(int newPageIndex) {
		super.pageChange(newPageIndex);
		updateStatusError();
	}
	
	/**
	 * Set the status.
	 * 
	 * @param status a status line manager
	 * @param item a status contribution item
	 */
	public void setStatus(IStatusLineManager status, StatusLineContributionItem item) {
		this.status = status;
		this.statusItem = item;
		updateStatusError();
	}
	
	/**
	 * Register for key and traversal events to enable/disable the cut/copy/paste actions.
	 */
	protected void registerEvents(Control control) {
		if (control == null)
			return;
		
		if (control instanceof Text || control instanceof Combo) {
			// register the world... any of these actions could cause the state to change
			control.addTraverseListener(new TraverseListener() {
				public void keyTraversed(TraverseEvent event) {
					updateActionsImpl();
				}
			});
			control.addKeyListener(new KeyListener() {
				public void keyPressed(KeyEvent event) {
					updateActionsImpl();
				}
				public void keyReleased(KeyEvent event) {
					updateActionsImpl();
				}
			});
			control.addMouseListener(new MouseListener() {
				public void mouseDown(MouseEvent event) {
					// do nothing
				}
				public void mouseUp(MouseEvent event) {
					updateActionsImpl();
				}
				public void mouseDoubleClick(MouseEvent event) {
					updateActionsImpl();
				}
			});
			control.addFocusListener(new FocusListener() {
				public void focusGained(FocusEvent event) {
					updateActionsImpl();
				}
				public void focusLost(FocusEvent event) {
					updateActionsImpl();
				}
			});
			if (control instanceof Text) {
				Text text = (Text) control;
				text.addModifyListener(new ModifyListener() {
					public void modifyText(ModifyEvent event) {
						updateActionsImpl();
					}
				});
				text.addSelectionListener(new SelectionListener() {
					public void widgetSelected(SelectionEvent event) {
						updateActionsImpl();
					}
					public void widgetDefaultSelected(SelectionEvent event) {
						updateActionsImpl();
					}
				});
			} else {
				Combo combo = (Combo) control;
				combo.addModifyListener(new ModifyListener() {
					public void modifyText(ModifyEvent event) {
						updateActionsImpl();
					}
				});
				combo.addSelectionListener(new SelectionListener() {
					public void widgetSelected(SelectionEvent event) {
						updateActionsImpl();
					}
					public void widgetDefaultSelected(SelectionEvent event) {
						updateActionsImpl();
					}
				});
			}
		}
		
		if (control instanceof Composite) {
			Control[] children = ((Composite)control).getChildren();
			if (children != null) {
				int size = children.length;
				for (int i = 0; i < size; i++)
					registerEvents(children[i]);
			}
		}
	}

	/* (non-Javadoc)
	 * Initializes the editor part with a site and input.
	 * <p>
	 * Subclasses of <code>EditorPart</code> must implement this method.  Within
	 * the implementation subclasses should verify that the input type is acceptable
	 * and then save the site and input.  Here is sample code:
	 * </p>
	 * <pre>
	 *		if (!(input instanceof IFileEditorInput))
	 *			throw new PartInitException("Invalid Input: Must be IFileEditorInput");
	 *		setSite(site);
	 *		setInput(editorInput);
	 * </pre>
	 */
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		commandManager = GlobalCommandManager.getInstance();
		super.init(site, input);

		if (input instanceof IFileEditorInput) {
			IFileEditorInput fei = (IFileEditorInput) input;
			IFile file = fei.getFile();
			if (file != null && file.exists()) {
				IServer server2 = ServerUIPlugin.findServer(file);
				if (server2 != null)
					serverId = server2.getId();
			}
			if (serverId == null) {
				if (file == null)
					throw new PartInitException(NLS.bind(Messages.errorEditor, Messages.elementUnknownName));
				throw new PartInitException(NLS.bind(Messages.errorEditor, file.getName()));
			}
		} else if (input instanceof IServerEditorInput) {
			IServerEditorInput sei = (IServerEditorInput) input;
			serverId = sei.getServerId();
		}

		if (serverId != null) {
			commandManager.getCommandManager(serverId);
			server = commandManager.getServerResource(serverId);
		}

		ILabelProvider labelProvider = ServerUICore.getLabelProvider();
		if (server != null) {
			setPartName(labelProvider.getText(server));
			setTitleImage(labelProvider.getImage(server));
			setTitleToolTip(serverId);
			serverName = server.getName();
		} else
			setPartName("-");
		labelProvider.dispose();
		labelProvider = null;
		
		cutAction = new TextAction(site.getShell().getDisplay(), TextAction.CUT_ACTION);
		copyAction = new TextAction(site.getShell().getDisplay(), TextAction.COPY_ACTION);
		pasteAction = new TextAction(site.getShell().getDisplay(), TextAction.PASTE_ACTION);
		
		listener = new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent event) {
				if (GlobalCommandManager.PROP_DIRTY.equals(event.getPropertyName())) {
					Object obj = event.getOldValue();
					if (obj == serverId)
						firePropertyChange(PROP_DIRTY);
				} else if (GlobalCommandManager.PROP_UNDO.equals(event.getPropertyName())) {
					Object obj = event.getOldValue();
					if (obj == serverId)
						updateUndoAction();
				} else if (GlobalCommandManager.PROP_REDO.equals(event.getPropertyName())) {
					Object obj = event.getOldValue();
					if (obj == serverId)
						updateRedoAction();
				} else if (GlobalCommandManager.PROP_RELOAD.equals(event.getPropertyName())) {
					Object obj = event.getOldValue();
					if (obj == serverId) {
						server = commandManager.getServerResource(serverId);
						refresh();
					}
				}
			}
		};
		if (server != null && commandManager.isDirty(serverId))
			firePropertyChange(PROP_DIRTY);
		
		commandManager.addPropertyChangeListener(listener);
		
		// create editor input
		ServerResourceCommandManager serverCommandManager = null;
		if (server != null)
			serverCommandManager = new ServerResourceCommandManager(this, serverId, commandManager);
		editorPartInput = commandManager.getPartInput(serverId, serverCommandManager);
		
		createActions();
		
		// add resource listener
		resourceListener = new LifecycleListener();
		ServerCore.addServerLifecycleListener(resourceListener);
		
		IWorkbenchWindow window = getSite().getWorkbenchWindow();
		window.getPartService().addPartListener(activationListener);
		window.getShell().addShellListener(activationListener);
	}

	/* (non-Javadoc)
	 * Returns whether the contents of this editor have changed since the last save
	 * operation.
	 * <p>
	 * Subclasses must override this method to implement the open-save-close lifecycle
	 * for an editor.  For greater details, see <code>IEditorPart</code>
	 * </p>
	 *
	 * @see IEditorPart
	 */
	public boolean isDirty() {
		if (commandManager != null) {
			if (server != null && commandManager.isDirty(serverId))
				return true;
		}
		return false;
	}

	/* (non-Javadoc)
	 * Returns whether the "save as" operation is supported by this editor.
	 * <p>
	 * Subclasses must override this method to implement the open-save-close lifecycle
	 * for an editor.  For greater details, see <code>IEditorPart</code>
	 * </p>
	 *
	 * @see IEditorPart
	 */
	public boolean isSaveAsAllowed() {
		return false;
	}

	/**
	 * Update the undo action.
	 */
	protected void updateUndoAction() {
		IUndoableOperation command = commandManager.getUndoCommand(serverId);
		if (command == null) {
			undoAction.setText(Messages.editorUndoDisabled);
			undoAction.setToolTipText("");
			undoAction.setDescription("");
			undoAction.setEnabled(false);
		} else {
			String text = NLS.bind(Messages.editorUndoEnabled, new Object[] {command.getLabel()});
			undoAction.setText(text);
			undoAction.setToolTipText(command.getLabel());
			undoAction.setDescription(command.getLabel());
			undoAction.setEnabled(true);
		}
	}

	/**
	 * Update the redo action.
	 */
	protected void updateRedoAction() {
		IUndoableOperation command = commandManager.getRedoCommand(serverId);
		if (command == null) {
			redoAction.setText(Messages.editorRedoDisabled);
			redoAction.setToolTipText("");
			redoAction.setDescription("");
			redoAction.setEnabled(false);
		} else {
			String text = NLS.bind(Messages.editorRedoEnabled, new Object[] {command.getLabel()});
			redoAction.setText(text);
			redoAction.setToolTipText(command.getLabel());
			redoAction.setDescription(command.getLabel());
			redoAction.setEnabled(true);
		}
	}
	
	/**
	 * Return the cut action.
	 * 
	 * @return org.eclipse.jface.action.IAction
	 */
	public IAction getCutAction() {
		return cutAction;
	}
	
	/**
	 * Return the copy action.
	 * 
	 * @return org.eclipse.jface.action.IAction
	 */
	public IAction getCopyAction() {
		return copyAction;
	}
	
	/**
	 * Return the paste action.
	 * 
	 * @return org.eclipse.jface.action.IAction
	 */
	public IAction getPasteAction() {
		return pasteAction;
	}
	
	/**
	 * Returns the editor actions.
	 * 
	 * @return org.eclipse.jface.action.IAction
	 */
	public IAction[] getEditorActions() {
		return editorActions;
	}
	
	/**
	 * Update the server pages with new input.
	 */
	protected void refresh() {
		// create editor input
		ServerResourceCommandManager serverCommandManager = null;
		if (server != null)
			serverCommandManager = new ServerResourceCommandManager(this, serverId, commandManager);
		editorPartInput = commandManager.getPartInput(serverId, serverCommandManager);
		
		Iterator iterator = serverPages.iterator();
		while (iterator.hasNext()) {
			IEditorPart part = (IEditorPart) iterator.next();						
			try {
				part.init(part.getEditorSite(), editorPartInput);
			} catch (Exception e) {
				if (Trace.SEVERE) {
					Trace.trace(Trace.STRING_SEVERE, "Error refresh()ing editor part", e);
				}
			}
		}	
	}
	
	/**
	 * 
	 */
	protected void promptReadOnlyServerFile(String id) {
		commandManager.setReadOnly(id, true);
		String title = Messages.editorResourceModifiedTitle;
		String message = Messages.editorReadOnlyMessage;
		MessageDialog.openInformation(getEditorSite().getShell(), title, message);
	}

	/**
	 * 
	 */
	protected void promptReloadServerFile(String id) {
		String title = Messages.editorResourceModifiedTitle;
		String message = Messages.editorServerModifiedMessage;
		
		if (MessageDialog.openQuestion(getEditorSite().getShell(), title, message)) {
			/*try {
				//wc.refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
				//TODO: refresh local server
			} catch (Exception e) {
				Trace.trace(Trace.SEVERE, "Error refreshing server", e);
			}*/
			commandManager.reload(id);
		}
	}

	/**
	 * 
	 */
	public void setFocus() {
		super.setFocus();
	}

	/**
	 * 
	 */
	protected void checkResourceState() {
		// do not check the resource state change if saving through the editor
		if (isSaving) {
			// do nothing
			return;
		}
		
		// check for deleted files
		if (resourceDeleted) {
			String title = Messages.editorResourceDeleteTitle;
			String message = null;
			if (server != null)
				message = NLS.bind(Messages.editorResourceDeleteServerMessage, server.getName());
			String[] labels = new String[] {Messages.editorResourceDeleteSave, IDialogConstants.CLOSE_LABEL};
			MessageDialog dialog = new MessageDialog(getEditorSite().getShell(), title, null, message, MessageDialog.INFORMATION, labels, 0);
			
			if (dialog.open() == 0)
				doSave(new NullProgressMonitor());
			else
				closeEditor();
			return;
		}
		resourceDeleted = false;
		
		// check for server changes
		if (serverId != null) {
			if (!commandManager.isDirty(serverId)) {
				if (commandManager.hasChanged(serverId)) {
					IServer newServer = ServerCore.findServer(serverId);
					if (newServer != null && ((Server)newServer).getTimestamp() > ((Server)server).getTimestamp())
						commandManager.reload(serverId);
					else
						promptReloadServerFile(serverId);
				}
			} else {
				if (commandManager.hasChanged(serverId) && !commandManager.areFilesReadOnly(serverId))
					promptReloadServerFile(serverId);
				else if (commandManager.areFilesReadOnly(serverId) && !commandManager.isReadOnly(serverId))
					promptReadOnlyServerFile(serverId);
			}
			if (commandManager.isReadOnly(serverId) && !commandManager.areFilesReadOnly(serverId))
				commandManager.setReadOnly(serverId, false);
			commandManager.updateTimestamps(serverId);
		}
		
		updateStatusLine();
	}

	/**
	 * Set the title tooltip.
	 * 
	 * @return the title tooltip
	 */
	public String getTitleToolTip() {
		Server server2 = (Server) server;
		if (server != null && server2.getFile() != null)
			return server2.getFile().getFullPath().toString();
		else if (server != null)
			return server.getName();
		else
			return "error";
	}

	public int getOrientation() {
		return Window.getDefaultOrientation();
	}
}