<% 
' Copyright 2000 Phone.com, Inc.  All rights reserved.
'
'   Subject to the terms and conditions of the SDK License Agreement,
'   Phone.com, Inc. hereby grants you the right to use the UP.SDK
'   software and its related documentation.
'
'   The Phone.com name and logo and the family of terms carrying the "UP."
'   prefix are trademarks of Phone.com, Inc. All other brands and product
'   names may be trademarks of the respective companies with which they
'   are associated.
'
' addCookie.asp
'
'   An example modeled upon the Perl cookie.cgi demonstration application.
'
'     The application requests information from the user, stores the user's
'     name and zip code in cookies, and then displays the information.
'   
'   Key concepts illustrated include:
'
'       Passing in and receiving Cookies using ASP built-in objects
'  
'   Application Flow:
'  
'   A user's navigation through the application is represented as state
'   machine transitions.  Each URL encodes the state to transition to in
'   the "NEXT" (Next State) argument.  The main routine of the application
'   examines the NEXT argument and either returns the appropriate static
'   WML deck, or invokes the appropriate routine to compute the dynamic
'   WML deck.
'  
'   The NEXT state could be one of the following:
'
'       HOME or blank - 
'           To start the application and jump to NEWINFO or SHOWINFO
'       NEWINFO  - 
'           To retrieve the user's name and zip code
'       SHOWINFO - 
'           To display the user's name and zip code
'
'   In contrast with the Perl example,
'
'       State-transition uses a Scripting Dictionary Object, 
'       rather than Perl associative-arrays. 
'
'       Cookies returned to the server in a request are extracted 
'       into a Scripting Dictionary by parsing the Query String.
'
'       Extracted cookies are returned to the client using the
'       ASP built-in Response object Cookies collection.
'
' Declarations
'
' Script-level scoped variables
Dim cookieDict, queryDict, stateDict
Dim nextState, cookieString
Dim home, show, eDeck, aDeck
Dim name, zip
Dim nameCookie, zipCookie
Dim nl

' Constants
'
' A newline (linefeed) is appended to each line of WML to
' aid legibility of source dumped to the Sim Info Window.
' 
nl      = Chr(10)

' Subroutines
'
Sub CreateQueryDictionary
    Dim qCount, queryArray, queryString, aQuery, qArray, qName, qValue

    Set queryDict   = CreateObject("Scripting.Dictionary")
    queryString     = Request.QueryString
    queryArray      = Split(queryString, "&")

    For qCount  = 0 to UBound(queryArray)
        aQuery  = queryArray(qCount)
        qArray  = Split(aQuery, "=")
        qName   = qArray(0)
        qValue  = qArray(1)
        queryDict.Add qName, qValue
    Next
End Sub

Sub GetNextStateFromQueryDictionary
    If queryDict.Exists("NEXT") then
        nextState   = queryDict.Item("NEXT")
    End If
End Sub

Sub UpdateCookies
    Set cookieDict  = CreateObject("Scripting.Dictionary")
    nameCookie      = Request.Cookies("name")
    zipCookie       = Request.Cookies("zip")

    If Len(nameCookie) > 0 Then
        aKey    = "name"
        aValue  = nameCookie
        If cookieDict.Exists(aKey) Then
             oldValue    = cookieDict.Item(aKey)
             If oldValue <> aValue then
                 cookieDict.Remove(aKey)
                 cookieDict.Add aKey, aValue
             End If
         Else
           cookieDict.Add aKey, aValue
         End If
    End If
    If Len(zipCookie) > 0 Then
        aKey    = "zip"
        aValue  = zipCookie
        If cookieDict.Exists(aKey) Then
             oldValue    = cookieDict.Item(aKey)
             If oldValue <> aValue then
                 cookieDict.Remove(aKey)
                 cookieDict.Add aKey, aValue
             End If
         Else
           cookieDict.Add aKey, aValue
         End If
    End If
End Sub

Sub CreateStateDictionary
    set stateDict   = CreateObject("Scripting.Dictionary")
    stateDict.Add   "HOME",     "SplashScreen"  
    stateDict.Add   "SHOWINFO", "ShowInfo"
    stateDict.Add   "NEWINFO",  "NewInfo"
End Sub

Sub GetDeck
    If stateDict.Exists(nextState) Then
        anItem = stateDict.Item(nextState)
        Select Case stateDict.Item(nextState)
            Case "SplashScreen"
                Call SplashScreen
            Case "ShowInfo"
                Call ShowInfo
            Case "NewInfo"
                Call NewInfo
            Case Else
                Call ErrorDeck(nextState)
        End Select
    Else
        Call ErrorDeck(nextState)
    End If
End Sub

