/**
 * Copyright 2003-2007 Jive Software.
 *
 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jivesoftware.smackx.workgroup.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.ListIterator;

/**
 * This class is a very flexible event dispatcher which implements Runnable so that it can
 * dispatch easily from a newly created thread. The usage of this in code is more or less:
 * create a new instance of this class, use addListenerTriplet to add as many listeners
 * as desired to be messaged, create a new Thread using the instance of this class created
 * as the argument to the constructor, start the new Thread instance.<p>
 *
 * Also, this is intended to be used to message methods that either return void, or have
 * a return which the developer using this class is uninterested in receiving.
 *
 * @author loki der quaeler
 */
public class ListenerEventDispatcher
    implements Runnable {

    protected transient ArrayList<TripletContainer> triplets;

    protected transient boolean hasFinishedDispatching;
    protected transient boolean isRunning;

    public ListenerEventDispatcher () {
        super();

        this.triplets = new ArrayList<TripletContainer>();

        this.hasFinishedDispatching = false;
        this.isRunning = false;
    }

    /**
     * Add a listener triplet - the instance of the listener to be messaged, the Method on which
     *  the listener should be messaged, and the Object array of arguments to be supplied to the
     *  Method. No attempts are made to determine whether this triplet was already added.<br>
     *
     * Messages are dispatched in the order in which they're added via this method; so if triplet
     *  X is added after triplet Z, then triplet Z will undergo messaging prior to triplet X.<br>
     *
     * This method should not be called once the owning Thread instance has been started; if it
     *  is called, the triplet will not be added to the messaging queue.<br>
     *
     * @param listenerInstance the instance of the listener to receive the associated notification
     * @param listenerMethod the Method instance representing the method through which notification
     *                          will occur
     * @param methodArguments the arguments supplied to the notification method
     */
    public void addListenerTriplet(Object listenerInstance, Method listenerMethod,
            Object[] methodArguments)
    {
        if (!this.isRunning) {
            this.triplets.add(new TripletContainer(listenerInstance, listenerMethod,
                    methodArguments));
        }
    }

    /**
     * @return whether this instance has finished dispatching its messages
     */
    public boolean hasFinished() {
        return this.hasFinishedDispatching;
    }

    public void run() {
        ListIterator<TripletContainer> li = null;

        this.isRunning = true;

        li = this.triplets.listIterator();
        while (li.hasNext()) {
            TripletContainer tc = li.next();

            try {
                tc.getListenerMethod().invoke(tc.getListenerInstance(), tc.getMethodArguments());
            } catch (Exception e) {
                System.err.println("Exception dispatching an event: " + e);

                e.printStackTrace();
            }
        }

        this.hasFinishedDispatching = true;
    }


    protected class TripletContainer {

        protected Object listenerInstance;
        protected Method listenerMethod;
        protected Object[] methodArguments;

        protected TripletContainer (Object inst, Method meth, Object[] args) {
            super();

            this.listenerInstance = inst;
            this.listenerMethod = meth;
            this.methodArguments = args;
        }

        protected Object getListenerInstance() {
            return this.listenerInstance;
        }

        protected Method getListenerMethod() {
            return this.listenerMethod;
        }

        protected Object[] getMethodArguments() {
            return this.methodArguments;
        }
    }
}