/*
 * Defines Standard UW Widget Client Side Framework Globals.
 *
 * These are referenced from by plugable client side object scripts
 *
 */

// Define the global lookup dictionary for UW, if another document has not
// already done so
var isNew = 0
// DOM standard
var DOCUMENT_NODE = 9

if (! top.glbDict) {
  top.glbDict = new Object()
  top.glbDict.debugMode = false
  top.glbDict.lastURL = top.location.href
  isNew = 1
}

if ( isNew ) {

  // The preferred way to obtain the global UW dictionary, in case
  // it moves somewhere else
  function uwGetGlobalDict() {
    return top.glbDict
  }

  var glbDict = top.glbDict
  
  // Following globals and functions keep track of widget updates and
  // alert boxes that are supposed to be generated from response to POSTs
  top.glbDict.renderingsInPost = new Array()
  top.glbDict.alertsInPost = new Array()
  top.glbDict.soundsInPost = new Array()
  top.glbDict.printoutsInPost = new Array()
  top.glbDict.timersInPost = new Array()
  function addRendering(widgetID,method, rendering) {
    top.glbDict.renderingsInPost.push( [ widgetID , method, rendering ] )
  }
  top.glbDict.addRendering = addRendering
  function addTimer( screen_id , timer_name , interval ) {
    top.glbDict.timersInPost.push( [ screen_id , timer_name , interval ] )
  }
  top.glbDict.addTimer = addTimer
  function addSound(src) {
    top.glbDict.soundsInPost.push(src)
  }
  top.glbDict.addSound = addSound
  function addAlert(msg) {
    top.glbDict.alertsInPost.push(msg)
  }
  top.glbDict.addAlert = addAlert
  function addPrintout(content) {
	  top.glbDict.printoutsInPost.push(content)
  }
  top.glbDict.addPrintout = addPrintout
  function clearRenderings() {
    top.glbDict.renderingsInPost = new Array()
  }
  top.glbDict.clearRenderings = clearRenderings
  function clearTimers() {
    top.glbDict.timersInPost = new Array()
  }
  top.glbDict.clearTimers = clearTimers
  function clearAlerts() {
    top.glbDict.alertsInPost = new Array()
  }
  top.glbDict.clearAlerts = clearAlerts
  function clearSounds() {
    top.glbDict.soundsInPost = new Array()
  }
  top.glbDict.clearSounds = clearSounds
  function clearPrintouts() {
	top.glbDict.printoutsInPost = new Array()
  }
  top.glbDict.clearPrintouts = clearPrintouts

  function googleAnalytics(msg) {
    var msg = decodeURIComponent(msg)
    try{ 
      var pageTracker = _gat._getTracker("UA-9459573-1");
      pageTracker._trackPageview(msg);
    }
    catch(err) {
    }
  }
  top.glbDict.googleAnalytics = googleAnalytics


  function reclaimMem(d) {
      var a = d.attributes, i, l, n;
      if (a) {
          l = a.length;
          for (i = 0; i < l; i += 1) {
              n = a[i].name;
              if (typeof d[n] === 'function') {
                  d[n] = null;
              }
          }
      }
      a = d.childNodes;
      if (a) {
          l = a.length;
          for (i = 0; i < l; i += 1) {
              top.glbDict.reclaimMem(d.childNodes[i]);
          }
      }
  }
  top.glbDict.reclaimMem = reclaimMem

  function innerHTML(node,newcontent) {
    top.glbDict.reclaimMem(node)
    node.innerHTML = newcontent
  }
  top.glbDict.innerHTML = innerHTML

  function removeChild(node,pnode) {
    if ( ! pnode ) {
      var pnode = node.parentNode
    }
    top.glbDict.reclaimMem(node)
    pnode.removeChild(node)
  }
  top.glbDict.removeChild = removeChild

  // Sets and maintains mouse and key events
  IE = (navigator.appName.indexOf('Microsoft') >= 0) ? true : false

  function handleRightClick(eType,evt) {
    evt = (evt) ? evt : ((event) ? event : null)
    if (evt) {
      var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
      var widget = top.glbDict.getMyInst(elem)
      if (widget) {
        widget.secondaryClick(elem)
      }
    }
    if (evt.preventDefault) { // Netscape
      evt.preventDefault()
    }
    return false
  }
  top.glbDict.handleRightClick = handleRightClick

  function handleKey(eType,evt) {
    evt = (evt) ? evt : ((event) ? event : null)
    if (evt) {
      var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
      if (elem) {
        elem = ((elem.nodeType == 1) || (elem.nodeType == 9)) ? elem : elem.parentNode
        var keyC = (IE) ? evt.keyCode : evt.charCode
        top.glbDict.uwEventController.postEvent(eType,[ evt.target , keyC , evt])
      }
      else {
        alert('Unable to determine element!')
      }
    }
    else {
      alert('Unable to determine event!')
    }
  }
  top.glbDict.handleKey = handleKey

  function handleMouse(eType,evt) {
    evt = (evt) ? evt : ((event) ? event : null)
    if (evt) {
      var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);

      if (! top.glbDict ) return // Mouse move before initialization has finished
      if (elem) {
        if (! top.glbDict.lastMouse ) {
          top.glbDict.lastMouse = new Object()
        }
        top.glbDict.lastMouse.target = elem
        top.glbDict.lastMouse.clientX = evt.clientX
        top.glbDict.lastMouse.clientY = evt.clientY
        top.glbDict.lastMouse.eType = eType
        if (eType == 'mousemove') {
          top.glbDict.uwEventController.postEvent('mouse_move', [ evt.target , evt.clientX , evt.clientY ] )
          if (top.glbDict.postIsBusy && top.glbDict.showAjax) {
            top.glbDict.showAjax()
          }
        }
        top.glbDict.uwEventController.postEvent('mouse_change', [ ] )
      }
      else {
        alert('Unable to determine element!')
      }
    }
    else {
      alert('Unable to determine event!')
    }
  }
  top.glbDict.handleMouse = handleMouse
  
  function getWidgetsUnderMouse(x, y) {
    //var widgets = document.getElementsByTagName('span')
    var widgets = top.glbDict.uwWidgetFactory.spans
    var foundWidgets = new Array()
    if (widgets.length == 0) {
      return widgets
    }
    for (var w = 0; w < widgets.length; w++) {
      if ((x >= parseInt(widgets[w].style.left)) && (x <= parseInt(widgets[w].style.left) + parseInt(widgets[w].childNodes[0].style.width))) {
        if ((y >= parseInt(widgets[w].style.top)) && (y <= parseInt(widgets[w].style.top) + parseInt(widgets[w].childNodes[0].style.height))) {
          foundWidgets.push(widgets[w].id)
        }
      }
    }
    return foundWidgets
  }

  function playSound(src) {
    // Remove other bgsound elements so they don't clutter things
    var bgsounds = top.document.body.getElementsByTagName('bgsound')
    for (var c = 0;c < bgsounds.length; c++) {
      top.document.body.removeChild(bgsounds[c])
    }
    var bgsound = top.document.createElement('bgsound')
        bgsound.setAttribute('src',src)
        bgsound.setAttribute('loop','0')
    top.document.body.appendChild(bgsound)
  }
  top.glbDict.playSound = playSound
  
  function printReport(report) {
	repdiv = top.document.getElementById('printwrap')
	top.glbDict.innerHTML(repdiv,report)
	top.print()
  }
  top.glbDict.printReport = printReport
  
  function doAllReports() {
    for (var a = 0; a < top.glbDict.printoutsInPost.length; a++) {
       var msg = top.glbDict.printoutsInPost[a]
       try {
         msg = decodeURIComponent(msg)
       }
       catch(e) {
       }
       try {
         msg = decodeURIComponent(msg)
       }
       catch(e) {
       }
       top.glbDict.printReport(msg)
    }
    top.glbDict.clearPrintouts()
  }
  top.glbDict.doAllReports = doAllReports

  // Define the global uw 'macro event' manager.  This
  // class maps custom script driven 'events' with registered handlers
  if (! top.glbDict.uwEventController ) {
    function UWEventController() {
      var mySelf = this

      mySelf.callbacksByEvent = new Object()
      
      mySelf.addListener = function( evname , evfunc ) {
        if (! (evname in mySelf.callbacksByEvent) ) {
          mySelf.callbacksByEvent[evname] = new Array()
        }
        mySelf.callbacksByEvent[evname].push(evfunc) 
      }

      mySelf.removeListener = function( evname , evfunc ) {
        if (! (evname in mySelf.callbacksByEvent)) return

        var cb = mySelf.callbacksByEvent[evname]
        for ( var c = 0; c < cb.length; c++ ) {
          var f = cb[c]
          if ( f == evfunc ) {
            delete cb[c]
            break
          }
        }
      }

      mySelf.postEvent = function(evname) {
        //alert( 'postEvent called for event: ' + evname + ', params: ' + arguments )
        if ( evname in mySelf.callbacksByEvent ) {
          var cbDict = mySelf.callbacksByEvent[evname]
          for ( var cbFuncKey in cbDict ) {
            var callback = cbDict[cbFuncKey]
            try {
              callback(arguments)
            }
            catch(e) {
              delete cbDict[cbFuncKey]
            }
          }
        }
      }

      return mySelf
    }

    top.glbDict.uwEventController = new UWEventController()
  }

  // Define global method to post a UW event
  if (! top.glbDict.postUWEvent ) {
    function postUWEvent(evname) {
      // Pass remaining arguments, stripping the first
      var args = new Array()
      if (arguments.length > 1) {
        for (var c = 1; c < arguments.length; c++) {
          args[c - 1] = arguments[c]
        }
      }
      top.glbDict.uwEventController.postEvent(evname,args)
    }
    top.glbDict.postUWEvent = postUWEvent
  }

  // Define global method for hiding IFRAMES - they ignore zIndex in Opera
  if ( !top.glbDict.hideIFrames ) {
    top.glbDict.hiddenIFrames = new Array()
    function hideIFrames(doc,bool,exceptions) {
      if (!exceptions) {
        exceptions = new Array()
      }
      if (bool) {
        var iframes = doc.body.getElementsByTagName('IFRAME')
        top.glbDict.hiddenIFrames = new Array()
        for (var c = 0; c < iframes.length; c++) {
          var ifr = iframes[c]
          if (getComputedStyle(ifr).visibility == 'visible') {
            var foundExc = 0
            for (var exc = 0; exc < exceptions.length;exc ++) {
              var exception = exceptions[exc]
              if (exception == ifr) {
                foundExc = 1
              }
            }
            if (!foundExc) {
              ifr.style.visibility = 'hidden'
              top.glbDict.hiddenIFrames.push(ifr)
            }
          }
        }
      }
      else {
        for (var c = 0; c < top.glbDict.hiddenIFrames.length ; c++) {
          var ifr = top.glbDict.hiddenIFrames[c]
          ifr.style.visibility = 'visible'
          delete top.glbDict.hiddenIFrames[c]
        }
      }
    }
    top.glbDict.hideIFrames = hideIFrames
  }

  // Define global method to notify of document initialization
  if (! top.glbDict.uwDocInit ) {
    function uwDocInit(doc) {
      top.glbDict.uwEventController.postEvent('doc_init' , doc ) 
    }
    top.glbDict.uwDocInit = uwDocInit
  }


  // Gets all of the widgets defined in a document
  top.glbDict.getWidgetSpans = function getWidgetSpans(doc) {
    var spans = doc.getElementsByTagName('SPAN')
    var outspans = new Array()
    for (var s = 0; s < spans.length; s++) {
      var span = spans[s]
      if (span.getAttribute('onserver')) {
        outspans[outspans.length] = span
      }
    }
    return outspans
  }

  // Defines the widget base class.  All widget classes inherit these attributes
  // and functions
  top.glbDict.makeWidgetManager = function (inst,span) {
    inst.dirty = false
    inst.span = span

    inst.setDirty = function() {
      inst.dirty = true
    }

    inst.watchChild = function (chld) {

      var onchange = function () { 
        if (! top.glbDict.postIsBusy ) {
          inst.setDirty()
        }
      }

      var onblur = function () { 
        if (! top.glbDict.postIsBusy ) {
          inst.setDirty()
        }
      }

      // Textareas don't respond to onchange in all versions of IE as you'd expect.
      // So, we need to monitor 'onblur' for a textarea, and assume it changed when
      // it looses focus.
      if ( inst.span.getAttribute('serverclass').toLowerCase() == 'textarea' && 
           document.all && (!window.opera)
         ) {
        top.glbDict.addEvent(chld,'onblur',onblur,[])
      }
      else {
        top.glbDict.addEvent(chld,'onchange',onchange,[])
      }
    }

    inst.beforeEvent = function (evtName, method , extra ) {

    }

    inst.preUpdate = function () {
    }
    inst.postUpdate = function() {
    }

    inst.enable = function(tf) {
      if (!tf) {
        inst.span.childNodes[0].disabled = 'true'
      }
      else {
        inst.span.childNodes[0].removeAttribute('disabled')

        if ( (! document.all ) ) {
          // Netscape/Mozilla needs.  IE doesn't like
          delete inst.span.childNodes[0].disabled
        }
        //delete inst.span.childNodes[0]['disabled']
      }
    }

    inst.isEnabled = function() {
      if ( inst.span.childNodes[0].disabled == 'true' || 
           inst.span.childNodes[0].disabled == 1 || 
           inst.span.childNodes[0].disabled == true) {
        return 0
      }
      return 1
    }

    inst.eventIsRegistered = function(evName) {
      var reg_ev_arr = inst.span.getAttribute('srvevents').split(',')
      for (var c = 0; c < reg_ev_arr.length; c++ ) {
        if (reg_ev_arr[c] == evName) {
          return true
        }
      }
      return false
    }

    inst.setAttr = function( parmString ) {
      var parms = eval(parmString)
      var attrName = parms[0]
      var attrVal = decodeURIComponent(parms[1])
      if (attrVal == '' || (attrName == 'disabled' && attrVal == 'false')) {
        if (inst.span.getAttribute(attrName)) {
          inst.span.removeAttribute(attrName)
        }
      }
      else inst.span.setAttribute(attrName,attrVal)
      inst.attrChange( attrName , attrVal )
    }

    inst.attrChange = function(attrName, attrVal) {
      // Deal with change in the 'disabled' property
      if (attrName == 'disabled') {
        if (attrVal != 'false') {
          inst.enable(0)
        }
        else inst.enable(1)
      }
    }

    inst.getID = function() {
      return inst.span.getAttribute('id')
    }

    // Global 'superclass' resize callback
    inst.baseApplyResize = function() {
      var span = inst.span
      var div = inst.span.childNodes[0]

      // Pre-apply percentage based resize
      if ( span.getAttribute('heightunit') == '%' ) {
        div.style.height = parseInt(div.ownerDocument.body.clientHeight * parseFloat(span.style.height) * .01 ) + 'px'
      }
      if ( span.getAttribute('widthunit') == '%' ) {
        div.style.width = parseInt(div.ownerDocument.body.clientWidth * parseFloat(span.style.width) * .01 ) + 'px'
      }

      inst.applyResize()
    }

    inst.applyResize = function() {
      // Called by dynresize.  Apply to widget specific interior sizing algorithms
    }

    inst.getServerUpdates = function() {
      inst.preUpdate()
      var out = [ '( "' + inst.span.getAttribute('id') + '" , "postDOM" , "' + encodeURIComponent(top.glbDict.walk_level(inst.span,1)) + '" )' ]
      inst.postUpdate()
      return out
    }

    inst.setEvents = function(eventsArray) {
      inst.events = eventsArray
    }

    inst.isDirty = function () {
      return inst.dirty
    }

    inst.markClean = function() {
      inst.dirty = false
    }

    inst.getSpan = function() {
      return inst.span
    }

    // Default widget secondary (i.e. right) click handler
    inst.secondaryClick = function(srcElement) {
      top.glbDict.queueServerEvent( inst.span , 'secondary_click' , false, '0' )
    }

    // Global 'superclass' initialize function.
    inst.baseInitialize = function() {
      var span = inst.span
      var div = inst.span.childNodes[0]

      // Pre-apply percentage based resize
      if ( span.getAttribute('heightunit') == '%' ) {
        div.style.height = parseInt(div.ownerDocument.body.clientHeight * parseFloat(span.style.height) * .01 ) + 'px'
      }
      if ( span.getAttribute('widthunit') == '%' ) {
        div.style.width = parseInt(div.ownerDocument.body.clientWidth * parseFloat(span.style.width) * .01 ) + 'px'
      }

      inst.initialize()
    }

    // Called immediately after construction.  Intended for
    // widget-specific initialization and state management.
    inst.initialize = function() {
      if (top.glbDict.debugMode) {
        alert('initializing of object with no client-side subclass\n' + inst.span.innerHTML)
      }
    }

    inst.finalize = function() {
    }

    // Re-sets the 'guts' of a widget to whatever is passed.  Typically accepts a
    // result sent from the server as a result of a server side event posting.
    inst.setdom = function( domXML ) {
      // Save off old width and height of 1st child of widget (this is client managed)
      var fc = inst.span.childNodes[0]
      var oldheight = fc.style.height
      var oldwidth = fc.style.width
      // Re-render the widget according to the server data
      top.glbDict.innerHTML(inst.span,domXML)

      // Once again, obtain the 1st child (which has a new reference), and re-assign height & width
      var fc = inst.span.childNodes[0]
      fc.style.height = oldheight
      fc.style.width = oldwidth

      //All text nodes have been URL encoded.  This decodes them.
      function decode_text_one_level(node) {
        var splits = new Array()
        for (var c = 0; c < node.childNodes.length; c++ ) {
          var child = node.childNodes[c]
          if (child.nodeType == 3) {
            var re = /#__#CR#__#/g
            var texts = decodeURIComponent( child.nodeValue ).replace(re,'\r')
            child.nodeValue = texts
            
            // Mozilla fix.  Mozilla doesn't automatically refresh the screen just because
            // the DOM node changes, atleast with TextArea elements.  So, we need to check
            // and override if necessary
            if (child.parentNode.tagName.toLowerCase() == 'textarea') {
              child.parentNode.value = child.nodeValue
            }
          }
          else decode_text_one_level(child)
        }
      }

      // Decode all text inside the given data
      decode_text_one_level(inst.span)

      // Call initialize again, as all guts have changed, and all references are bad
      inst.baseInitialize()

      // Enable / Disable widget per new attributes
      if (inst.span.getAttribute('disabled') == 'true') {
        inst.enable(0)
      }

    }

  }

  // Basic widget manager wrapper.  Used as a default when a widget exists
  // with no registered client-side manager.
  BaseWidget = function (span) {
    // "Superclass"
    top.glbDict.makeWidgetManager(this,span)
  }


  // Defines a widget factory, where instances are created to manage widgets
  // defined in a given document body
  WidgetFactory = function () {
    var mySelf = this
    mySelf.managedWidgets = new Object()
    mySelf.managers = new Object()
    mySelf.events = new Object()
    mySelf.widgetInitData = new Object()
    mySelf.spans = new Array()
    mySelf.managedDocs = new Object()
    mySelf.deferredReloads = new Object()
    mySelf.initializing = 0

    mySelf.isInitializing = function() {
      return mySelf.initializing
    }

    mySelf.addWidgetInitData = function ( widgetID , dataName , data ) {
      if (! (widgetID in mySelf.widgetInitData) ) {
        mySelf.widgetInitData[widgetID] = new Object()
      }
      mySelf.widgetInitData[widgetID][dataName] = data
    }

    mySelf.getInitDataForWidget = function (widgetID) {
      if (! (widgetID in mySelf.widgetInitData) ) {
        return new Object()
      }
      else return mySelf.widgetInitData[widgetID]
    }

    mySelf.registerWidgetEvent = function (evname , widgetID , callback , extra ) {
      if (! (widgetID in mySelf.events) ) {
        mySelf.events[widgetID] = new Object()
      }
      widgetEvts = mySelf.events[widgetID]

      widgetEvts[evname] = [ callback , extra ]
    }

    mySelf.registerWidgetClass = function (widgetClassName, widgetClassFunc ) {
      mySelf.managers[ widgetClassName ] = widgetClassFunc
    }

    mySelf.getManagers = function() {
      return mySelf.managers
    }

    mySelf.getWidgetInsts = function () {
      return mySelf.managedWidgets
    }

    mySelf.getWidgetInst = function (id) {
      var out = null
      try {
        out = mySelf.getWidgetInsts()[id]
      }
      catch(e) {
      }
      if ((!out) && top.opener && ( top.opener != top) ) {
        var out = top.opener.glbDict.uwWidgetFactory.getWidgetInst(id)
      }
      return out
    }

    mySelf.unloadDoc = function(doc) {
      if ( ! doc ) { 
        alert('unloadDoc called with no doc')
      }
      if (doc.body) {
        var body = doc.body
        body.onresize = null
        body.onload = null
        body.onunload = null
        body.onselectstart = null
        body.sizer = null
        body.onmousemove = null
        body.onmousedown = null
        body.onmouseup = null
        body.onkeypress = null
        body.onkeyup = null
        body.onkeydown = null
        body.oncontextmenu = null
        if ( top.glbDict.lastMouse && top.glbDict.lastMouse.target && (top.glbDict.lastMouse.target == body) ) {
          top.glbDict.lastMouse.target = null
          top.glbDict.lastMouse = null
        }
        spans = body.getElementsByTagName('span')
        for (var c=0; c< spans.length; c++) {
          var span = spans[c]
          if ( ! span.getAttribute('onserver') ) { continue }
          if ( span.getAttribute('_in_designer') ) { continue }
          var inst = mySelf.getWidgetInst( span.getAttribute('id') )
          inst.finalize()
          mySelf.removeWidget( span.getAttribute('id') )
        }
      }
      mySelf.managedDocs[doc.location] = null
      delete mySelf.managedDocs[doc.location]
      //alert('unloaded')
    }

    // Reloads the given document.  If defer is non-zero,
    // then document will be re-loaded after post
    mySelf.reloadDocument = function(doc,defer) {
      if (defer) {
        mySelf.deferredReloads[doc.location.pathname] = doc
      }
      else {
        doc.location = doc.location
      }
    }

    // Reloads all deferred documents
    mySelf.reloadDeferredDocs = function() {
      for( key in mySelf.deferredReloads ) {
        var doc = mySelf.deferredReloads[key]
        doc.location = doc.location // Re GET the doc
      }
      mySelf.deferredReloads = new Object()
    }

    mySelf.initializeDoc = function () {
      mySelf.initializing = 1
      doc = arguments[0][1]
      var m

      mySelf.managedDocs[doc.location] = doc

      outer_func = function() {
        var x = doc
        f = function() {
          mySelf.unloadDoc(x)
        }
        return f
      }
      doc.body._othercleanup = outer_func()

      // Apply attributes to content wrap element
      var body = doc.getElementsByTagName('body')[0]

      // Handily get rid of IE insisted IFrame borders
      body.style.border = '0'



      var bwdiv = doc.getElementById('bodywrap')
      if (body.getAttribute('bgimage')) {
        if (body.getAttribute('bgrepeat') && body.getAttribute('bgrepeat').toUpperCase() == 'SCALE') {
          var bwimg = doc.createElement('IMG')
          bwimg.style.width = '100%'
          bwimg.style.height = '100%'
          bwimg.style.top = '0px'
          bwimg.style.left = '0px'
          bwimg.style.zIndex = -1 
          bwimg.style.backgroundColor = 'transparent'
          bwimg.style.position = 'absolute'
          bwimg.src = body.getAttribute('bgimage')
          bwdiv.appendChild(bwimg)
        }
        else {
          //bwdiv.style.backgroundImage = body.getAttribute('bgimage')
          //bwdiv.style.backgroundSize = body.getAttribute('bgsize')
          //bwdiv.style.backgroundOrigin = body.getAttribute('bgorigin')
          //bwdiv.style.backgroundRepeat = body.getAttribute('bgrepeat')
        }
      }

      // Add default events to document body
      top.glbDict.addEvent(body,'onmousemove', top.glbDict.handleMouse, ['mousemove'] )
      top.glbDict.addEvent(body,'onmousedown', top.glbDict.handleMouse, ['mousedown'] )
      top.glbDict.addEvent(body,'onmouseup', top.glbDict.handleMouse, ['mouseup'] )
      top.glbDict.addEvent(doc,'onkeypress', top.glbDict.handleKey, ['keypress'] )
      top.glbDict.addEvent(doc,'onkeyup', top.glbDict.handleKey, ['keyup'] )
      top.glbDict.addEvent(doc,'onkeydown', top.glbDict.handleKey, ['keydown'] )
      top.glbDict.addEvent(doc,'oncontextmenu' , top.glbDict.handleRightClick , ['contextmenu'] )


      // Add widgets
      var newSpans = top.glbDict.getWidgetSpans(doc)
      for (var c = 0; c < newSpans.length ; c++ ) {
        var s = newSpans[c]
        top.glbDict.innerHTML(s,s.innerHTML)
        mySelf.initializeWidget(s)
      }


      mySelf.initializing = 0


    }

    mySelf.removeWidget = function(id) {
      delete mySelf.managedWidgets[id]
      delete mySelf.widgetInitData[id]
    }

    mySelf.initializeWidget = function(s) {
      mySelf.spans.push(s)
      var managerClass = null
      var sclass = s.getAttribute('serverclass')
      if (sclass in mySelf.managers) {
        managerClass = mySelf.managers[sclass]
      }
      if(managerClass) {
        m = new managerClass(s)
      }
      else {
        m = new BaseWidget(s)
      }
      if ( s.getAttribute('id') in mySelf.events ) {
        m.setEvents( mySelf.events[ s.getAttribute('id') ] )
      }
      mySelf.managedWidgets[s.getAttribute('id')] = m
      m.baseInitialize()
      if (m.span.getAttribute('disabled') == 'true') {
        m.enable(0)
      }

    }

    mySelf.changeDocAttribute = function(docurl,attr,val) {
      // For now cheat on this implementation, and force the browser
      // to re-get the page
      for ( key in mySelf.managedDocs ) {
        var doc = mySelf.managedDocs[key]
        try {
          if ( doc.location.pathname.split('_fake_')[0] == docurl ) {
            
            // DO THE WORK HERE!
            if (attr == 'bgcolor') {
              doc.body.style.backgroundColor = val
              var bodywrap = doc.getElementById('bodywrap')
              bodywrap.style.backgroundColor = val

              return // Done
            }
          }
        }
        catch(e) {
          if ( top.glbDict.debugMode ) {
            alert('caught invalid doc inside changeDocAttribute: ' + docurl )
          }
          // Invalid pointer. Lets remove the key now
          delete mySelf.managedDocs[key]
        }
      }
      // Catch new widget post to parent windows also
      if (top.opener && (top.opener != top)) {
        top.opener.glbDict.uwWidgetFactory.changeDocAttribute(docurl,attr,val)
      }
    }

    mySelf.addWidgetFromPost = function(id,domStr,docurl) {
      // For now cheat on this implementation, and force the browser
      // to re-get the page
      if ( top.glbDict.debugMode ) {
        alert('addWidgetFromPost called with (' + id + ',' + domStr + ',' + docurl + ')' )
      }
      for ( key in mySelf.managedDocs ) {
        var doc = mySelf.managedDocs[key]
        try {
          if ( doc.location.pathname.split('_fake_')[0] == docurl ) {
            if ( top.glbDict.debugMode ) {
              alert('deloading doc ' + doc.location.href)
            }
            mySelf.reloadDocument(doc,1) // Indicates to deferr reload
          }
        }
        catch(e) {
          // Invalid pointer. Lets remove the key now
          if ( top.glbDict.debugMode ) {
            alert('init.js debugging - removing doc w/ key ' + key)
          }
          delete mySelf.managedDocs[key]
        }
      }
      // Catch new widget post to parent windows also
      if (top.opener && (top.opener != top)) {
        top.opener.glbDict.uwWidgetFactory.addWidgetFromPost(id,domStr,docurl)
      }
    }

    mySelf.removeWidgetFromPost = function(id,docurl) {
        // For now, cheat on this just as for adding widgets from a post
      for ( key in mySelf.managedDocs ) {
        var doc = mySelf.managedDocs[key]
        try {
          if ( doc.location.pathname.split('_fake_')[0] == docurl ) {
            mySelf.reloadDocument(doc,1) // Indicates to deferr reload
          }
        }
        catch(e) {
          // Invalid pointer. Lets remove the key now
          delete mySelf.managedDocs[key]
        }
      }
      // Catch new widget post to parent windows also
      if (top.opener && (top.opener != top)) {
        top.opener.glbDict.uwWidgetFactory.removeWidgetFromPost(id,docurl)
      }
    }

    mySelf.getChangedWidgets = function() {
      var out = new Array()
      for (var i in mySelf.managedWidgets) {
        var m = mySelf.managedWidgets[i]
        if (m.isDirty()) {
          out[out.length] = m
        }
      }
      return out
    }

    mySelf.markAllClean = function () {
      for (var i in mySelf.managedWidgets) {
        var m = mySelf.managedWidgets[i]
        m.dirty = false
      }
    }

    return mySelf
  }
  top.glbDict.uwWidgetFactory = new WidgetFactory()
  top.glbDict.getWidgetInst = top.glbDict.uwWidgetFactory.getWidgetInst

  top.glbDict.showAjax = function() {
    // This scary looking block is the way it is because if an event causes a
    // close of a document, the indicator will be trying to be displayed as
    // parts of the document/body/etc start to disappear.  So, it can fail
    // on nearly any line, and it's not such a big deal
    try {
      if (! (top.glbDict.lastMouse && top.glbDict.lastMouse.target) ) return
      try {
        var target_doc = top.glbDict.lastMouse.target.ownerDocument
        if ( top.glbDict.ajaxIndicator && (target_doc != top.glbDict.ajaxIndicator.ownerDocument)) {
          top.glbDict.hideAjax()
        }
      }
      catch(e) {
        // IE Permissions error can occur....ignore
      }
      if (! target_doc ) return
      if (! target_doc.getElementById('ajax_img') ) {
        var d = target_doc.createElement('img')
        d.id = 'ajax_img'
        d.src='/shared/image/indicator/indicator_medium.gif'
        d.style.position = 'absolute'
        target_doc.body.appendChild(d)
      }
      var cY = top.glbDict.lastMouse.clientY + 10
      var cX = top.glbDict.lastMouse.clientX + 10
      if (cY + 50 > target_doc.body.clientHeight ) cY -= 50
      if (cX + 50 > target_doc.body.clientWidth ) cX -= 50
      var d = target_doc.getElementById('ajax_img')
      if (d) {
        d.style.top = cY + 'px'
        d.style.left = cX + 'px'
        top.glbDict.ajaxIndicator = d
      }
    }
    catch(e) {
      if (top.glbDict.debugMode) {
        alert('Error inside showAjax')
      }
    }
  }

  top.glbDict.hideAjax = function() {
    if (! top.glbDict.ajaxIndicator) return
    try {
      var aji_doc = top.glbDict.ajaxIndicator.ownerDocument
    }
    catch(e) {
      aji_doc = null
      return
    }
    if (aji_doc && aji_doc.body) { // Won't be true if this was set for server communication that resulted in close of the window or frame
      var d = top.glbDict.ajaxIndicator
      try {
        top.glbDict.removeChild(d)
      }
      catch(e) {
      }
    }
    top.glbDict.ajaxIndicator = null
  }


  top.glbDict.getMyInst = function(obj) {
    var parentObj = obj
    var c = 0
    while ( parentObj && (parentObj.tagName != 'SPAN') && ( !parentObj.getAttribute || !parentObj.getAttribute('onserver')) ) {
      parentObj = parentObj.parentNode
      c += 1
      if (c >= 200) {
        alert('endless loop detected in init.js')
        return null
      }
    }
    if (parentObj) {
      return top.glbDict.uwWidgetFactory.getWidgetInst(parentObj.getAttribute('id'))
    }
  }

  // Add the widget factory's initializeDoc method as a listener
  // to 'doc_init' events
  top.glbDict.uwEventController.addListener('doc_init', top.glbDict.uwWidgetFactory.initializeDoc )



  // Framework client event handlers
  top.glbDict.addEvent = function (obj, evType, fn, parms) {
    //alert('add Event:\n' + obj + '\n' + evType + '\n' + fn )
    var Intf = function(fn,parms) {
      if ( ! parms ) {
        parms = []
      }
      var mySelf = this
      mySelf.fn = fn
      mySelf.parms = parms

      mySelf.apply = function() {
        var out = []
        for (var c = 0; c < mySelf.parms.length; c++) {
          out.push( mySelf.parms[c] )
        }
        for (var c = 0; c < arguments.length; c++) {
          out.push( arguments[c] )
        }
        return mySelf.fn.apply(mySelf,out)
      }

      return mySelf
    }
    var intf = new Intf(fn,parms)

    // Remove the 'on' from event names like 'onclick'.  Netscape doesn't like them.  We
    // tack them back on for IE
    if ( evType.slice(0,2).toUpperCase() == 'ON' ) {
      evType = evType.slice(2)
    }

    if ( obj.attachEvent ) {
      evType = 'on' + evType.toLowerCase()
      var evUnload = 'onunload'
    }
    else {
      evType = evType.toLowerCase()
      var evUnload = 'unload'
    }

    var obj_body = null
    if ( obj.tagName && obj.tagName == 'body' ) {
      obj_body = obj
    }
    else {
      if ( obj.ownerDocument ) {
        obj_body = obj.ownerDocument.body
      }
    }

    function cleanup() {
      for (var c=0;c < obj_body._uwthandlers.length;c++) {
        var obj = obj_body._uwthandlers[c][0]
        var ev = obj_body._uwthandlers[c][1]
        var fn = obj_body._uwthandlers[c][2]
        if (obj.detachEvent) {
          obj.detachEvent(ev,fn)
        }
        else {
          obj.removeEventListener(ev,fn,true)
        }
      }
      obj_body._uwthandlers = null
      obj_body.onunload = null
      if ( obj_body._othercleanup ) {
        var x = obj_body._othercleanup
        obj_body._othercleanup = null
        x()
      }
    }

    if ( obj_body ) {
      if ( ! obj_body._uwthandlers ) {
        obj_body._uwthandlers = new Array()
        obj_body._uwthandlers.push( [ obj_body, evUnload , cleanup ] )
        obj_body.onunload = cleanup
        if (obj.attachEvent) {
          obj_body.attachEvent(evUnload, cleanup )
        }
        else {
          obj_body.addEventListener(evUnload, cleanup , false )
        }
      }
      obj_body._uwthandlers.push( [ obj , evType , intf.apply ] )
    }
    if (obj.attachEvent) {
      return obj.attachEvent(evType, intf.apply )
    }
    else {
      obj.addEventListener(evType, intf.apply , true )
      return true
    }
  }

  top.glbDict.removeEvent = function (obj, evType, fn, useCapture) {
    if (obj.removeEventListener) {
      obj.removeEventListener(evType, fn, useCapture)
      return true
    }
    else if (obj.detachEvent) {
      var r = obj.detachEvent("on" + evType, fn)
      return r
    }
    else {
      alert("Handler could not be removed")
    }
  }

  // Client Timers -- auto post back to server with app-specified event names
  function TimerManager() {
    var mySelf = this

    mySelf.timers = new Object()

    mySelf.addTimer = function( screen , timername , interval ) {
      var tmr = new Object()
      tmr.timername = timername
      tmr.screen = screen
      tmr.interval = interval * 1000
      tmr.lastFire = new Date()

      mySelf.timers[ tmr.screen + ':' + tmr.timername ] = tmr

    }

    mySelf.removeTimer = function( screen , timername ) {
      delete mySelf.timers[screen + ':' + timername]
    }

    mySelf.processTimers = function() {
      for ( timerkey in mySelf.timers ) {
        var tmr = mySelf.timers[timerkey]
        var now = new Date()

        if ( now - tmr.lastFire  > tmr.interval ) {
          // Make an object that looks enough like a widget to allow event posting
          var timerObj = new Object()
          timerObj.tagName = 'SPAN'
          timerObj.getAttribute = function(something) { return true }
          timerObj.id = '__TIMER__'

          // Fire the timer event
          top.glbDict.queueServerEvent( timerObj , tmr.timername , '', tmr.screen )

          // Update the last fire time
          tmr.lastFire = new Date()
        }
      }
      // Set us up for next time
      setTimeout('top.glbDict.uwTimerManager.processTimers()',500)
    }
  } // TimerManager
  top.glbDict.uwTimerManager = new TimerManager()
  setTimeout('top.glbDict.uwTimerManager.processTimers()',800)

  sendCustomEvent = function( evName , evData ) {
    // Make an object that looks enough like a widget to allow event posting
    var cObj = new Object()
    cObj.tagName = 'SPAN'
    cObj.getAttribute = function(something) { return true }
    cObj.id = '__CUSTOM__'
    top.glbDict.queueServerEvent( cObj , evName , '' , evData )
  }
  top.glbDict.sendCustomEvent = sendCustomEvent


  function popupManager() {
    var mySelf = this
    
    mySelf.screens = new Array
    mySelf.widgetStateStack = new Array()
    mySelf.popupSeq = 0

    mySelf.disableAll = function() {
      var insts = top.glbDict.uwWidgetFactory.getWidgetInsts()
      var oldState = new Object()
      for( var wid in insts ) {
        try {
          var inst = insts[wid]
          oldState[wid] = inst.isEnabled()
          inst.enable(0)
        }
        catch(e) {
          // OK , IE dies here somewhere in the loop.  This could be figured out I think.  Somehow,
          // one of the references to variables defined earlier in the routine goes stale.  Doesn't happen all
          // of the time, but when it does, it causes this loop to die, which means objects might get disabled, 
          // and have no way to be re-enabled.  So, that's why the try catch is here.  With the catch, we
          // hopefully don't try to disable an object unless we've pushed it's state, and the bottom 
          // line of this function gets executed no matter what.
          //alert(e.message)
        }
      }
      mySelf.widgetStateStack.push(oldState)
    }

    mySelf.undoDisable = function() {
      var oldState = mySelf.widgetStateStack.pop()
      if (oldState) {
        var insts = top.glbDict.uwWidgetFactory.getWidgetInsts()
        for ( var wid in oldState ) {
          var inst = insts[wid]
          if ( inst.span.ownerDocument ) { // Don't bother if it's been unloaded...
            inst.enable( oldState[wid] )
          }
        }
      }
    }

    mySelf.getNextSeq = function() {
      mySelf.popupSeq += 1
      return mySelf.popupSeq
    }

    mySelf.showPopup = function(url,width,height,posref,closebtn,title) {
      if ( posref != 'center' && posref != 'mouse' ) {
        var pw = top.glbDict.getWidgetInst(posref)
        var topdoc = pw.span.ownerDocument
      }
      else {
        var topdoc = top.document
      }
      if ( closebtn ) {
        var it = 20
      }
      else {
        var it = 0
      }
      var bs = 2 // border size
      if ( document.all && !(window.opera) ) { // IE
        var bo = bs * 2
      }
      if ( window.opera ) {
        var bo = bs  * 2
      }
      if ( ! document.all ) {
        var bo = 0
      }
      height += (bo + it)
      width += bo
      var ch = topdoc.body.clientHeight
      var cw = topdoc.body.clientWidth
      // Corrects really wierd Mozilla bug in child windows
      if ( (!document.all) && window.opener) {
        ch = topdoc.defaultView.innerHeight
        cw = topdoc.defaultView.innerWidth
      }

      if (posref == 'center' || posref == 'mouse') {
        if (posref == 'center') {
          var pl = (cw - width) / 2
          var pt = (ch - height) / 2
        }
        else {
          var pt = top.glbDict.lastMouse.clientY + 10
          var pl = top.glbDict.lastMouse.clientX + 10
          if (pt + height > topdoc.body.clientHeight ) pt -= height
          if (pl + width >  topdoc.body.clientWidth ) pl -= width
        }
      }
      else {
        var pl = parseInt(pw.span.style.left)
        var pt = parseInt(pw.span.style.top)

        // Ignore width and match to the control, if width is 0
        if (width <= bo ) {
          width = parseInt(pw.span.childNodes[0].style.width)
        }

        // Prefer to render upward from the given position
        if ( pt - height > 0 ) {
          pt -= height
        }
        else {
          pt = pt + parseInt(pw.span.childNodes[0].style.height)
        }
        // Render to left of position widget if we have to
        if ( pl + width > cw ) {
          pl -= width
        }
        if ( pt + height > ch ) {
          pt = Math.max(pt - ((pt + height) - ch),0)
        }
        if ( pt == 0 ) {
          height = Math.min(ch,height)
        }
      }
      var nn = topdoc.createElement('DIV')

      if (!it) {
        top.glbDict.addEvent(nn,'click',mySelf.hidePopup,[])
      }
      else {
        top.glbDict.addEvent(nn,'click',mySelf.stopEvent,[])
      }
      topdoc.body.appendChild(nn)

      if (it) {
        woff = 20 + bo
        var clstr = '<BUTTON style="background-color:lightGray;position:absolute;top:0px;left:' + (width - woff) + 'px;height:20px;width:20px;padding:0px;cursor:pointer;margin:0px;border:inset black 1px;text-align:center;font-family:arial;font-weight:700;font-size:16">X</BUTTON>'
        var titlestr = '<DIV style="text-indent:5px;text-align:left;color:white;font-weight:700;font-size:16;font-family:arial">' + title + '</DIV>'
      }
      else {
        var titlestr = ''
        var clstr = ''
      }

      var ifrSeq = mySelf.getNextSeq()
      var ifrName = "popup" + ifrSeq

      var ifr = ""
      ifr += '<DIV style="visibility:hidden;background-color:blue;position:absolute;top:' + pt + 'px;left:' + pl + 'px;height:' + height + 'px;width:' + width + 'px;border:solid black ' + bs + 'px"> '
      ifr += titlestr
      ifr += clstr
      ifr += '<IFRAME name="' + ifrName +'" id="' + ifrName + '" style="background-color:gray;position:absolute;top:' + it + 'px;left:0px;width:' + (width - bo) + 'px;height:' + (height - bo - it) + 'px;border:none;margin:0px;padding:0px" src = "' + url + '"></IFRAME></DIV>'

      top.glbDict.innerHTML(nn,ifr)
      nn.style.zIndex = 10

      if (it) {
        var btn = nn.getElementsByTagName('BUTTON')[0]
        top.glbDict.addEvent(btn,'click',mySelf.hidePopup,[])
      }

      mySelf.screens[ mySelf.screens.length ] = [ nn , url , ifrSeq ] // PUSH

      //if (window.opera) { // Opera needs IFRAMES hidden, except for this, because it makes their zIndex highest
      //  top.glbDict.hideIFrames( top.document , 1 , [ nn.getElementsByTagName('IFRAME')[0] ] )
      //}

      mySelf.disableAll()


      if (it) {
        nn.childNodes[0].positionedObject = true

        getResizer = function(node,bo,it,woff) { 
          var outer_div = node
          var border_offset = bo
          var iframe_top = it
          var button_offset = woff
          var rf = function() {
            var titleDiv = outer_div.getElementsByTagName('div')[0]
            var button = outer_div.getElementsByTagName('button')[0]
            var iframe = outer_div.getElementsByTagName('iframe')[0]
            button.style.left = parseInt(outer_div.style.width) - button_offset + 'px'
            button.style.width = '20px'
            button.style.height = '20px'
            iframe.style.width = parseInt(outer_div.style.width) - border_offset + 'px'
            iframe.style.height = parseInt(outer_div.style.height) - border_offset - iframe_top + 'px'
          }
          return rf
        }
        resizer = getResizer(nn.childNodes[0],bo,it,woff)

        nn.childNodes[0].resizer = resizer

        // This is necessary just to confirm we have initialized the layout manager
        var iflm = top.glbDict.getIFrameLayoutController()
      }

      // Do a nice fade
      nn.childNodes[0].style.visibility = 'visible'
      var ed = top.glbDict.asyncEffectManager.newEffectDef('fadetransparent',nn.childNodes[0])
      ed.fromval = 0 
      ed.toval = 100
      ed.increment = 20 
      ed.interval = 30
      //top.glbDict.asyncEffectManager.runEffect(ed)

    }

    mySelf.stopEvent = function(evt) {
      if (window.event) {
        window.event.cancelBubble = true
      } else {
        if (evt && evt.stopPropogation) {
          evt.stopPropogation()
        }
      }
      return false
    }

    mySelf.hidePopup = function(evt) {
      if (mySelf.screens.length > 0 ) {
        var ref = mySelf.screens.length - 1
        var scrn = mySelf.screens[ref]
        var modalDiv = scrn[0]
        var url = scrn[1]
        var ifrSeq = scrn[2]

        iframe = modalDiv.getElementsByTagName('iframe')[0]
        iframe.contentWindow.document.write('')
        top.glbDict.removeChild(modalDiv)

        top.glbDict.serverpost( null , 'windowClose' , '' , url )

        mySelf.screens = mySelf.screens.slice(0, mySelf.screens.length - 1 ) // POP

        
        if (window.opera) {
          top.glbDict.hideIFrames( top.document , 0 )
        }

        mySelf.undoDisable()
      }
    }

    return mySelf
  }
  top.glbDict.uwPopupManager = new popupManager()

  // Internal Frame Layout Controller
  function IFrameLayoutController (contentRegion) {

    // Allow unambiguous reference to created instances
    var mySelf = this
    mySelf.editObject = null
    mySelf.prevObject = null
    mySelf.contentRegion = contentRegion

    // Instance state
    mySelf.windowSize = null
    mySelf.ctrlDown = false
    mySelf.shiftDown = false
    mySelf.selectedObjArray = new Array() /* Selected Object for 'Property Edit' */
    mySelf.objChangeDict = new Object()
    mySelf.keystrokes = []

    // Retreives object identifier and detects reference to 'document' object
    mySelf.getObjId = function (obj) {
      if(obj.getAttribute) {
        id = obj.getAttribute('id')
      }
      else {
        id = "{document}"
      }
      return id
    }

    // Keyboard handling via UWT global handlers
    mySelf.keyup = function() {
      var parms = arguments[0][1]
      var obj = parms[0]
      var keyc = parms[1]
      if ( mySelf.keystrokes.length > 0 ) {
        var lastkey = mySelf.keystrokes[ mySelf.keystrokes.length - 1 ]
        delete mySelf.keystrokes[ mySelf.keystrokes.length - 1 ]
        if ( lastkey == 'f' ) {
          mySelf.ctrlDown = false
        }
        if ( lastkey == 'a' ) {
          mySelf.shiftDown = false
        }
      }
    }

    mySelf.keypress = function() {
      var parms = arguments[0][1]
      var obj = parms[0]
      var keyc = String.fromCharCode(parms[1])
      mySelf.keystrokes[ mySelf.keystrokes.length ] = keyc

      if ( keyc == 'f' ) {
        mySelf.ctrlDown = true
      }
      if ( keyc == 'a' ) {
        mySelf.shiftDown = true
      }
    }
    top.glbDict.uwEventController.addListener( 'keyup' , mySelf.keyup )
    top.glbDict.uwEventController.addListener( 'keypress' , mySelf.keypress )

    // Mouseover handler
    mySelf.setMouseOver = function (obj) {
      // In case we want to do something with a mouseover
      mySelf.mouseDownXY = mySelf.setMouseInBounds(obj, evt.clientX , evt.clientY )
      mySelf.lastMouseObj = obj
      //
    }

    // Mouseout handler
    mySelf.setMouseOut = function (obj) {
      // In case we want to do something with a mouseout
    }

    mySelf.getParentSize = function (obj,xy) {
      if (obj.tagName == 'SPAN') {
        if (xy == 0) return parseInt(obj.parentNode.style.width) 
        else return parseInt(obj.parentNode.style.height)
      }
      else {
        if (xy == 0) {
          return mySelf.getWindowSize()[0]
        }
        else return mySelf.getWindowSize()[1]
      }
    }

    // Bounds checker for returned mouse coordinates
    mySelf.setMouseInBounds = function (obj,x,y) {
      var adj = mySelf.adjustXY(x,y)
      x = adj[0]
      y = adj[1]
      return [ Math.min(Math.max(x,0), mySelf.getParentSize(obj,0) ) , Math.min(Math.max(y,0), mySelf.getParentSize(obj,1) ) ]
    }

    mySelf.adjustXY = function(x,y) {
      // This is to adjust offset of x,y if IFrame container is offset from document
      return [ x , y ]
    }

    // Mouse movement handler
    mySelf.postMouseMove = function (obj,evt) {
      if (! mySelf.targetObj ) { return }

      if ( obj != mySelf.lastMouseObj ) {
        mySelf.lastMouseObj = obj
        mySelf.mouseDownXY = mySelf.setMouseInBounds(obj, evt.clientX , evt.clientY )
        return
      }

      var obj = mySelf.targetObj
      var adj = mySelf.adjustXY(evt.clientX,evt.clientY)
      var adjX = adj[0]
      var adjY = adj[1]
      var bounds = mySelf.setMouseInBounds(obj,evt.clientX, evt.clientY)

      if (obj != mySelf.contentRegion) {
        //obj.ownerDocument.getElementById('xpos').value = parseInt(obj.style.left)
        //obj.ownerDocument.getElementById('ypos').value = parseInt(obj.style.top)
        //obj.ownerDocument.getElementById('hgt').value = parseInt(obj.childNodes[0].style.height)
        //obj.ownerDocument.getElementById('wid').value = parseInt(obj.childNodes[0].style.width)
        //obj.ownerDocument.getElementById('obj_id').value = obj.getAttribute('name')
      }
      else {
        //obj.ownerDocument.getElementById('xpos').value = adjX
        //obj.ownerDocument.getElementById('ypos').value = adjY
        //obj.ownerDocument.getElementById('hgt').value = parseInt(obj.style.height)
        //obj.ownerDocument.getElementById('wid').value = parseInt(obj.style.width)
        //obj.ownerDocument.getElementById('obj_id').value = ''
      }

      // If actual mouse event is outside of bounds, force release the mouse button
      if(bounds[0] != adjX || bounds[1] != adjY) {
        mySelf.setMouseUp(obj,evt)
      }

      // Detects last mouse movement state as reference point for offset in 
      // move and stretch operations
      if (mySelf.mouseDownXY) {
        // Do Stretch if control key is down
        if (mySelf.ctrlDown == true) {
          for (var c = 0; c < mySelf.selectedObjArray.length; c++ ) {
            mySelf.doObjectSize(mySelf.selectedObjArray[c][1],adjX,adjY)
          }
        }
        // Or move if it isn't
        else {
          for (var c = 0; c < mySelf.selectedObjArray.length; c++ ) {
            mySelf.doObjectMove(mySelf.selectedObjArray[c][1],adjX,adjY)
          }
        }

        // Set mousedown position to new position for next go-round
        mySelf.mouseDownXY = mySelf.setMouseInBounds(obj, evt.clientX , evt.clientY )
      }


    }

    // Routine to move objects with mouse move
    mySelf.doObjectMove = function  (obj,x,y) {
      mySelf.moving = true
      tgt = obj

      var newLeft, newTop
      newLeft = parseInt(tgt.style.left) + ( x - mySelf.mouseDownXY[0] ) 
      if (newLeft + tgt.clientWidth + 4 + 1 > mySelf.getParentSize(obj,0) ) {
        newLeft = mySelf.getParentSize(obj,0) - tgt.clientWidth - (4 + 1 )
      }
      newTop =  parseInt(tgt.style.top) + ( y - mySelf.mouseDownXY[1] ) 
      if (newTop + tgt.clientHeight + 4 > mySelf.getParentSize(obj,1)) {
        newTop = mySelf.getParentSize(obj,1) - tgt.clientHeight - (4 + 1 )
      }

      tgt.style.left = Math.max(newLeft,0) + "px"
      tgt.style.top = Math.max(newTop,0) + "px"

      mySelf.objChangeDict[obj.getAttribute('id')] = obj
      mySelf.moving = false
    }

    // Routine to re-size objects with mouse move
    mySelf.doObjectSize = function (obj,x,y) {
      tgt = obj
      var sx = ''
      var sy = ''

      var sel_adj = 4 + 1 // offset for selection (border of 4) + 1 to keep in bounds

      var t,l,b,r,pct,w,h,dx,dy
      w = tgt.clientWidth
      h = tgt.clientHeight
      t = parseInt(tgt.style.top)
      l = parseInt(tgt.style.left)
      b = parseInt(tgt.style.top) + h
      r = parseInt(tgt.style.left) + w
      pct = .30
      dx = ( x - mySelf.mouseDownXY[0] )  
      dy = ( y - mySelf.mouseDownXY[1] )  
      minX = 5 
      minY = 5 

      /* Check for left stretch */
      if( x - l < (pct * w) ) {
        sx = 'Left'
      }
      /* Check for right stretch */
      if ( r - x < (pct * w) ) {
        sx = 'Right'
      }
      /* Check for top stretch */
      if( y - t < (pct * h) ) {
        sy = 'Top'
      }
      /* Check for bottom stretch */
      if ( b - y < (pct * h) ) {
        sy = 'Bottom'
      }
      c = tgt
      switch(sx) {
        case 'Left':
          if (dx + l < 0) {
            dx = 0
          }
          c.style.width = Math.max(parseInt(c.style.width) - dx,minX) + "px"
          if(parseInt(c.style.width) != minX) {
            tgt.style.left = parseInt(tgt.style.left) + dx + "px"
          }
          break
        case 'Right':
          if (dx + l + parseInt(c.style.width) + sel_adj > mySelf.getParentSize(obj,0)) {
            dx = mySelf.getParentSize(obj,0) - (l + parseInt(c.style.width)) - sel_adj
          }
          c.style.width = Math.max(parseInt(c.style.width) + dx,minX) + "px"
          break
      }
      switch(sy) {
        case 'Top':
          if (dy + t < 0) {
            dy = 0
          }
          c.style.height = Math.max(parseInt(c.style.height) - dy,minY) + "px"
          if(parseInt(c.style.height) != minY) {
            tgt.style.top = parseInt(tgt.style.top) + dy + "px"
          }
          break
        case 'Bottom':
          if (dy + t + parseInt(c.style.height) + sel_adj > mySelf.getParentSize(obj,1)) {
            dy = mySelf.getParentSize(obj,1) - (t + parseInt(c.style.height)) - sel_adj
          }
          c.style.height = Math.max(parseInt(c.style.height) + dy,minY) + "px"
          break
      }

      if ( obj.resizer ) {
        obj.resizer()
      }

      mySelf.objChangeDict[obj.getAttribute('id')] = obj
    }

    // Helper function to remove a selected object.  Returns 0 if
    // object was not selected, or 1 if object was selected and 
    // therefore removed.
    mySelf.removeselectedObjArray = function (obj) {
      // Check to see if this object is already in the list of selected objects.
      // If so, remove it now
      var ta = new Array()
      var didIt = 0
      for (var c = 0; c < mySelf.selectedObjArray.length; c++) {
        if ( mySelf.selectedObjArray[c][1] == obj ) {
          mySelf.setNormalVisual(c)
          didIt = 1
        }
        else {
          ta[ta.length] = mySelf.selectedObjArray[c]
        }
      }
      mySelf.selectedObjArray = ta

      if (didIt) {
        mySelf.postSelections()
      }

      return didIt
    }

    // Sets the visual characteristics of a given object to the
    // 'selected' state.  Encapsulated so it can change easily
    mySelf.setSelectedVisual = function(obj) {
      var ostuff = null
      mySelf.selectedObjArray.push( [ ostuff , obj ] )
    }

    // Restores original visual characteristics of the object at the nth element
    // of the selected object array
    mySelf.setNormalVisual = function(n) {
     var ostuff = mySelf.selectedObjArray[n][0]
     var obj = mySelf.selectedObjArray[n][1]
    }

    // Helper function to add a selected object
    mySelf.addselectedObjArray = function (obj) {
      // If this object is already in the array, don't do anything , unless
      // the shift button is down, in which case, remove it from the array
      for (var c = 0; c < mySelf.selectedObjArray.length;c++) {
        if ( mySelf.selectedObjArray[c][1] == obj) {
          if (! mySelf.shiftDown) return

          mySelf.removeselectedObjArray(obj)
          return
        }
      }
      // Clear any old selection
      if (mySelf.selectedObjArray.length > 0 & (! mySelf.shiftDown)) {
        mySelf.clearselectedObjArray()
      }

      if (mySelf.removeselectedObjArray(obj)) {
        return
      }

      // Mark the visual of the object as selected
      mySelf.setSelectedVisual(obj)

      mySelf.postSelections()

    }

    mySelf.postSelections = function() {
      var ids = ''
      for ( c=0; c < mySelf.selectedObjArray.length; c++) {
        ids += mySelf.selectedObjArray[c][1].getAttribute('id')
        if (c < mySelf.selectedObjArray.length - 1) {
          ids += ','
        }
      }
      //top.glbDict.queueServerEvent(mySelf.layoutwidget,'object_select', false , ids )
    }

    mySelf.postObjectChanges = function() {
      return
      var out = '{'
      var didOne = 0
      for ( name in mySelf.objChangeDict ) {
        var obj = mySelf.objChangeDict[name]

        didOne = 1

        out += "'" + obj.getAttribute('id') + "': ("
        out += parseInt(obj.style.left) + ','
        out += parseInt(obj.style.top) + ','
        out += parseInt(obj.childNodes[0].style.width) + 4 + ',' // adjust by selected border width
        out += parseInt(obj.childNodes[0].style.height) + 4 + ',' // adjust by selected border height
        out += "),"
      }
      out += '}'
      mySelf.objChangeDict = new Object()


      if (didOne) {
        //top.glbDict.queueServerEvent(mySelf.layoutwidget,'object_change', false , out )
      }
    }

    mySelf.initDesigner = function (obj) {
      if (obj == mySelf.contentRegion) {
        mySelf.editObject = obj
        mySelf.prevObject = obj
      }

      // Don't do anything if the object doesn't have a 
      // designer interface.
      if (! obj.designerInterface) {
        return
      }

      mySelf.editObject = obj
      mySelf.prevObject = obj

    }

    // Helper function to clear selected objects
    mySelf.clearselectedObjArray = function () {
      // If we have a selected object, return it's border style to
      // previously saved style, and remove it from selected state
      for (var c = 0; c < mySelf.selectedObjArray.length; c ++ ) {
        mySelf.setNormalVisual(c)
      }
      mySelf.selectedObjArray = new Array()

      mySelf.postSelections()
    }

    // Mouse down handler
    mySelf.setMouseDown = function (obj,evt) {
      if( obj.positionedObject) {
        // Change mouse down state
        mySelf.mouseDownXY = mySelf.setMouseInBounds(obj, evt.clientX , evt.clientY )
        mySelf.targetObj = obj
        mySelf.lastMouseObj = obj

        obj.getElementsByTagName('iframe')[0].style.visibility = 'hidden'
        obj.style.opacity = .3
        obj.style.filter = 'alpha(opacity=30)'

        // Change selected object state
        mySelf.addselectedObjArray(obj)
      }
      else {
        // Clear selected object state
        mySelf.clearselectedObjArray()
      }
    }

    // Mouse up handler
    mySelf.setMouseUp = function (obj,evt) {
      if (obj !== mySelf.prevObject) {
        // Initialize the designer for the selected object
        if (mySelf.selectedObjArray.length > 0) {
          mySelf.initDesigner(mySelf.selectedObjArray[0][1])
        }
      }
      mySelf.mouseDownXY = null
      mySelf.lastMouseObj = null
      mySelf.targetObj = null

      for ( var c = 0 ; c < mySelf.selectedObjArray.length; c++ ) {
        var co = mySelf.selectedObjArray[c][1]
        co.getElementsByTagName('iframe')[0].style.visibility = 'visible'
        co.style.opacity = 1
        co.style.filter = 'alpha(opacity=100)'
      }

      mySelf.postObjectChanges()
    }

    // Window size used for bounds checking
    mySelf.setWindowSize = function (win) {
      // Initialize height and width
      mySelf.windowSizeObject = win
    }

    // Helper method to get window size
    mySelf.getWindowSize = function () {
      var win = mySelf.windowSizeObject
      return [ win.clientWidth , win.clientHeight ]
    }



    mySelf.globalMouseHandler = function() {
      if ( mySelf.moving ) { return }
      if ( top.glbDict.lastMouse ) {
        var lm = top.glbDict.lastMouse
        var obj = lm.target

        var x = lm.clientX
        var y = lm.clientY
        var t_obj = obj
        while ( t_obj && ( t_obj.nodeType != DOCUMENT_NODE ) ) {
          if ( t_obj.clientLeft ) { 
            x += parseInt(t_obj.clientLeft)
          }
          if ( t_obj.clientTop ) { 
            y += parseInt(t_obj.clientTop)
          }
          t_obj = t_obj.parentNode
        }
        var sim_evt = Object()
        sim_evt.clientX = x
        sim_evt.clientY = y

        if ( lm.eType == 'mousemove' ) {
          mySelf.postMouseMove( obj , sim_evt )
        }

        if ( lm.eType == 'mousedown' ) {
          mySelf.setMouseDown( obj , sim_evt )
        }

        if ( lm.eType == 'mouseup' ) {
          mySelf.setMouseUp( obj , sim_evt )
        }

      }
    }

    // Register to receive global mouse events
    top.glbDict.uwEventController.addListener('mouse_change', mySelf.globalMouseHandler )



    // 'Constructor' returns an explicit reference to the created instance
    return mySelf

  } // IFrameLayoutController


  top.glbDict.getIFrameLayoutController = function() {
    if ( ! top.glbDict.iFrameLayoutController ) {
      var iflc = new IFrameLayoutController(top.document.body)
      iflc.setWindowSize(top.document.body)
      top.glbDict.iFrameLayoutController = iflc
    }
    return top.glbDict.iFrameLayoutController
  }


  // Window Manager Object
  function WindowManager() {
    var mySelf = this
    mySelf.managedWindows = new Object()
    mySelf.modalId = null
    
    // Determines if a window object is still valid, on both Mozilla and IE
    mySelf.isValidWindow = function(win) {
        if (!win) return false
        try {
          var x = win.document.location
        }
        catch(e) {
          return false
        }
        return true
    }

    // Creates a new window
    mySelf.newWindow = function(url,local,modal,newId,features) {
      var mkNew = 0
      if ( newId in mySelf.managedWindows ) {
        var sw = mySelf.managedWindows[newId]
        if (mySelf.isValidWindow(sw.win)) {
          sw.win.focus()
          return true
        }
        else {
          mkNew = 1
        }
      }
      else {
        mkNew = 1
      }

      if (mkNew) {
        if (modal) {
          if (!document.all) { //Firefox/Mozilla
            features += ',alwaysRaised=yes'
          }
        }
        var sw = new Object()
        sw.win = window.open(url,newId,features)
        sw.local = local
        sw.modal = modal
        sw.url = url
        mySelf.managedWindows[newId] = sw

        
        if (sw.modal) {
          mySelf.modalId = newId
          var nn = document.createElement('DIV')
          nn.style.position = 'absolute'
          nn.style.top = '0px'
          nn.style.left = '0px'
          nn.style.height = '100%'
          nn.style.width = '100%'
          nn.style.zIndex = '10'
          if (!document.all) {
            nn.style.backgroundColor = 'transparent'
          }
          nn.style.textAlign = 'center'
          top.glbDict.addEvent(nn,'click',mySelf.popModal,[])
          //nn.innerHTML = '<H1>MODAL DIALOG DISPLAYED</H1><BR><B>Close Dialog to Continue</B>'
          top.document.body.appendChild(nn)
          mySelf.modalDiv = nn
        }
      }
    }

    mySelf.popModal = function() {
      if (mySelf.modalId) {
        mySelf.getWindow(mySelf.modalId).win.focus()
      }
    }

    mySelf.redirect = function(loc) {
      top.location.href = loc
    }

    // Returns a window object given an ID, or null if
    // not present
    mySelf.getWindow = function(id) {
      if (id in mySelf.managedWindows) {
        return mySelf.managedWindows[id]
      }
      return null
    }

    mySelf.navWindow = function(id,loc) {
      var sw = mySelf.getWindow(id)
      sw.win.location.href = loc
    }

    mySelf.closeWindow = function(name) {
      var sw = mySelf.getWindow(name)
      if (sw && sw.win) {
        try {
          sw.win.close()
        }
        catch(e) {
          // do nothing
        }
      }
      delete mySelf.managedWindows[name]
    }

    mySelf.windowChecker = function() {
      for (id in mySelf.managedWindows) {
        var sw = mySelf.getWindow(id)
        if (sw && sw.local && (!mySelf.isValidWindow(sw.win))) {
          top.glbDict.queueServerEvent( null , 'windowClose' , id , sw.url )
          delete mySelf.managedWindows[id]
          if (mySelf.modalId == id) {
             document.body.removeChild(mySelf.modalDiv)
             mySelf.modalId = null
             window.focus()
          }
        }
      }
      setTimeout('top.glbDict.uwWindowManager.windowChecker()',500)
    }

  }
  top.glbDict.uwWindowManager = new WindowManager()

  function EffectDefinition(effect_type,node,sequence,manager) {
    var mySelf = this
    mySelf.effect_type = effect_type
    mySelf.node = node
    mySelf.interval = 30
    mySelf.sequence = sequence
    mySelf.cancelled = 0
    mySelf.processor = null
    mySelf.manager = manager
    mySelf.value = null
    mySelf.started = 0

    mySelf.setProcessor = function(proc) {
      mySelf.processor = proc
    }

    mySelf.setValue = function(val) {
      mySelf.value = val
    }

    mySelf.getValue = function() {
      return mySelf.value
    }

    mySelf.getType = function() {
      return mySelf.effect_type
    }

    mySelf.run = function() {
      mySelf.next()
    }

    mySelf.next = function() {

      if ( mySelf.cancelled ) {
        mySelf.processor.finalize(mySelf)
        mySelf.manager.removeEDInstance(mySelf)
        return
      }

      mySelf.processor.next(mySelf)

      setTimeout("top.glbDict.asyncEffectManager.getEDInstance(" + mySelf.sequence + ").next()" , mySelf.interval )
    }

    mySelf.cancel = function() {
      mySelf.cancelled = 1
    }
  }

  function BaseEffectProcessor(inst) {
    if (inst) {
      var mySelf = inst
    }
    else {
      var mySelf = this
    }

    mySelf.initialize = function(effect_def) {
    }

    mySelf.more = function(effect_def) { return 1 }

    mySelf.process = function(effect_def) {  
    }

    mySelf.next = function(effect_def) {
      if ( ! effect_def.started ) {
        mySelf.initialize(effect_def)
        effect_def.started = 1
      }


      if ( ! ( mySelf.more(effect_def) ) ) {
        effect_def.cancel()
        return
      }

      mySelf.process(effect_def)
    }
  }

  function BackgroundCrossFader() {
    var mySelf = this
    BaseEffectProcessor(mySelf)

    mySelf.initialize = function(effect_def) {
      effect_def.setValue(effect_def.fromval)

      // Calculate one-iteration-factors for R,G,B
      var fromval = effect_def.fromval
      var toval = effect_def.toval
      var oifs = new Array()
      for (var c = 0; c < 3; c++) {
        oifs.push( (toval[c] - fromval[c]) / effect_def.increments )
      }
      effect_def._oifs = oifs

      mySelf.setBackground( effect_def.node, effect_def.fromval )
    }

    mySelf.setBackground = function(node,val) {
      try {
        var valstr = 'rgb(' + val[0] + ',' + val[1] + ',' + val[2] + ')'
        node.style.backgroundColor = valstr
      }
      catch(e) {
        if (! mySelf.alerted ) {
          mySelf.alerted = 1
        }
      }
    }

    mySelf.more = function(effect_def) {
      var fromval = effect_def.fromval
      var toval = effect_def.toval
      for ( var c = 0; c < 3; c ++ ) {
        if ( fromval[c] != toval[c] ) {
          return true
        }
      }
      return false
    }

    mySelf.process = function(effect_def) {
      var fromVals = effect_def.getValue()
      mySelf.setBackground( effect_def.node, fromVals )

      var toVals = effect_def.toval
      var newVals = new Array()
      var increments = effect_def._oifs

      for (var c = 0; c < 3 ; c ++) {
        var f = fromVals[c]
        var t = toVals[c]
        var inc = increments[c]
        if ( t > f ) {
          newVals.push( Math.min( t , f + Math.max(inc,1) ) )
        }
        else {
          newVals.push( Math.max( t , f + Math.min(inc,-1) ) )
        }
      }

      effect_def.setValue( newVals )
    }

    mySelf.finalize = function(effect_def) {
      mySelf.setBackground( effect_def.toval )
    }
  }

  function FadeTransparentProcessor() {
    var mySelf = this
    BaseEffectProcessor(mySelf)

    mySelf.initialize = function(effect_def) {
      effect_def.setValue(effect_def.fromval)
      mySelf.setOpacity( effect_def.node, effect_def.fromval )
      effect_def.node.style.visibility = 'visible'

      if ( effect_def.fromval < effect_def.toval ) {
        effect_def.direction = 1
      }
      else {
        effect_def.direction = 0
      }

    }

    mySelf.setOpacity = function(node,val) {
      if ( document.all && ! (window.opera) ) {
        node.style.filter = 'alpha(opacity=' + val + ')'

        return
      }
      node.style.opacity = parseFloat(val/100)
    }

    mySelf.more = function(effect_def) {
      if ( effect_def.direction == 1 ) {
        return ( effect_def.getValue() < effect_def.toval ) 
      }
      return ( effect_def.getValue() > effect_def.toval ) 
    }

    mySelf.process = function(effect_def) {
      mySelf.setOpacity( effect_def.node, effect_def.getValue() )
      effect_def.setValue( effect_def.getValue() + effect_def.increment )
    }

    mySelf.finalize = function(effect_def) {
      mySelf.setOpacity(effect_def.node,100)
      effect_def.node.style.filter = null
      if ( effect_def.node.style.opacity ) { 
        effect_def.node.style.opacity = null
        effect_def.node.style.MozOpacity = null
      }

      if ( effect_def.toval > 0 ) {
        effect_def.node.style.visibility = 'visible'
      }
      else {
        effect_def.node.style.visibility = 'hidden'
      }
    }
  }

  function AsyncEffectManager() {
    var mySelf = this
    mySelf.effectProcessorsByType = new Object()
    mySelf.effectsById = new Object()
    mySelf.idsByNode = new Object()
    mySelf.eff_seq = 0

    mySelf.getNextEffectSeq = function() {
      mySelf.eff_seq += 1
      return mySelf.eff_seq
    }

    mySelf.registerProcessor = function(effect_type,proc_run_func) {
      mySelf.effectProcessorsByType[effect_type] = proc_run_func
    }

    mySelf.newEffectDef = function(effect_type,node) {
      var seq = mySelf.getNextEffectSeq()
      return new EffectDefinition(effect_type,node,seq,mySelf)
    }
    
    mySelf.runEffect = function(effectDef) {
      mySelf.effectsById[ effectDef.sequence ] = effectDef

      if ( effectDef.node in mySelf.idsByNode ) {
        for ( var id in mySelf.idsByNode[effectDef.node] ) {
          var oldDef = mySelf.idsByNode[effectDef.node][id]
          oldDef.cancel()
        }
      }

      if (! ( effectDef.node in mySelf.idsByNode )) {
        mySelf.idsByNode[ effectDef.node ] = new Object()
      }
      mySelf.idsByNode[ effectDef.node ][ effectDef.sequence ] = effectDef

      var proc = mySelf.effectProcessorsByType[ effectDef.getType() ]

      effectDef.setProcessor(proc)
      effectDef.run()
    }

    mySelf.getEDInstance = function(seq) {
      return mySelf.effectsById[seq]
    }

    mySelf.removeEDInstance = function(effectDef) {
      if ( effectDef.sequence in mySelf.effectsById ) {
        delete mySelf.effectsById[ effectDef ]
      }
      if ( effectDef.node in mySelf.idsByNode ) {
        var ids = mySelf.idsByNode[ effectDef.node ]
        if ( effectDef.sequence in ids ) {
          delete ids[ effectDef.sequence ]
        }
      }

    }

  }

  top.glbDict.asyncEffectManager = new AsyncEffectManager()
  top.glbDict.asyncEffectManager.registerProcessor('fadetransparent', new FadeTransparentProcessor() )
  top.glbDict.asyncEffectManager.registerProcessor('fadebackground', new BackgroundCrossFader() )



  top.glbDict.close = function() {
    // Mozilla won't close inside a post event loop unless this is asynchronous
    setTimeout('top.close()',1)
  }

  setTimeout('top.glbDict.uwWindowManager.windowChecker()',500)

  // Next stanza detects if this window is a chaild window of another 
  // UWT window.  If so, it monitors for death of the parent window, and
  // closes this window as well (cross-platform dependent window functionality)
  top.glbDict.parentWindowMonitor = function() {
    try {
      var x = window.opener.document.location // This will fail if the parent window closed
      setTimeout('top.glbDict.parentWindowMonitor()',500)
    }
    catch(e) {
      window.close()
    }
  }
  if (window.opener) {
    try {
      var x = window.opener.document.location // This will fail if another server opened us
      setTimeout('top.glbDict.parentWindowMonitor()',500)
    }
    catch(e) {
    }
  }

  // Primary content rendering function.  This needs to produce well-formed XML,
  // even if the browser ignores it.  
  // TODO:  Make cross-platform.  Current implementation is surely IE specific.
  function walk_level(domnode,depth) {
    // Render opening tag and attributes
    var out = ''


    if (domnode.nodeType == 3) {
      return encodeURIComponent(domnode.nodeValue)
    }

    if (domnode.nodeName.indexOf('/') > -1) {
      return ''
    }

    /*
     * Checkboxes don't work right.  Hack in place here
     */
    if (domnode.tagName == 'INPUT' && ( domnode.getAttribute('type') == 'checkbox' || domnode.getAttribute('type') == 'radio')  ) {
      domnode.setAttribute('checkValue', domnode.checked )
    }

    out += '<' + domnode.tagName 
    var didStyle = 0
    var attrDict = new Object()
    for (var a = 0; a < domnode.attributes.length; a++ ) {
      var attr = domnode.attributes[a]
      var attrname = attr.name.toLowerCase()
      if (attrname == 'style' && !window.opera) continue // Mozilla's style is an attribute, skip it
      if (attrname in attrDict) continue
      attrDict[attrname] = attrname
      if ( (attr.expando || attr.value != 'null' )  && attr.value != '' && attr.value.indexOf('[') < 0) {

        // Even if these attributes are false, IE assumes they are true at
        // the mere existence of them
        if (attrname == 'disabled' && attr.value == 'false') continue
        if (attrname == 'readOnly' && attr.value == 'false') continue
        if (attrname == 'style') didStyle = 1



        if (attrname == 'value' && domnode.tagName == 'INPUT' && domnode.getAttribute('type') == 'text'  ) {
          out += ' ' + attrname + '="' + encodeURIComponent(attr.value) + '" '
        }
        else {
          out += ' ' + attrname + '="' + attr.value + '" '
        }
      }
    }

    if (domnode.style && !didStyle) {
      out += ' style="' + domnode.style.cssText + '" '
      /*
      for (var css in domnode.style) {
        var x = css
        if (domnode.style[css]) {
          out += css + ':' + domnode.style[css] + ';'
          alert( css + ':' + domnode.style[css] )
        }
      }
      out += '"'
      */
    }
    out += '>'

    // Render Children
    for (var c = 0; c < domnode.childNodes.length; c++) {
      var chld = domnode.childNodes[c]
      out += walk_level(chld,depth + 1)
    }

    // Render closing tag
    out += '</' + domnode.tagName + '>'

    return out
  }
  top.glbDict.walk_level = walk_level

  function getEffectiveStyle(node,attr) {
    if (window.opera) {
      var x = getComputedStyle(node)[attr]
      return x
    }
    if (document.all && (!window.opera)) {
      return node.currentStyle[attr]
    }
    else { // Moz , Safari?
      return window.getComputedStyle(node,"")[attr]
    }
  }
  top.glbDict.getEffectiveStyle = getEffectiveStyle


  // Color list
  top.glbDict.colorRGB = [
    ['', ''],
    ['AliceBlue', '#F0F8FF'],
    ['AntiqueWhite', '#FAEBD7'],
    ['Aqua', '#00FFFF'],
    ['Aquamarine', '#7FFFD4'],
    ['Azure', '#F0FFFF'],
    ['Beige', '#F5F5DC'],
    ['Bisque', '#FFE4C4'],
    ['Black', '#000000'],
    ['BlanchedAlmond', '#FFEBCD'],
    ['Blue', '#0000FF'],
    ['BlueViolet', '#8A2BE2'],
    ['Brown', '#A52A2A'],
    ['BurlyWood', '#DEB887'],
    ['CadetBlue', '#5F9EA0'],
    ['Chartreuse', '#7FFF00'],
    ['Chocolate', '#D2691E'],
    ['Coral', '#FF7F50'],
    ['CornflowerBlue', '#6495ED'],
    ['Cornsilk', '#FFF8DC'],
    ['Crimson', '#DC143C'],
    ['Cyan', '#00FFFF'],
    ['DarkBlue', '#00008B'],
    ['DarkCyan', '#008B8B'],
    ['DarkGoldenRod', '#B8860B'],
    ['DarkGray', '#A9A9A9'],
    ['DarkGreen', '#006400'],
    ['DarkKhaki', '#BDB76B'],
    ['DarkMagenta', '#8B008B'],
    ['DarkOliveGreen', '#556B2F'],
    ['Darkorange', '#FF8C00'],
    ['DarkOrchid', '#9932CC'],
    ['DarkRed', '#8B0000'],
    ['DarkSalmon', '#E9967A'],
    ['DarkSeaGreen', '#8FBC8F'],
    ['DarkSlateBlue', '#483D8B'],
    ['DarkSlateGray', '#2F4F4F'],
    ['DarkTurquoise', '#00CED1'],
    ['DarkViolet', '#9400D3'],
    ['DeepPink', '#FF1493'],
    ['DeepSkyBlue', '#00BFFF'],
    ['DimGray', '#696969'],
    ['DodgerBlue', '#1E90FF'],
    ['Feldspar', '#D19275'],
    ['FireBrick', '#B22222'],
    ['FloralWhite', '#FFFAF0'],
    ['ForestGreen', '#228B22'],
    ['Fuchsia', '#FF00FF'],
    ['Gainsboro', '#DCDCDC'],
    ['GhostWhite', '#F8F8FF'],
    ['Gold', '#FFD700'],
    ['GoldenRod', '#DAA520'],
    ['Gray', '#808080'],
    ['Green', '#008000'],
    ['GreenYellow', '#ADFF2F'],
    ['HoneyDew', '#F0FFF0'],
    ['HotPink', '#FF69B4'],
    ['IndianRed', ' #CD5C5C'],
    ['Indigo', ' #4B0082'],
    ['Ivory', '#FFFFF0'],
    ['Khaki', '#F0E68C'],
    ['Lavender', '#E6E6FA'],
    ['LavenderBlush', '#FFF0F5'],
    ['LawnGreen', '#7CFC00'],
    ['LemonChiffon', '#FFFACD'],
    ['LightBlue', '#ADD8E6'],
    ['LightCoral', '#F08080'],
    ['LightCyan', '#E0FFFF'],
    ['LightGoldenRodYellow', '#FAFAD2'],
    ['LightGrey', '#D3D3D3'],
    ['LightGreen', '#90EE90'],
    ['LightPink', '#FFB6C1'],
    ['LightSalmon', '#FFA07A'],
    ['LightSeaGreen', '#20B2AA'],
    ['LightSkyBlue', '#87CEFA'],
    ['LightSlateBlue', '#8470FF'],
    ['LightSlateGray', '#778899'],
    ['LightSteelBlue', '#B0C4DE'],
    ['LightYellow', '#FFFFE0'],
    ['Lime', '#00FF00'],
    ['LimeGreen', '#32CD32'],
    ['Linen', '#FAF0E6'],
    ['Magenta', '#FF00FF'],
    ['Maroon', '#800000'],
    ['MediumAquaMarine', '#66CDAA'],
    ['MediumBlue', '#0000CD'],
    ['MediumOrchid', '#BA55D3'],
    ['MediumPurple', '#9370D8'],
    ['MediumSeaGreen', '#3CB371'],
    ['MediumSlateBlue', '#7B68EE'],
    ['MediumSpringGreen', '#00FA9A'],
    ['MediumTurquoise', '#48D1CC'],
    ['MediumVioletRed', '#C71585'],
    ['MidnightBlue', '#191970'],
    ['MintCream', '#F5FFFA'],
    ['MistyRose', '#FFE4E1'],
    ['Moccasin', '#FFE4B5'],
    ['NavajoWhite', '#FFDEAD'],
    ['Navy', '#000080'],
    ['OldLace', '#FDF5E6'],
    ['Olive', '#808000'],
    ['OliveDrab', '#6B8E23'],
    ['Orange', '#FFA500'],
    ['OrangeRed', '#FF4500'],
    ['Orchid', '#DA70D6'],
    ['PaleGoldenRod', '#EEE8AA'],
    ['PaleGreen', '#98FB98'],
    ['PaleTurquoise', '#AFEEEE'],
    ['PaleVioletRed', '#D87093'],
    ['PapayaWhip', '#FFEFD5'],
    ['PeachPuff', '#FFDAB9'],
    ['Peru', '#CD853F'],
    ['Pink', '#FFC0CB'],
    ['Plum', '#DDA0DD'],
    ['PowderBlue', '#B0E0E6'],
    ['Purple', '#800080'],
    ['Red', '#FF0000'],
    ['RosyBrown', '#BC8F8F'],
    ['RoyalBlue', '#4169E1'],
    ['SaddleBrown', '#8B4513'],
    ['Salmon', '#FA8072'],
    ['SandyBrown', '#F4A460'],
    ['SeaGreen', '#2E8B57'],
    ['SeaShell', '#FFF5EE'],
    ['Sienna', '#A0522D'],
    ['Silver', '#C0C0C0'],
    ['SkyBlue', '#87CEEB'],
    ['SlateBlue', '#6A5ACD'],
    ['SlateGray', '#708090'],
    ['Snow', '#FFFAFA'],
    ['SpringGreen', '#00FF7F'],
    ['SteelBlue', '#4682B4'],
    ['Tan', '#D2B48C'],
    ['Teal', '#008080'],
    ['Thistle', '#D8BFD8'],
    ['Tomato', '#FF6347'],
    ['Turquoise', '#40E0D0'],
    ['Violet', '#EE82EE'],
    ['VioletRed', '#D02090'],
    ['Wheat', '#F5DEB3'],
    ['White', '#FFFFFF'],
    ['WhiteSmoke', '#F5F5F5'],
    ['Yellow', '#FFFF00'],
    ['YellowGreen', '#9ACD32']
  ]

} // if isNew