Sub SplashScreen
    If cookieDict.Exists("name") And cookieDict.Exists("zip") Then
        Call ShowInfo
    Else 
        Call NewInfo
    End If
End Sub

Sub CreateHomeDeck
    If cookieDict.Exists("name") Then
        name = nameCookie
    End If
    If cookieDict.Exists("zip") Then
        zip  = zipCookie
    End If
    home =        "<wml>" & nl
    home = home & "  <head>" & nl
    home = home & "    <meta http-equiv=""Cache-Control"" "
    home = home &        "content=""max-age=0""/>" & nl
    home = home & "  </head>" & nl
    home = home & "  <card title=""home"">" & nl
    home = home & "    <do type=""accept"" label=""Set"">" & nl
    home = home & "      <go method=""post"" "
    home = home &          "href=""?NEXT=SHOWINFO"">" & nl
    home = home & "        <postfield name=""name"" value=""$(name)""/>" & nl
    home = home & "        <postfield name=""zip""  value=""$(zip)""/>" & nl
    home = home & "      </go>" & nl
    home = home & "    </do>" & nl
    home = home & "    <p>"  & nl
    home = home & "      First name: " & nl
    home = home & "      <input name=""name"" format=""A*a"" "
    home = home &          "maxlength=""20""/>" & nl
    home = home & "      Zip code: " & nl
    home = home & "      <input name=""zip"" format=""NNNNN""/>" & nl
    home = home & "    </p>" & nl
    home = home & "  </card>" & nl
    home = home & "</wml>" & nl
End Sub

Sub NewInfo
    Call WriteDigest(home)
End Sub

Sub ShowInfo
    If "POST"       = Request.ServerVariables("REQUEST_METHOD") then
        name        = Request.Form("name")
        zip         = Request.Form("zip")
    End If

    Response.Cookies("name")        = name
    Response.Cookies("name").Path   = "/"
    Response.Cookies("zip")         = zip
    Response.Cookies("zip").Path    = "/"

    show =        "<wml>" & nl
    show = show & "  <head>" & nl
    show = show & "    <meta http-equiv=""Cache-Control"" "
    show = show &        "content=""max-age=0""/>" & nl
    show = show & "  </head>" & nl
    show = show & "  <card title=""ShowInfo"">" & nl
    show = show & "    <do type=""accept"" label=""Home"">" & nl
    show = show & "      <go href=""device:home""/>" & nl
    show = show & "    </do>" & nl
    show = show & "    <do type=""options"" label=""New"">" & nl
    show = show & "      <go href=""?NEXT=NEWINFO""/>" & nl
    show = show & "    </do>" & nl
    show = show & "    <p>" & nl
    show = show & "      Name: " & name & "<br/>" & nl
    show = show & "      Zip: " & zip & " " & nl
    show = show & "    </p>" & nl
    show = show & "  </card>" & nl
    show = show & "</wml>" & nl
    
    Call WriteDigest(show)
End Sub

Sub ErrorDeck(nextState)
    If nextState = Empty Then
        nextState   = queryDict.Item("NEXT")
    End If
    eDeck =         "<wml>" & nl
    eDeck = eDeck & "  <card>" & nl
    eDeck = eDeck & "    <p>" & nl
    eDeck = eDeck & "      Next state: " & nextState & nl
    eDeck = eDeck &        " was not expected." & nl
    eDeck = eDeck & "    </p>" & nl
    eDeck = eDeck & "  </card>" & nl
    eDeck = eDeck & "</wml>" & nl
    Call WriteDigest(eDeck)
End Sub

Sub WriteDigest(aDeck)
    ' Create a new COM Digest object.
    '
    set myDigest            = Server.CreateObject("PDCDigestUtils.CPDCDigest")

    ' Add the deck to the digest object.
    '
    myDigest.DigestAddDeck  "", aDeck

    ' Suppress content type output within the digest to prevent a 
    ' server from encapsulating WML content within a second boundary.
    '
    myDigest.DigestSuppressContentType 1
    
    ' Serialize the digest into a single output buffer, digestString.
    '
    digestString    = myDigest.DigestSerialize(0)
    
    ' Specify a deck of type WML to the digest object.
    '
    myDigest.DeckType         = 1

    ' Specify content type through the server response,
    ' rather than within the digest.
    '
    Response.ContentType    = myDigest.DigestGetContentType

    ' Write the response buffer to the client.
    '
    Response.BinaryWrite(digestString)
End Sub

' Main routine
'
Sub Main
    nextState   = "HOME"
    Call    CreateQueryDictionary
    Call    UpdateCookies
    Call    CreateHomeDeck
    Call    CreateStateDictionary
    Call    GetNextStateFromQueryDictionary
    Call    GetDeck
End Sub

' Main routine starts here
' 
Call Main
%>
