/*******************************************************************************
 * Copyright (c) 2008,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.cnf;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.navigator.CommonNavigator;
import org.eclipse.ui.navigator.CommonViewer;
import org.eclipse.wst.server.core.*;
import org.eclipse.wst.server.core.internal.Server;
import org.eclipse.wst.server.core.internal.UpdateServerJob;
import org.eclipse.wst.server.core.util.PublishAdapter;
import org.eclipse.wst.server.ui.internal.Messages;
import org.eclipse.wst.server.ui.internal.ServerToolTip;
import org.eclipse.wst.server.ui.internal.Trace;
/**
 * A view of servers, their modules, and status.
 */
public class ServersView2 extends CommonNavigator {
	private static final String SERVERS_VIEW_CONTEXT = "org.eclipse.ui.serverViewScope";
	
	protected CommonViewer tableViewer;
	
	protected IServerLifecycleListener serverResourceListener;
	protected IPublishListener publishListener;
	protected IServerListener serverListener;
		
	// servers that are currently publishing and starting
	protected static Set<String> publishing = new HashSet<String>(4);
	protected static Set<String> starting = new HashSet<String>(4);
	protected boolean animationActive = false;
	protected boolean stopAnimation = false;

	/**
	 * ServersView constructor comment.
	 */
	public ServersView2() {
		super();
	}

