package org.eclipse.jst.jsf.common.internal.locator;

import java.util.concurrent.CopyOnWriteArrayList;

import org.eclipse.jst.jsf.common.internal.locator.ILocatorChangeListener.LocatorChangeEvent;

/**
 * The abstract base class of all ILocator implementations.
 * 
 * @author cbateman
 *
 * @param <LOCATORTYPE>
 * @param <CONTEXTTYPE>
 * @param <IDTYPE>
 */
public abstract class AbstractLocator<LOCATORTYPE, CONTEXTTYPE, IDTYPE>
        implements ILocator<LOCATORTYPE, CONTEXTTYPE, IDTYPE>
{
    /**
     * The default value used for "no result".
     */
    protected static final Object   DEFAULT_NO_RESULT_VALUE = null;
    
    private final CopyOnWriteArrayList<ILocatorChangeListener> _listeners;
    private final LOCATORTYPE _noResultValue;
    private final IDTYPE _id;
    private final String _displayName;
    private boolean _isStarted;

    private Exception _startTrace;

    /**
     * Available for sub-classes that want to use reasonable defaults and only provide
     * mandatory data.
     * 
     * No result value is null.
     * A new instance of CopyOnWriteArrayList is used and held private.
     * 
     * @param id 
     * @param displayName 
     * 
     */
    public AbstractLocator(final IDTYPE id, final String displayName)
    {
        this(id,
             displayName,
             null,
             new CopyOnWriteArrayList<ILocatorChangeListener>());
    }

    /**
     * Available for sub-classes to manually inject dependencies.
     * 
     * @param id 
     * @param displayName 
     * @param noResultValue 
     * @param mutableListenerList
     */
    protected AbstractLocator(
            final IDTYPE id,
            final String displayName,
            final LOCATORTYPE noResultValue,
            final CopyOnWriteArrayList<ILocatorChangeListener> mutableListenerList)
    {
        _id = id;
        _displayName = displayName;
        _listeners = mutableListenerList;
        _noResultValue = noResultValue;
    }

    public final LOCATORTYPE perform(final CONTEXTTYPE context)
            throws Exception
    {
        return locate(context);
    }

    public LOCATORTYPE getNoResult()
    {
        return _noResultValue;
    }

    public IDTYPE getId()
    {
        return _id;
    }

    public String getDisplayName()
    {
        return _displayName;
    }

    public LOCATORTYPE locate(final CONTEXTTYPE context)
    {
        if (isStarted())
        {
            return doLocate(context);
        }
        throw new IllegalStateException("Locator not started"); //$NON-NLS-1$
    }
    

    /**
     * @param context
     * @return the located type.
     */
    protected abstract LOCATORTYPE doLocate(CONTEXTTYPE context);

    public void start(final CONTEXTTYPE initialContext)
    {
        if (isStarted())
        {
            throw new IllegalStateException("Locator was already started", _startTrace); //$NON-NLS-1$
        }

        // set the started flag
        setStarted(true);
        _startTrace = new Exception("Locator was started on this trace"); //$NON-NLS-1$
    }

    public void stop()
    {
        // set the started flag
        // clear all listeners
        _listeners.clear();
        setStarted(false);
        _startTrace = null;
    }

    /**
     * @param listener
     */
    public  void addListener(final ILocatorChangeListener listener)
    {
        _listeners.addIfAbsent(listener);
    }

    /**
     * @param listener
     */
    public void removeListener(final ILocatorChangeListener listener)
    {
        _listeners.remove(listener);
    }
    
    /**
     * @param event
     */
    protected void fireChangeEvent(final LocatorChangeEvent event)
    {
        for (final ILocatorChangeListener listener : _listeners)
        {
            listener.changed(event);
        }
    }

    public final boolean isStarted()
    {
        return _isStarted;
    }

    public boolean canStart()
    {
        if (isStarted())
        {
            return false;
        }
        return true;
    }

    /**
     * @param newValue
     */
    protected final void setStarted(final boolean newValue)
    {
        _isStarted = newValue;
    }
}
