// ---------------------------------------------------------------
//
// -----------------------------------------------------
// copyright 2000 by voxeo corporation. (see LGPL.txt)
//
// US Postal Codes database, Copyright (c) 2000 CD Light
//                           All Rights Reserved.
// -----------------------------------------------------
//
// v1.0 Coded in Java
// v1.0 Coded by Omi Chandiramani
//
// This application is prompts users over the phone for a 5 digit
// zipcode, then accesses a database containing the US Postal Code
// information for the year 2000 to find cities (and states) that
// match the zipcode.  It will read the results to the caller,
// then ask for another zipcode.  The same application has been
// written in ASP, JSP, PERL, Cold Fusion and PHP (q.v.) as sample code on
// how to use CallXML and backend scripting languages.  
//
// This file is associated with the following files:				 
//     US Postal Codes.mdb   <---- The actual database file itself
//
// Several audio files are associated with this application:
//           MainMenu.wav
//           Results.wav
//           MultipleResults.wav
//           NotFound.wav
//           YouHaveTakenTooLong.wav
//
// All audio files are PCM format, 8-bit, mono, unsigned.
//
//----------------------------------------------------------------
  
//-----------------------------------------------------------------------------------------
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 

import java.io.IOException;
import java.io.PrintWriter;

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;


import java.util.Vector;


public class ZipcodeApp extends HttpServlet {

  private PrintWriter out;

  /**
   * Change baseURL to point to your web server!
   */
  private static String baseURL = "http://MyServer.com/MyDirectory";
  private static String servletURL = baseURL + "/ZipcodeApp";
  
  public void init() 
    throws ServletException {
    super.init();
    
    // Initialise the JDBC driver
    try {
      Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");
    } catch (Exception e) {
      e.printStackTrace();
    }
    
    
  }  


  public void doGet (HttpServletRequest request,
                     HttpServletResponse response)
    throws ServletException, IOException
  {

  
    /* set content type */
    response.setContentType("text/html");	
    /* prepare the response output stream for writing  */
    out = response.getWriter();

    out.println ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    out.println ("<callxml>");
    
 
    //------------------------------------------------------------------------
    // This annoying little variable is simply incremented and passed along to
    // avoid the AGS//s caching.  This helps to ensure that a different URL
    // query string will be passed.
    //------------------------------------------------------------------------
    
    if (request.getParameter("cachekiller") == null) {
      out.println ("<assign var=\"cachekiller\" value=\"1\"/>");
    }  
    else {
      out.println ("<assign var=\"cachekiller\" value=\"" + (request.getParameter("cachekiller") + 1) + "\"/>");
    }  

    //---------------------------------------------------
    // The Querystring variable zipcode determine whether 
    // we need to go to the main menu, or if a caller has
    // just entered in a ZipCode.
    //---------------------------------------------------
    
    String zipcode = request.getParameter ("zipcode");
    
    if (zipcode == null) { 
      // just starting the application, send the main menu..
      mainMenu ();
    } else {
      printCitiesXML (findCities (request));
    }
    
    out.println ("</callxml>");

  }


  private void mainMenu() {
      out.println ("<inputdigits label=\"input_selection\" " +
                   "repeat=\"3\" " +
                   "var=\"ZipCode\" " +
                   "format=\"audio/wav\" " + 
                   "value=\"" + baseURL + "/MainMenu.wav\" " + 
                   "cleardigits=\"TRUE\" " +
                   "includetermdigit=\"FALSE\" " +
                   "maxdigits=\"5\" " +
                   "maxtime=\"15s\" " +
                   "maxsilence=\"5s\" >");
      
      out.println ("<onmaxdigits>");
      out.println ("<goto value=\"" + servletURL + "\" submit=\"*\" method=\"get\" />");
      out.println ("</onmaxdigits>");
      
      out.println ("<onmaxtime>");
      out.println ("<playaudio format=\"audio/wav\" value=\"" + baseURL + "/YouHaveTakenTooLong.wav\" />"); 
      out.println ("<hangup/>");
      out.println ("</onmaxtime>");
      
      out.println ("<onmaxsilence>");
      out.println ("<playaudio format=\"audio/wav\" value=\"" + baseURL + "/YouHaveTakenTooLong.wav\" />"); 
      out.println ("<hangup/>");
      out.println ("</onmaxsilence>");
      
      out.println ("</inputdigits>");
      
      //-----------------------------------
      // One last message in case the block 
      // loops through before maxsilence or
      // maxtime has been reached.
      //-----------------------------------
      
      out.println ("<playaudio format=\"audio/wav\" value=\"" + baseURL + "/YouHaveTakenTooLong.wav\" />");      
  }
  

