/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2015 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package action;

import ilog.views.faces.dhtml.IlvDHTMLConstants;
import ilog.views.faces.dhtml.event.FacesMethodBindingActionListener;
import ilog.views.util.servlet.IlvPopupMenuServletSupport;
import ilog.views.util.servlet.event.JavaScriptActionListener;

import java.util.EventObject;

/**
 * This extension of the JavaScriptActionListener, provides the advanced 
 * ability to execute actions in both server and client environment at once.
 *  
 * It allows one to specify an Expression Language code segment to a method
 * binding that will be invoked in the server side and a JavaScript code 
 * segment that will be executed in the client side.
 * 
 * This ActionListener enforces that the client side code segment is 
 * executed after the server side code segment has completed its execution. 
 */
public class ServerClientActionListener extends JavaScriptActionListener {
  
  private FacesMethodBindingActionListener support;

  /**
   * Creates a new ServerClientActionListener instance.
   * @param serverActionCode The method binding expression.
   * @param clientActionCode The javascript code to execute once the server
   *                         action is executed.
   * @param updateAll        Defines how to refresh the view after the client
   *                         action is executed: <code>true</code> indicates
   *                         that the image and capabilities will be refreshed,
   *                         and <code>false</code> indicates that only the
   *                         image will be refreshed.
   */
  public ServerClientActionListener(String serverActionCode, 
                                    String clientActionCode, boolean updateAll) {
    support = new FacesMethodBindingActionListener(serverActionCode);
    support.setInvocationContext(IlvDHTMLConstants.IMAGE_SERVLET_CONTEXT);
    support.setUpdateAll(updateAll);
    buildAction(clientActionCode);   
  }   
  
  /**
   * Performs the action requested.
   * @param event The server action event.
   */
  Override
  public void actionPerformed(EventObject event) {
    try {
      support.actionPerformed(event);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
    
  /**
   * Returns the invocation context of this action which 
   * is IlvDHTMLConstants#IMAGE_SERVLET_CONTEXT. 
   * @return The invocation context.
   */
  public int getInvocationContext() {
    return IlvDHTMLConstants.IMAGE_SERVLET_CONTEXT;
  }
  
  /**
   * Returns whether refresh the image and capabilities or the image 
   * only after the action.
   * @return Whether refresh the image and capabilities or the image only.
   */
  public boolean isUpdateAll() {
    return support.isUpdateAll();
  }
    
  /**
   * Builds the JavaScript code that will be executed internally.
   */
  private void buildAction(String clientSidecode) {
    String s = "var l=function(v){v.removeImageOnLoadListener(l);"+clientSidecode+";};";
    s += "viewObj.addImageOnLoadListener(l);";
    s += "itemObj.performServerAction('"+IlvPopupMenuServletSupport.SERVLET_ACTION_NAME 
      + "',new Array(),"+isUpdateAll()+");";
    setJsAction(s);
  }
}