/*
 * Copyright (c) 2000-2009 TeamDev Ltd. All rights reserved.
 * TeamDev PROPRIETARY and CONFIDENTIAL.
 * Use is subject to license terms.
 */
package com.jniwrapper.win32.hook;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Implementation of CBT hook.
 */
final public class CBTHook extends Hook
{
    private final List listeners = new LinkedList();

    CBTHook()
    {
        super(Hook.Descriptor.CBT);
        setSynchronous(true);
        addListener(new HookEventListener()
        {
            public void onHookEvent(HookEventObject event)
            {
                CBTEvent cbtEvent = (CBTEvent) event;
                try
                {
                    notifyListeners(cbtEvent);
                }
                catch (Exception e)
                {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    private void notifyListeners(CBTEvent cbtEvent)
    {
        List listenersCopy = new LinkedList(listeners);
        for (Iterator i = listenersCopy.iterator(); i.hasNext();)
        {
            CBTHookListener listener = (CBTHookListener) i.next();
            cbtEvent.dispatch(listener);
        }
    }

    /**
     * Adds {@link com.jniwrapper.win32.hook.CBTHookListener} to this hook.
     *
     * @param listener CBT hook listener
     */
    public void addListener(CBTHookListener listener)
    {
        listeners.add(listener);
    }

    /**
     * Removes {@link com.jniwrapper.win32.hook.CBTHookListener} from this hook.
     *
     * @param listener CBT hook listener
     */
    public void removeListener(CBTHookListener listener)
    {
        listeners.remove(listener);
    }

    public void setSynchronous(boolean synchronous)
    {
        if (!synchronous) {
            throw new IllegalArgumentException(this.getDescriptor().getName()  + " is not designed to work in asynchronous mode");
        }
        super.setSynchronous(synchronous);
    }
}