if (! top.glbDict.dynContentInitialized ) {
  top.glbDict.postMechanism = 'httpreq'
  top.glbDict.dynContentInitialized = 1
  top.glbDict.postIsBusy = false
  top.glbDict.postArray = new Array()

  function queueServerEvent( obj , evstr , method , extra ) {
    // Check the queued events.  If the same event is already in the queue for
    // this object, DON'T post the old event.  Override it with the given one
    for (var c = 0; c < top.glbDict.postArray.length; c++) {
      var msg = top.glbDict.postArray[c]
      if (msg) {
        var tobj = msg[0]
        var tevt = msg[1]
        if ( (tobj == obj) && (tevt == evstr) ) {
          delete top.glbDict.postArray[c]
        }
      }
    }
    top.glbDict.postArray.push( [ obj , evstr , method , extra ] )
  }
  top.glbDict.queueServerEvent = queueServerEvent

  function sendQueuedEvents() {
    // Return if queue is empty
    if (top.glbDict.postArray.length == 0) return

    // Return if post is already busy
    if (top.glbDict.postIsBusy) {
      return
    }

    // Notify the rest of the framework that we are in the middle of a post
    top.glbDict.postIsBusy = true

    top.glbDict.showAjax()

    // Get the form and input that form the mechanism we use to post events
    // to the server
    //var post_mechanism = getPostMechanism()

    // If the post frame failed, give up this go around
    //if (! post_mechanism) {
    //  top.glbDict.postIsBusy = false
    //  return
    //}

    //var frm = post_mechanism[0]
    //var inp = post_mechanism[1]

    var postTuple = null
    var out = '['
    var c = 0
    while (top.glbDict.postArray.length > 0) {
      // Skip events that have been deleted (already overridden by subsequent events)
      postTuple = top.glbDict.postArray.shift()
      c += 1
      if ( c > 200) {
        alert('endless loop detected in sendQueuedEvents')
        return
      }
      if (! postTuple) continue

      out += renderServerEvent(postTuple[0], postTuple[1], postTuple[2] , postTuple[3])

      // Add a ',' to the rendered output if there are more events in the queue...
      if (top.glbDict.postArray.length > 0) {
        out += ',\n'
      }
    }
    out += '\n]'

    transmitEventData(out)
   
    //var enc = encodeURIComponent(out)
    //inp.value = enc
    //frm.action = "http://localhost/dynamic/widgetupdate"
    //frm.method = "post"
    //frm.submit()

  }

  function timerFunc() {
    sendQueuedEvents()
    setTimeout('timerFunc()',100)
  }
  timerFunc()

  function serverpost(obj,evtname,method,extra) {
    queueServerEvent( obj , evtname , method , extra )
    sendQueuedEvents()
  }
  top.glbDict.serverpost = serverpost



  // Returns true if a given object is a UW Widget
  function objIsWidget(obj) {
    if (!obj) return false

    if (typeof(obj) != 'object') return false

    if (! obj.tagName) return false

    if (obj.tagName == 'SPAN' && obj.getAttribute('onserver')) return true

    return false
  }

  // Gets the UW widget node associated with a child HTML element
  function widgetFromObj(obj) {
      if (!obj) return null

      if (objIsWidget(obj)) return obj

      var parentObj = obj
      var c = 0
      while ( parentObj.tagName != 'SPAN') {
        parentObj = parentObj.parentNode
        c += 1
        if ( c >= 200) {
          alert('endless loop detected in dyncontent.js')
          return null
        }
      }
      return parentObj
  }

  function transmitEventData(data) {
    if (document.all && (!window.opera)) {
      var xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    else {
      var xhr = new XMLHttpRequest()
    }

    function callback() {
        if (xhr.readyState == 4) {
          if (xhr.status == 200) {
            if (xhr.responseText != '') {
              try {
                eval(xhr.responseText)
              }
              catch(e) {
                //alert(e)
              }
            }
            top.glbDict.postFinished()
          } 
          else {
            alert("Problem receiving response:\n" + xhr.status)
            alert(xhr.responseText)
            top.glbDict.postFinished()
          }
        }
        if (top.glbDict.debugMode) {
          alert(xhr.readyState)
        }
    }

    xhr.open('POST','/dynamic/widgetupdate',true)
    xhr.onreadystatechange = callback
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')

    /* This is redundant, but some browsers need one and some need the other */
    xhr.setRequestHeader('Proxy-Connection','close')
    xhr.setRequestHeader('Connection','close')

    xhr.send('postcontents=' + encodeURIComponent(data))

  }



  function xtransmitEventData(data) {
    if (!data) {
      data = '[]'
    }
    // This is where the data gets posted
    var url = location.protocol + '//' + location.host + '/dynamic/widgetupdate'
    // This will be null 1st time function is called
    var pf = document.getElementById('postframe')
    if (!pf) {
      var tsrc = location.protocol + "//" + location.host + "/dynamic/__null" 
      var pd = document.createElement('div')
      document.body.appendChild(pd)
      if ( document.all && (!window.opera) ) { // IE Version
        // IE needs to be initialized with a source pointing at our server, with HTTPS if the main
        // page is over HTTPS.  Otherwise it will pop up a stupid dialog about 'page displays both secure
        // and insecure data...'
        pd.innerHTML = '<iframe id="postframe" style="visibility:hidden" src="' + tsrc + '">'
      }
      else {
        pd.innerHTML = '<iframe id="postframe" style="visibility:hidden" >'
      }
      pf = document.getElementById('postframe')
    }
    var out =  '<HTML>\n'
        out += '<HEAD>\n'
        out += '<SCRIPT language="javascript">\n'
        out += 'function doit() {\n'
        out += '  var src = "' + encodeURIComponent(data) + '"\n'
        out += '  var inp = document.getElementById("postcontents")\n'
        out += '  var frm = document.getElementById("postform")\n'
        out += '  inp.value = src\n'
        out += '  frm.method = "post"\n'
        out += '  frm.action = "' + url + '"\n'
        out += '  frm.submit()\n'
        out += '}\n'
        out += '</SCRIPT>\n'
        out += '</HEAD>\n'
        out += '<BODY onload="doit()">'
        out += '<FORM id="postform"><INPUT type="text" name="postcontents" id="postcontents">'
        out += '</BODY>'
        out += '</HTML>'

    if (window.opera) { // Opera 8
      pf.location = 'data:text/html;charset=utf-8,' + escape(out)
    }
    else {
      pf.contentWindow.document.write(out)
      pf.contentWindow.document.close()
    }

  }

  // Returns the hidden form and input field used to submit events
  // to the server.
  function getPostMechanism() {
   var pf = document.getElementById('postframe')

    if (!pf) {
      var pd = document.createElement('div')
      document.body.appendChild(pd)
      pd.innerHTML = '<iframe id="postframe" src="/play/test.html" style="visibility:hidden" >'
      pf = document.getElementById('postframe')
    }
    var cw = pf.contentWindow
    var cd = cw.document
    var cb = cd.body
    if (!cb) {
      cb = cd.createElement('body')
      try {
        cd.appendChild(cb)
      }
      catch(e) {
        alert(e)
        try {
          pf.parentNode.removeChild(pf)
          //document.removeChild(pf)
          delete pf
        }
        catch(e) {
          alert(e)
        }
        return null
      }
    }

    // Just a piece of trivia.  IE will recognize a relative URL in a dynamically created IFRAME.
    // Mozilla requires an absolute URL.  Both will work with an absolute URL, so we are doing it
    // that way
    var postURL = location.protocol + "//" + location.host + "/dynamic/widgetupdate"
    cb.innerHTML = '<form action="' + postURL + '" method="post" id="postform"><input id="postinput" type="text" name="postcontents"></input></form>'

    var frm = cd.getElementById('postform')
    //frm.method = "post"
    //frm.action = document.location
    //frm.action = "/dynamic/widgetupdate"
    var inp = cd.getElementById('postinput')

    var out = [ frm , inp ]
    return out
  }

  // Formats a server-side widget event for posting to the server
  function renderServerEvent( obj , evtname , method , extra ) {
    // If the object that posted the event is not a SPAN, with the onserver attribute,
    // pass the ID of the object's parent span as the ID to use.
    // Otherwise, pass the object's id (because it is a widget)
    var idtouse = ''
    if (objIsWidget(obj)) {
        idtouse = obj.id
    }
    else {
      try {
        var w = widgetFromObj(obj)
      }
      catch(e) {
        var w = null
      }
      if (w) {
        idtouse = w.id
      }
      else idtouse = 'NULL'
    }

    // Format the event message to the server and send it
    var out ='{ \n  "event" : ( "' + idtouse + '","' + evtname + '","' + encodeURIComponent(extra) + '"),\n'

    // Let the client side representation of the widget know we are about to
    // send an event, in case it wants to make some last minute changes
    var widget = top.glbDict.uwWidgetFactory.getWidgetInst(idtouse)
    if (widget) {
      widget.beforeEvent(evtname,method,extra)
    }

    out += ' "updates" : [ ' 
    var changed_widgets = top.glbDict.uwWidgetFactory.getChangedWidgets()
    for (var c = 0; c < changed_widgets.length; c++ ) {
      var wm = changed_widgets[c]

      var chgs = wm.getServerUpdates()
      out += chgs.join(',')

      if (c != changed_widgets.length - 1) {
        out += ',\n'
      }
    }
    out += ']\n}\n'

    return out
  }


  // Called upon completion of the server-side widget event post response (i.e. the
  // server specifies this to be called opon body.onload of the response document it sends)
  function postFinished() {
    var rs = top.glbDict.renderingsInPost
    for (var c = 0; c < rs.length; c++) {
      r = rs[c]

      // r[0] = widget ID
      // r[1] = method to call on widget's client side manager instance
      // r[2] = string data to pass to method

      // Get a reference to the widget's client-side manager instance
      try {
        var mgr = top.glbDict.uwWidgetFactory.getWidgetInst( r[0] )

        // Call the specified method on the manager object, with the specified data
        var func = eval('mgr.' + r[1])


        // func.apply broken in IE when calling from a child window to a
        // function defined in a parent window.
        func(r[2])
        //func.apply(mgr,[ r[2] ])
      }
      catch(e) {
        if ( top.glbDict.debugMode ) {
          alert('error posting rendering for widget ' + r[0] + '\ncalling "' + r[1] + '" with\n' + r[2] )
          alert(e)
        }
      }
   
    }
    if (rs.length > 0 ) { // force a resize if messages have been received
      //top.glbDict.forceResize()
    }

    top.glbDict.uwWidgetFactory.markAllClean()

    // Render alert boxes as needed
    for (var a = 0; a < top.glbDict.alertsInPost.length; a++) {
       var msg = top.glbDict.alertsInPost[a]
       try {
         msg = decodeURIComponent(msg)
       }
       catch(e) {
       }
       try {
         msg = decodeURIComponent(msg)
       }
       catch(e) {
       }
       alert( msg )
    }
    // Render sounds needed
    for (var a = 0; a < top.glbDict.soundsInPost.length; a++) {
       var msg = top.glbDict.soundsInPost[a]
       top.glbDict.playSound( msg )
    }

    // Add timers as needed
    for (var a = 0; a < top.glbDict.timersInPost.length; a++) {
       var te = top.glbDict.timersInPost[a]
       var screen_id = te[0]
       var timer_name = te[1]
       var interval = te[2]
       top.glbDict.uwTimerManager.addTimer( screen_id , timer_name , interval )
    }
    
    top.glbDict.clearTimers()
    top.glbDict.clearSounds()
    top.glbDict.clearRenderings()
    top.glbDict.clearAlerts()

    // Reload documents where reload was deferred
    top.glbDict.uwWidgetFactory.reloadDeferredDocs()

    top.glbDict.postIsBusy = false
    top.glbDict.hideAjax()
  }

  function init_dyncontent(spans) {
    if (!top.glbDict) {
      top.glbDict = new Object()
    }
    top.glbDict.postFinished = postFinished

    // Send an event to the global framework to let anything that might be waiting know
    // we are finished initializing dyncontent for this document
    top.glbDict.postUWEvent('dyncontent_initialized' , document )
  }

  // Make init_dyncontent a listener for doc_init events
  top.glbDict.uwEventController.addListener('dynresize_initialized' , init_dyncontent )

  // Mozilla warps the rendering on the 1st post when it is creating the iframe to post with.
  // So, we send a fake post up front so that the user doesn't see it.
  if (!document.all && top.glbDict.postMechanism == 'iframe') {
    x = function() {
      transmitEventData()
    }
    top.glbDict.uwEventController.addListener('doc_init' , x )
  }
}

