/*
 * $Id$
 *
 * Copyright 2005 (C) Guillaume Laforge. All Rights Reserved.
 *
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided that the
 * following conditions are met:
 *  1. Redistributions of source code must retain copyright statements and
 * notices. Redistributions must also contain a copy of this document.
 *  2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *  3. The name "groovy" must not be used to endorse or promote products
 * derived from this Software without prior written permission of The Codehaus.
 * For written permission, please contact info@codehaus.org.
 *  4. Products derived from this Software may not be called "groovy" nor may
 * "groovy" appear in their names without prior written permission of The
 * Codehaus. "groovy" is a registered trademark of The Codehaus.
 *  5. Due credit should be given to The Codehaus - http://groovy.codehaus.org/
 *
 * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 */
package org.codehaus.groovy.scriptom;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.DispatchEvents;
import groovy.lang.Closure;
import groovy.lang.GroovyObjectSupport;
import groovy.lang.GroovyShell;
import groovy.lang.Binding;

import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.Date;

import org.codehaus.groovy.control.CompilationFailedException;

/**
 * Provides a hooking mechanism to use an "events" property belonging to the ActiveXProxy,
 * containing closures for the event handling.
 * <p/>
 * This "events" is backed by a Map that contains keys representing the event to subscribe to,
 * and closures representing the code to execute when the event is triggered.
 * <p/>
 * Jacob allows only to pass to the <code>DispatchEvents</code> class.
 * But Scriptom pass a dynamically generated class in Groovy through GroovyShell,
 * which delegates calls to the closures stored in the Map.
 * <p/>
 *
 * <p>
 * Event support can be done by adding closures to the event object,
 * then calling listen() method will subscribe to all events:
 * <code>
 * comProxy.events.SomeEvent = { // do something }
 * comProxy.events.OtherEvent = { // do something else }
 * comProxy.events.listen()
 * </code>
 * </p>
 *
 * @author Guillaume Laforge
 */
public class EventSupport extends GroovyObjectSupport
{
    /**
     * Map containing closures for each events which has been subscribed to
     */
    private Map eventHandlers = new HashMap();

    /**
     * Underlying Jacob ActiveXComponent
     */
    private ActiveXComponent activex;

    /**
     * Source code of the class dealing with event support
     */
    private String eventClassSourceCode = "// no event support script generated";

    /**
     * In the constructor, we pass the reference to the <code>ActiveXComponent</code>.
     *
     * @param activex the component
     */
    EventSupport(ActiveXComponent activex)
    {
        this.activex = activex;
    }

    /**
     * Invokes directly a closure in the <code>eventHandlers</code> Map,
     * or call the <code>listen()</code> pseudo-method that triggers the creation of the <code>EventHandler</code>
     * and registers it with <code>DispatchEvents</code>.
     *
     * @param name name of the closure to call, or the "listen" pseudo-method.
     * @param args arguments to be passed to the closure
     * @return result returned by the closre
     */
    public Object invokeMethod(String name, Object args)
    {
        if ("listen".equals(name))
        {
            try {
                StringBuffer methods = new StringBuffer();
                for (Iterator iterator = eventHandlers.keySet().iterator(); iterator.hasNext();) {
                    String eventName = (String) iterator.next();
                    methods.append("    void ")
                    .append(eventName)
                    .append("(Variant[] variants) {\n")
                    .append("        evtHandlers['")
                    .append(eventName)
                    .append("'].call( VariantProxy.defineArray(variants) )\n    }\n");
                }

                // time token to avoid duplicate classes with the same name
                long time = new Date().getTime();
                StringBuffer classSource = new StringBuffer();
                classSource.append("import com.jacob.com.*\n")
                .append("import org.codehaus.groovy.scriptom.VariantProxy\n")
                .append("class EventHandler")
                .append(time)
                .append(" {\n")
                .append("    def evtHandlers\n")
                .append("    EventHandler")
                .append(time)
                .append("(scriptBinding) {\n")
                .append("        evtHandlers = scriptBinding\n")
                .append("    }\n")
                .append(methods.toString())
                .append("}\n")
                .append("new EventHandler")
                .append(time)
                .append("(binding)\n");

                Map eventHandlersContainer = new HashMap();
                eventHandlersContainer.put("eventHandlers", eventHandlers);
                Binding binding = new Binding(eventHandlers);
                eventClassSourceCode = classSource.toString();
                Object generatedInstance = new GroovyShell(binding).evaluate(eventClassSourceCode);

                new DispatchEvents(this.activex, generatedInstance);
            } catch (CompilationFailedException e) {
                e.printStackTrace();
            }
            return null;

        }
        else
        {
            // call the closure from the eventHandlers Map
            return ((Closure) eventHandlers.get(name)).call(args);
        }
    }

    /**
     * Sets the property only if a <code>Closure</code> for event handling is passed as value.
     * The name of the property represents the name of the events triggered by the ActiveX/COM component.
     * The closure is the code to be executed upon the event being triggered.
     *
     * @param property the name of the event
     * @param newValue the closure to execute
     */
    public void setProperty(String property, Object newValue)
    {
        if (newValue instanceof Closure)
            eventHandlers.put(property, newValue);
    }

    /**
     * <p>Retrieves the action event closure associated with a given event.</p>
     *
     * <p>
     * For debugging purpose, the generated scripted can be retrieved with:
     * <code>
     * println comProxy.events.eventSourceScript
     * </code>
     * </p>
     *
     * @param property the name of the event
     * @return the closure associated with the handling of the given event
     */
    public Object getProperty(String property)
    {
        // used to print the source of the generated class dealing with event support for debugging purpose
        if ("eventSourceScript".equals(property)) {
            return eventClassSourceCode;
        }
        return eventHandlers.get(property);
    }
}
