/**
 * Copyright @ 2000 Peter Roßbach (pr@webapp.de) and Lars Röwekamp (Lars@openKnowlege.de)
 *
 * Source is only for non commercial and coaching usage.
 *
 * Not Warranty to use it.
 */
package de.ix.jspTutorial.controller;

import java.util.Vector;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import de.ix.jspTutorial.constants.*;

import de.ix.jspTutorial.exception.MissingInputParamsException;
import de.ix.jspTutorial.controller.ModelManager;

import de.ix.jspTutorial.model.Order;
import de.ix.jspTutorial.model.Customer;
import de.ix.jspTutorial.model.PersonalPizza;
import de.ix.jspTutorial.model.PizzaAccessor;

import de.ix.jspTutorial.xml.XMLOrderBuilder;

import de.ix.jspTutorial.mail.MailHelper;

/**
  * This class processes all requests recived from
  * the applications main entry point and generates
  * all depending and necessary events
  *
  * @author Peter Rossbach (<a href="mailto://pr@webapp.de">pr@webapp.de</a>), Lars Röwekamp ( <a href="mailto://lars.roewekamp@openKnowledge.de">lars.roewekamp@openKnowledge.de</a>)
  * @version $Id:$
  */
public class RequestProcessor implements RequestParameterConstants,
                                         MailConstants {

  /**
    * version of the source
    */
  public static String vcid = "$Id:$";

  /**
   *  current session of user
   */
  private HttpSession httpSession;

  /**
   *  the application
   */
  private ServletContext myApplication;

   /**
     * main manager for all models
     */
  private ModelManager pizzaModelManager;

  /**
    *  This method initializes all private attributes of the
    *  the given <code>RequestProcessor</code> instance
    *
    *  @param servletContext  actual Servlet Context
    *  @param httpSession     actual HTTP Session
    */
  public void init(ServletContext servletContext, HttpSession httpSession) {
    this.httpSession    = httpSession;
    this.myApplication = servletContext;

    pizzaModelManager     = (ModelManager)httpSession.getValue(SessionConstants.MODEL_MANAGER);
  }




  /**
    * This method proceesses the actual http request. Doing this,
    * it checks the given parameters of the current request and
    * delegates this request to a request specific handler-method.
    *
    * @param request actual HttpServletRequest
    *
    */
  public void processRequest(HttpServletRequest request)
                       throws MissingInputParamsException  {

    String doAction ="";
    try {
      doAction = (String)request.getParameter(DO_ACTION);
    } catch(Exception ex) {
      doAction = "";
    }

    checkParameters(doAction,request);
    handleEvent(doAction,request);
  }


  /**
    * Handler-method for logout request.
    *
    * @param request Current httpRequest
    */
  public void handleLogoutEvent(HttpServletRequest request) {
    pizzaModelManager.resetCustomer();
  }


  /**
    * Handler-method for login request. Checks if the given
    * customer exists and creates a new one if necessary.
    *
    * @param request Current httpRequest
    */
  public void handleLoginEvent(HttpServletRequest request) {

    boolean isLoginValid = false ;

    PizzaAccessor accessor   = pizzaModelManager.getPizzaAccessor();
    Customer newCustomer = accessor.generateCustomer(request);
    if (newCustomer.getId() > 0) {
       log("Check Customer " + newCustomer ) ;
       isLoginValid = accessor.checkCustomer(newCustomer);
    } else {
       log("new Customer " + newCustomer ) ;
       isLoginValid = accessor.newCustomer(newCustomer) ;
    }

    log("valid Customer " + isLoginValid ) ;
    if(isLoginValid) {
      pizzaModelManager.setCustomer(newCustomer);
    } else {
      pizzaModelManager.resetCustomer();
    }
  }


  /**
    * Handler-method for choice request. Creates a <code>PersonalPizza</code>
    * with the help of the current request.
    *
    * @param request Current httpRequest
    */
  public void handleChoiseEvent(HttpServletRequest request) {
    String[] paramIngredients = request.getParameterValues(INGREDIENT_IDS);
    StringBuffer theParamI    = new StringBuffer() ;
    if(paramIngredients != null) {
       for(int i=0; i<paramIngredients.length;i++) {
          theParamI.append(paramIngredients[i]) ;
          if(i+1 <paramIngredients.length)
            theParamI.append(",") ;
      }
    }
    String paramPizza = request.getParameter(PIZZA_ID);
    log("Pizza-ID: " + paramPizza);
    log("Ingredient-IDs: " + paramIngredients);
    PersonalPizza personalPizza = new PersonalPizza(request,
                                                    paramPizza,
                                                    theParamI.toString());
    pizzaModelManager.setPersonalPizza(personalPizza);
  }



   /**
    * Handler-method for order request. Saves the current order and
    * changes also the current customer if necessary.
    *
    * Additional create XML order and send this to via eMail to
    * pizza online service.
    *
    * @param request Current httpRequest
    */
  public void handleOrderEvent(HttpServletRequest request) {
    PizzaAccessor pizzaAccessor = pizzaModelManager.getPizzaAccessor();
    PersonalPizza personalPizza = pizzaModelManager.getPersonalPizza();

    // accept address changes
    Customer newCustomer = pizzaAccessor.generateCustomer(request);
    pizzaModelManager.setCustomer(newCustomer);

    // save new order


    Order order =  pizzaAccessor.newOrder(newCustomer,personalPizza);
    log("Order-ID: " + order);
    if (order == null)
        throw new RuntimeException("Can't save Order - " + newCustomer + " ## " + personalPizza) ;

    // create order
    String sender      = newCustomer.getEmail();
    if (sender != null && getUseEMail()) {
	    // create order and write it out
	    XMLOrderBuilder xmlOrder = new XMLOrderBuilder();
	    Document xmlDocument = xmlOrder.createXMLOrder(order);
	
	    xmlOrder.writeOut((Node)xmlDocument, "");


      Vector recipients  = new Vector();
      recipients.add(getMailRecipient());

      String smtpServer  = getMailSmtpHost() ;
      String subject     = "Online Pizza Service - Order: " + order.getId();
      String messageText = xmlOrder.generateXMLString((Node)xmlDocument, "");

      Vector attchFiles  = new Vector();

      MailHelper mailHelper = new MailHelper( sender,
                                              recipients,
                                              smtpServer,
                                              subject,
                                              messageText,
                                              attchFiles, getMailDebug());

      mailHelper.sendMail();

    }

  }


  /**
    * Method to delegate the differnt request types to specialized
    * handler-method.
    *
    * @param action  Current request type
    * @param request Current httpRequest
    */
  public void handleEvent(String action, HttpServletRequest request) {
    // handle differnt events
    if (action.equals(RequestParameterConstants.DO_LOGOUT)) {
      handleLogoutEvent(request);
    } else if (action.equals(RequestParameterConstants.DO_LOGIN)) {
      handleLoginEvent(request);
    } else if (action.equals(RequestParameterConstants.SHOW_LOGIN)) {
      // no special action required ...
    } else if (action.equals(RequestParameterConstants.DO_CHOICE)) {
      handleChoiseEvent(request);
    } else if (action.equals(RequestParameterConstants.SHOW_CHOICE)) {
      // no special action required ...
    } else if (action.equals(RequestParameterConstants.DO_ORDER)) {
      handleOrderEvent(request);
    }else
      new RuntimeException("Wrong Action") ;
}


  /**
    * Method to check all given parameters depending on the current request type.
    *
    * @param action  Current request type
    * @param request Current httpRequest
    */
 public void checkParameters(String action, HttpServletRequest request) throws MissingInputParamsException {

    boolean isParamMissing = false;

    Vector missingParamVector = new Vector();
    RequestInfo requestInfo   = new RequestInfo();

    for (Enumeration e = requestInfo.getParamNames(action); e.hasMoreElements();) {

      String param = (String)e.nextElement();

      if (request.getParameter(param)==null) {
        isParamMissing = true;
        missingParamVector.addElement(param);
      }
    }

    if (isParamMissing) {
      throw new MissingInputParamsException(action,missingParamVector);
    }
  }

 /**
   *
   * Output of a message to the servlet log of the container.
   *
   * @param msg 	The message
   *
   */
  public void log(String msg)
  { myApplication.log(msg) ; }


  /**
   * Put the given message and exception the servlet log of the container.
   *
   * @param message 	Error message
   * @param throwable 	Exception
   *
   */
  public void log(String message, Throwable throwable)
  { myApplication.log(message,throwable) ; }

  
  /**
   * Is Use Email order.
   * You can it config at web.xml as ServletContext Init parameter "USE_EMAIL"
   */
  public boolean getUseEMail()
  {
    String use_EMAIL = myApplication.getInitParameter(C_CONFIG_USE_EMAIL) ;
    if(use_EMAIL == null) {
    	 return USE_EMAIL ;
    } else
      return new Boolean(use_EMAIL).booleanValue() ;
  }
  
  /**
   * Is Mail debug.
   * You can it config at web.xml as ServletContext Init parameter "MAIL_DEBUG"
   */
  public boolean getMailDebug()
  {
    String debug = myApplication.getInitParameter(C_CONFIG_MAIL_DEBUG) ;
    if(debug == null) {
    	 return MAIL_DEBUG ;
    } else
      return new Boolean(debug).booleanValue() ;
  }
  
  /**
   * get Mail Recipient
   * You can it config at web.xml as ServletContext Init parameter "MAIL_RECIPIENT"
   */
  public String getMailRecipient()
  {
    String recipient = myApplication.getInitParameter(C_CONFIG_MAIL_RECIPIENT) ;
    if(recipient == null) {
    	 recipient = MAIL_RECIPIENT ;
    }
    log("Mail recipient: " + recipient) ;
    return recipient;
  }
  /**
   * get Mail Smtp Host
   * You can it config at web.xml as ServletContext Init parameter "MAIL_SMTP_HOST"
   */
  public String getMailSmtpHost()
  {
    String host = myApplication.getInitParameter(C_CONFIG_MAIL_SMTP_HOST) ;
    if(host == null) {
    	 host = MAIL_SMTP_HOST ;
    }
    log("Mail host: " + host) ;
    return host;
  }
  ;
}

//
// History:
//
// $Log:$
//
//