/**
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 *
 * Copyright (C)
 * <a href="http://www.inab.org">Spanish National Institute of Bioinformatics (INB)</a>
 * <a href="http://www.bsc.es">Barcelona Supercomputing Center (BSC)</a>
 * <a href="http://inb.bsc.es">Computational Node 6</a>
 */

package org.inb.biomoby.client.gui;

import java.lang.ref.SoftReference;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.inb.biomoby.client.gui.IDynamicComponent.MobyComponentListener;

/**
 * @author Dmitry Repchevsky
 */

public class MobyMessageQueue<T extends MobyComponentListener> implements IDynamicComponent<T>
{
    private ConcurrentLinkedQueue<SoftReference<? super T>> listeners;

    @Override
    public synchronized void addListener(MobyComponentListener listener)
    {
        for (Iterator<SoftReference<? super T>> iter = getQueue().iterator(); iter.hasNext();)
        {
            SoftReference<? super T> ref = iter.next();
            Object l = ref.get();

            if (l == null)
            {
                iter.remove();
            }
            else if (l == listener)
            {
                return;
            }
        }

        listeners.add(new SoftReference<MobyComponentListener>(listener));
    }

    @Override
    public synchronized void removeListener(MobyComponentListener listener)
    {
        for (Iterator<SoftReference<? super T>> iter = getQueue().iterator(); iter.hasNext();)
        {
            SoftReference<? super T> ref = iter.next();
            MobyComponentListener l = (MobyComponentListener) ref.get();

            if (l == null)
            {
                iter.remove();
            }
            else if (l == listener)
            {
                iter.remove();
                return;
            }
        }
    }

    public synchronized Iterator<SoftReference<? super T>> getListeners()
    {
        return getQueue().iterator();
    }

    private synchronized ConcurrentLinkedQueue<SoftReference<? super T>> getQueue()
    {
        if (listeners == null)
        {
            listeners = new ConcurrentLinkedQueue<SoftReference<? super T>>();
        }

        return listeners;
    }
}