  private String[] findCities (HttpServletRequest request) {
  
    Connection lConnection = null;
    Statement lStatement = null;
    ResultSet lResultSet = null;

    String [] Cities = null;
    Vector tmpCities = new Vector();
    
    
    try {
      
      
      //-----------------------------------------------------------------------------
      // Initialize our databasing routines and select out all matches to the zipcode
      //-----------------------------------------------------------------------------
      
      lConnection = DriverManager.getConnection("jdbc:odbc:USPostalCodes");
      
      String TempSQL = "SELECT * FROM PostalCodes where Zipcode = '" + request.getParameter("zipcode") + "'";
      lStatement = lConnection.createStatement();
      lResultSet = lStatement.executeQuery(TempSQL);
      
      while ( lResultSet.next() ) {
          
        String City  = lResultSet.getString("City");
        String State = lResultSet.getString("State");  
        
        //-----------------------------------------------------
        // We have to check for certain states because the
	    // callxml TTS engine will not pronounce them correctly
        //-----------------------------------------------------
	  
   	    if (State == "AL") { State = "Alabama";       }
	    if (State == "CT") { State = "Connecticut";   }
	    if (State == "CO") { State = "Colorado";      }
	    if (State == "DE") { State = "Delaware";      }
	    if (State == "HI") { State = "Hawaii";        }
	    if (State == "ID") { State = "Idaho";         }
	    if (State == "IN") { State = "Indiana";       }
	    if (State == "LA") { State = "Louisiana";     }
	    if (State == "MA") { State = "Massachusetts"; }
	    if (State == "MD") { State = "Maryland";      }
	    if (State == "ME") { State = "Maine";         }
	    if (State == "MI") { State = "Michigan";      }
	    if (State == "MO") { State = "Missouri";      }
	    if (State == "MS") { State = "Mississippi";   }
	    if (State == "MT") { State = "Montana";       }
	    if (State == "NE") { State = "Nebraska";      }
	    if (State == "OH") { State = "Ohio";          }
	    if (State == "OK") { State = "Oklahoma";      }
	    if (State == "OR") { State = "Oregon";        }
	    if (State == "PA") { State = "Pennsylvania";  }
	    if (State == "WA") { State = "Washington";    }
	    if (State == "WY") { State = "Wyoming";       }
        
        tmpCities.addElement (City + ", " + State);
        
      }
      
    } catch (SQLException sqle) { sqle.printStackTrace(); 
    } catch (Exception e) { e.printStackTrace(); 
    } finally {
      try {
        lResultSet.close(); lResultSet = null;
        lStatement.close(); lStatement = null;
        lConnection.close(); lConnection = null;
      } catch (Exception e) { e.printStackTrace(); }
    }

    Cities = new String [ tmpCities.size() ];
    tmpCities.copyInto (Cities);
      
    return Cities;
    
  }
  

  private void printCitiesXML (String [] Cities) {

      out.println ("<block>");  
  
      String CallXMLText = "";

      for (int i = 0; i < Cities.length; i++) {
          CallXMLText = CallXMLText + "<text>" + Cities[i] + "</text>\n";
      }

      //-------------------------------------------
      // We need to play the appropriate prompt for 
      // no matches, 1 match, or multiple matches.
      //-------------------------------------------  

      switch (Cities.length) {
      case 0:
        out.println ("<playaudio format=\"audio/wav\" value=\"" + baseURL + "/NotFound.wav\" />");
        break;
      case 1:
        out.println ("<playaudio format=\"audio/wav\" value=\"" + baseURL + "/Results.wav\" />");
        break;
      default:
        out.println ("<playaudio format=\"audio/wav\" value=\"" + baseURL + "/MultipleResults.wav\" />");
      } 
      
      out.println (CallXMLText);
      
      //------------------------------------------------------
      // We want to pause for 2 seconds, clear out the zipcode 
      // variable, and then return to the main menu.
      //------------------------------------------------------  
      
      out.println ("<wait value=\"2s\"/>");
      out.println ("<clear var=\"ZipCode\"/>");
      out.println ("<goto value=\"" + servletURL + "\" submit=\"*\" method=\"get\" />");
      out.println ("</block>");

  }
  
}