	@Override
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);

		IContextService contextSupport = (IContextService)getSite().getService(IContextService.class);
		contextSupport.activateContext(SERVERS_VIEW_CONTEXT);

		deferInitialization();
	}

	private void deferInitialization() {
		// TODO Angel Says: Need to do a final check on this line below. I don't think there is anything else
		// that we need from to port from the old Servers View
		//initializeActions(getCommonViewer());
		
		Job job = new Job(Messages.jobInitializingServersView) {
			public IStatus run(IProgressMonitor monitor) {
				IServer[] servers = ServerCore.getServers();
				int size = servers.length;
				for (int i = 0; i < size; i++) {
					((Server)servers[i]).getAllModules().iterator();
				}
				deferredInitialize();
				return Status.OK_STATUS;
			}
		};
		
		job.setSystem(true);
		job.setPriority(Job.SHORT);
		job.schedule();
	}
	
	protected void deferredInitialize() {
		addListener();
		
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				try {
					tableViewer = getCommonViewer();
					getSite().setSelectionProvider(tableViewer);
					
					// init the tooltip
					ServerToolTip toolTip = new ServerToolTip(tableViewer.getTree());
					toolTip.setShift(new Point(10, 3));
					toolTip.setPopupDelay(400); // in ms
					toolTip.setHideOnMouseDown(true);
					toolTip.activate();
					
				} catch (Exception e) {
					// ignore - view has already been closed
				}
			}
		});
		
		UpdateServerJob job = new UpdateServerJob(ServerCore.getServers());
		job.addJobChangeListener(new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				Display.getDefault().asyncExec(new Runnable() {
					public void run() {
						if (tableViewer.getTree().getItemCount() > 0) {
							Object obj = tableViewer.getTree().getItem(0).getData();
							tableViewer.setSelection(new StructuredSelection(obj));
						}
					}
				});
			}
		});
		job.schedule();
	}
	
	protected void handlePublishChange(IServer server, boolean isPublishing) {
		String serverId = server.getId();
		if (isPublishing)
			publishing.add(serverId);
		else
			publishing.remove(serverId);
	
		refreshServerState(server);
	}
	
	/**
	 * @deprecated
	 * @param server
	 */
	protected void refreshServer(final IServer server){
		if (Trace.FINEST) {
			Trace.trace(Trace.STRING_FINEST, "Refreshing UI for server=" + server);
		}
		ServerDecoratorsHandler.refresh(tableViewer);
	}
	
	protected void refreshServerContent(final IServer server){
		if (Trace.FINEST) {
			Trace.trace(Trace.STRING_FINEST, "Refreshing Content for server=" + server);
		}
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				if(!tableViewer.getTree().isDisposed())
					tableViewer.refresh(server, true);
			}
		});
	}
	
	protected void refreshServerState(final IServer server){
		if (Trace.FINEST) {
			Trace.trace(Trace.STRING_FINEST, "Refreshing UI for server=" + server);
		}
		ServerDecoratorsHandler.refresh(tableViewer);
	}
	
	protected void addListener(){
		// To enable the UI updating of servers and its childrens  
		serverResourceListener = new IServerLifecycleListener() {
			public void serverAdded(IServer server) {
				addServer(server);
				server.addServerListener(serverListener);
				((Server) server).addPublishListener(publishListener);
			}
			public void serverChanged(IServer server) {
				refreshServerContent(server);
			}
			public void serverRemoved(IServer server) {
				removeServer(server);
				server.removeServerListener(serverListener);
				((Server) server).removePublishListener(publishListener);
			}
		};
		ServerCore.addServerLifecycleListener(serverResourceListener);
		
		// To enable the refresh of the State decorator
		publishListener = new PublishAdapter() {
			public void publishStarted(IServer server) {
				handlePublishChange(server, true);
			}
			
			public void publishFinished(IServer server, IStatus status) {
				handlePublishChange(server, false);
			}
		};
		
		serverListener = new IServerListener() {
			public void serverChanged(ServerEvent event) {
				if (event == null)
					return;
								
				int eventKind = event.getKind();
				IServer server = event.getServer();
				if ((eventKind & ServerEvent.SERVER_CHANGE) != 0) {
					// server change event
					if ((eventKind & ServerEvent.STATE_CHANGE) != 0) {
						int state = event.getState();
						String id = server.getId();
						if (state == IServer.STATE_STARTING || state == IServer.STATE_STOPPING) {
							boolean startThread = false;
							synchronized (starting) {
								if (!starting.contains(id)) {
									if (starting.isEmpty())
										startThread = true;
									starting.add(id);
								}
							}
							if (startThread)
								startThread();
						} else {
							boolean stopThread = false;
							synchronized (starting) {
								if (starting.contains(id)) {
									starting.remove(id);
									if (starting.isEmpty())
										stopThread = true;
								}
							}
							if (stopThread)
								stopThread();
						}
						refreshServerState(server);
						refreshServerContent(server);
					}
					else if ((eventKind & ServerEvent.PUBLISH_STATE_CHANGE) != 0 || (eventKind & ServerEvent.STATUS_CHANGE) != 0) {
						refreshServerState(server);
					}
				} else if ((eventKind & ServerEvent.MODULE_CHANGE) != 0) {
					// module change event
					if ((eventKind & ServerEvent.STATE_CHANGE) != 0 || (eventKind & ServerEvent.PUBLISH_STATE_CHANGE) != 0 ||
							(eventKind & ServerEvent.STATUS_CHANGE) != 0) {
						refreshServerContent(server);
					}
				}
				// TODO Angel Says: I don't think we need this
				//refreshServer(server);
			}
		};
		
		// add listeners to servers
		IServer[] servers = ServerCore.getServers();
		if (servers != null) {
			int size = servers.length;
			for (int i = 0; i < size; i++) {
				servers[i].addServerListener(serverListener);
				((Server) servers[i]).addPublishListener(publishListener);
			}
		}
	}
	
	protected void addServer(final IServer server) {
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				tableViewer.add(tableViewer.getInput(), server);
			}
		});
	}

	protected void removeServer(final IServer server) {
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				tableViewer.remove(server);
			}
		});
	}
	
	@Override
	public void dispose() {
		ServerCore.removeServerLifecycleListener(serverResourceListener);

		// remove listeners from servers
		IServer[] servers = ServerCore.getServers();
		if (servers != null) {
			int size = servers.length;
			for (int i = 0; i < size; i++) {
				servers[i].removeServerListener(serverListener);
				((Server) servers[i]).removePublishListener(publishListener);
			}
		}
		super.dispose();
	}
	
	/**
	 * Start the animation thread
	 */
	protected void startThread() {
		if (animationActive)
			return;
		
		stopAnimation = false;
		
		final Display display = tableViewer == null ? Display.getDefault() : tableViewer.getControl().getDisplay();
		final int SLEEP = 200;
		final Runnable[] animator = new Runnable[1];
		animator[0] = new Runnable() {
			public void run() {
				if (!stopAnimation) {
					try {
						int size = 0;
						String[] servers;
						synchronized (starting) {
							size = starting.size();
							servers = new String[size];
							starting.toArray(servers);
							
						}
						
						for (int i = 0; i < size; i++) {
							IServer server = ServerCore.findServer(servers[i]);
							if (server != null ) {
								ServerDecorator.animate();
								tableViewer.update(server, new String[]{"ICON"});
							}
						}
					} catch (Exception e) {
						if (Trace.FINEST) {
							Trace.trace(Trace.STRING_FINEST, "Error in Servers view animation", e);
						}
					}
					display.timerExec(SLEEP, animator[0]);
				}
			}
		};
		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				display.timerExec(SLEEP, animator[0]);
			}
		});
	}

	protected void stopThread() {
		stopAnimation = true;
	}
}
