/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © 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 demo.runner;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ilog.views.IlvManagerView;
import ilog.views.IlvRect;
import ilog.views.diagrammer.IlvDiagrammer;
import ilog.views.diagrammer.faces.dhtml.servlet.IlvFacesDiagrammerServlet;
import ilog.views.diagrammer.faces.dhtml.servlet.IlvFacesDiagrammerServletSupport;
import ilog.views.diagrammer.servlet.IlvDiagrammerServlet;
import ilog.views.sdm.servlet.IlvSDMServletSupport;
import ilog.views.servlet.ServerActionEvent;
import ilog.views.servlet.ServerActionListener;

/**
 * <p>
 * A subclass of {@link IlvDiagrammerServlet} that loads a Diagrammer project
 * file.
 * </p>
 * 
 * <p>
 * This subclass simply sets the parameters of the servlet in its
 * <code>init</code> methods. The basic behavior of the servlet is fully
 * implemented by the base class {@link IlvDiagrammerServlet}.
 * </p>
 * 
 * <p>
 * This demo also shows how to implement interactions in thin-client mode. The
 * user can click on the objects on the client-side to select objects in the
 * diagram. This is implemented by adding a server action listener.
 * <p>
 * 
 * <p>
 * Additionally, the data required to preserve all view state (as the current
 * active node, whether the animation should loop and animation period) is
 * stored per page, which means that this demo supports multiple browser pages
 * (tabs).
 * </p>
 */
public class RunnerServlet extends IlvFacesDiagrammerServlet implements ServerActionListener {
  /**
   * Method overridden to provide custom access to the manager view, plus
   * logging.
   */
  Override
  protected IlvSDMServletSupport createServletSupport(ServletContext context) {
    return new ServletSupport(context);
  }

  /**
   * Method overridden to add an action listener to handle view clicks
   */
  Override
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    addServerActionListener(this);
  }

  // public float getMaxZoomLevel(HttpServletRequest request, IlvManagerView
  // view) {
  // return(12);
  // }

  // ----- ServerActionListener -----------------------------------------------
  /**
   * <p>
   * Implementation of the <code>ServerActionListener</code> that handles the
   * simulation start and stop.
   * </p>
   */
  Override
  public void actionPerformed(ServerActionEvent event) {
    // Return the IlvDiagrammer. Since there is no managed beans
    // controlling this property, JViews will retrieve the diagrammer
    // instance associated with the web page that originated this
    // action
    IlvDiagrammer diagrammer = getDiagrammer(event.getRequest());

    // Retrieves the DiagramRunner, which contains all needed data
    DiagramRunner runner = DiagramRunner.getRunner(diagrammer);
    if (null == runner) {
      // The IlvDiagrammer doesn't still have a DiagramRunner
      // associated to it.
      runner = new DiagramRunner.Flow(diagrammer);
    }

    // Get action name
    String name = event.getActionName();

    // Check for possible actions
    if ("start".equals(name)) {
      String[] params = event.getParameters();
      if (params.length > 0) {
        try {
          // Try to retrieve the update interval from the client,
          // in case the user has updated it
          int updateInterval = Integer.parseInt(params[0]);
          runner.setPeriod(updateInterval);
        } catch (NumberFormatException nfe) {
        }
      }
      runner.start();
    } else if ("stop".equals(name)) {
      runner.stop();
    } else if ("setLooping".equals(name)) {
      String[] params = event.getParameters();
      if (params.length > 0) {
        try {
          // Try to retrieve the looping flag from the client
          boolean looping = Boolean.valueOf(params[0]).booleanValue();
          runner.setLooping(looping);
        } catch (Exception ec) {
        }
      }
    } else if ("setUpdateInterval".equals(name)) {
      String[] params = event.getParameters();
      if (params.length > 0) {
        try {
          // Try to retrieve the update interval from the client
          int updateInterval = Integer.parseInt(params[0]);
          runner.setPeriod(updateInterval);
          runner.restart();
        } catch (NumberFormatException nfe) {
          nfe.printStackTrace();
        }
      }
    }
  }

  /**
   * Custom servlet support, implements a different method to retrieve the
   * manager bounding box.
   */
  class ServletSupport extends IlvFacesDiagrammerServletSupport {
    /**
     * Constructor.
     * 
     * @param context
     *          The servlet context.
     */
    public ServletSupport(ServletContext context) {
      super(context);
    }

    /**
     * Method overridden to retrieve the bounding box from the
     * {@link DiagramRunner#getManagerBBox(HttpServletRequest, IlvManagerView)}.
     */
    Override
    protected IlvRect getManagerBBox(HttpServletRequest request, IlvManagerView view) throws ServletException {
      IlvDiagrammer diagrammer = getDiagrammer(getSDMView(request));
      DiagramRunner runner = DiagramRunner.getRunner(diagrammer);
      IlvRect rect = null == runner ? null : runner.getManagerBBox(request, view);
      if (null == rect) {
        rect = super.getManagerBBox(request, view);
      }
      return rect;
    }

    /**
     * Method overridden for error handling.
     */
    Override
    public boolean handleRequest(HttpServletRequest req, HttpServletResponse resp) {
      try {
        return super.handleRequest(req, resp);
      } catch (IOException e) {
        Logger.getLogger("demo").log(Level.SEVERE, e.getMessage(), e);
      } catch (Throwable e) {
        Logger.getLogger("demo").log(Level.SEVERE, e.getMessage(), e);
      }
      return true;
    }
  }
}