/*=============================================================================#
 # Copyright (c) 2010, 2019 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.r.ui.dataeditor;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.ts.core.Tool;

import org.eclipse.statet.nico.core.util.ToolTerminateListener;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.rj.services.FQRObjectRef;
import org.eclipse.statet.rj.ts.core.RTool;


public class RToolDataTableInput implements IRDataTableInput {
	
	
	private final RElementName elementName;
	
	private final String fullName;
	private final String shortName;
	
	private final FQRObjectRef elementRef;
	
	private final RTool tool;
	private ToolTerminateListener processListener;
	
	private final CopyOnWriteIdentityListSet<IRDataTableInput.StateListener> listeners= new CopyOnWriteIdentityListSet<>();
	
	
	public RToolDataTableInput(RElementName elementName, final FQRObjectRef elementRef) {
		if (elementName == null) {
			throw new NullPointerException("name"); //$NON-NLS-1$
		}
		if (elementRef == null) {
			throw new NullPointerException("elementRef"); //$NON-NLS-1$
		}
		if (!(elementRef.getRHandle() instanceof RTool)) {
			throw new IllegalArgumentException("Unsupported elementRef.rHandle"); //$NON-NLS-1$
		}
		
		this.elementName= elementName;
		this.elementRef= elementRef;
		this.fullName= RElementName.createDisplayName(elementName, RElementName.DISPLAY_FQN | RElementName.DISPLAY_EXACT);
		
		RElementName name= elementName;
		while (elementName.getNextSegment() != null) {
			if (elementName.getType() == RElementName.MAIN_DEFAULT) {
				name= elementName;
			}
			
			elementName= elementName.getNextSegment();
		}
		this.shortName= name.getDisplayName();
		
		this.tool= (RTool) elementRef.getRHandle();
	}
	
	
	@Override
	public RElementName getElementName() {
		return this.elementName;
	}
	
	@Override
	public String getFullName() {
		return this.fullName;
	}
	
	@Override
	public String getName() {
		return this.shortName;
	}
	
	@Override
	public FQRObjectRef getElementRef() {
		return this.elementRef;
	}
	
	@Override
	public Tool getTool() {
		return this.tool;
	}
	
	@Override
	public boolean isAvailable() {
		return !this.tool.isTerminated();
	}
	
	@Override
	public void addStateListener(final StateListener listener) {
		synchronized (this.listeners) {
			if (this.listeners.add(listener)
					&& this.processListener == null) {
				this.processListener= new ToolTerminateListener(this.tool) {
					@Override
					public void toolTerminated() {
						final ImList<StateListener> listeners;
						synchronized (RToolDataTableInput.this.listeners) {
							dispose();
							RToolDataTableInput.this.processListener= null;
							
							listeners= RToolDataTableInput.this.listeners.toList();
						}
						for (final IRDataTableInput.StateListener listener : listeners) {
							listener.tableUnavailable();
						}
					}
				};
				this.processListener.install();
			}
		}
	}
	
	@Override
	public void removeStateListener(final StateListener listener) {
		synchronized (this.listeners) {
			if (this.listeners.remove(listener)
					&& this.listeners.isEmpty() && this.processListener != null) {
				this.processListener.dispose();
				this.processListener= null;
			}
		}
	}
	
	
	@Override
	public int hashCode() {
		return this.shortName.hashCode();
	}
	
	@Override
	public boolean equals(final Object obj) {
		if (!(obj instanceof RToolDataTableInput)) {
			return false;
		}
		final RToolDataTableInput other= (RToolDataTableInput) obj;
		return (this == other || (
				this.tool.equals(other.tool)
				&& this.fullName.equals(other.fullName) ));
	}
	
	@Override
	public String toString() {
		return getClass().getName() + "(" + this.fullName //$NON-NLS-1$
				+ " in " + this.tool.getLabel(Tool.LONG_LABEL) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
	}
	
}
