/*
 * 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 demo.runner;

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;

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;

/**
 * <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>
   */
  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;
    }
  }
}