// Copyright © 2004-2008 BungeeLabs, Inc.  All rights reserved.
//  
// Use of this software is subject to the terms of the Bungee 
// Labs Developer License Agreement, the Bungee Labs Application 
// End User License Agreement, or an applicable source code 
// license available from Bungee Labs (http://www.bungeelabs.com).

//***********************************************************************
//***********************************************************************
//********                  bl_dragdrop.js                      *********
//***********************************************************************
//***********************************************************************

function bl_dd_cleanForDrag(el)
{
  try
  {
    if (!bl_port_isTextNode(el))
    {
      var curStyle = bl_port_getComputedStyle(el);
      
      if (curStyle.backgroundImage != "none")
      {
        el.style.backgroundImage  = "none";
        el.style.color            = "black";
      }
      
      var len = el.childNodes.length;
      
      for (var i = 0; i < len; i++)
      {
        bl_dd_cleanForDrag(el.childNodes[i]);
      }
    }
  }
  catch (exception)
  {
  }
}

function bl_dd_createDragShadow(ddObj, event)
{
  var topWin  = cb_sys_getTopWindow();    
  var doc     = topWin.document;
  var body    = doc.body;
  var srcContext = ddObj.srcContext;
  var html    = "<div style='position:absolute;z-index:10000;-webkit-user-select:none;'>" 
              + srcContext.computeShadow(event) 
              + "</div>";
  
  topWin.bl_port_insertAdjacentHTML(body, "beforeend", html);
  
  var shadow = body.lastChild;
  
  bl_dd_cleanForDrag(shadow);
  ddObj.shadow = shadow;
  bl_dd_moveDragShadow(ddObj, event);
  
  var opacity = srcContext.shadowOpacity;
  
  bl_port_set_opacity(shadow, ((opacity ? opacity:60)));
}

function bl_dd_moveDragShadow(ddObj, event)
{
  var topw    = cb_sys_getTopWindow();
  var shadow  = ddObj.shadow;
  var srcContext = ddObj.srcContext;
  var x       = event.screenX;
  var y       = event.screenY;
  
  if (srcContext.shadowPosition)
  {
    srcContext.shadowPosition(ddObj, shadow, x, y);
  }
  else
  {
    var cpStyle  = shadow.style;
    
    cpStyle.left = (x - bl_port_getScreenLeft(topw) + 10 + document.body.scrollLeft)+"px";
    cpStyle.top  = (y - bl_port_getScreenTop(topw) + 10 + document.body.scrollTop)+"px";
    
    var feedback = ddObj.feedbackItem;
    
    if (feedback)
    {
      with (feedback.style)
      {
        left = (x - bl_port_getScreenLeft(topw) - 2 + document.body.scrollLeft)+"px";
        top  = (y - bl_port_getScreenTop(topw) - feedback.offsetHeight - 10 -  document.body.scrollTop)+"px";
      }
    }
  }
}

function bl_dd_docDrag(event)
{
  var ddObj = bl_dd_getDragDropObj();
  var event = bl_dd_getEvent(ddObj, event);
  
  if (event && ddObj && ddObj.shadow)
  {
    bl_dd_moveDragShadow(ddObj, event)
  }
}

// TODO: for right now it is assumed that this function is allways
//       the toplevel window for the dialog we are in
//       NOTE:truth is we should not need to do this as the current window 
//       should have enough context to set the ddObj however untill 
//       we implement an appContext obj for windows this will not 
//       always true so when we do that we can change this.
function bl_dd_setDragDropObj(ddObj)
{
  var list     = window.bl_window_list;
  var oldDDObj = list.dragDropObj;

  if (oldDDObj)
  {
    with (oldDDObj)
    {
      delete zoneObj;
      delete dropZoneObj;
      delete srcContext;
      
      zoneObj       = null;
      win           = null;
      srcContext    = null;
      dropZoneObj   = null;
      currentTarget = null;
    }
      
    delete oldDDObj;
  }
  
  list.dragDropObj = ddObj;
}

function bl_dd_getDragDropObj()
{
  return cb_sys_getTopWindow().bl_window_list.dragDropObj;
}

function bl_dd_cleanUp()
{
  this.setHint(null);

  if (!this.cleaned && this.srcContext)
  {
    var srcContext  = this.srcContext;
    var item        = srcContext.item;
    var overEl      = this.currentOverEl;
    var overDragEnd = this.overDragEnd;
    var shadow      = this.shadow;

    if (overEl && overDragEnd)
    {
      overDragEnd(srcContext.source, overEl, this.inDrag);
    }

    this.shadow = null;
    
    try
    {
      if (shadow)
      {
        shadow.parentNode.removeChild(shadow);
      }
    } catch (ex) {}

    // detatchDetectEvents must be called before because it
    // will remove the mouse move and mouse up events of the source
    // element but not restore the old ones 
    // that is the job of detatchItemEvents
    this.detatchDetectEvents();
    this.detatchItemEvents();

    if (srcContext.dragEnd)
    {
      srcContext.dragEnd(srcContext.source, item, this.inDrag);
    }
    
    if (bl_browserInfo.firefox || bl_browserInfo.safari)
    {
      bl_dd_customCleanUp(this);
    }
    else
    {
    }
    
    this.inDrag = false;
    this.cleand = true;
    cb_sys_getTopWindow().bl_dd_setDragDropObj(null);
  }
}

function bl_dd_detatchDetectEvents()
{
  if (!this.detectEventDetatched)
  {
    var item = this.srcContext.item;
    var body = item.ownerDocument.body;
  
    // set the items handler to null fo now the
    // cleanup function will call to have them restored 
    // old valuesto there    
    item.onmouseup   = null;
    item.onmousemove = null;
    body.onmousemove = null;
    body.onmouseup   = null;
    this.detectEventDetatched = true;
  }
}

// for documentation on the args for this function please look at 
// bl_dd_detect.  
// NOTE: this function should not be called directly it is for bl_dd_detect's use
//       The args at this point are assumed to be valid
function bl_dd_createDDObj(event, srcContext)
{
  var zoneNameTxt = srcContext.zoneName;
  
  if (!zoneNameTxt)
  {
    zoneNameTxt = srcContext.source.getAttribute("bl_zone");
  }
  
  var zoneContext = bl_dd_createEffectObj(zoneNameTxt);
  var indexList   = srcContext.indexes;
  var item        = srcContext.item;
  var body        = item.ownerDocument.body;
  var ddObj       = { srcContext:srcContext,
                      zoneName:zoneNameTxt,
                      zoneObj:zoneContext,
                      editorId:(srcContext.did + "." + srcContext.source.id),
                      indexes:indexList.join(" "),
                      indexCount:indexList.length,
                      inDrag:false,
                      currentEffect:zoneContext.effect,
                      dropZoneObj:null,
                      oldBodyMouseMove:body.onmousemove,
                      oldBodyMouseUp:body.onmouseup,
                      oldMouseUp:item.onmouseup,
                      oldMouseMove:item.onmousemove,
                      sysKeyDown:item.onkeydown,
                      sysKeyUp:item.onkeyup,
                      startX:event.screenX,
                      startY:event.screenY,
                      kill:bl_dd_cleanUp,
                      clearEffect:bl_dd_clearEffect,
                      hintImage:null,
                      isTopLeft:false,
                      hintContext:null,
                      detatchItemEvents:bl_dd_detatchItemEvents,
                      detatchDetectEvents:bl_dd_detatchDetectEvents,
                      setFeedbackItem:bl_dd_setFeedbackItem,
                      setDragOverNotify:bl_dd_setDragOverNotify,
                      setHint:bl_dd_objSetHint,
                      regenHint:bl_dd_objRegenHint
                    };
  
  body.onmouseup   = bl_dd_end;
  body.onmousemove = bl_dd_detectDragMouseMove;
  item.onmouseup   = bl_dd_end;
  item.onmousemove = bl_dd_detectDragMouseMove;
  bl_dd_setDragDropObj(ddObj);
}

function bl_dd_end(event)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    ddObj.kill();
    bl_port_stop_event(event);
  }
}

function bl_dd_start(event)
{
  try
  {
    var ddObj = bl_dd_getDragDropObj();
    var event = bl_dd_getEvent(ddObj, event);

    if (ddObj && event)
    {
      var srcContext = ddObj.srcContext;
      var item       = srcContext.item;

      bl_dd_checkList(ddObj, event);

      if (event.dataTransfer)
      {
        event.dataTransfer.effectAllowed = ddObj.zoneObj.effect;
        event.returnValue = true;
      }
      
      if (srcContext.dragStart)
      {
        srcContext.dragStart(srcContext.source, srcContext.item);
      }
    }
  }
  catch (exception)
  {
    alert("DRAG EXCEPTION: " + exception.message);
  }
}

// this is the drag drop detect function control use to determin if there is 
// a valid context for a drag drop  (NOTE: ALL args are required for this function)
// Parameters: event: the event triggering the detect
//             srcContext  (required) - an object that gives context to the drag drop 
//                         (posible valus on this object are as follows)
//
//                         source             (required) - the source of drag operation, 
//                         item               (required) - the item that is the focus of the drag operation, 
//                         did                (required) - the id for the item's window, 
//                         indexes            (required) - array of indexes for drag
//                         computeShadow      (required) - function called to retrieve html to be 
//                                                         rendered for the drag operations shadow
//                                                         (args: event)
//
//                         zoneName           (optional) - indicates the zoneName to use if not defined then the 
//                                                         zone name is computed from the src 
//                         shadowOpacity      (optional) - custom oposity for shadow
//                         shadowPosition     (optional) - custom function for positioning the shadow
//                         shadowUpdate       (optional) - custom function for updating shadow relative to effect changes
//                         dragContext        (optional) - context string for the drag operation (for source controls use.)
//                         dragEnd            (optional) - function called when drag operation is done (args: source, item, dragStarted) 
//                         dragStart          (optional) - function called when drag operation starts (args: source, item) 
//                         detectNotify       (optional) - function called when drag operation is detected (args: source, item)
function bl_dd_detect(event, srcContext)
{
  try
  {
    if (event && srcContext && srcContext.source.getAttribute("bl_ddFrozen") == null)
    {
      bl_port_clear_selection();

      if (!bl_port_point_on_scrollbar(bl_port_getEventTarget(event), event.clientX, event.clientY))
      {
        cb_sys_getTopWindow().bl_dd_createDDObj(event, srcContext);
        return true;
      }
    }
  }
  catch (ex)
  {
  }
  
  return false;
}

function bl_dd_getEvent(ddObj, event)
{
  if (!event)
  {
    event = window.event;
  }
  
  if (!event && ddObj)
  {
  
    var srcContext = ddObj.srcContext;
    
    var itemWindow = bl_port_docWindow(srcContext.item.ownerDocument);

    if (itemWindow)
    {
      event = itemWindow.event;
    }
  }

  if (!event && ddObj)
  {
    ddObj.kill();
  }

  return event;
}

function bl_dd_detectDragMouseMove(event)
{
  var ddObj = bl_dd_getDragDropObj();
  var event = bl_dd_getEvent(ddObj, event);
  
  if (ddObj && event)
  {
    // Returning false here causes the detect element to be cleaned up.
    var screenX    = event.screenX;
    var screenY    = event.screenY;
    var startX     = ddObj.startX;
    var startY     = ddObj.startY;
    
    // allow for a 5 pixel boundry around the starting position
    if (!ddObj.inDrag && (screenX > startX + 5 || screenX < startX - 5 ||screenY > startY + 5 || screenY < startY - 5))
    {
      if (bl_port_isLeftDown(event))
      {
        ddObj.inDrag = true;
        
        var srcContext = ddObj.srcContext;
        var item       = srcContext.item;
        
        if (srcContext.detectNotify)
        {
          srcContext.detectNotify(srcContext.source, item);
        }
        
        bl_port_emptyAllSelections();
        ddObj.detatchDetectEvents();
        bl_dd_createDragShadow(ddObj, event);

        if (bl_browserInfo.ie)
        {
          item.ondrag      = bl_dd_docDrag;
          item.onkeydown   = bl_dd_keyDown;
          item.onkeyup     = bl_dd_keyUp;
          item.ondragstart = bl_dd_start;
          item.ondragend   = bl_dd_end;
          // Begins a drag+drop operation in IE. This method does NOT return
          // until the drag+drop operation is complete so we can just kill 
          // the drag/drop object after this
          if (!item.dragDrop())
          {
            ddObj.kill();
          }
        }
        else if (bl_browserInfo.firefox || bl_browserInfo.safari)
        {
          // Initializes the generic drag+drop system. This method sets the
          // appropriate drag+drop handlers, and returns immediately. Cleanup
          // is done when the handlers detect that the operation is complete.
          bl_dd_startCustomDrag(ddObj, event);
        }
      }
    }

    bl_port_stop_event(event);
  }
  else if (document.body.onmousemove == bl_dd_detectDragMouseMove)
  {
    document.body.onmousemove = null;
    document.body.onmouseup   = null;
  }
}

function bl_dd_createEffectObj(val)
{
  var index = val.indexOf(".");
  return (index > -1)? { effect:val.substring(index + 1, val.length), zoneName:val.substring(0, index) }:
                       { effect:"move", zoneName:val };
}

function bl_dd_setDragOverNotify(overEl, callback)
{
  this.currentOverEl = overEl;
  this.overDragEnd   = callback;
}

function bl_dd_setFeedbackItem(item)
{
  this.feedbackItem = item;
}

// FIREFOX DRAG ENGINE - UTILITY FUNCTIONS /////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

// Function to return a list of all bungee Window objects (including
// the contents of IFRAMEs).
function bl_moz_listAllWindows(mainWin)
{
  var list = [];
  
  if (mainWin)
  {
    var blList  = mainWin.bl_window_list;
    var len     = blList.length;
    
    // *copy* the window list. (We will add to our list but
    // don't want the changes propagated to the master list)
    for (var i = 0; i < len; i++)
    {
      try
      {
        var item = blList[i];
        
        if (!item.closed)
        {
          if (item.location.host == location.host)
          {
            list.push(item);
          }
        }
      } catch (e_) {}
    }
    
    len = list.length;
    
    for (var i = 0; i < len; i++)
    {
      var win   = list[i];
      var flist = win.frames;
      var flen  = flist.length;
      
      for (var j = 0; j < flen; j++)
      {
        try
        {
          var candidateWin = flist[j];
          
          // 1. Window must not be a tracked (ie. no bl_did)
          // 2. Window must have bl_ddInclude set to true.
          // 3. must not be closed
          // we are garenteed that there will not be duplicates
          // because we do not allow any windows being tracked in.
          if (!candidateWin.bl_did       &&
               candidateWin.bl_ddInclude && 
              !candidateWin.closed)
          {
            if (candidateWin.location.host == location.host)
            {
              list.push(candidateWin);
            }
          }
        }
        catch(ex)
        {
          // An exception will be thrown if we scan a frame that
          // is owned by a different URL. We want to ignore those
          // frames and continue searching.
        }
      }
    }
  }    
  return list;
}

// Takes 2 DOM nodes and returns their nearest common ancestor. If there is
// no common ancestor, null is returned.
function bl_moz_findCommonAncestor(el1,el2)
{
  if (!el1 || !el2 || el1.ownerDocument != el2.ownerDocument)
  {
    return null;
  }
  if (el1 == el2)
  {
    return el1;
  }
  
  var doc      = el1.ownerDocument;
  var a        = el1;
  var b        = el2;
  var ancestor = null;
  
  if (!el1.parentNode || !el2.parentNode)
  {
    // At least one of the elements isn't in the DOM.
    // (The only time an argument element can have a null
    // parent node is when it is the Document element, and
    // a Document object is not a valid parameter)
    return null;
  }
  
  do
  {
    if (a != doc)
    {
      if (a.bl_moz_fca_mark)
      {
        ancestor = a;
        break;
      }
      a.bl_moz_fca_mark = true;
      a = a.parentNode;        
    }
    if (b != doc)
    {
      if (b.bl_moz_fca_mark)
      {
        ancestor = b;
        break;
      }
      b.bl_moz_fca_mark = true;
      b = b.parentNode;        
    }
  } while (true);
  
  // Cleanup marks...
  while (el1.bl_moz_fca_mark)
  {
    delete el1.bl_moz_fca_mark;
    el1 = el1.parentNode;
  }

  // Cleanup marks...
  while (el2.bl_moz_fca_mark)
  {
    delete el2.bl_moz_fca_mark;
    el2 = el2.parentNode;
  }
  
  return ancestor;
}

// Takes screen coordinates and returns client coordinates in the srcContext of
// the specified window.
function bl_moz_getClientCoords(contextWin, screenX, screenY)
{
  var clientX = screenX - bl_port_getScreenLeft(contextWin);
  var clientY = screenY - bl_port_getScreenTop(contextWin);
  return {x:clientX,y:clientY};
}

// Contains the context in which "bl_moz_findElement_filter_acceptNode" runs.
function bl_moz_findElement_filter(win, screenX, screenY)
{
  this.win         = win;
  this.doc         = win.document;
  this.x           = screenX;
  this.y           = screenY;
  this.scans       = 0;
  this.hasZoneList = 0;
}

// Determines whether or not an element is an eligible drag target at the specified coordinates.
// The coordinates are contained within the "this" object.
bl_moz_findElement_filter.prototype.acceptNode = function(node)
{
  this.scans++;

  // TODO: Formalize/optimize/verify trivial-reject rules a better.
  var tagName     = node.tagName;
  var isCandidate = (tagName != "SPAN" && tagName != "IMG");
  
  if (isCandidate)
  {
    // element.hasAttribute is *not* IE friendly (safari/firefox only).
    isCandidate   = (tagName == "TD" || 
                     tagName == "LABEL" || 
                     tagName == "TABLE" || 
                     node.id=="LIST_PARENT" || 
                     node.hasAttribute("bl_zone_list") || 
                     node.hasAttribute("ondrag") || 
                     node.hasAttribute("ondragenter") || 
                     node.hasAttribute("ondragleave") || 
                     node.hasAttribute("bl_tree_node"));
  }
  
  if (!isCandidate)
  {
    return NodeFilter.FILTER_SKIP;
  }
  
  this.hasZoneList++;

  var box  = this.doc.getBoxObjectFor(node);
  if (!box)
  {
    return NodeFilter.FILTER_SKIP;
  }
  
  var left   = box.screenX;
  var top    = box.screenY;
  var width  = box.width;
  var height = box.height;

  if (this.x >= left && this.x <= left+width    && this.y >= top && this.y <= top+height)
  {
    return NodeFilter.FILTER_ACCEPT;
  }

  if (node.style.display == "inline")
  {
    // Size not properly computed by firefox for inline elements.
    return NodeFilter.FILTER_SKIP;
  }
  return NodeFilter.FILTER_REJECT;
}

function bl_dd_customFindEl(rootEl, screenX, screenY)
{
  var el = null;
  
  if (rootEl.ownerDocument.elementFromPoint)
  {
    var win     = rootEl.ownerDocument.defaultView;
    var clientX = screenX - bl_port_getScreenLeft(win);
    var clientY = screenY - bl_port_getScreenTop(win);
    
    el = rootEl.ownerDocument.elementFromPoint(clientX,clientY);
  }
  else
  {
    var doc      = rootEl.ownerDocument;
    var win      = doc.defaultView;
    var filter   = new bl_moz_findElement_filter(win,screenX,screenY);
    var w        = doc.createTreeWalker(doc.body,NodeFilter.SHOW_ELEMENT,filter,false);
    var maxZ     = -32000;

    while (w.nextNode())
    {
      var item   = w.currentNode;
      var style  = win.getComputedStyle(item,null);
      var zIndex = style.getPropertyValue("z-index");

      if (zIndex >= maxZ || (!el && zIndex == "auto"))
      {
        el   = item;
        maxZ = zIndex;
      }
    }
  }
  return el;
}

// Determine whether or not a window is hidden. (Hidden windows cannot
// receive drag events for mozilla).
function bl_moz_isWindowHidden(win)
{
  if (win.frameElement && !win.bl_is_main)
  {
    try
    {
      var style = win.frameElement.style;
      return (style.visibility == "hidden" || style.display == "" || style.display == "none");
    }
    catch(securityEx)
    {
      // Ignore security exceptions here -- it just means we can't
      // access the window's corresponding IFRAME element.
    }
  }
  return false;
}

// Finds the top window at the specified screen coordinates.
// Can only be called during a firefox drag operation.
function bl_dd_customFind(list, screenX, screenY)
{
  var foundTopWin = null;
  var foundChild  = null;
  
  if (!list)
  {
    return null;
  }
  
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    var win = list[i];

    try 
    {
      // ff2 has permission issues
      if (foundTopWin && foundTopWin.bl_dd_customPriority > win.bl_dd_customPriority)
      {
        // The current window already has a higher priority (is on top).
        continue;
      }
    } catch (e_) {}
    
    if (!bl_moz_isWindowHidden(win))
    {
      var left   = bl_port_getScreenLeft(win);
      var top    = bl_port_getScreenTop(win);
      var width  = win.innerWidth;
      var height = win.innerHeight;

      if (screenX >= left && screenX <= left+width && screenY >= top && screenY <= top+height)
      {
        foundTopWin = win;
      }
    }
  }

  if (foundTopWin)
  {
    foundChild = bl_moz_findIFrame(foundTopWin,screenX,screenY);
    while (foundChild != foundTopWin)
    {
      foundTopWin = foundChild;
      foundChild  = bl_moz_findIFrame(foundTopWin,screenX,screenY);
    }
  }
  
  return foundChild;
}

function bl_moz_findIFrame(parentWin,screenX,screenY)
{
  var list = parentWin.frames;
  var len  = list.length;
  
  for (var i = 0; i < len; i++)
  {
    try
    {
      var win = list[i];
      
      if (win.bl_is_main || !win._bl_port_last)
      { 
        // Ignore any bungee apps embedded within this one. 
        // Also ignore any iframes from the bungee domain that 
        // aren't bungee script windows.
        continue;
      }
      
      var left   = bl_port_getScreenLeft(win);
      var top    = bl_port_getScreenTop(win);
      var width  = win.innerWidth;
      var height = win.innerHeight;
      
      // Z-index order is not calculated, so incorrect behavior may occur 
      // if IFRAME elements overlap.
      if (screenX >= left && screenX <= left + width && screenY >= top && screenY <= top + height)
      {
        if (!bl_moz_isWindowHidden(win))
        {
          return win;
        }
      }
    }
    catch(ex)
    {
      // An IFrame could point to somebody else's page (HTMLEmbed).
      // Accessing somebody elses site will throw an exception, so we
      // ignore it and look at the next IFrame.
    }
  }
  
  return parentWin;
}

// FIREFOX DRAG ENGINE - INIT/CLEANUP///////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

function bl_dd_startCustomDrag(ddObj, event)
{
  // 1. Dispatch "dragstart" event.
  // 2. Install custom drag handlers.
  // 3. Turn off moz-user-select globally.
  var mainWin = bl_sys_get_main(window);
  var item    = ddObj.srcContext.item;
  var win     = item.ownerDocument.defaultView;

  ddObj.currentTarget = null;

  // Dispatch [dragstart] event to [moz_drag_sourceEl]
  win.bl_dd_start.call(item, event);

  var list = ddObj.windowList = bl_moz_listAllWindows(mainWin);
  var len  = list.length;
  
  for (var i = 0; i < len; i++)
  {
    win = list[i];

    var doc = win.document;
    
    // Add custom handlers.
    win.addEventListener("mousemove", win.bl_dd_customMove,    true);
    win.addEventListener("mouseover", win.bl_dd_customOver,    true);
    win.addEventListener("mouseout",  win.bl_dd_customOut,     true);
    win.addEventListener("mouseup",   win.bl_dd_customUp,      true);
    win.addEventListener("keydown",   win.bl_dd_customKeyDown, true);
    win.addEventListener("keyup",     win.bl_dd_customKeyUp,   true);
    win.addEventListener("click",     win.bl_dd_customClick,   true);
    
    // Prevent text/image selection.
    doc.body.style.mozUserSelect = "none";

    var style = doc.createElement('style');

    style.type = 'text/css';
    doc.getElementsByTagName("head")[0].appendChild(style);
    style.appendChild(doc.createTextNode("* { cursor: not-allowed !important; }"));
    win.bl_dd_cursorStyle = style;
  }
}

function bl_dd_customCursor(ddObj)
{
  if (ddObj)
  {
    var list    = ddObj.windowList;
    var last    = ddObj.lastCustomEffect; 
    var current = ddObj.currentEffect;
    if (list && current != last)
    {
      var len  = list.length;
      var cursor = "* { cursor: not-allowed !important; }";
      
      if (current == "copy")
      {
        cursor = (bl_browserInfo.safari)? "* { cursor: crosshair !important; }":"* { cursor: copy !important; }";
      }
      else if (current == "move")
      {
        cursor = "* { cursor: default !important; }";
      }
      ddObj.lastCustomEffect = current;
      
      for (var i = 0; i < len; i++)
      {
        var win = list[i];
        
        var style = win.bl_dd_cursorStyle;
        
        if (style)
        {
          style.removeChild(style.firstChild);
          style.appendChild(win.document.createTextNode(cursor));
        }
      }
    }
  }
}

function bl_dd_customCleanUp(ddObj)
{
  // 2. Remove custom handlers.
  // 3. Turn on moz-user-select globally.
  if (ddObj)
  {
    var list = ddObj.windowList;
    
    if (list)
    {
      var len  = list.length;
      
      for (var i = 0; i < len; i++)
      {
        var win = list[i];
        
        // Remove custom handlers.
        win.removeEventListener("mousemove", win.bl_dd_customMove,    true);
        win.removeEventListener("mouseover", win.bl_dd_customOver,    true);
        win.removeEventListener("mouseout",  win.bl_dd_customOut,     true);
        win.removeEventListener("mouseup",   win.bl_dd_customUp,      true);
        win.removeEventListener("keydown",   win.bl_dd_customKeyDown, true);
        win.removeEventListener("keyup",     win.bl_dd_customKeyUp,   true);
        win.removeEventListener("click",     win.bl_dd_customClick,   true);
        
        if (win.bl_dd_scrollCheckID)
        {
          win.clearTimeout(win.bl_dd_scrollCheckID);
        }

        // Re-allow text/image selection.
        win.document.body.style.mozUserSelect = "";
        
        var style = win.bl_dd_cursorStyle;
        if (style)
        {
          style.parentNode.removeChild(style);
          win.bl_dd_cursorStyle = null;
        }
      }
      
      delete ddObj.windowList;
      ddObj.windowList = null;
    }
    
    ddObj.currentTarget = null;
  }
}

// FIREFOX DRAG ENGINE - EVENT HANDLERS ////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

function bl_dd_customFocus(event)
{
  // 1. Find all all top-level windows.
  // 2. Decrement the priority of all windows.
  // 3. Set the priority of this window to be maximum priority (ONE).
  var list = bl_moz_listAllWindows(bl_sys_get_main(window));
  var len  = list.length;
  
  for (var i = 0; i < len; i++)
  {
	  try
	  {
      list[i].bl_dd_customPriority--;
    } catch (e_) {}
  }

  // ONE is always the highest priority (as it's larger than "undefined").
  window.bl_dd_customPriority = 1;
  
  // TODO: Figure out how to receive focus events for the main
  // window when it lives in an IFRAME.
}

function bl_dd_customKeyDown(event)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    if (event.which == 17)
    {
      bl_dd_computeEffect(ddObj, event, ddObj.dropZoneObj);
      bl_dd_customCursor(ddObj);
    }
    else if (event.which == 27)
    {
      ddObj.kill();
    }
  }
  
  bl_port_killEvent(event);
}

function bl_dd_customKeyUp(event)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    if (event.which == 17)
    {
      bl_dd_computeEffect(ddObj, event, ddObj.dropZoneObj);
      bl_dd_customCursor(ddObj);
    }
  }
  
  bl_port_killEvent(event);
}

function bl_dd_customClick(event)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    ddObj.kill();
  }
  bl_port_killEvent(event);
}

function bl_dd_customOver(event)
{
  // There is no guarantee we'll get this event from the browser,
  // so we've completely synthysized it within the moz_drag_onMousemove
  // handler.
  bl_port_killEvent(event);
}

function bl_dd_customOut(event)
{
  // There is no guarantee we'll get this event from the browser,
  // so we've completely synthysized it within the moz_drag_onMousemove
  // handler.
  bl_port_killEvent(event);
}

function bl_dd_customMove(event)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    // 1. Find target element.
    // 2. Dispatch "dragenter" and "dragleave" events as needed.
    // 3. Dispatch "drag" event.
    // 4. Dispatch "dragover" event.
    var targetWin;
    var targetEl;
    var sourceItem    = ddObj.srcContext.item;
    var currentTarget = ddObj.currentTarget;
    var screenX       = event.screenX;
    var screenY       = event.screenY;
    
    targetWin = bl_dd_customFind(ddObj.windowList, screenX, screenY);
    
    if (targetWin)
    {
      targetEl = bl_dd_customFindEl(targetWin.document.body,screenX,screenY);
    }
    if (targetEl != currentTarget)
    {
      var commonAncestor = bl_moz_findCommonAncestor(targetEl, currentTarget);

      if (currentTarget)
      {
        // Dispatch [dragleave] event to [moz_drag_currentTargetEl]
        var doc    = currentTarget.ownerDocument;
        var win    = doc.defaultView;
        var coords = bl_moz_getClientCoords(win,screenX,screenY);
        var ev     = doc.createEvent("MouseEvents");
        
        ev.initMouseEvent("dragleave", true, true, win, 0, screenX, screenY, coords.x, coords.y,
                          event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, event.which,
                          sourceItem);
        win.bl_moz_dispatchEvent(currentTarget, ev, commonAncestor);
      }
      
      ddObj.currentTarget = currentTarget = targetEl;
          
      if (currentTarget)
      {
        // Dispatch [dragenter] event to [moz_drag_currentTargetEl]
        var doc    = currentTarget.ownerDocument;
        var win    = doc.defaultView;
        var coords = bl_moz_getClientCoords(win,screenX,screenY);
        var ev     = doc.createEvent("MouseEvents");
        ev.initMouseEvent("dragenter", true, true, win, 0, screenX, screenY, coords.x, coords.y,
                          event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, event.which,
                          sourceItem);
        win.bl_moz_dispatchEvent(currentTarget, ev, commonAncestor);
      }
    }

    // Dispatch [drag] event to [moz_drag_sourceEl]
    // we can just send in the original event as that will work fine                      
    sourceItem.ownerDocument.defaultView.bl_dd_docDrag.call(sourceItem, event);

    if (currentTarget)
    {
      // Dispatch [dragover] event to [moz_drag_currentTargetEl]
      var doc    = currentTarget.ownerDocument;
      var win    = doc.defaultView;
      var coords = bl_moz_getClientCoords(win,screenX,screenY);
      var ev     = doc.createEvent("MouseEvents");
      
      ev.initMouseEvent("dragover", true, true, win, 0, screenX, screenY, coords.x, coords.y,
                        event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, event.which,
                        sourceItem);
      win.bl_moz_dispatchEvent(currentTarget, ev, null);
      
      win._bl_customScrollCheck(screenX, screenY);
    }
 
    bl_dd_customCursor(ddObj)
  }  
  bl_port_killEvent(event);
}

function _bl_customScrollCheck(screenX, screenY)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    var mainWin   = bl_sys_get_main(window)
    var node      = ddObj.currentTarget;
    var didScroll = false;

    for (; !didScroll && node; node = node.parentNode)
    {
      if (node.nodeType != 1)
      {
        continue;
      }

      var width  = 0;
      var height = 0;
      var left   = 0;
      var right  = 0;
      var top    = 0;
      var bottom = 0;
      var box    = null;

      if (bl_browserInfo.firefox)
      {
        box = node.ownerDocument.getBoxObjectFor(node);
        width  = box.width;
        height = box.height;
        left  = screenX - box.screenX;
        right = (box.screenX + width) - screenX;
        top  = screenY - box.screenY;
        bottom = (box.screenY + height) - screenY;
      }
      else
      {
        var coords = bl_sys_find_xy(node, null, false);
        var boxScreenX = coords.x + bl_port_getScreenLeft(window);
        var boxScreenY = coords.y + bl_port_getScreenTop(window);
        width  = node.offsetWidth;
        height = node.offsetHeight;

        left  = screenX - boxScreenX;
        right = (boxScreenX + width) - screenX;
        top  = screenY - boxScreenY;
        bottom = (boxScreenY + height) - screenY;
      }

      var canScrollX = (node.scrollWidth > width) && node.style.overflowX != "hidden";
      var canScrollY = (node.scrollHeight > height) && node.style.overflowY != "hidden";

      if (canScrollX)
      {
        if (left < 25 && left < right)
        {
          node.scrollLeft -= ((left < 15)? 10:5);
          didScroll = true;
        }
        else if (right < 40)
        {
          node.scrollLeft += ((right < 30)? 10:5);
          didScroll = true;
        }
      }

      if (canScrollY)
      {
        if (top < 25 && top < bottom)
        {
          node.scrollTop -= ((top < 15)? 10:5);
          didScroll = true;
        }
        else if (bottom < 40)
        {
          node.scrollTop += ((bottom < 30)? 10:5);
          didScroll = true;
        }
      }
    }

    if (window.bl_dd_scrollCheckID)
    {
      clearTimeout(bl_dd_scrollCheckID);
    }
    bl_dd_scrollCheckID = mainWin.setTimeout("_bl_customScrollCheck(" + screenX + "," + screenY + ")", 25);
  }
}

function bl_dd_customUp(event)
{
  // 1. Find target element.
  // 2. Dispatch "drop" event.
  // 3. Cleanup custom drag handlers.
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    var sourceItem    = ddObj.srcContext.item;
    var currentTarget = ddObj.currentTarget;

    // Assume that [moz_drag_currentTargetEl] is correctly tracking.
    if (currentTarget)
    {
      // Dispatch [drop] event to [moz_drag_currentTargetEl]
      var screenX = event.screenX;
      var screenY = event.screenY;
      var doc     = currentTarget.ownerDocument;
      var win     = doc.defaultView;
      var coords  = bl_moz_getClientCoords(win, screenX, screenY);
      var ev      = doc.createEvent("MouseEvents");

      ev.initMouseEvent("drop", true, true, win, 0, screenX, screenY, coords.x, coords.y,
                        event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, event.which,
                        sourceItem);
      win.bl_moz_dispatchEvent(currentTarget, ev, null);
    }

    ddObj.kill();
  }
  
  bl_port_killEvent(event);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
function bl_dd_computeEffect(ddObj, event, dropZoneObj)
{
  var ret = false;

  if (ddObj)
  {
    var computedEffect = "none";
    var srcContext     = ddObj.srcContext;
    
    ddObj.dropZoneObj = dropZoneObj;

    if (dropZoneObj)
    {  
      var zEffect  = ddObj.zoneObj.effect;
      var dZEffect = dropZoneObj.effect;
      
      // reverse the return to asume that it will be a success
      ret = true;

      if ((event.ctrlKey || zEffect == "copy") && dZEffect != "move" && zEffect != "move")
      {
        computedEffect = "copy";
      }
      else
      {
        if (dZEffect != "copy" && zEffect != "copy")
        {
          computedEffect = "move";
        }
        else if (dZEffect == "copy" && (zEffect == "copy" || zEffect == "all"))
        {
          computedEffect = "copy";
        }
        else
        {
          computedEffect = "none";
          ret = false;
        }
      }
    }  

    if (event && event.dataTransfer)
    {
      event.dataTransfer.dropEffect = computedEffect;
      event.returnValue = false;
    }
    
    if (srcContext.shadowUpdate)
    {
      srcContext.shadowUpdate(ddObj, ddObj.shadow, computedEffect);
    }
    
    ddObj.currentEffect = computedEffect;
  }
  
  return ret;
}

function bl_dd_clearEffect()
{
  var srcContext = this.srcContext;

  this.currentEffect = "none";
  if (srcContext.shadowUpdate)
  {
    srcContext.shadowUpdate(this, this.shadow, this.currentEffect);
  }
}

function bl_dd_checkList(ddObj, event, zoneList)
{
  var dZoneObj = null;
  
  if (ddObj && zoneList)
  {
    var zlist    = zoneList.split(",");
    var len      = zlist.length;
    var zoneName = ddObj.zoneObj.zoneName;
    
    for (var i = 0; i < len; i++)
    {
      var zObj = bl_dd_createEffectObj(zlist[i]);
      
      if (zoneName == zObj.zoneName)
      {
        dZoneObj = zObj;
        break;
      }
    }
  }
  
  return bl_dd_computeEffect(ddObj, event, dZoneObj);
}

// process drop take one arg
//     target (required) - object containing context for drop the properties on the object are as folows
//                         id          (required) - the id for the drop target
//                         index       (required) - index for the drop
//                         dropContext (optional) - context for the drop target
//                         aboutToDrop (optional) - call back for when the drop has been decided (arg: ddObj)
function bl_dd_procDrop(target)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {
    var currentEffect = ddObj.currentEffect;
    var srcContext = ddObj.srcContext;
    var source     = srcContext.source;
    
    if (currentEffect && currentEffect != "none")
    {
      if (target.aboutToDrop)
      {
        target.aboutToDrop(ddObj);
      }

      var xmlStr = "<itemDrop><source>";
      var dragContext = srcContext.dragContext;
      
      if (dragContext && dragContext.length)
      {
        xmlStr += "<dragContext>";
        xmlStr += dragContext;
        xmlStr += "</dragContext>";
      }
      
      xmlStr += "<editorId>";
      xmlStr += ddObj.editorId;
      xmlStr += "</editorId><zoneName>";
      xmlStr += ddObj.zoneObj.zoneName;
      xmlStr += "</zoneName><index>";
      xmlStr += ddObj.indexes;
      xmlStr += "</index></source><dest><editorId>";
      xmlStr += target.id;
      xmlStr += "</editorId>";
      
      var dropContext = target.dropContext;

      if (dropContext && dropContext.length)
      {
        xmlStr += "<dropContext>";
        xmlStr += dropContext;
        xmlStr += "</dropContext>";
      }
      
      xmlStr += "<index>";
      xmlStr += target.index;
      xmlStr += "</index><effect>";
      xmlStr += currentEffect;
      xmlStr += "</effect></dest></itemDrop>";

      // send the data to the server
      bl_mpr_send(xmlStr, target.id);
      return true;
    }
  }

  return false;
}

function bl_dd_keyDown(event)
{
  var ddObj = bl_dd_getDragDropObj();
  var event = bl_dd_getEvent(ddObj, event);

  if (event && ddObj && bl_port_keyCode(event) == 17)
  {
    bl_dd_computeEffect(ddObj, event, ddObj.dropZoneObj);
  }
}

function bl_dd_keyUp(event)
{
  var ddObj = bl_dd_getDragDropObj();
  var event = bl_dd_getEvent(ddObj, event);

  if (event && ddObj && bl_port_keyCode(event) == 17)
  {
    bl_dd_computeEffect(ddObj, event, ddObj.dropZoneObj);
  }
}

function bl_dd_detatchItemEvents()
{
  var item = this.srcContext.item;
  
  if (bl_browserInfo.ie)
  {
    item.ondragstart = null;
    item.ondragend   = null;
    item.ondrag      = null;
  }
  
  item.onmouseup   = null;
  item.onmousemove = null;
  item.onkeydown   = null;
  item.onkeyup     = null;
  
  if (this.oldMouseUp)
  {
    item.onmouseup = this.oldMouseUp;
  }
  if (this.oldMouseMove)
  {
    item.onmousemove = this.oldMouseMove;
  }
  if (this.sysKeyDown)
  {
    item.onkeydown = this.sysKeyDown;
  }
  if (this.sysKeyUp)
  {
    item.onkeyup = this.sysKeyUp;
  }
  
  var body   = item.ownerDocument.body;
  
  body.onmousemove = this.oldBodyMouseMove;
  body.onmouseup   = this.oldBodyMouseUp;
}

/////////////////////////////////////////////
//
// Drag Hint
//
/////////////////////////////////////////////

function bl_dd_hintOver(event)
{
  if (!event)
  {
    event = window.event;
  }

  var ddObj = bl_dd_getDragDropObj();   
  
  if (ddObj)
  {
    if (ddObj.lastCustomEffect != undefined)
    {
      ddObj.currentEffect = ddObj.lastCustomEffect;
    }
    if (ddObj && event && event.dataTransfer)
    {
      event.dataTransfer.dropEffect = ddObj.currentEffect;
    }
  }
    
  bl_port_killEvent(event);
}

function bl_dd_hintDrop(event)
{
  if (!event)
  {
    event = window.event;
  }

  if (event)
  {
    var ddObj = bl_dd_getDragDropObj();

    if (ddObj)
    {
      if (ddObj.hintContext)
      {
        var hintContext = ddObj.hintContext;
        
        if (hintContext.hintDrop)
        {
          hintContext.hintDrop(event, ddObj.hintImage);
        }  
      }
      
      ddObj.setHint(null);
    }
    
    bl_port_killEvent(event);
  }
}

// setHint text a context argument wich is required (below are all posible 
// context objectproperties on the 
//     child (required) - element the hint is relative to
//     width (required) - width of hint
//     height (required) - height of hint
//     useOffsets (optional) - if true specifies that the offsets provided must be used
//     offsetX    (optional but required if us offset is true) - left position of hint
//     offsetY    (optional but required if us offset is true) - top position of hint
//     isVertical (optional) - orientation of the hint
//     color      (optional) - color for the hint 
//     hintDrop   (optional) - drag drop call back,
function bl_dd_objSetHint(hintContext)
{
  this.hintContext = hintContext;
  
  if (hintContext)
  {
    var relativeDoc = hintContext.child.ownerDocument;
    var hintImage   = this.hintImage;
    var child       = hintContext.child;
    
    if (!hintImage || relativeDoc != hintImage.ownerDocument)
    {
      hintImage = this.regenHint(relativeDoc);
    }

    var body = relativeDoc.body;
    var pos  = bl_sys_find_xy(child, null, false);
    
    if (!hintContext.useOffsets)
    {
      pos.y  += body.scrollTop;
      pos.x  += body.scrollLeft;
    }

    var childHeight = child.offsetHeight;
    var childWidth  = child.offsetWidth;
    
    with (hintImage.style)
    {
      backgroundColor = (hintContext.color) ? hintContext.color : "black";
      
      if (hintContext.isVertical)
      {
        height = hintContext.dimension + "px";
        width  = (hintContext.size > 0 ? hintContext.size : childWidth) + "px";
        
        if (hintContext.useOffsets)
        {
          top  = (pos.y + hintContext.y) + "px";
          left = (pos.x + hintContext.x) + "px";
          this.isTopLeft  = true;
        }
        else
        {
          left = pos.x + "px";
          
          if (hintContext.y > (pos.y + (childHeight/2)))
          {
            top = (pos.y + childHeight) + "px";
            this.isTopLeft = false;
          }
          else
          {
            top = pos.y + "px";
            this.isTopLeft = true;
          }
        }
      }
      else
      {
        width  = hintContext.dimension + "px";
        height = (hintContext.size > 0 ? hintContext.size : childHeight) + "px";
        
        if (hintContext.useOffsets)
        {
          top  = (pos.y + hintContext.y) + "px";
          left = (pos.x + hintContext.x) + "px";
          this.isTopLeft  = true;
        }
        else
        {
          top = pos.y + "px";
          if (hintContext.x > (pos.x + (childWidth / 2)))
          {
            left = (pos.x + childWidth)+"px";
            this.isTopLeft  = false;
          }
          else
          {
            left = pos.x + "px";
            this.isTopLeft  = true;
          }
        }
      }
    }
  }
  else
  {
    this.regenHint(null);
  }
}

function bl_dd_objRegenHint(doc)
{
  if (this.hintImage)
  {
    var parent = this.hintImage.parentNode;
    
    if (parent)
    {
      parent.removeChild(this.hintImage);
    }
    
    this.hintImage = null;
  }

  if (doc)
  {
    var win = bl_port_docWindow(doc);
  
    var el   = doc.createElement("DIV");
    var els  = el.style;
    
    with (el.style)
    {
      position = "absolute";
      overflow = "hidden";
    }
    
    el.bl_isDragHint = true;
    el.ondragover    = win.bl_dd_hintOver;
    el.ondragenter   = win.bl_dd_hintOver;
    el.ondrop        = win.bl_dd_hintDrop;
  
    doc.body.appendChild(el);
    this.hintImage  = el;
  }
  
  return this.hintImage;
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_dd_last()
{
  var x = 0;
}


//***********************************************************************
//***********************************************************************
//********                    bl_port.js                        *********
//***********************************************************************
//***********************************************************************

//Browser test object call
if (!window.bl_browserInfo)
{
  var info = new Object();
  var agt  = navigator.userAgent.toLowerCase();
  
  info.major    = parseInt(navigator.appVersion);
  info.minor    = parseFloat(navigator.appVersion);
  info.gecko    = (agt.indexOf('gecko') != -1);
  
  info.firefox  = ((agt.indexOf("mozilla") != -1) && ((agt.indexOf("firefox") != -1) || agt.indexOf("granparadiso") != -1));
  info.firefox3 = ((agt.indexOf("firefox/3") != -1) || (agt.indexOf("granparadiso/3") != -1));
  info.firefox2 = ((agt.indexOf("firefox/2") != -1) || (agt.indexOf("granparadiso/2") != -1));
  info.safari   = (agt.indexOf("safari") != -1);
  
  info.ie       = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
  info.ie5_5    = (info.ie && (info.major == 4) && (agt.indexOf("msie 5.5") != -1));
  info.ie5up    = (info.ie  && !info.ie3 && !info.ie4);
  info.ie5_5up  = (info.ie && !info.ie3 && !info.ie4 && !info.ie5);
  info.ie6      = (info.ie && (info.major == 4) && (agt.indexOf("msie 6.") != -1) );
  info.ie6up    = (info.ie  && !info.ie3 && !info.ie4 && !info.ie5 && !info.ie5_5);
  
  info.opera     = (agt.indexOf("opera") != -1);
  info.opera2    = (agt.indexOf("opera 2") != -1 || agt.indexOf("opera/2") != -1);
  info.opera3    = (agt.indexOf("opera 3") != -1 || agt.indexOf("opera/3") != -1);
  info.opera4    = (agt.indexOf("opera 4") != -1 || agt.indexOf("opera/4") != -1);
  info.opera5    = (agt.indexOf("opera 5") != -1 || agt.indexOf("opera/5") != -1);
  info.opera5up  = (info.opera && !info.opera2 && !info.opera3 && !info.opera4);
  
  // *** PLATFORM ***
  info.win      = ((agt.indexOf("win") != -1) || (agt.indexOf("16bit") != -1));
  info.winnt    = ((agt.indexOf("winnt") != -1) || (agt.indexOf("windows nt") != -1));
  info.win32    = (info.win95 || info.winnt || info.win98 ||
                  ((info.major >= 4) && (navigator.platform == "Win32")) ||
                  (agt.indexOf("win32") != -1) || (agt.indexOf("32bit") != -1));
  info.linux    = (agt.indexOf("inux") != -1);
  info.isXP     = (agt.indexOf("windows nt 5.1") > -1);
  info.isXPSP2  = (info.isXP && agt.indexOf("sv1") > -1);
  info.mac      = !info.win && !info.linux;
  
  window.bl_browserInfo = info;
}


/* MAIN PROTOTYPES */

if (bl_browserInfo.firefox)
{
  /////////////////////////////////////////////////////////////////////////////////////////////////////////    
  /* HTMLBodyElement prototypes */
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
    /* This was added because document.body.offsetHeight and document.body.offsetWidth are
     * not the same in both IE and Firefox. This turned out to be much more appropriate */
    HTMLBodyElement.prototype.__defineGetter__("offsetHeight", bl_port_get_bodyOffsetHeight);
    HTMLBodyElement.prototype.__defineGetter__("offsetWidth", bl_port_get_bodyOffsetWidth);
    
  /* Attr prototypes */
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
    Attr.prototype.__defineGetter__("text", bl_port_get_attrText);
}
/*******************************************************************************************/
function bl_port_get_cellIndex(cell)
{
  if (cell)
  {
    if (typeof cell.cellIndex == "undefined")
    {
      var cellList = cell.parentNode.childNodes;
      var len      = cellList.length;
      
      for (var i = 0; i < len; i++)
      {
        if (cell == cellList[i])
        {
          return i;
        }
      }
    }
    
    return cell.cellIndex;
  }
  
  return -1
}

function bl_port_get_rowIndex(row)
{
  if (row)
  {
    if (row.rowIndex == undefined)
    {
      var rowList = row.parentNode.childNodes;
      var len     = rowList.length;
      
      for (var i = 0; i < len; i++)
      {
        if (row == rowList[i])
        {
          return i;
        }
      }
    }
    else
    {
      return row.rowIndex;
    }
  }
  
  return -1;
}

/* @class
 * A simple string builder object.
 * This was created to overcome performance issues
 * with string concatenation. */
function cb_StringBuilder()
{
  if (!cb_StringBuilder.__initialized__)
  {
    /**
     * Appends a string to the string builder.
     * @param {String} value The string to be appended. */
    cb_StringBuilder.prototype.append = function(value)
    {
      this.push(value);
    }
    
    /**
     * Gets the complete string stored in the string builder.
     * @param {String} delimiter [optional | ""] The delimiter to use when joining the string.
     * @type String */
    cb_StringBuilder.prototype.toString = function(delimiter)
    {
      delimiter = delimiter || "";
      return this.join(delimiter);
    }
    
    /**
     * Indicates that @see cb_StringBuilder has been prototyped.
     * @type Boolean
     * @private */
    cb_StringBuilder.__initialized__ = true;
  }
}

cb_StringBuilder.prototype = new Array();

/* Window Methods */
function bl_port_initWindow(win)
{
  if (bl_browserInfo.ie)
  {
    window.attachEvent("onload", bl_port_onLoad);
    // Attempts to force IE to cache background images, rather than
    // issuing a new request to the server for each time it's displayed.
    try 
    {
      document.execCommand("BackgroundImageCache", false, true);
    } 
    catch(err) 
    {
    }
  }
  else if (bl_browserInfo.firefox)
  {
    // Firefox supports the "draggesture" event. We have implemented
    // our own (which has fewer limitations), so we ignore the
    // browser based one.
    win.addEventListener("draggesture", bl_port_killEvent, true);
    win.addEventListener("load", bl_port_onLoad, false);
    win.addEventListener("unload", bl_port_onUnload, false);
    win.addEventListener("mousedown", bl_port_onMousedown, true);
    win.addEventListener("mousemove", bl_port_onMousemove, true);
    win.addEventListener("focus", bl_dd_customFocus, true);
    
    // This handler allows each window to know it's priority. This
    // allows us to *relatively* accurately track which window is
    // on top, so we know which window to send drag events to.
    win.bl_dd_customPriority = 1;
  }
  else if (bl_browserInfo.safari)
  {
    win.addEventListener("load", bl_port_onLoad, false);
    win.addEventListener("unload", bl_port_onUnload, false);
    win.addEventListener("mousedown", bl_port_onMousedown, true);
    win.addEventListener("mousemove", bl_port_onMousemove, true);
    win.addEventListener("focus", bl_dd_customFocus, true);

    // Safari doesn't send mousedown and mouseup events for a context
    // menu click, so we generate synthetic ones.
    win.addEventListener("contextmenu", bl_safari_onContextmenu, true);

    // This prevents drag operations from selecting text.
    win.addEventListener("selectstart", bl_port_onSelectStart, true);

    // Currently, these events only exist to cancel events sent to
    // disabled elements. This is only required for safari.
    win.addEventListener("mouseover", bl_port_onMouseover, true);
    win.addEventListener("mouseout", bl_port_onMouseout, true);
    win.addEventListener("mouseup", bl_port_onMouseup, true);

    // When a backspace keypress hits the main window, the browser
    // leaves the page for the previous history entry. This function
    // should prevent that.    
    win.onkeydown = bl_safari_killBackspace;

	  win.bl_dd_customPriority = 1;
  }
}

// Selectively kills the event if the backspace key is pressed, if the event
// source is not an input element.
// TODO: Figure out how to more selectively kill this?
function bl_safari_killBackspace(event)
{
  if (!cb_sys_isInput(bl_port_getEventTarget(event)) && event.which == 8)
  {
    bl_port_killEvent(event);
  }
}

// Kills "onSelectStart" events that were not generated by a valid input element.
function bl_port_onSelectStart(event)
{
  var target = bl_port_getEventTarget(event);
  
  if (!cb_sys_isInput(target))
  {
    bl_port_killEvent(event);
  }
}

// Dispatch synthetic mousedown and mouseup event handlers for safari.
function bl_safari_onContextmenu(event)
{
  var target = bl_port_getEventTarget(event);

  var synthEvent = document.createEvent("MouseEvents");
  synthEvent.initMouseEvent("mousedown",true,true,window,1,event.screenX,event.screenY,event.clientX,event.clientY,event.ctrlKey,event.altKey,event.shiftKey,event.metaKey,3,null);
  var dispatchOk = target.dispatchEvent(synthEvent);
  
  if (dispatchOk)
  {
    synthEvent = document.createEvent("MouseEvents");
    synthEvent.initMouseEvent("mouseup",true,true,window,1,event.screenX,event.screenY,event.clientX,event.clientY,event.ctrlKey,event.altKey,event.shiftKey,event.metaKey,3,null);
    target.dispatchEvent(synthEvent);
  }

  // Continue to bubble, but don't show the default menu.
  bl_port_preventDefault(event);
}

function bl_port_getMouseX(e)
{
  var posx;
  
  if (e.pageX)
  {
    posx = e.pageX;
  } 
  else if (e.clientX)
  {
    posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
  }

  if (typeof posx == "undefined")
  {
    return 0;
  }
  
  return posx;
}

function bl_port_getMouseY(e)
{
  var posy;
  
  if (e.pageY)
  {
    posy = e.pageY;
  } 
  else if (e.clientY)
  {
    posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
  }

  if (typeof posy == "undefined")
  {
    return 0;
  }

  return posy;
}

function bl_port_context_menu(event)
{
  if (!event)
  {
    event = window.event;
  }

  if (event)
  {
    if (!cb_sys_isInput(bl_port_getEventTarget(event)))
    {
      return false;
    }
  }
}

function bl_port_onLoad(event)
{
  var designAttr = document.body.getAttribute("designmode");
  if (designAttr != null)
  {
    document.designMode = designAttr;
    cb_sys_getTopWindow().moz_editFrame = window;
  }
  
  if (window.addEventListener)
  {
    addEventListener("keyup", bl_kb_onKeyup, false);
    addEventListener("keydown", bl_kb_onKeydown, false);
    addEventListener("keypress", bl_kb_onKeypress, false);
  }
  else
  {
    document.attachEvent("onkeyup", bl_kb_onKeyup);
    document.attachEvent("onkeydown", bl_kb_onKeydown);
    document.attachEvent("onkeypress", bl_kb_onKeypress);
  }
  
  window.oncontextmenu = bl_port_context_menu;
}

function bl_port_onUnload(event)
{
  if (this.bl_topOpener)
  {
    this.bl_topOpener.bl_port_enableEvents();
  }
}

function bl_port_eval_call(script,event)
{
  eval(script);
}

function bl_port_onMouseup(event)
{
  // NOTE: This handler is only added for safari. See note in initWindow.
  if (bl_browserInfo.safari && event.target.disabled)
  {
    bl_port_killEvent(event);
  }
}

function bl_port_onMouseover(event)
{
  this.__screenX__    = event.screenX;
  this.__screenY__    = event.screenY;
  this.__screenLeft__ = event.screenX - event.clientX;
  this.__screenTop__  = event.screenY - event.clientY;
  // NOTE: This handler is only added for safari. See note in initWindow.
  if (bl_browserInfo.safari && event.target.disabled)
  { 
    bl_port_killEvent(event);
  }
}

function bl_port_onMouseout(event)
{
  // NOTE: This handler is only added for safari. See note in initWindow.
  if (bl_browserInfo.safari && event.target.disabled)
  {
    bl_port_killEvent(event);
  }
}

function bl_port_onMousedown(event)
{
  if (!event) // need to manually set event in ie
  {
    event = window.event;
  }

  var top_win = cb_sys_getTopWindow();


  // ctrl-clicking on ff w/ OSX tiggers an oncontextmenu then onmousedown event. Firing these events in
  // this order keeps context menus from working (the onmousedown clears out the oncontextmenu before it
  // has time to show). The code below fixes this behavior.
  if (bl_browserInfo.firefox && bl_browserInfo.mac && event.ctrlKey)
  {
    return bl_port_killEvent(event);
  }

  if (bl_browserInfo.safari)
  {
    if (event.target.disabled)
    {
      return bl_port_killEvent(event);
    }
    var focusTarget = event.target;
    while (focusTarget && !bl_port_hasAttribute(focusTarget,"tabindex"))
    {
      focusTarget = focusTarget.parentNode;
    }
    if (focusTarget != top_win.bl_safari_focusEl)
    {
      var ev = null;
      if (top_win.bl_safari_focusEl)
      {
        ev = document.createEvent("Events");
        ev.initEvent("blur",false,false);
        bl_moz_dispatchEvent(top_win.bl_safari_focusEl, ev, null);
      }
      top_win.bl_safari_focusEl = focusTarget;
      if (top_win.bl_safari_focusEl)
      {
        ev = document.createEvent("Events");
        ev.initEvent("focus",false,false);
        bl_moz_dispatchEvent(top_win.bl_safari_focusEl, ev, null);
      }
    }
  }
}

function bl_port_onMousemove(event)
{
  this.__screenX__    = event.screenX;
  this.__screenY__    = event.screenY;
  this.__screenLeft__ = event.screenX - event.clientX;
  this.__screenTop__  = event.screenY - event.clientY;
  
  if (bl_browserInfo.safari && event.target.disabled)
  {
    bl_port_killEvent(event);
  }
    
  if (!bl_browserInfo.ie)
  {
    var overImage = window.bl_w3c_overImg;

    if (overImage)
    {
      var doc       = overImage.ownerDocument;
      var targetEl  = bl_port_getEventTarget(event);

      if (targetEl.id == "")
      {
        var node = targetEl;
        
        while (node && node.id == "")
        {
          node = node.parentNode;
        }

        if (node)
        {
          targetEl = node;
        }
      }
    	
      if (overImage != targetEl)
      {
        var x,y,right,bottom;
        var dispatch = false;
        
        if (overImage.getBoundingClientRect)
        {
          var rect = overImage.getBoundingClientRect();
          var cx   = event.clientX;
          var cy   = event.clientY;
          
          x      = rect.left;
          y      = rect.top;
          right  = rect.right;
          bottom = rect.bottom;
          
          if (cx < x || cx > right || cy < y || cy > bottom)
          {
            dispatch = true;
          }
        }
        else if (doc.getBoxObjectFor)
        {
          try
          {
            var box = doc.getBoxObjectFor(overImage);
            
            x      = box.screenX;
            y      = box.screenY;
            right  = x + box.width;
            bottom = y + box.height;
            var sx = event.screenX;
            var sy = event.screenY;
            if (sx < x || sx > right || sy < y || sy > bottom)
            {
              dispatch = true;
            }
          }
          catch (error)
          {
            // In case the element becomes invalid for whatever reason
            window.bl_w3c_overImg = null;
          }
        }
        else
        {
          var coords = bl_sys_find_xy(overImage, null, false);
          var cx     = event.clientX;
          var cy     = event.clientY;
          
          x      = coords.x;
          y      = coords.y;
          right  = overImage.offsetWidth + x;
          bottom = overImage.offsetHeight + y;
          
          if (cx < x || cx > right || cy < y || cy > bottom)
          {
            dispatch = true;
          }
        }
        
        if (dispatch)
        {
          var mouseout = doc.createEvent("MouseEvents");
          mouseout.initMouseEvent("mouseout", true, true, doc.defaultView, 
                                  0, event.screenX, event.screenY, event.clientX, event.clientY, 
                                  event.ctrlKey, event.altKey, event.shiftKey,
                                  event.metaKey, event.which, event.target);
          overImage.dispatchEvent(mouseout);
        }
      }
    }
  }
}

function bl_port_stop_event(event)
{
  if (event)
  {
    if (bl_browserInfo.ie)
    {
      event.cancelBubble = true;
    } 
    else
    {
      event.bl_customCancelBubble = true;
    }

    if (bl_browserInfo.ie || bl_browserInfo.firefox)
    {
      bl_port_set_returnValue(event, false);
    }
    
    if (event.stopPropagation)
    {
      event.stopPropagation();
    }
  }
}

function bl_port_killEvent(event)
{
  if (event)
  {
    if (bl_browserInfo.ie)
    {
      event.cancelBubble = true;
      event.returnValue  = false;
      if (event.stopPropagation)
      {
        event.stopPropagation();
      }
      if (event.preventDefault)
      {
        event.preventDefault();
      }
    }
    else
    {
      // Firefox drag engine hack -- indirectly sets event.moz_cancel_event = true.
      // TODO: Get rid of the ".bl_customCancelBubble" prototype.
      event.bl_customCancelBubble = true;
      event.stopPropagation();
      event.preventDefault();
    }
  }
}

function bl_port_stopPropagation(event)
{
  if (bl_browserInfo.ie)
  {
    event.cancelBubble = true;
  } 
  else
  {
    event.bl_customCancelBubble = true;
  }

  if (event.stopPropagation)
  {
    event.stopPropagation();
  }
}

function bl_port_preventDefault(event)
{
  if (event.preventDefault)
  {
    event.preventDefault();
  }
  if (bl_browserInfo.ie)
  {
    event.returnValue = false;
  }
}

function bl_port_findDefaultButton()
{
  var els = document.getElementsByTagName("INPUT");
  var len = els.length;
  
  for (var i = 0; i < len; i++)
  {
    var el = els[i];
    if (el.type == "submit" && !cb_sys_disabled(el))
    {
      return el;
    }
  }

  // StyleButton in any layout EXCEPT HorizontalFlow
  els = document.getElementsByTagName("DIV");
  len = els.length;

  for (var i = 0; i < len; i++)
  {
    var el = els[i];
    if (el.getAttribute("cb_tag") == "SIB" && bl_port_hasAttribute(el,"bl_default") && !cb_sys_disabled(el))
    {
      return el;
    }
  }
  
  // StyleButton in HorizontalFlow
  els = document.getElementsByTagName("SPAN");
  len = els.length;
  
  for (var i = 0; i < len; i++)
  {
    var el = els[i];
    if (el.getAttribute("cb_tag") == "SIB" && bl_port_hasAttribute(el,"bl_default") && !cb_sys_disabled(el))
    {
      return el;
    }
  }

  els = document.getElementsByTagName("IMG");
  len = els.length;
  
  for (var i = 0; i < len; i++)
  {
    var el = els[i];
    if (el.getAttribute("cb_tag") == "IB" && bl_port_hasAttribute(el,"bl_default") && !cb_sys_disabled(el))
    {
      return el;
    }
  }

  // Recursively search all frames for a default.
  len = frames.length;
  for (var i = 0; i < len; i++)
  {
    try
    {
      var iframeEl = frames[i].frameElement;

      if (iframeEl && bl_sys_iframeDisabled(iframeEl))
      {
        continue;
      }
      
      el = frames[i].bl_port_findDefaultButton();
      
      if (el)
      {
        return el;
      }
    }
    catch (ignored)
    {
      // Accessing all child frames is a very likely to throw a SecurityException.
      // (Maybe one of them is an HTMLElement that points to cnn.com for example,
      // and cross-site-scripting is disabled)
    }
  }
  
  return null;
}

function bl_port_findCancelButton()
{
  var els = document.getElementsByTagName("INPUT");
  var len = els.length;

  for (var i = 0; i < len; i++)
  {
    var el = els[i];
    
    if (el.value.toLowerCase() == "cancel" && !cb_sys_disabled(el))
    {
      return el;
    }
  }

  // StyleButton in any layout EXCEPT HorizontalFlow
  els = document.getElementsByTagName("DIV");
  len = els.length;
  
  for (var i = 0; i < len; i++)
  {
    var el = els[i];
    
    if (el.getAttribute("cb_tag") == "SIB" && bl_port_getInnerText(el).toLowerCase() == "cancel" && !cb_sys_disabled(el))
    {
      return el;
    }
  }

  // StyleButton in HorizontalFlow
  els = document.getElementsByTagName("SPAN");
  len = els.length;
  
  for (var i = 0; i < len; i++)
  {
    var el = els[i];
    
    if (el.getAttribute("cb_tag") == "SIB" && bl_port_getInnerText(el).toLowerCase() == "cancel" && !cb_sys_disabled(el))
    {
      return el;
    }
  }

  // Recursively search all frames for a default.
  var len = frames.length;
  for (var i = 0; i < len; i++)
  {
    try
    {
      var iframeEl = frames[i].frameElement;
      if (iframeEl && bl_sys_iframeDisabled(iframeEl))
      {
        continue;
      }
      el = frames[i].bl_port_findCancelButton();
      
      if (el)
      {
        return el;
      }
    }
    catch (ignored)
    {
      // Accessing all child frames is a very likely to throw a SecurityException.
    }
  }
  
  return null;
}

function bl_port_clickButton(buttonEl)
{
  if (buttonEl)
  {
    if (buttonEl.getAttribute("cb_tag") == "BTN")
    {
      buttonEl.click();
    }
    else
    {
      // The use flag should be replaced with a calculation to determine
      // whether or not the mouse is over the default element.
      if (!buttonEl.bl_mouseIsIn)
      {
        if (buttonEl.fireEvent)
        {
          buttonEl.fireEvent("onmouseover");
          buttonEl.fireEvent("onmouseenter");
          buttonEl.fireEvent("onmousedown");
          buttonEl.fireEvent("onmouseup");
          buttonEl.fireEvent("onmouseleave");
          buttonEl.fireEvent("onmouseout");
        }
        else
        {
          bl_moz_dispatchEvent(buttonEl, bl_port_createSyntheticEvent("mouseover",true,true), null);
          bl_moz_dispatchEvent(buttonEl, bl_port_createSyntheticEvent("mousedown",true,true), null);
          bl_moz_dispatchEvent(buttonEl, bl_port_createSyntheticEvent("mouseup",true,true), null);
          bl_moz_dispatchEvent(buttonEl, bl_port_createSyntheticEvent("mouseout",true,true), null);
        }
      }
      else
      {
        if (buttonEl.fireEvent)
        {
          buttonEl.fireEvent("onmousedown");
          buttonEl.fireEvent("onmouseup");
        }
        else
        {
          bl_moz_dispatchEvent(buttonEl, bl_port_createSyntheticEvent("mousedown",true,true), null);
          bl_moz_dispatchEvent(buttonEl, bl_port_createSyntheticEvent("mouseup",true,true), null);
        }
      }
    }
  }
}

function bl_port_clickLink(linkEl)
{
  if (linkEl)
  {
    if (bl_browserInfo.ie)
    {
      linkEl.click();
    }
    else
    {
      var clickEvent = bl_port_createSyntheticEvent("click",true,true);
      
      bl_moz_dispatchEvent(linkEl, bl_port_createSyntheticEvent("mousedown",true,true), null);
      bl_moz_dispatchEvent(linkEl, clickEvent, null);
      bl_moz_dispatchEvent(linkEl, bl_port_createSyntheticEvent("mouseup",true,true), null);
      
      if (!clickEvent.defaultPrevented)
      {
        var target = linkEl.target;
        var href   = linkEl.href;
        if (target != null && target.toLowerCase != "_self")
        {
          window.open(href,target);
        }
        else
        {
          _bl_redirect(href);
        }
      }
    }
  }
}

function bl_port_showModeless(win, url, did, args, features)
{
  var newWin = null;
  
  if (bl_browserInfo.ie)
  {
    var closeTracker = bl_sys_initCloseTracker(did, url, args, true, false);
    
    newWin = win.showModelessDialog(url, args, features);
    
    if (newWin == null)
    {
      closeTracker.blocked = true;
    }

    closeTracker.win = newWin;
  }
  else
  {
    newWin = bl_port_openWindow(win, url, args, did, "", features, false, null);
  }
  
  return newWin;
}

function bl_port_windowSize()
{
  var width  = 0;
  var height = 0;
  
  if (window.innerWidth)
  {
    width  = window.innerWidth;
    height = window.innerHeight;
  }
  else
  {
    var body = document.body;
    width  = body.offsetWidth;
    height = body.offsetHeight;
  }
  
  return {width:width,height:height};
}

function bl_port_computeFeature(event, preCompute, width, height)
{
  var top_win = cb_sys_getTopWindow();
  var screenX = bl_port_getScreenLeft(top_win);
  var screenY = bl_port_getScreenTop(top_win);

  return { preComputed:preCompute, 
           x:((event.screenX - screenX) - (width/2)), 
           y:((event.screenY - screenY) - (height) + 30), 
           computedWidth:width, 
           computedHeight:height, 
           positionType:'left-top'
         };  
}

/*
type > 0 if we have a modal dialog
features = <unparsed attribs>|left|top|width|height|
  position = {center-screen,center, control,right-top,bottom-left,bottom-right}|
  controlId|scrollable|resizeable|statusbar
*/
function bl_port_openFeatures(type, features)
{
  var ret = "";
  
  if (features)
  {
    var top_win = cb_sys_getTopWindow();
    var screenX = bl_port_getScreenLeft(top_win);
    var screenY = bl_port_getScreenTop(top_win);

    ret = features.preComputed;
    
    if (features.positionType == "center-screen")
    {
      var sheight = screen.height;
      var swidth  = screen.width;

      pos  = { y:((sheight/2) - (height/2) + features.y), 
               x:((swidth/2) - (width/2)  + features.x)
             }; 
      
      if (screenX > swidth)
      {
        pos.x += swidth;
      }
      if (screenY > sheight)
      {
        pos.y += sheight;
      }
    }
    else
    {
      if (features.controlId)
      {
        features.el = bl_wn_findControl(features.controlId);
      }
      pos = blu_computeDialogPos(features, top_win);
      pos.x += screenX;
      pos.y += screenY;
    }
    
    if (type > 0 && bl_browserInfo.ie)
    {
      if (ret.length > 0)
      {
        ret += ";";
      }
      ret += "dialogLeft=";
      ret += pos.x;
      ret += "px;dialogTop=";
      ret += pos.y;
      ret += "px";

      if (features.computedWidth > 0)
      {
        ret += ";dialogWidth: ";
        ret += features.computedWidth;
        ret += "px";
      }
      if (features.computedHeight > 0)
      {
        ret += ";dialogHeight: ";
        ret += features.computedHeight;
        ret += "px";
      }
    }
    else
    {
      if (ret.length > 0)
      {
        ret += ",";
      }

      ret += "left=";
      ret += pos.x;
      ret += ",top=";
      ret += pos.y;

      if (features.computedWidth > 0)
      {
        ret += ",width=";
        ret += features.computedWidth;
      }
      if (features.computedHeight > 0)
      {
        ret += ",height=";
        ret += features.computedHeight;
      }
    }
  }
  
  return ret;
}

function bl_port_openWindow(winOpener, url, args, did, name, features, replace, enableContext)
{
  // Ensures that the resources consumed by this popup on the server are
  // released even if the window is closed before it is loaded.
  var closeTracker = bl_sys_initCloseTracker(did, url, args, true, enableContext);
  var newWin       = winOpener.open(url, name, features, replace);

  if (args && !args.isRaw && !bl_browserInfo.ie)
  {
    try
    {
      if (args.isPrint)
      {
        bl_port_setDialogWindowProperty(newWin, "isPrint", args.isPrint);
      }
      
      bl_port_setDialogWindowProperty(newWin, "__dialogArguments__", args);
    }
    catch (e)
    {
      // it is posible that the dialog we popup here is not ours
    }
  }
  
  closeTracker.win = newWin;
  if (newWin == null) 
  {
    closeTracker.blocked = true;
  }
  return newWin;
}

function bl_port_setDialogWindowProperty(win, name, value)
{
  if (bl_browserInfo.safari)
  {
    // After a window is opened by "window.open", you can set arbitrary
    // properties on the object. Unfortunately, these properties are erased
    // when the window actually loads. This framework allows us to store
    // any required arbitrary properties which will be retrieved by the
    // window during loading.
    if (!win.opener.bl_port_dialogData)
    {
      win.opener.bl_port_dialogData = [];
    }
    
    // Search for an existing entry to hold values for this window.
    var data = win.opener.bl_port_dialogData;
    var len  = data.length;
    
    for (var i = 0; i < len; i++)
    {
      if (data[i]["window"] == win)
      {
        data[i][name] = value;
        return;
      }
    }

    // An existing entry for the window was not found so add a new one.
    var obj       = new Array();
    obj["window"] = win;
    obj[name]     = value;
    
    data.push(obj);
  }
  else
  {
    // Other browsers allow arbitrary properties to remain during and after
    // the loading phase of windows opened with "window.open".
    win[name] = value;
  }
}

function bl_port_retrieveDialogWindowProperties(win, retainData)
{
  if (bl_browserInfo.safari)
  {
    // Safari clobbers variables set on the window when the
    // page *begins* to load (sometime after window.open, but
    // before any javascript is run from within the page).
    //
    // For safari, this function retrieves any specified values
    // from the opening window.
    if(win.opener && win.opener.bl_port_dialogData)
    {
      var list = win.opener.bl_port_dialogData;

      for (var i = 0; i < list.length; i++)
      {
        if (list[i]["window"] == win)
        {
          var pkg = list[i];
          
          for (k in pkg)
          {
            if (k != "window")
            {
              win[k] = pkg[k];
            }
          }
          
          if (!retainData)
          {
            list.splice(i,1);
          }
          return true;
        }
      }
    }
    return false;
  }
  else
  {
    // All other browsers ok
    return true;
  }
}

function bl_port_getDialogArguments(win)
{
  if (!win)
  {
    win = window;
  }

  if (win.bl_is_main)
  {
    return null;
  }
  
  if (bl_browserInfo.ie)
  {
    return win.dialogArguments;
  }
  
  return win.__dialogArguments__;
}

function bl_port_disableEvents()
{
  var top_win = cb_sys_getTopWindow();
  
  if (top_win)
  {
    var list = top_win.bl_port_getWindows(true);
    var len  = list.length;

    for (var i = 0; i < len; i++)
    {
      try
      {
        var win = list[i];
        
        win.addEventListener("mouseover", bl_port_focusModal, true);
        win.addEventListener("mousedown", bl_port_focusModal, true);
        win.addEventListener("mousemove", bl_port_focusModal, true);
        win.addEventListener("mouseup", bl_port_focusModal, true);
        win.addEventListener("mouseout", bl_port_focusModal, true);
        win.addEventListener("click", bl_port_focusModal, true);
      }
      catch (e)
      {
      }
    }
  }
}

function bl_port_enableEvents()
{
  var top_win = cb_sys_getTopWindow();
  
  if (top_win)
  {
    var list = top_win.bl_port_getWindows(false);
    var len  = list.length;

    for (var i = 0; i < len; i++)
    {
      try
      {
        var win = list[i];

        win.removeEventListener("mouseover", bl_port_focusModal, true);
        win.removeEventListener("mousedown", bl_port_focusModal, true);
        win.removeEventListener("mousemove", bl_port_focusModal, true);
        win.removeEventListener("mouseup", bl_port_focusModal, true);
        win.removeEventListener("mouseout", bl_port_focusModal, true);
        win.removeEventListener("click", bl_port_focusModal, true);
      } 
      catch (e) 
      {
        // this window may no longer be valid  
      }
    }
  }
}

function bl_port_focusModal(e)
{
  if (window.bl_port_open_modal)
  {
    bl_port_focus(window.bl_port_open_modal);
    bl_port_killEvent(e);
  }
  else
  {
    // Assume that the modal window has been closed, but was unable to
    // remove it's listeners for whatever reason. Specifically, safari
    // has trouble removing the event listeners from within the context
    // of its onunload event.
    bl_port_enableEvents();
  }
}

function bl_port_selectSingleNode(xmlDoc, expr)
{
  if (bl_browserInfo.ie)
  {
    return xmlDoc.selectSingleNode(expr);
  }
  else if (bl_browserInfo.safari)
  {
    var elements = [];
    (xmlDoc.getElementsByTagName(expr).length) ? elements = xmlDoc.getElementsByTagName(expr) : elements = xmlDoc.getElementsByTagName(expr.toUpperCase());
    return elements[0];
  }
  else if (bl_browserInfo.firefox)
  {
    if (expr.substring(0, 2) != "//")
    {
      if (expr.substring(0, 1) != "/")
      {
        expr = "//" + expr
      }
      else
      {
        expr = "/" + expr
      }
    }
    
    var result = xmlDoc.evaluate(expr, xmlDoc, xmlDoc.createNSResolver(xmlDoc.documentElement),
                                 XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    
    if (result && result.singleNodeValue)
    {
      return result.singleNodeValue;
    }
    return null;
  }
}

function bl_port_emptyAllSelections()
{
  var flist = window.frames;
  var flen  = flist.length;
  
  bl_port_get_selection(window.document).empty();

  for (var i = 0; i < flen; i++)
  {
    try
    {
      bl_port_get_selection(flist[i].window.document).empty();
    } catch (ex){}
  }
}

function bl_port_selectionEmpty()
{
  var sel = window.getSelection();
  
  if (bl_browserInfo.ie || bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    sel.removeAllRanges();
  }
  sel = undefined;
}

function bl_port_selectionCreateRange(start, end)
{
  var top_win = cb_sys_getTopWindow();
  var win     = (top_win.moz_editFrame)? top_win.moz_editFrame:window;

  var rangeObj     = win.document.createRange();
  var selectionObj = win.getSelection();

  win.document.selectionObj = selectionObj;

  if ((start || start == 0) && end)
  {
    rangeObj.offsetSelStart = start;
    rangeObj.offsetSelEnd   = end;
  }
  else
  {
    if (selectionObj.anchorOffset < selectionObj.focusOffset)
    {
      rangeObj.offsetSelStart = selectionObj.anchorOffset;
      rangeObj.offsetSelEnd   = selectionObj.focusOffset;
    }
    else
    {
      rangeObj.offsetSelStart = selectionObj.focusOffset;
      rangeObj.offsetSelEnd   = selectionObj.anchorOffset;
    }
  }
  
  if (selectionObj.anchorNode != null)
  {
    rangeObj.setStart(selectionObj.anchorNode, rangeObj.offsetSelStart);
    rangeObj.setEnd(selectionObj.anchorNode, rangeObj.offsetSelEnd);
  }
  
  rangeObj.htmlText = win.getSelection().toString();
  rangeObj.text     = win.getSelection().toString();
  
  return rangeObj;
}

function bl_port_get_selection(doc)
{
  if (doc.selection)
  {
    return doc.selection;
  }
  
  return { empty:bl_port_selectionEmpty, createRange:bl_port_selectionCreateRange };
}

function bl_port_clear_selection()
{
  if (bl_browserInfo.ie)
  {
    var ael = bl_port_get_activeElement(document);
    
    if (ael && ael.tagName == "INPUT" && ael.type == "text")
    {
      var tr = ael.createTextRange();
      tr.execCommand("Unselect");
    }
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    // TODO: implement.
  }
}

function bl_port_range_duplicate(ran)
{
  if (bl_browserInfo.ie)
  {
    return ran.duplicate();
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var range = bl_port_get_selection(document).createRange(ran.offsetSelStart, ran.offsetSelEnd);
    range.offsetSelStart = ran.offsetSelStart;
    range.offsetSelEnd   = ran.offsetSelEnd;
    range.htmlText       = ran.toString();
    range.text           = ran.toString();
    return range;
  }
}

function bl_port_range_moveStart(ran, unit, count)
{
  if (bl_browserInfo.ie)
  {
    return ran.moveStart(unit, count);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var top_win = cb_sys_getTopWindow();
    if (top_win.moz_editFrame)
    {
      var win = top_win.moz_editFrame;
    }
    else
    {
      var win = window;
    }
    ran.htmlText    = ran.toString();
    ran.text        = ran.toString();
    var inc         = 0;
    var move_num    = 0;
    var check_space = 0;
    if (count < 0)
    {
      while (inc > count)
      {
        try
        {
          ran.setStart(win.document.selectionObj.anchorNode, (ran.offsetSelStart - 1));
          move_num++;
          ran.offsetSelStart--;
          ran.text = ran.toString();
        }
        catch(e)
        {
          break;
        }
        if (unit == "character")
        {
          inc--;
        }
        else if (unit == "word")
        {
          var letter = ran.text[0];
          if (letter.match(/\s/) && check_space > 0)
          {
            try
            {
              ran.setStart(win.document.selectionObj.anchorNode, (ran.offsetSelStart + 1));
              move_num--;
              ran.offsetSelStart++;
              ran.text = ran.toString();
            }
            catch(e)
            {
              break;
            }
            inc--;
          }
        }
        check_space++;
      }
    }
    else if (count > 0)
    {
      while (inc < count)
      {
        try
        {
          ran.setStart(win.document.selectionObj.anchorNode, (ran.offsetSelStart + 1));
          ran.offsetSelStart++;
          ran.text = ran.toString();
        }
        catch(e)
        {
          break;
        }
        if (ran.offsetSelStart == ran.offsetSelEnd)
        {
          try
          {
            ran.setEnd(win.document.selectionObj.anchorNode, (ran.offsetSelEnd + 1));
            ran.offsetSelEnd++;
            ran.text = ran.toString();
          }
          catch(e)
          {
          }
        }
        if (unit == "character")
        {
          inc++;
          move_num++;
        }
        else if (unit == "word")
        {
          var letter = ran.text[0];
          if (letter && letter.match(/\s/))
          {
            ran.setStart(win.document.selectionObj.anchorNode, (ran.offsetSelStart + 1));
            ran.offsetSelStart++;
            inc++;
            move_num++;
          }
        }
      }
    }
    ran.htmlText = ran.toString();
    ran.text     = ran.toString();
    return move_num;
  }
}

function bl_port_range_moveEnd(ran, unit, count)
{
  if (bl_browserInfo.ie)
  {
    return ran.moveEnd(unit, count);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var top_win = cb_sys_getTopWindow();
    if (top_win.moz_editFrame)
    {
      var win = top_win.moz_editFrame;
    }
    else
    {
      var win = window;
    }
    ran.htmlText = ran.toString();
    ran.text     = ran.toString();
    var inc      = 0;
    var move_num = 0;
    if (count < 0)
    {
      while (inc > count)
      {
        try
        {
          ran.setEnd(win.document.selectionObj.anchorNode, (ran.offsetSelEnd - 1));
          ran.offsetSelEnd--;
          ran.text = ran.toString();
        }
        catch(e)
        {
          break;
        }
        if (ran.offsetSelEnd == ran.offsetSelStart)
        {
          try
          {
            ran.setStart(win.document.selectionObj.anchorNode, (ran.offsetSelStart - 1));
            ran.offsetSelStart--;
            ran.text = ran.toString();
          }
          catch(e)
          {
          }
        }
        var letter = ran.text[ran.text.length - 1];
        if (unit == "character")
        {
          inc--;
          move_num++;
        }
        else if (unit == "word")
        {
          if (letter && letter.match(/\s/))
          {
            inc--;
            move_num++;
          }
        }
      }
    }
    else if (count > 0)
    {
      while (inc < count)
      {
        try
        {
          ran.setEnd(win.document.selectionObj.anchorNode, (ran.offsetSelEnd + 1));
          ran.offsetSelEnd++;
          ran.text = ran.toString();
        }
        catch(e)
        {
          break;
        }
        var letter = ran.text[ran.text.length - 1];
        if (unit == "character")
        {
          inc++;
          move_num++;
        }
        else if (unit == "word")
        {
          if (letter && letter.match(/\s/))
          {
            inc++;
            move_num++;
          }
        }
      }
    }
    ran.htmlText = ran.toString();
    ran.text     = ran.toString();
    return move_num;
  }
}

function bl_port_range_collapse(ran, where)
{
  if (bl_browserInfo.ie)
  {
    return ran.collapse(where);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var top_win = cb_sys_getTopWindow();
    if (top_win.moz_editFrame)
    {
      var win = top_win.moz_editFrame;
    }
    else
    {
      var win = window;
    }
    if (where == true)
    {
      try
      {
        ran.setEnd(win.document.selectionObj.anchorNode, ran.offsetSelStart);
      }
      catch(e)
      {
      }
      ran.text         = ran.toString();
      ran.offsetSelEnd = ran.offsetSelStart;
    }
    else if (where == false)
    {
      try
      {
        ran.setStart(win.document.selectionObj.anchorNode, ran.offsetSelEnd);
      }
      catch(e)
      {
      }
      ran.text           = ran.toString();
      ran.offsetSelStart = ran.offsetSelEnd;
    }
  }
}

function bl_port_range_expand(ran, unit, count)
{
  if (bl_browserInfo.ie)
  {
    return ran.expand(unit, count);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var top_win = cb_sys_getTopWindow();
    if (top_win.moz_editFrame)
    {
      var win = top_win.moz_editFrame;
    }
    else
    {
      var win = window;
    }
    if (unit == "character")
    {
      bl_port_range_moveEnd(ran, "character", count);
    }
    else if (unit == "word")
    {
      var letter;
      try
      {
        ran.setStart(win.document.selectionObj.anchorNode, (ran.offsetSelStart - 1));
        ran.text = ran.toString();
        letter   = ran.text[0];
        ran.setStart(win.document.selectionObj.anchorNode, ran.offsetSelStart);
      }
      catch(e)
      {
      }
      if (letter && !letter.match(/\s/))
      {
        bl_port_range_moveStart(ran, "word", -1);
      }
      if (!ran.text[ran.text.length - 1] || !ran.text[ran.text.length - 1].match(/\s/))
      {
        bl_port_range_moveEnd(ran, "word", 1);
      }
      ran.text = ran.toString();
    }
    return true;
  }
}

function bl_port_range_isEqual(ran, compareRange)
{
  if (bl_browserInfo.ie)
  {
    return ran.isEqual(compareRange);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    if (compareRange.offsetSelStart == ran.offsetSelStart && compareRange.offsetSelEnd == ran.offsetSelEnd && compareRange.text == ran.text)
    {
      return true;
    }
    else
    {
      return false;
    }
  }
}

function bl_port_range_setEndPoint(ran, type, range)
{
  if (bl_browserInfo.ie)
  {
    return ran.setEndPoint(type, range);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var top_win = cb_sys_getTopWindow();
    if (top_win.moz_editFrame)
    {
      var win = top_win.moz_editFrame;
    }
    else
    {
      var win = window;
    }
    if (type == "StartToStart")
    {
      //1. Compare current range end with source range start.
      //2. If current range end is less than source range start, then current range start is wanting to cross it's end position.
      //3. Collapse false.
      //4. Align current range end to source range start.
      //5. If current range end is greater than source range start, then align current range start to source range start as usual.
      var compare = ran.compareBoundaryPoints("END_TO_START", range);
      if (compare == -1)
      {
        bl_port_range_collapse(ran, false);
        ran.setEnd(win.document.selectionObj.anchorNode, range.offsetSelStart);
        ran.offsetSelEnd = range.offsetSelStart;
      }
      else if (compare == 0)
      {
        bl_port_range_collapse(ran, false);
      }
      else if (compare == 1)
      {
        ran.setStart(win.document.selectionObj.anchorNode, range.offsetSelStart);
        ran.offsetSelStart = range.offsetSelStart;
      }
      ran.text = ran.toString();
    }
    else if (type == "EndToStart")
    {
      //1. Compare current range start with source range start.
      //2. If current range start is greater than source range start, then current range end is wanting to cross it's start position.
      //3. Collapse true.
      //4. Align current range start to source range start.
      //5. If current range start is greater than source range start, then align current range end to source range start as usual.
      var compare = ran.compareBoundaryPoints("START_TO_START", range);
      if (compare == 1)
      {
        bl_port_range_collapse(ran, true);
        ran.setStart(win.document.selectionObj.anchorNode, range.offsetSelStart);
        ran.offsetSelStart = range.offsetSelStart;
      }
      else if (compare == 0)
      {
        bl_port_range_collapse(ran, true);
      }
      else if (compare == -1)
      {
        ran.setEnd(win.document.selectionObj.anchorNode, range.offsetSelEnd);
        ran.offsetSelEnd = range.offsetSelEnd;
      }
      ran.text = ran.toString();
    }
  }
}

function bl_port_range_move(ran, unit, count)
{
  if (bl_browserInfo.ie)
  {
    return ran.move(unit, count);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    if (count > 0)
    {
      bl_port_range_moveEnd(ran, unit, count);
    }
    var move_num = bl_port_range_moveStart(ran, unit, count);
    bl_port_range_collapse(ran, true);
    return move_num;
  }
}

function bl_port_inRange(ran, inrange)
{
  if (bl_browserInfo.ie)
  {
    return ran.inRange(inrange);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var offsetStart = inrange.startOffset;
    var offsetEnd   = inrange.endOffset;
    if ((ran.startOffset >= offsetStart && ran.startOffset <= offsetEnd) || (ran.endOffset <= offsetEnd && ran.endOffset >= offsetStart))
    {
      return true;
    }
    else
    {
      return false;
    }
  }
}

function bl_port_range_pasteHTML(ran, val)
{
  if (bl_browserInfo.ie)
  {
    return ran.pasteHTML(val);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var top_win = cb_sys_getTopWindow();
    if (top_win.moz_editFrame)
    {
      var win = top_win.moz_editFrame;
    }
    else
    {
      var win = window;
    }
    var div       = win.document.createElement("div");
    div.innerHTML = val;
    var ele       = div.childNodes[0];
    ran.deleteContents();
    ran.insertNode(ele);
    div = null;
  }
}

function bl_port_range_select(ran)
{
  if (bl_browserInfo.ie)
  {
    return ran.select();
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    
  }
}

function bl_port_moveToElementText(ran, replaceEl)
{
  if (bl_browserInfo.ie)
  {
    ran.moveToElementText(replaceEl);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
  
  }
}

/* HTMLDocument Methods */
function bl_port_get_activeElement(doc)
{
  var ret = null;
  
  try
  {
    if (bl_browserInfo.ie)
    {
      ret = doc.activeElement;
    }
    else if (bl_browserInfo.firefox || bl_browserInfo.safari)
    {
      ret = doc.bl_activeElement;
    }
  }
  catch (ex)
  {
    // active element on the document may be in a bad state
  }
    
  return ret;
}

function bl_port_onblur(event, el)
{
  if (el == document.bl_activeElement)
  {
    document.bl_activeElement = null;
  }

  // Stops propagation/bubble, but doesn't prevent the default action.
  bl_port_stop_event(event);
}

function bl_port_onfocus(event, el)
{
  var targetEl = bl_port_getEventTarget(event);
  if (cb_sys_isInput(targetEl))
  {
    // Other elements are handled via the "mousedown" routine.
    bl_kb_focusOnElement(targetEl);
  }
  document.bl_activeElement = el;

  // Stops propagation/bubble, but doesn't prevent the default action.
  bl_port_stop_event(event);
}

// Document Methods 
function bl_port_docWindow(doc)
{
  return doc.parentWindow || doc.defaultView;
}

/* CSSStyleDeclaration Methods */

// opacity is handle in different way for ie it is the 'filter' property on style in firefox and safari it is the opacity property on style
//
// opacity is a number between 0-100. An empty string or undefined opacity are treated as 100.
function bl_port_set_opacity(el, opacity)
{
  if (opacity == undefined || opacity === "")
  {
    opacity = 100;
  }
  
  if (bl_browserInfo.ie)
  {
    // An opacity equal to or greater than 100 should turn off the opacity filter.
    if (opacity < 100)
    {
      el.style.filter = "alpha(opacity=" + opacity + ")";
    }
    else
    {
      el.style.filter = "";
    }
  }
  else if (bl_browserInfo.firefox)
  {
    el.style.MozOpacity = opacity/100;
  }
  else if (bl_browserInfo.safari)
  {
    el.style.opacity = opacity/100;
  }
}

//
// opacity is a numer between 0-100
function bl_port_compute_opacity_style(opacity, computeName)
{
  var ret = "";
  
  if (bl_browserInfo.ie)
  {
    if (computeName)
    {
      ret += "filter:"
    }
    
    ret +=  ("alpha(opacity=" + opacity + ")");
  }
  else if (bl_browserInfo.firefox)
  {
    if (computeName)
    {
      ret += "-moz-opacity:"
    }
    
    ret +=  opacity/100;
  }
  else if (bl_browserInfo.safari)
  {
    if (computeName)
    {
      ret += "-khtml-opacity:"
    }
    
    ret +=  opacity/100;
  }
  
  if (computeName)
  {
    ret += ";"
  }
  
  return ret;
}

// this is for saving off original values of this style
function bl_port_orig_opacity_style(el)
{
  if (bl_browserInfo.ie)
  {
    return el.style.filter;
  }
  else if (bl_browserInfo.firefox)
  {
    if (el.style.MozOpacity != "")
    {
      return Math.ceil(el.style.MozOpacity * 100);
    }
    return 100;
  }
  else if (bl_browserInfo.safari)
  {
    if (el.style.opacity != "")
    {
      return Math.ceil(el.style.opacity * 100);
    }
    return 100;
  }
  
  return "";
}

// this is for coping opacity over from one element to another
function bl_port_copy_opacity(src, dest)
{
  if (bl_browserInfo.ie)
  {
    dest.style.filter = src.style.filter;
  }
  else if (bl_browserInfo.firefox)
  {
    dest.style.MozOpacity = src.style.MozOpacity;
  }
  else if (bl_browserInfo.safari)
  {
    dest.style.opacity = src.style.opacity;
  }
}

/* Element Methods */
function bl_port_get_xml(el)
{
  if (bl_browserInfo.ie)
  {
    return el.xml;
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var xml_text = bl_port_get_text(el);
//TODO: REMOVE COMMENTED CODE SOON.  Commented out by Tom on 2/5/2007.
//      Also remove the commented code in bl_port_get_text(...)
//    xml_text     = xml_text.replace(/\[/g, "&#91");
//    xml_text     = xml_text.replace(/\]/g, "&#93");
//    xml_text     = xml_text.replace(/--/g, "&#8211&#8211");
    var xml_id   = el.getAttribute("ID");

    // Firefox and safari sometimes have issues with CDATA sections within
    // HTML. This completly encapsulates the XML data within escaped text.
    // WARNING: This is not analagous to the IE "[Element].xml" property,
    // and should only be used with the bl_port_get_xmlDocument function.
    var xml_data = "<XML id=\"" + xml_id + "\"><sdata><![CDATA[" + xml_text + "]]></sdata></XML>";
    xml_data     = "<XML id=\"" + xml_id + "\">" + escape(xml_data) + "</XML>";
    return xml_data;
  }
}

function bl_port_get_text(item)
{
  var text;
  
  // Sometimes the element doesn't exist. At some point, figure out why. Until then, return empty string.
  if (item)
  {
    // IE uses the ".text" property.
    // Firefox uses .textContent with quirks.
    // Safari uses .textContent seamlessly.
    if (bl_browserInfo.ie)
    {
      text = item.text;
    }
    else if (bl_browserInfo.firefox || bl_browserInfo.safari)
    {
      text = item.textContent || item.value;
      
      if (!text && item.childNodes[0] && item.childNodes[0].nodeType == Node.COMMENT_NODE)
      {
        // XML CDATA sections are not allowed within the HTML DOM, so they are
        // converted to the non-equivalent comment nodes.
        // <el><![CDATA[content]]></el> becomes <el><!--[CDATA[content]]--></el>
        //              ^^^^^^^                         ^^^^^^^^^^^^^^^^
        // The text content of each node has been underlined, so the differences
        // are apparent. This hack is to remove the no-longer-necessary CDATA
        // wrapper.
        text = item.childNodes[0].textContent;
        text = text.substr(7, text.length-9);
      }
    }

    try
    {
      if (item.getAttribute("isEscaped") != null)
      {
        text = unescape(text);
      }
      
    } catch (e) {}
  }

  if (text == undefined)
  {
    text = "";
  }
    
  return text;
}

function bl_port_encodeChar(c)
{
  var code = c.charCodeAt(0);
  return "&#"+code+";";
}

function bl_port_encodeXml(val)
{
  return (typeof val == "string")? val.replace(/[&<>;\x0-\x32\x7F-\xFF]/g, bl_port_encodeChar) : val;
}

function bl_port_mergeAttributes(el, source, preserve)
{
  if (bl_browserInfo.ie)
  {
    return el.mergeAttributes(source);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var len = source.attributes.length;
    for (var i = 0; i < len; i++)
    {
      var attr_name  = source.attributes[i].name;
      var attr_value = source.getAttribute(attr_name);
      el.setAttribute(attr_name, attr_value);
    }
    for (i in source)
    {
      if (i == "onmouseover" || i == "onmousedown" || i == "onmousemove" || i == "onmouseup" || i == "onmouseout" || i == "onclick" || i == "ondblclick")
      {
        var event_name = i;
        var event_value = source.eval(i);
        switch(event_name)
        {
          case "onmouseover" : el.onmouseover = eval(event_value);
          case "onmousedown" : el.onmousedown = eval(event_value);
          case "onmousemove" : el.onmousemove = eval(event_value);
          case "onmouseup"   : el.onmouseup   = eval(event_value);
          case "onmouseout"  : el.onmouseout  = eval(event_value);
          case "onclick"     : el.onclick     = eval(event_value);
          case "ondblclick"  : el.ondblclick  = eval(event_value);
        }
      }
    }
  }
}

// [XMLDocument].parseError is not supported by Firefox or Safari. This creates
// and returns the appropriate parseError method
function bl_port_parseError(el)
{
  if (bl_browserInfo.ie)
  {
    return el.parseError;
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var hasError =
        !el || !el.documentElement || el.documentElement.localName == "parsererror" &&
        el.documentElement.getAttribute("xmlns") == "http://www.mozilla.org/newlayout/xml/parsererror.xml";

    if (!hasError && bl_browserInfo.safari)
    {
      hasError = el.documentElement.childNodes[0].localName == "parsererror";
    }

    var tempParseError =
    {
      errorCode: 0,
      filepos: 0, // not supported
      line:  0,
      linepos: 0,
      reason:  "",
      srcText: "",
      url:  ""
    };
    
    if (hasError)
    {
      tempParseError.errorCode = -1;
      try
      {
        tempParseError.srcText = el.getElementsByTagName("sourcetext")[0].firstChild.data;
        tempParseError.srcText = tempParseError.srcText.replace(/\n\-\^$/, "");
      }
      catch(ex)
      {
        tempParseError.srcText = "";
      }
      
      try
      {
        // now we need to parse the first text node
        var s = el.documentElement.firstChild.data;
        
        var re = /XML Parsing Error\: (.+)\nLocation\: (.+)\nLine Number (\d+)\, Column (\d+)/;
        var a  = re.exec(s);
        tempParseError.reason  = a[1];
        tempParseError.url     = a[2];
        tempParseError.line    = a[3];
        tempParseError.linepos = a[4];
      }
      catch(ex)
      {
        tempParseError.reason = "Unknown";
      }
    }
    return tempParseError;
  }
}

/* HTMLElement Methods */

function bl_port_coverDialog()
{
  var topWin = cb_sys_getTopWindow();
  
  if (topWin)
  {
    var cover = topWin.document.getElementById("bl_cover_id");

    if (cover)
    {
      cover.style.display = "block";
    }
  }  
}

function bl_port_uncoverDialog()
{
  var topWin = cb_sys_getTopWindow();
  
  if (topWin)
  {
    var cover = topWin.document.getElementById("bl_cover_id");

    if (cover)
    {
      cover.style.display = "none";
    }
  }  
}

// Covers child IFRAME elements with transparent DIV elements (to keep
// events in the right context). If "coverAll" is true, ALL child frames
// will be covered regardless of whether or not they are part of this
// application.
function bl_port_coverFrames(win,coverAll)
{
  // TODO: Make this function reuse DIV elements, rather than creating
  // new ones each time.
  if (win.bl_cover_divs)
  {
    // Clear old divs to avoid leaks.
    bl_port_uncoverFrames(win);
  }
  win.bl_cover_divs = [];
  var list          = win.document.getElementsByTagName("IFRAME");

  for (var j = 0; j < list.length; j++)
  {
    var el          = list[j];
    var innerWin    = el.contentWindow;
    var coverWindow = true;
    try
    {
      coverWindow = (coverAll || (!innerWin._bl_sys_last || innerWin.bl_is_main));
    }
    catch (ex)
    {
      // Access to the window was denied. It must not be ours.
    }
    if (coverWindow)
    {
      if (el.getBoundingClientRect)
      {
        var box    = el.getBoundingClientRect();
        var x      = box.left;
        var y      = box.top;
      }
      else if (win.document.getBoxObjectFor)
      {
        var box    = win.document.getBoxObjectFor(el);
        var x      = box.screenX-bl_port_getScreenLeft(win);
        var y      = box.screenY-bl_port_getScreenTop(win);
      }
      else
      {
        // TODO: create a bl_sys_find_xy function (to avoid the cost of going up the tree twice).
        var x      = bl_sys_find_x(el,null,false);
        var y      = bl_sys_find_y(el,null,false);
      }

      var coverDiv               = win.document.createElement("DIV");
      var coverStyle             = coverDiv.style;
      coverStyle.position        = "absolute";
      coverStyle.left            = x+"px";
      coverStyle.top             = y+"px";
      coverStyle.width           = el.offsetWidth+"px";
      coverStyle.height          = el.offsetHeight+"px";
      coverStyle.zIndex          = "32001";

      win.bl_cover_divs.push(coverDiv);
      win.document.body.appendChild(coverDiv);
    }
  }
}

// Removes all DIV elements created/positioned by bl_port_coverFrames(...)
function bl_port_uncoverFrames(win)
{
  if (win.bl_cover_divs)
  {
    var list = win.bl_cover_divs;
    for (var i=0; i<list.length; i++)
    {
      var coverEl = list[i];
      coverEl.parentNode.removeChild(coverEl);
    }
    delete win.bl_cover_divs;
  }
}

function bl_port_computeEventEl(el)
{
  if (!bl_browserInfo.ie)
  {
    var top_win = cb_sys_getTopWindow();
    if (el && !el.tagName && top_win.captureEl)
    {
      el = top_win.captureEl;
    }
  }
  
  return el;
}

function bl_port_computeEventElEXE(el)
{
  if (!bl_browserInfo.ie)
  {
    var top_win = cb_sys_getTopWindow();
    
    if (top_win.captureEl)
    {
      el = top_win.captureEl;
    }
  }
  
  return el;
}

/*  set/releaseCapture functions.  These functions will set capture on any element passed in for all frames and
    iframes in the document. */
function bl_port_setCapture(el)
{
  if (bl_browserInfo.ie)
  {
    el.setCapture();
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var topWin = cb_sys_getTopWindow();
    var list   = topWin.bl_port_getWindows(true);
    var len    = list.length;
    
    topWin.captureEl = el;
    
    for (var i = 0; i < len; i++)
    {
      var win = list[i];
      
      try
      {
        win.addEventListener("mouseover", bl_port_capture_event, true);
        win.addEventListener("mousedown", bl_port_capture_event, true);
        win.addEventListener("mousemove", bl_port_capture_event, true);
        win.addEventListener("mouseup", bl_port_capture_event, true);
        win.addEventListener("mouseout", bl_port_capture_event, true);
        win.addEventListener("click", bl_port_capture_event, true);
      }
      catch(exception)
      {
        // WARNING: Sometimes list[i] throws an error
        // when calling addEventListener. Caught to prevent this error,
        // but the root cause should really be found/fixed.
      }
    }
  }
}

function bl_port_releaseCapture(el)
{
  if (bl_browserInfo.ie)
  {
    el.releaseCapture();
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var topWin = cb_sys_getTopWindow();
    var list   = topWin.bl_port_getWindows(false);
    var len    = list.length;
    
    for (var i = 0; i < list.length; i++)
    {
      var win = list[i];
      
      try
      {
        win.removeEventListener("mouseover", bl_port_capture_event, true);
        win.removeEventListener("mousedown", bl_port_capture_event, true);
        win.removeEventListener("mousemove", bl_port_capture_event, true);
        win.removeEventListener("mouseup", bl_port_capture_event, true);
        win.removeEventListener("mouseout", bl_port_capture_event, true);
        win.removeEventListener("click", bl_port_capture_event, true);
      }
      catch (exception)
      {
        // WARNING: Sometimes list[i] throws an error
        // when calling removeEventListener. Caught to prevent this error,
        // but the root cause should really be found/fixed.
      }
    }
    
    topWin.captureEl = null;
  }
}

function bl_port_clientLeft(el)
{
  if (el.clientLeft == undefined)
  {
    var cstyle = getComputedStyle(el, null);
    return parseInt(cstyle.borderLeftWidth);
  }
  
  return el.clientLeft;
}

function bl_port_clientTop(el)
{
  if (el.clientTop == undefined)
  {
    var cstyle = getComputedStyle(el, null);
    return parseInt(cstyle.borderTopWidth);
  }
  
  return el.clientTop;
}

function bl_port_capture_event(e)
{
  var top_win = cb_sys_getTopWindow();
  var winLeft = 0;
  var winTop  = 0;
  var win     = this;

  while (win != top_win)
  {
    if (win.frameElement)
    {
      var coords = bl_sys_find_xy(win.frameElement, null, false);
      winLeft   += coords.x;
      winTop    += coords.y;
    }
    else
    {
      break;
    }
    win = win.parent;
  }
  
  var clientX = winLeft + e.clientX;
  var clientY = winTop + e.clientY;
  var el      = top_win.captureEl;
  
  e.captureEl     = el;
  e.bl_capturePos = {x:clientX,y:clientY};
  
  if (el)
  {
    var type = e.type;
    
    if (el.getAttribute && el.getAttribute("on" + type) != null)
    {
      bl_port_eval_call.call(el, el.getAttribute("on" + type), e)
    }
    else
    {
      var func = "el.on" + type;
      if (eval(func))
      {
        eval(func + "(e)");
      }
    }
  }  
}

function bl_port_getWindows(recompute)
{
  var topWin = cb_sys_getTopWindow();
  var list   = topWin.bl_computedWindowList;
  
  if (!list || recompute)
  {
    topWin.bl_computedWindowList = list = [];
  }
  
  if (recompute)
  {
    bl_port_computeWindows(list);
  }
  return list
}

function bl_port_computeWindows(list)
{
  list.push(this);

  var win_iframes = document.getElementsByTagName("IFRAME");
  var len         = win_iframes.length;

  for (var i = 0; i <= len; i++)
  {
    try
    {
      var iframe_el = win_iframes[i];
      
      if (iframe_el)
      {
        var contentWindow = iframe_el.contentWindow;
        
        if (contentWindow.bl_port_computeWindows)
        {
          contentWindow.bl_port_computeWindows(list);
        }
        else
        {
          list.push(contentWindow);
        }
      }
    }
    catch (e)
    {
      continue;
    }
  }
}
/* end of set/releaseCapture */

/* componentFromPoint returns if you are over a scroll bar */
// TODO: this algorthym is not quit right for safri and firefox yet
//       the scroll bar actuall needs to be showing for it to return true
//       and this just returns true if we are 20 pixels away from the element
//       right or bottom (also there has got to be a way to do this with out having to 
//       compute the real x and y of of the element
function bl_port_point_on_scrollbar(el, x, y)
{
  if (bl_browserInfo.ie)
  {
    var val =  el.componentFromPoint ? el.componentFromPoint(x, y) : "";
    return (val != "" && val != "outside");
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    with (el.style)
    {
      if (overflow  == "auto" || 
          overflow  == "scroll" || 
          overflowY == "scroll" || 
          overflowY == "auto" || 
          overflowX == "scroll" || 
          overflowX == "auto")
      {
        var realX = bl_sys_real_x(el, null, false);
        var realY = bl_sys_real_y(el, null, false);
        var realW = el.offsetWidth;
        var realH = el.offsetHeight;
        
        if ((x < (realX + realW) && x > ((realX + realW) - 20)) || 
            (y < (realY + realH) && y > ((realY + realH) - 20)))
        {
          return true;
        }
      }
    }
  }
  
  return false;
}

// Dispatches an event to an element and (optionally) bubbles up the DOM.
function bl_moz_dispatchEvent(el, event, bubbleToEl)
{
  var handlerName = "on"+event.type;
  var handler     = null;
	
  event.bl_targetEl           = el;
  event.bl_customCancelBubble = false;

  while (el && !event.bl_customCancelBubble)
  {
    handler = el[handlerName];
    
    if (!handler && el.getAttribute)
    {
      handler = el.getAttribute(handlerName);
    }
    
    if (handler)
    {
      if (typeof handler == "function")
      {
        // Call the handler in the context of the element, with the event as the parameter.
        handler.call(el, event);
      }
      else
      {
        // Make sure it's called in the context of the correct window
        var win = el.ownerDocument.defaultView;
        win.bl_moz_dispatchEval.call(el, handler, event);
      }
      handler = null;
    }
    if (!event.bubbles || el == bubbleToEl)
    {
      break;
    }
    el = el.parentNode;
  }

  delete event.bl_customCancelBubble;
}

function bl_moz_dispatchEval(strToEval, event)
{
  eval(strToEval);
}

function bl_port_insertAdjacentElement(el, where, element)
{
  if (bl_browserInfo.ie)
  {
    el.insertAdjacentElement(where, element);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    switch (where.toLowerCase())
    {
      case "beforebegin":
        el.parentNode.insertBefore(element, el);
      break;
      case "afterbegin":
        if (el.firstChild)
        {
          el.insertBefore(element, el.firstChild);
        }
        else
        {
          el.appendChild(element);
        }
      break;
      case "beforeend":
        el.appendChild(element);
      break;
      case "afterend":
        el.parentNode.insertBefore(element, el.nextSibling);
      break;
    }
  }
}

function bl_port_contains(el, canidateChild, includeEl)
{
  if (!el || !canidateChild)
  {
    return false;
  }

  if (canidateChild == el)
  {
    return includeEl;
  }

  try
  {
    if (el.contains)
    {
      return el.contains(canidateChild);
    }
    
    while (canidateChild)
    {
      if (canidateChild == el)
      { 
        return true;
      }
      canidateChild = canidateChild.parentNode;
    }
  }
  catch (exception)
  {
    // there are situations that cause this 
    // exception. like when the element was remove 
    // from the dom some how
  }
  
  return false;
}

function bl_port_setActive(el)
{
  try
  {
    if (el)
    {
      if (bl_browserInfo.ie)
      {
        if (el.setActive)
        {
          el.setActive();
        }
      }
      else
      {
        if (el.click)
        {
          el.click();
        }
      }
    }
  }
  catch(exception)
  {
    // ensuring that if this call is not
    // leagle in this context than ignore 
    // the error
  }
}

function bl_port_focus(el)
{
  try
  {
    if (el)
    {
      if (el.getAttribute)
      {
        // Only focus on elements...
        bl_kb_focusOnElement(el);
        bl_dfl_notifyInnerSelect(el);
      }
      else if (el.focus)
      {
        el.focus();
      }
    }
  }
  catch (e)
  {
    // it is posible to call this on a dialig window we do not own, and also
    // the focus method can throw an error if the element is not showing properly.
  }
}

// This function was build to allow seamless traversal of elements nested within
// IFrame elements. Provides a method to return the next node in the element's
// DOM hierarchy. This differs from el.parentNode in that if the top of the
// document is reached, this function will attempt to go to it's parent document
// for the next element.
// Returns: The parent element, crossing IFrame DOM boundaries.
function bl_port_findTrueParent(childEl)
{
  var parentEl = childEl.parentNode;
  
  if (parentEl && parentEl.tagName == "BODY")
  {
    var win = bl_port_docWindow(childEl.ownerDocument);
    
    try
    {
      parentEl = win.frameElement;
  
      if (parentEl)
      {
        // Ping the element to see if it's ours. (If it's not our IFrame,
        // this will throw an exception)
        parentEl.getAttribute("style");
      }
    }
    catch (error)
    {
      // The frame must not be ours. Return null.
      parentEl = null;
    }
  }
  
  return parentEl;
}


// insertAdjacentHTML is an IE specific method for inserting an HTML at certain points within the DOM
// We have to first render the element in an unseen DIV, then insert it's child as the inserted element 
function bl_port_insertAdjacentHTML(el, sWhere, sHTML)
{
  if (bl_browserInfo.ie)
  {
    el.insertAdjacentHTML(sWhere, sHTML);
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var r  = document.createRange();
	  var df;
		
    switch (sWhere.toLowerCase())
    {
      case "beforebegin":
        r.selectNodeContents(document.body);
        r.collapse(true);
        df = r.createContextualFragment(sHTML);
        el.parentNode.insertBefore(df, el);
      break;
      
      case "afterbegin":
        r.selectNodeContents(el);
        r.collapse(true);
        df = r.createContextualFragment(sHTML);
        el.insertBefore(df, el.firstChild);
      break;
      
      case "beforeend":
        r.selectNodeContents(el);
        r.collapse(false);
        df = r.createContextualFragment(sHTML);
        el.appendChild(df);
      break;
      
      case "afterend":
        r.setStartAfter(el);
        df = r.createContextualFragment(sHTML);
        el.parentNode.insertBefore(df, el.nextSibling);
      break;
    }
    r.detach();
  }
}

function bl_port_createTextRange(el)
{
  // Note: This function has been deprecated since different browsers provide very different range capabilities.
  if (el.createTextRange)
  {
    return el.createTextRange();
  }
  
  var range = bl_port_get_selection(document).createRange();
  var html  = el.innerHTML;
  
  range.htmlText = html;
  range.text     = html;
  
  return range;
}

/* HTMLBodyElement Methods */
function bl_port_get_bodyOffsetHeight()
{
  return this.clientHeight;
}

function bl_port_get_bodyOffsetWidth()
{
  return this.clientWidth;
}

// Event Methods 
function bl_addEventListener(el, name, func, capture)
{
  if (bl_browserInfo.ie)
  {
    var eventName = "on" + name;
    el.attachEvent(eventName, func);
  }
  else
  {
    el.addEventListener(name, func, capture);
  }  
}

function bl_removeEventListener(el, name, func, capture)
{
  if (bl_browserInfo.ie)
  {
    var eventName = "on" + name;
    el.detachEvent(eventName, func);
  }
  else
  {
    el.removeEventListener(name, func, capture);
  }  
}

function bl_port_set_returnValue(event, value)
{
  if (bl_browserInfo.ie)
  {
    event.returnValue = value;
  }
  if (!value && (bl_browserInfo.firefox || bl_browserInfo.safari))
  {
    event.stopPropagation();
  }
}

// compute rleative offset of an event with regard to 
// given target
function bl_port_offsetToItem(event, item)
{
  var el = item;
  var x  = 0;
  var y  = 0;
  
  while (el)
  {
    if (el.scrollLeft)
    {
      x += el.scrollLeft;
    }
    if (el.scrollTop)
    {
      y += el.scrollTop;
    }
    el = el.parentNode;
  }
  
  return {x:((event.clientX - bl_sys_real_x(item, null, false)) + x), 
          y:((event.clientY - bl_sys_real_y(item, null, false)) + y)};
}

function bl_port_keyCode(event)
{
  var ret = event.keyCode;
  
  if (ret == undefined)
  {
    ret = event.which;
  }

  return ret;
}

function bl_port_getVirtualKey(kcode)
{
  if (!window.bl_virtualKeyMap)
  {
    var map = {};
    map[ "32" ]  = "space";
    map[ "27" ]  = "esc";
    map[ "13" ]  = "enter";
    map[ "9" ]   = "tab";
    map[ "8" ]   = "bksp";
    map[ "16" ]  = "shift";
    map[ "17" ]  = "ctrl";
    map[ "18" ]  = "alt";
    map[ "37" ]  = "left";
    map[ "38" ]  = "up";
    map[ "39" ]  = "right";
    map[ "40" ]  = "down";
    map[ "33" ]  = "pgup";
    map[ "34" ]  = "pgdn";
    map[ "35" ]  = "end";
    map[ "36" ]  = "home";
    map[ "45" ]  = "ins";
    map[ "46" ]  = "del";
    map[ "190" ] = "dot";   // [ . > ]
    map[ "191" ] = "slash"; // [ / ? ]
    map[ "192" ] = "bktk";  // [ ` ~ ]
    map[ "220" ] = "bksla"; // [ \ | ]
    map[ "222" ] = "quote"; // [ ' " ]
    
    if (bl_browserInfo.firefox)
    {
      map[ "59" ]  = "colon"; // [ ; : ]
      map[ "61" ]  = "equal"; // [ = + ]
      map[ "188" ] = "comma"; // [ , < ]
      map[ "109" ] = "dash";  // [ - _ ]
    }
    else
    {
      map[ "186" ]  = "colon"; // [ ; : ]
      map[ "187" ]  = "equal"; // [ = + ]
      map[ "188" ]  = "comma"; // [ , < ]
      map[ "189" ]  = "dash";  // [ - _ ]
    }

    if (bl_browserInfo.safari)
    {
      // Safari seems to return unicode numbers for the keyCode value inside the keypress event.
      map[ "63272" ] = "del";
      map[ "63273" ] = "home";
      map[ "63274" ] = "ins";
      map[ "63275" ] = "end";
      map[ "63276" ] = "pgup";
      map[ "63277" ] = "pgdn";
      map[ "63232" ] = "up";
      map[ "63233" ] = "down";
      map[ "63234" ] = "left";
      map[ "63235" ] = "right";
      
      for (var i = 0; i < 12; i++)
      {
        map["" + (i + 63236)] = "f" + (i + 1);
      }
    }

    for (var i=65; i<=90; i++)
    {
      map["" + i] = String.fromCharCode(i).toLowerCase();
    }
    
    for (var i=0; i<=9; i++)
    {
      map["" + (i + 48) ] = "key" + i;
      map["" + (i + 96) ] = "num" + i;
    }
    
    for (var i=0; i<12; i++)
    {
      map["" + (i + 112)] = "f" + (i + 1);
    }
    
    window.bl_virtualKeyMap = map;
  }
  
  return window.bl_virtualKeyMap[kcode] || "undefined" + kcode;
}

function bl_port_removeComplexEl(el, parent)
{
  // ie  in ssl mode will throw up the mixed content warning
  // for removing dom that was freshly added this was the only way 
  // I could find to keep that from happening.  setting the outer
  // HTML of a dom element is esentially removing it from it's
  // parent with out invoking the warning. (eeeek)
  if (bl_browserInfo.ie)
  {
    el.outerText = "";
  }
  else
  {
    parent.removeChild(el);
  }
}

/* Attr Methods */
function bl_port_get_attrText()
{
  return this.value;
}

function bl_port_isTextNode(el)
{
  return (el.nodeType == 3 || (bl_browserInfo.firefox && el.nodeType == Node.TEXT_NODE));
}

// Function to determine whether or not the right mouse button was pressed for a given event.
function bl_port_isRightDown(event)
{
  return (event.type == "contextmenu" || event.button == 2 || event.button == 3 || event.which == 3)
}

function bl_port_button(event)
{
  return (event.which || event.button);
}

function bl_port_getInnerText(el)
{
  var ret = el.innerText;
  
  if (ret == undefined)
  {
    // TODO: include more input elements here
    if (el instanceof HTMLTextAreaElement)
    {
      ret = el.value;
    }
    else
    {
      var item  = el;
      var value = new cb_StringBuilder();
      
      var child = item.firstChild;
      
      while (child != null)
      {
        if (child.nodeType == Node.TEXT_NODE)
        {
          value.append(child.nodeValue.replace(/\n/g, ""));
        }
        else if (child.nodeType == Node.ELEMENT_NODE)
        {
          value.append(bl_port_getInnerText(child));
        }
        
        child = child.nextSibling;
      }
      
      ret = value.toString();
    }
  }
  
  return ret;
}

function bl_port_setInnerText(el, val)
{
  if (el.innerText == undefined)
  {
    el.innerHTML = "";
    
    if (el instanceof HTMLTextAreaElement)
    {
      el.value = val;
    }
    else
    {
      var doc = el.ownerDocument;
      
      if (typeof val == "string" && val.indexOf("\n") != -1)
      {
        // We can't just replace newlines with "<br>" and set the contents using
        // innerHTML, because it would not preserve the safety of special chars
        // (such as "<" and ">"). So we have to split on newlines, and manually
        // add text nodes and "BR" elements.
        var lines = val.split("\n");
        var len   = lines.length;
        
        el.appendChild(doc.createTextNode(lines[0]));
        
        for (var i = 1; i < len; i++)
        {
          el.appendChild(doc.createElement("BR"));
          el.appendChild(doc.createTextNode(lines[i]));
        }
      }
      else
      {
        el.appendChild(doc.createTextNode(val));
      }
    }
  }
  else
  {
    el.innerText = val;
  }
}

function bl_port_getOuterHTML(el)
{
  if (el.outerHTML == undefined)
  {
    var list = el.attributes;
    var len  = list.length;
    var name = el.tagName.toLowerCase();
    var str  = "<" + name;
    
    for (var i = 0; i < len; i++)
    {
      var attr = list[i];
      
      if (attr.specified)
      {
        str += " " + attr.name + '="' + attr.value + '"';
      }
    }
    
    switch (el.tagName)
    {
      case "AREA":
      case "BASE":
      case "BASEFONT":
      case "COL":
      case "FRAME":
      case "HR":
      case "IMG":
      case "BR":
      case "INPUT":
      case "ISINDEX":
      case "LINK":
      case "META":
      case "PARAM":
        return str + ">";
    }
    
    return str + ">" + el.innerHTML + "</" + name + ">";
  }
  
  return el.outerHTML;
}

function bl_port_setOuterHTML(el, val)
{
  if (el.outerHTML == undefined)
  {
    var r = el.ownerDocument.createRange();
    
    r.setStartBefore(el);
    
    var df = r.createContextualFragment(val);
    
    el.parentNode.replaceChild(df, el);
  }
  else
  {
    el.outerHTML = val;
  }
}

// Function to determine whether or not the left mouse button was pressed for a given event.
function bl_port_isLeftDown(event)
{
  if (bl_browserInfo.ie)
  {
    // IE is inconsistent regarding the "button" property of event.
    // For "mousedown", "mouseup", and "mousemove" events, if the left
    // button is down, the "button" property will be "1". For other
    // mouse events, the "button" property will be "0".
    if (event.type == "mousedown" || event.type == "mouseup" || event.type == "mousemove")
    {
      return (event.button == 1);
    }

    return (event.button == 0);
  }

  // WC3 DOM spec defines button "0" as the left button.
  // The "which" property uses "1" for the left button, but is not supported by IE.
  return (event.button == 0 || event.which == 1);
}

function bl_port_isCharEvent(event)
{
  // Check keys that are reasonably within the normal ASCII set
  if (typeof event.charCode != "undefined")
  {
    return (event.charCode >= 32 && event.charCode <= 255);
  }

  var kcode = bl_port_keyCode(event);
  return (kcode >= 32 && kcode <= 255);
}

/* HTMLUnknownElement Methods */
function bl_port_get_XMLDocument(xmlData)
{
  if (bl_browserInfo.ie)
  {
    return xmlData.XMLDocument;
  }
  else if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var domParser = new DOMParser();
    var preparsed = xmlData.innerHTML;
    if (xmlData.firstChild && xmlData.firstChild.nodeType == Node.TEXT_NODE)
    {
      // firefox and safari have issues with CDATA sections in HTML
      // so this takes an extra step to unwrap XML data that has been
      // previously wrapped up and stored within the element.
      //
      // This extra step is only needed if the XML node was added 
      // using the bl_port_get_xml function. This method assumes that
      // if unescaping is necessary if the "<xml>" node contains only
      // a single text node (and no other nodes).
      preparsed = unescape(preparsed);
    }
    return domParser.parseFromString(preparsed, "text/xml");
  }
}

bl_port_initWindow(window);

function bl_port_getScreenLeft(win)
{
  if (bl_browserInfo.ie)
  {
    return win.screenLeft;
  }
  else if (win.__screenLeft__)
  {
    // This value only works if a normal mouseover event has ever been fired into the window.
    return win.__screenLeft__;
  }
  else if (bl_browserInfo.firefox)
  {
    // Performance can potentially be gained by caching the box object.
    if (!win.moz_boxObject)
    {
      win.moz_boxObject = win.document.getBoxObjectFor(win.document.documentElement);
    }
    return win.moz_boxObject.screenX;
  }
  return 0;
}

function bl_port_getScreenTop(win)
{
  if (bl_browserInfo.ie)
  {
    return win.screenTop;
  }
  else if (win.__screenTop__)
  {
    // This value only works if a normal mouseover event has ever been fired into the window.
    return win.__screenTop__;
  }
  else if (bl_browserInfo.firefox)
  {
    // Performance can potentially be gained by caching the box object.
    if (!win.moz_boxObject)
    {
      win.moz_boxObject = win.document.getBoxObjectFor(win.document.documentElement);
    }
    return win.moz_boxObject.screenY;
  }
  return 0;
}

function bl_port_hasAttribute(el, attrName)
{
  if (el)
  {
    if (typeof el.hasAttribute != "undefined")
    {
      return el.hasAttribute(attrName);
    }
    if (typeof el.getAttribute != "undefined")
    {
      return (el.getAttribute(attrName) != null)
    }
  }
  return false;
}

function bl_port_computeColor(el)
{
  var ret = "";
  
  if (el)
  {
    if (bl_browserInfo.ie)
    {
      ret = el.currentStyle.color;
    }
    else
    {
      ret = getComputedStyle(el, null).getPropertyValue("color");
    }
  }
  return ret;
}

function bl_port_getComputedStyle(el)
{
  if (el.currentStyle)
  {
    return el.currentStyle;
  }
  else if (typeof getComputedStyle == "function")
  {
    return getComputedStyle(el,null);
  }
  else
  {
    throw new Error("Unsupported browser error: Missing getComputedStyle/currentStyle implementation.");
  }
}

function bl_port_initScrollbarStyle()
{
  if (!window.bl_sb_dim)
  { // we don't need to add the scrollbar style if we already did it on this window.
    var sb  = bl_port_getScrollbarDim();
    var el  = document.createElement('style');
    var css = " .bl_sb_width { width: " 
             + sb.width 
             + "px; } .bl_sb_height { height: " 
             + sb.height 
             + "px; } ";

    el.type = 'text/css';
    document.getElementsByTagName("head")[0].appendChild(el);
    
    if(el.styleSheet)
    {
      el.styleSheet.cssText = css;
    }
    else
    {
      el.appendChild(document.createTextNode(css));
    }
  }
}

// This function calculates the correct size of the scrollbar.
function bl_port_getScrollbarDim()
{
  if (!window.bl_sb_dim)
  {
    var el = document.createElement("DIV");
    el.style.overflow = "scroll";
    el.style.width    = "75px";
    el.style.height   = "75px";
    el.innerHTML      = "<div style='width:100px;height:100px'></div>";
    document.body.appendChild(el);
    window.bl_sb_dim = { width: (75-el.clientWidth), height: (75-el.clientHeight) };
    document.body.removeChild(el);
  }
  
  return window.bl_sb_dim;
}

function bl_port_getEventTarget(event)
{
  // The ECMAScript "||" operator does not return a simple boolean.
  // It returns the first value in the expression that does not evaluate
  // to false.
  return event.bl_targetEl || event.srcElement || event.target;
}

function bl_port_syntheticEvent(winView)
{
  this.altKey                = false;
  this.bubbles               = true;
  this.button 	             = 0;
  this.bl_customCancelBubble = false;

  if (bl_browserInfo.ie)
  {
    this.cancelBubble   = false;
  }

  this.cancelable       = true;
  this.charCode         = 0;
  this.clientX 	        = 0;
  this.clientY 	        = 0;
  this.ctrlKey 	        = false;
  this.currentTarget    = null;
  this.detail 	        = 0;
  this.eventPhase       = "";
  this.isChar 	        = false;
  this.keyCode 	        = 0;
  this.layerX 	        = 0;
  this.layerY 	        = 0;
  this.metaKey 	        = false;
  this.pageX 	          = 0;
  this.pageY 	          = 0;
  this.relatedTarget    = null;
  this.screenX 	        = 0;
  this.screenY 	        = 0;
  this.srcElement       = null;
  this.shiftKey         = false;
  this.target 	        = null;
  this.timeStamp        = new Date();
  this.type 	        = "";
  this.view 	        = winView;
  this.which 	        = 0;
  
  this.defaultPrevented = false;
}

bl_port_syntheticEvent.prototype.preventDefault = function()
{
  this.defaultPrevented = true;
}

bl_port_syntheticEvent.prototype.stopPropagation = function()
{
  if (bl_browserInfo.ie)
  {
    this.cancelBubble = true;
  } 
  else
  {
    this.bl_customCancelBubble = true;
  }
  
  this.bubbles = false;
}

bl_port_syntheticEvent.prototype.initEvent = function(type, bubble, cancelable)
{
  this.type = type;
  this.bubbles = bubble;
  this.cancelable = cancelable;
}

function bl_port_createSyntheticEvent(type, bubble, cancelable)
{
  var e = new bl_port_syntheticEvent();
  e.initEvent(type, bubble, cancelable);
  return e;
}

function _bl_sys_fixIE6Size()
{
  // In IE6, the dialog sizes specify the outer width of the window instead
  // of the content area. Discover the size of the chrome by subtracting the
  // dialog dimensions from the size of the body. Then resize the window to
  // the corrected size.

  if (!document.body)
  {
    // Unfortunately, we don't know the body size until the window has been
    // loaded, so we will re-call this function as many times as necessary.
    setTimeout("_bl_sys_fixIE6Size()",10);
    return;
  }
  
  var outerHeight  = parseInt(window.dialogHeight);
  var outerWidth   = parseInt(window.dialogWidth);
  var chromeHeight = outerHeight - document.body.offsetHeight;
  var chromeWidth  = outerWidth - document.body.offsetWidth;
  
  window.dialogHeight = outerHeight + chromeHeight + "px";
  window.dialogWidth  = outerWidth + chromeWidth + "px";
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_port_last()
{
  var x = 0;
}

//***********************************************************************
//***********************************************************************
//********                    bl_util.js                        *********
//***********************************************************************
//***********************************************************************

/*receives the window.search.location to parse and return a map of name value pairs*/
function blu_DecodeQueryString(str)
{
  if (str.charAt(0) == '?')
  {
    str = str.substr(1);
  }
  var pairs = str.split("&");
  var map = {};
  for (var i=0;i<pairs.length;++i)
  {
    var kv = pairs[i].split("=");
    map[escape(kv[0])] = escape(kv[1]);
  }
  return map;
}

// this function is for setting the contents of and html
// element depending on the type of text being set on it's
// content.  NOTE: this is a utility for control handlers to 
// use set content coming from an mpr message. 
// args: el        (required) - the html element
//       value     (required) - the xml node that contains the content
//       isEscaped (optional) - indicates if the content is url encoded and needs 
//                              unescaping,
// returns: the length of the context
function blu_setElContent(el, value)
{
  var content = bl_port_get_text(value);

  if (value.getAttribute("isHTML") != null)
  {
    el.innerHTML = content;
  }
  else
  {
    bl_port_setInnerText(el, content);
  }
  
  return content.length;
}

function blu_Rounder(desired, cnt)
{
  this.count   = cnt;
  this.remain  = 0.0;
  this.total   = 0;
  this.desired = desired;
}

blu_Rounder.prototype.round = function(value)
{
  if (this.count <= 1)
  {
    result = this.desired - this.total;
  }
  else
  {
    this.count--;
    var result   = Math.round(value);
    this.remain += (value - result);
    if (this.remain >= 1)
    {
      result      += 1;
      this.remain -= 1;
    }
  }

  this.total += result;
  return result;
}

function blu_getChild(topEl, tagName, childId)
{
  var list = topEl.getElementsByTagName(tagName);
  var len  = list.length;
  var ret  = null;
  
  for (var i = 0; i < len; i++)
  {
    var child = list[i];
    
    if (child.id == childId)
    {
      ret = child;
      break;
    }
  }
  
  return ret;
}

function blu_createRect(left, top, width, height)
{
  this.left    = left;
  this.right   = left + width;
  this.top     = top;
  this.bottom  = top + height;
  this.width   = width;
  this.height  = height;
}

blu_createRect.prototype.intersects = function(left, top, right, bottom)
{
  if (this.left > right ||
      left > this.right ||
      this.top > bottom ||
      top > this.bottom)
  {
    return false;
  }
  return true;
}

blu_createRect.prototype.intersectsRect = function(rect)
{
  if (this.left > rect.right ||
      rect.left > this.right ||
      this.top > rect.bottom ||
      rect.top > this.bottom)
  {
    return false;
  }
  return true;
}

function bl_sys_find_scrollOffset(el, toParent, lookforAbsoluteParent)
{
  var p = el.offsetParent;
  var x = el.scrollLeft;
  var y = el.scrollTop;
  
  while (p && p != toParent)
  {
    if (lookforAbsoluteParent)
    {
      var pos = p.style.position;
      
      if (pos == "absolute" || pos == "relative")
      {
        break;
      }
    }
    
    x += p.scrollLeft;
    y += p.scrollTop;
    p = p.offsetParent;
  }
  return {left:x,top:y};
}

function bl_sys_find_xy(el, toParent, lookforAbsoluteParent)
{
  var p = el.offsetParent;
  var x = el.offsetLeft;
  var y = el.offsetTop;
  
  while (p && p != toParent)
  {
    if (lookforAbsoluteParent)
    {
      var pos = p.style.position;
      
      if (pos == "absolute" || pos == "relative")
      {
        break;
      }
    }
    
    x += (p.offsetLeft - p.scrollLeft);
    y += (p.offsetTop - p.scrollTop);
    p = p.offsetParent;
  }
  return {x:x,y:y};
}

function bl_sys_find_x(el, toParent, lookforAbsoluteParent)
{
  var p = el.offsetParent;
  var x = el.offsetLeft;
  
  while (p && p != toParent)
  {
    if (lookforAbsoluteParent)
    {
      var pos = p.style.position;
      
      if (pos == "absolute" || pos == "relative")
      {
        break;
      }
    }
    
    x += (p.offsetLeft - p.scrollLeft);
    p = p.offsetParent;
  }
  return x;
}

function bl_sys_find_y(el, toParent, lookforAbsoluteParent)
{
  var y = el.offsetTop;
  var p = el.offsetParent;
  
  while (p && p != toParent)
  {
    if (lookforAbsoluteParent)
    {
      var pos = p.style.position;
      
      if (pos == "absolute" || pos == "relative")
      {
        break;
      }
    }

    y += (p.offsetTop - p.scrollTop);
    p = p.offsetParent;
  }
  
  return y;
}


function bl_sys_real_x(el, toParent, lookforAbsoluteParent)
{
  var p = el.offsetParent;
  var x = el.offsetLeft;
  
  while (p && p != toParent)
  {
    if (lookforAbsoluteParent)
    {
      var pos = p.style.position;
      
      if (pos == "absolute" || pos == "relative")
      {
        break;
      }
    }
    
    x += p.offsetLeft;
    p = p.offsetParent;
  }
  return x;
}

function bl_sys_real_y(el, toParent, lookforAbsoluteParent)
{
  var y = el.offsetTop;
  var p = el.offsetParent;
  
  while (p && p != toParent)
  {
    if (lookforAbsoluteParent)
    {
      var pos = p.style.position;
      
      if (pos == "absolute" || pos == "relative")
      {
        break;
      }
    }

    y += p.offsetTop;
    p = p.offsetParent;
  }
  
  return y;
}

function bl_sys_real_xy(el, toParent, lookforAbsoluteParent)
{
  var x = el.offsetLeft;
  var y = el.offsetTop;
  var p = el.offsetParent;
  
  while (p && p != toParent)
  {
    if (lookforAbsoluteParent)
    {
      var pos = p.style.position;
      
      if (pos == "absolute" || pos == "relative")
      {
        break;
      }
    }

    y += p.offsetTop;
    x += p.offsetLeft;
    p = p.offsetParent;
  }
  
  return {x:x,y:y};
}

function cb_sys_getTopWindow()
{
  var win = window;
  while (win.parent != win)
  {
    if (win.bl_is_main)
    {
      return win;
    }
    win = win.parent;
  }
  return win;
}

function cb_sys_getTopLevelWindow()
{
  var win = window;
  while (win.parent != win)
  {
    if (win.bl_is_main)
    {
      return win;
    }
    
    if (win.frameElement && win.frameElement.container && win.frameElement.container.popup_obj.popup_arg.sticky)
    {
      // A popup is only a top level window if it is sticky. This should prevent weird behavior in many cases
      return win;
    }
    
    win = win.parent;
  }
  return win;
}

function cb_sys_isInput(el)
{
  if (el == undefined || el.tagName == undefined || el.getAttribute == undefined)
  {
    return false;
  }
  return (el.tagName == "TEXTAREA"              ||
          (el.tagName == "A" && el.href != "")  ||
          el.tagName == "INPUT"                 ||
          el.tagName == "SELECT"                ||
          el.tagName == "OPTION"                ||
          el.isContentEditable);
}

function bl_sys_get_main(refWin)
{
  if (refWin == undefined)
  {
    refWin = window;
  }
  
  // The main window should always be accesible from a child window
  // (because no window can have more than 2 parents).
  var list;
  
  while (refWin)
  {
    if (refWin.bl_is_main || refWin.mpr)
    {
      return refWin;
    }
    
    list = refWin.bl_window_list;
    
    if (list)
    {
      var len = list.length;
      
      for (var i = 0; i < len; i++)
      {
        var item = list[i];
        
        if (item.bl_is_main || item.mpr)
        {
          return item;
        }
      }
    }

    if (refWin.opener && refWin.opener != refWin)
    {
      refWin = refWin.opener;
    }
    else if (refWin.parent != refWin)
    {
      refWin = refWin.parent;
    }
    else
    {
      refWin = null;
    }
  }
  
  return null;
}

function cb_sys_getScreenTop(pass)
{
  if (window.bl_sys_isInPopup() && !pass)
  {
    return bl_port_getScreenTop(window);
  }
  
  var topw = cb_sys_getTopWindow();
  var y    = bl_port_getScreenTop(topw);
  var win  = window;
  
  while (win && !win.bl_is_main)
  {
    if (win.frameElement)
    {
      y += bl_sys_find_y(win.frameElement, null, false);
    }
    if (win == win.parent)
    {
      break;
    }
    win = win.parent;
  }
  return y;
}

function cb_sys_getScreenLeft(pass)
{
  if (window.bl_sys_isInPopup() && !pass)
  {
    return bl_port_getScreenLeft(window);
  }
  
  var top = cb_sys_getTopWindow();
  var x   = bl_port_getScreenLeft(top);
  var win = window;
  
  while (win && !win.bl_is_main)
  {
    
    if (win.frameElement)
    {
      x += bl_sys_find_x(win.frameElement, null, false);
    }
    if (win == win.parent)
    {
      break;
    }
    win = win.parent;
  }
  return x;
}

function bl_removeFromList(list, item)
{
  if (list)
  {
    var len = list.length;
    
    for (var i = 0; i < len; ++i)
    {
      if (list[i] == item)
      {
        list.splice(i, 1);
        break;
      }
    }
  }
}

function cb_util_getParent(el, tagName)
{
  var ret = el;
  
  while (ret)
  {
    if (ret.getAttribute && ret.getAttribute("cb_tag") == tagName)
    {
      break;
    }
    ret = ret.parentNode;
  }
  
  if (!ret && window.frameElement && window.frameElement.getAttribute("cb_tag") == tagName)
  {
    ret = window.frameElement;
  }
  
  return ret;
}

// ie will throw an exception if the value of the
// color is invalide
function bl_port_setBGColor(style, color)
{
  try
  {
    style.backgroundColor = color;
  }
  catch (ex)
  {
    // ie will an throw exception if the color value is not valid
    style.backgroundColor = "";
  }
}

function blu_computeDialogPos(arg, topWindow)
{
  var body           = topWindow.document.body;
  var windowWidth    = bl_browserInfo.ie ? body.clientWidth : topWindow.innerWidth;
  var windowHeight   = bl_browserInfo.ie ? body.clientHeight : topWindow.innerHeight;
  var positionType   = arg.positionType;
  var computedHeight = arg.computedHeight;
  var computedWidth  = arg.computedWidth;

  show_top  = arg.y;
  show_left = arg.x;
  
  if (positionType == "left-top" || positionType == "at-mouse")
  {
    // do nothing
  }
  else if (positionType == "bottom-right")
  {
    show_top  = windowHeight - show_top - computedHeight;
    show_left = windowWidth - show_left - computedWidth;
  }
  else if (positionType == "right-top")
  {
    show_left = windowWidth - show_left - computedWidth;
  }
  else if (positionType == "bottom-left")
  {
    show_top = windowHeight - show_top - computedHeight;
  } 
  else if (positionType == "control" && arg.el)
  {
    var el             = arg.el;
    var parentWindow   = bl_port_docWindow(el.ownerDocument)
    var bounds         = bl_sys_find_xy(el, null, false);
    var hbuddy         = el.getAttribute("bl_hilite_buddy");
    var controlHAlign  = arg.controlHAlign;
    var controlVAlign  = arg.controlVAlign;
    var screenTopDiff  = bl_port_getScreenTop(parentWindow) - bl_port_getScreenTop(topWindow)
    var screenLeftDiff = bl_port_getScreenLeft(parentWindow) - bl_port_getScreenLeft(topWindow)

    // if the window is supposed to be displayed on a content item inside the control find the offset
    bounds.y += screenTopDiff;
    bounds.x += screenLeftDiff;
    var positionedOnContents = false;
    if (el.contentPosition)
    {
      positionedOnContents = el.contentPosition(arg.itemIndex, bounds);
    }

    if (!positionedOnContents)
    {
      bounds.bottom = bounds.y + el.offsetHeight;  
      bounds.right  = bounds.x + el.offsetWidth;
      bounds.width  = el.offsetWidth;  
      bounds.height = el.offsetHeight;
    }

    if (hbuddy)
    {
      var buddyEl = document.getElementById(hbuddy);
      
      if (buddyEl)
      {
        var buddyBounds = bl_sys_find_xy(buddyEl, null, false);
        buddyBounds.y += screenTopDiff;
        buddyBounds.x += screenLeftDiff;
        buddyBounds.bottom = buddyBounds.y + el.offsetHeight;  
        buddyBounds.right  = buddyBounds.x + el.offsetWidth;
        
        bounds.x      = Math.min(buddyBounds.x, bounds.x);
        bounds.y      = Math.min(buddyBounds.y, bounds.y);
        bounds.bottom = Math.max(buddyBounds.bottom, bounds.bottom);
        bounds.right  = Math.max(buddyBounds.right, bounds.right);
        bounds.width  = bounds.right - bounds.x;  
        bounds.height = bounds.bottom - bounds.y;
      }
    }

    if (arg.doSideCart)
    {
      if (controlVAlign == "Middle")
      {
        show_top  = bounds.y + (bounds.height/2) - (computedHeight/2);
      }
      else if (controlVAlign == "Top")
      {
        show_top  = bounds.y;
        
        if (show_top + computedHeight > windowHeight)
        {
          show_top = bounds.bottom - computedHeight;
        }
      }
      else 
      {
        show_top = bounds.bottom - computedHeight;
        
        if (show_top < 0)
        {
          show_top = bounds.bottom;
        }
      }
      
      if (controlHAlign == "Center")
      {
        show_left = bounds.x + (bounds.width/2) - (computedWidth/2);
      }
      else if (controlHAlign == "Right")
      {
        show_left = bounds.right;
        
        if (show_left + computedWidth > windowWidth)
        {
          show_left = bounds.x - computedWidth;
        }
      }
      else 
      {
        show_left = bounds.x - computedWidth;
        
        if (show_left < 0)
        {
          show_left = bounds.right;
        }
      }
    }
    else
    {
      if (controlVAlign == "Middle")
      {
        show_top  = bounds.y + (bounds.height/2) - (computedHeight/2);
      }
      else if (controlVAlign == "Top")
      {
        show_top  = bounds.y - computedHeight;
        
        if (show_top < 0)
        {
          show_top = bounds.bottom;
        }
      }
      else 
      {
        show_top = bounds.bottom;
        
        if (show_top + computedHeight > windowHeight)
        {
          show_top = bounds.y - computedHeight;
        }
      }

      if (controlHAlign == "Center")
      {
        show_left = bounds.x + (bounds.width/2) - (computedWidth/2);
      }
      else if (controlHAlign == "Right")
      {
        show_left = bounds.right - computedWidth;
      }
      else
      {
        show_left = bounds.x;
      }
    }

    show_top  += arg.y;
    show_left += arg.x;
  }
  else
  {
    show_left += parseInt((windowWidth/2) - (computedWidth/2));
    show_top  += parseInt((windowHeight/2) - (computedHeight/2));
  } 
  
  if (show_left + computedWidth > windowWidth)
  {
    show_left = windowWidth - computedWidth;
  }
    
  if (show_top + computedHeight > windowHeight)
  {
    show_top = windowHeight - computedHeight;
  }
    
  if (show_left < 0)
  {
    show_left = 0;
  }
  if (show_top < 0)
  {
    show_top = 0;
  }

  return { x:show_left, y:show_top };
}
/*Find the index of an item within an array */
function blu_array_findIndex(list, item)
{
  for (var i in list)
  {
    if (list[i] == item)
    {
      return (i);
    }
  }
  return -1;
}

//***********************************************************************
//***********************************************************************
//********                    bl_mpr.js                         *********
//***********************************************************************
//***********************************************************************

var BL_MPR_ASAP     = 0;
var BL_MPR_DEFER    = 1;
var BL_MPR_APPEND   = 2;
var BL_MPR_SYNC     = 3;

function bl_sys_readSendType(el)
{
  var sendType = el.getAttribute("bl_send_type");
  return (sendType != null)? parseInt(sendType):BL_MPR_ASAP;
}

function bl_sys_get_mpr(win)
{
  if (win != undefined)
  {
    curWin = win;
  }
  else
  {
    curWin = window;
  }
  
  var mainWin = bl_sys_get_main(curWin);
  var mpr = null;
  
  try
  {
    mpr = mainWin.mpr;
  }
  catch (exception)
  {
    // WARNING: When this exception is thrown, a null MPR object is
    // returned. In most cases, this function is invoked because a
    // message must be sent to the server. If this function returns
    // null, either the calling function will crash (null exception),
    // or quietly fail to send the message.
    //
    // In any case, there are only 2 reasons this might fail:
    //   1) The main window is unavailable from here - BAD!
    //   2) The main window has not yet initialized - less bad.
  }
  return mpr;
}

function cb_sys_new_request_obj()
{
  var progIDs = ["msxml2.XMLHttp.3.0", "msxml2.XMLHttp", "Microsoft.XMLHttp"];
  var tmpObj;
  
  // Mozilla
  if (typeof(XMLHttpRequest) != "undefined")
  {
    tmpObj              = new XMLHttpRequest();
    this.requestObjName = "XMLHttpRequest";
    this.create         = cb_sys_new_request_obj_found;
    return tmpObj;
  }
  
  for (var i = 0; i < progIDs.length; i++)
  {
    var doBreak = true;
    
    tmpObj = new ActiveXObject(progIDs[i]);

    if (doBreak)
    {
      // now that we know what can be created then lets swap out the create function
      // so we do not need to find it again
      this.requestObjName = progIDs[i];
      this.create         = cb_sys_new_request_obj_found;
      break;
    }
  }
  
  return tmpObj;
}

function cb_sys_new_request_obj_found()
{
  return (this.requestObjName == "XMLHttpRequest")? new XMLHttpRequest(): new ActiveXObject(this.requestObjName);
}

function cb_sys_mpr_create()
{
  // data
  this.requestList         = new Array();
  this.syncResponseList    = new Array();
  this.flushBlocked        = false;
  this.flushASAP           = false;
  this.handleException     = true;
  this.pendingPopupContext = null;
  this.requestObj          = null;
  this.requestObjName      = null;
  this.pulseTime           = 0;
  this.parseTime           = 0;
  this.pulseId             = 0;
  this.retryCount          = 0;
  this.startTime           = 0;
  this.syncTimeStart       = 0;
  this.syncPulseTime       = 0;
  this.sessionClosed       = false;
  
  // funcs
  this.create              = cb_sys_new_request_obj;
  this.send                = cb_sys_mpr_send;
  this.asyncFlush          = bl_sys_asyncFlush;
  this.release             = cb_sys_mpr_releaseFlush;
  this.flush               = cb_sys_mpr_flush;
  this.response            = cb_sys_mpr_response;
  this.request             = cb_sys_http_request;
  this.setPopupContext     = cb_sys_mpr_setContext;
  this.findMessage         = cb_sys_mpr_findMessage;
  this.addCloseTracker     = bl_sys_closeTrackerAdd;
}

function cb_sys_mpr_setContext(context, isKill)
{
  var oldContext = this.pendingPopupContext;

  if (oldContext)
  {
    if (isKill)
    {
      var el = oldContext.el;
      
      if (el.cb_popup_cleanup)
      {
        el.cb_popup_cleanup(el);
      }
    }
    
    if (oldContext.el)
    {
      oldContext.el.style.cursor = "";
    }
    
    oldContext.el = null;
    delete this.pendingPopupContext;
    this.pendingPopupContext = null;
  }
  
  this.pendingPopupContext = context;
}

/*
 *
 */
function cb_sys_mpr_releaseFlush()
{
  bl_sys_mpr_fb_dettach();
  if (this.flushASAP)
  {
    this.flush();
  }
  else
  {
    this.flushBlocked = false;
  }
}

/*
 *
 */
function cb_sys_mpr_cleanUp(mpr)
{
  if (mpr)
  {
    delete mpr.pendingPopupContext;
    mpr.pendingPopupContext = null;
    delete mpr.requestList;

    mpr.requestList         = null;
    mpr.release             = null;
    mpr.send                = null;
    mpr.flush               = null;
    mpr.asyncFlush          = null;
    mpr.flushItems          = null;
    mpr.response            = null;
    mpr.request             = null;
    mpr.parentWin           = null;
    mpr.setPopupContext     = null;
    mpr.requestObj          = null;
    mpr.findMessage         = null;
    mpr.addCloseTracker     = null;
    delete mpr;
  }
}

/*
 *
 */
function cb_sys_mpr_findMessage(elementId, eventId)
{
  var list = mpr.requestList;
  var len  = list.length;
  
  for (var i = 0; i < len; i++)
  {
    var item = list[i];
    
    if (item.id == elementId && item.eventId == eventId)
    {
      return item;
    }
  }
  
  return null;
}

function bl_mpr_buildControlUrl(frm)
{
  var src = null;
  
  if (frm && frm.id != "")
  {
    frm.bl_count = (frm.bl_count == undefined)? 1:++frm.bl_count;
    var src = window.bl_runtimepath
            + "?cmd=createWithEditor&xclientId="
            + window.cb_clientId
            + "&parentId="
            + window.bl_did
            + "&editorId="
            + frm.id
            + "&cnt="
            + frm.bl_count;
   }
   
   return src;
}

// this is the helper function  for all interactions
// to send mpr messages to the server
// NOTE: (AND VERY IMPORTANT!!) it is assumed that the current window context is the right
//       context for the interaction sending the message.  Therefore
//       it is assumed that this windows id is the right id for the message
// ARGS: msg       - (REQUIRED)the message (xml string to be sent to the server)
//       id        - (REQUIRED)the id of the control on this window context
//       eventId   - (OPTIONAL)the id of the event 
//                   NOTE: if this value is undefined or less than zero than this arg is ignored
//                   otherwise it is used to match this msg with a message if it already 
//                   exists on the MPR stack
//       sendType  - (OPTIONAL)how to send this message. there are 4 posible values
//                   -BL_MPR_ASAP(0)   - send as soon as posible
//                   -BL_MPR_DEFER(1)  - defer til next message to be sent asap(means that this message just get queued not sent
//                   -BL_MPR_APPEND(2) - the message will be added to an existing event if the eventId matches aganst one 
//                                       (this message is sent asap)                                      
//                   -BL_MPR_SYNC(3)   - send this message syncronous and imediate (this becomes a blocking call if this value is set)
//                   NOTE: if the value is undefined it is asumed that the value is BL_MPR_ASAP
//       systemMsg - (OPTIONAL)indicates that this message was not initiated by the user so we do not bring down any 
//                    right click menus or stuff like that
//                   NOTE: if the value is undefined than this is ignored and in most case will be undefined
//       suspend   - (OPTIONAL)suspend id for the interactionrequesting the mesage
//                   NOTE: if the value is undefined than this is ignored and in most case will be undefined
function bl_mpr_send(msg, id, eventId, sendType, systemMsg, suspend)
{
  var mpr = bl_sys_get_mpr();
  
  if (mpr)
  {
    var winName = window.bl_did;

    if (!systemMsg)
    {
      var tlw = cb_sys_getTopWindow();

      if (tlw.popup_is_loading)
      {
        tlw.popup_is_loading = false;
        tlw.bl_sys_popupVeilDown();
      }

      cb_sys_popup_close(false);
      mpr.setPopupContext(null, true);
    }
        
    if (!window.bl_is_main && window.frameElement && window.frameElement.bl_winName)
    {
      winName = window.frameElement.bl_winName;
    }
    
    if (winName && winName != "")
    {
      mpr.send(winName, msg, id, eventId, sendType, suspend);
    }
  }
}

function cb_sys_mpr_send(winId, msg, id, eventId, sendType, suspend)
{
  if (this.sessionClosed)
  {
    return false;
  }
  
  var list     = this.requestList;
  var wasSet   = false;
  var sendSync = (sendType == BL_MPR_SYNC);
  
  // check if msg stomps previous msg
  if (eventId != undefined && eventId >= 0)
  {
    var len = list.length;
    for (var i = 0; i < len; i++)
    {
      var item = list[i];
      
      if (item.id == id && item.eventId == eventId)
      {
        // stomp prev message (assumes suspend state is the same)
        if (sendType == BL_MPR_APPEND)
        {
          item.msg += msg;
        }
        else
        {
          item.msg = msg;
        }
        wasSet = true;
      }
    }
  }
  
  // if wasn't set above, add
  if (!wasSet)
  {
    var newItem = { msg:msg,
                    id:id,
                    eventId:eventId,
                    winId:winId,
                    sendSync:sendSync,
                    suspend:suspend
                  };
    
    list.push(newItem);
  }
  if (sendType != BL_MPR_DEFER)
  {
    if (sendSync)
    {
      // allways flush for a synchroneous request
      this.flushBlocked = true;
      this.flush();
    }
    else if (this.flushBlocked)
    {
      this.flushASAP = true;
    }
    else if (!this.flushTimer)
    {
      // to ensure that all browsers send there
      // request we send on a timer.  For example 
      // safari and some versions firefox will kill 
      // a request if that request in initiated from a window
      // that is being closed at the same time.  (the likly reason for this
      // is that, while the request object is created in the main window 
      // contect, the resources for the request are created in the context
      // of the closing window.  thus when that window goes down so do 
      // the resources for that request object and the request fails.
      //
      // This is an atempt to remidy that by allowing the main window to send the 
      // request fully in it's own context
      if (bl_browserInfo.firefox || bl_browserInfo.safari)
      {
        this.flushTimer = window.setTimeout("bl_sys_get_mpr().asyncFlush()", 0);
      }
      else
      {
        this.asyncFlush();
      }
    }
  }
}

function bl_sys_asyncFlush()
{
  window.clearTimeout(this.flushTimer);
  this.flushTimer   = undefined;
  
  // send sync will call flush so we can not have 
  // flushBlocked set in flush because it would have the 
  // potential of block mprs indefinately
  this.flushBlocked = true;

  this.flush();
}

// Flush the MPR queue out to the server, this puts all the pending 
// requests into a single request xml string and sends it to the server
function cb_sys_mpr_flush()
{
  // build an item string
  var requestStr = "<?xml version='1.0'?><request>";
  var len        = this.requestList.length;
  var list       = this.requestList.splice(0, len);
  var sendSync   = false;

  this.flushASAP = false;

  for (var i = 0; i < len; i++)
  {
    var item = list[i];
    
    requestStr += "<item pageId='" 
                + item.winId 
                +  "' id='" 
                + item.id 
                + "'";
                
    if (item.suspend)
    {
      requestStr += " suspendId='" 
                  + item.suspend 
                  + "'";
    }
    
    if (item.sendSync)
    {
      sendSync = true;
    }
   
    requestStr += ">" 
                + item.msg 
                + "</item>";
  }
  
  requestStr += "</request>";

  this.requestStr = requestStr;
  this.request(sendSync, false);
}

 // Parse a raw pulse response, this will retry if the connection is aborted or it will 
 // send the items returned to the next response handler for processing
function bl_sys_mpr_http_callback()
{
  // there are times when firefox is going done and a timer goes off and fires 
  // a send sometime during that period of time where the js wil have benn unloaded 
  // but the callback for the http request object will fire.  At that point 
  // bl_sys_get_mpr will not exist on the window so we check for its existance 
  // before proceeding
  if (window.bl_sys_get_mpr)
  {
    var mpr = bl_sys_get_mpr();
    
    if (mpr)
    {
      if (mpr.requestObj)
      {
        var req = mpr.requestObj;
        
        if (req && req.readyState == 4)
        {
          mpr.requestObj = null;

          var reqType = bl_sys_mpr_requestType(req);
          
          if (reqType == 0)
          {
            mpr.pulseTime = new Date().getTime() - mpr.startTime;
            try
            {
              // handle the assync responce
              mpr.response(req);
              
              // no handle any sync responces left over
              var list = mpr.syncResponseList;
              var item = list.shift();
              
              while (item)
              {
                mpr.response(item);
                delete item;
                item  = list.shift();
              }
            }
            catch (exception)
            {
              // Catch-all to keep one bad MPR message from killing the
              // entire application.
            }
            
            mpr.parseTime = (new Date().getTime() - mpr.startTime) - mpr.pulseTime;
            mpr.startTime = 0;
          }
          
          // we only want to release the mpr stack if it is not
          // retry
          if (reqType == 1)
          {
            bl_sys_mpr_fb_dettach();
            mpr.request(false, true);
          }
          else
          {
            if (bl_browserInfo.ie)
            {
              // If a modal dialog has been called, this timer will never get called,
              // so we can't use it as a timer.
              mpr.release();
            }
            else
            {
              // Modal dialogs are fakes in firefox and safari, so we can safely run
              // this as a timeout.
              window.setTimeout("bl_sys_get_mpr().release()",1);
              // TODO: Call mpr.release() directly. The webkit browser sometimes crashes
              // within this call. Re-enable the direct call (and remove the timeout) as
              // soon as Webkit bug #13124 is fixed.
              //
              // See http://bugs.webkit.org/show_bug.cgi?id=13124 for details.
            }
          }
          delete req;
        }
      }
    }
  }
}

// comute what type of responce we got;
// 0 = everything is ok
// 1 = retry
// 2 = something is not right with the responce but does not warant
//     a retry 
function bl_sys_mpr_requestType(request)
{
  var ret       = 0;
  var reqStatus = 200;
  
  try
  {
    reqStatus = request.status;
  }
  catch(err)
  {
    // An exception occurs when accessing the reqStatus object if any sort of
    // connection related exception occurs. See mozilla bug #238559 for more
    // details: https://bugzilla.mozilla.org/show_bug.cgi?id=238559
    // Also, this will occur if the window that initiated the call chain that
    // started this request has been closed. See mozilla bug #317600 for more
    // details: https://bugzilla.mozilla.org/show_bug.cgi?id=317600
    //
    // TODO: WARNING! This fix can cause duplicate requests to be sent to the
    // server. This needs to be replaced with a sane fix (that completely
    // de-couples MPR messenging from child windows.
    reqStatus = 99999;
  }

  switch (reqStatus)
  {
    case 200:
    break;

    case 0:
      //Unable to Connect (safari), retry
    case 12029:
      //Unable To Connect (ie), retry
    case 12152:   
      //Invalid Server Response, retry
    case 12030:
      //Connection Aborted, retry
    case 99999:
      //Unspecified Network Error, retry
      ret = 1;
    break;

    default:
      // other server error for not we will try to handle all response we know nothing about
      ret = 2;
    break;
  }

  if (ret == 0)
  {
    var parseError = bl_port_parseError(request.responseXML);
    
    if (parseError.errorCode != 0)
    {
      cb_sys_outputParseError(parseError);
    }
    
    var el = request.responseXML.documentElement;
    var firstItem  = null;
    var secondItem = null;
    
    if (el && el.nodeName == "response")
    {
      if (el.childNodes.length)
      {
        firstItem = el.childNodes.item(0);
        if (firstItem.nodeName == "item")
        {
          secondItem = firstItem.childNodes.item(0);
        }
        else
        {
          secondItem = firstItem;
        }
        
        if (secondItem.nodeName == "retry")
        {
          ret = 1;
        }
      }
    }
  }
    
  return ret;
}

function cb_sys_mpr_response(request)
{
  if (window.bl_window_list.bl_fb_attachedCount <= 1)
  {
    // we now switch the type to green
    // 5 is the scrollLeft of the green icon
    bl_sys_mpr_fb_doAttachAction(window.bl_window_list, 5);
  }
  cb_sys_handleResponse(request.responseXML);
}

function cb_sys_handleResponse(response)
{
  // get the root node
  var el = response.documentElement;

  if (el && el.childNodes.length)
  {
    var closeWindowList = [];
    var itemList        = el.childNodes;
    var length          = itemList.length;

    if (el.attributes && length == 1)
    {      
      var bl_error = el.attributes.getNamedItem("bl_error");
    
      if (bl_error)
      {
        var item = el.childNodes.item(0);
        bl_sys_serverError(parseInt(bl_port_get_text(bl_error)));
        return ;
      }
    }
    
    // call handle function on each item
    for (var i = 0; i < length; i++)
    {
      var item      = itemList[i];
      var theWindow = bl_sys_findWindow(item);

      if (theWindow)
      {
        var windowToClose = bl_sys_executeResponse(theWindow, item);
        
        if (windowToClose)
        {
          closeWindowList.push(windowToClose);
        }
      }
    }
    
    var closeLen = closeWindowList.length;
    for (var i = 0; i < closeLen; i++)
    {
      try
      {
        if (bl_browserInfo.firefox)
        {
          // Gecko seems to use a deferred closing mechanism-- If we call
          // win.close() directly, the window will not actually close until
          // the the user performs an interation (mouse event, keyboard
          // event, etc).
          //
          // Fix for bug #5038 - http://bugger/bug.php?op=show&bugid=5098
          closeWindowList[i].setTimeout("window._bl_sys_closeWindow()",0);
        }
        else if (bl_browserInfo.safari)
        {
          // There is a bug within safari that causes the browser to crash
          // sometimes when a window is closed. The bug has not yet been
          // reproducible outside the context of bungee, but manually
          // dispatching the onunload event and delaying the actual close
          // of the window seems to be effective.
          //
          // See webkit bug #13218 for more details.
          // http://bugs.webkit.org/show_bug.cgi?id=13218
          //
          // TODO: Call the shutdown window function directly and avoid the
          // event dispatching machinery. (Also put it into a port function
          // so all cases of window.close benefit equally)
          var ev = closeWindowList[i].document.createEvent("Events");
          ev.initEvent("unload",true,true);
          bl_moz_dispatchEvent(closeWindowList[i], ev, null);
          closeWindowList[i].onunload = null;
          closeWindowList[i].setTimeout("window._bl_sys_closeWindow()",500);
        }
        else
        {
          closeWindowList[i]._bl_sys_closeWindow();
        }
      }
      catch (exception)
      {
      }
    }
  
    delete closeWindowList;
    closeWindowList = null;
    el              = null;
    
    if (bl_lostPages != undefined && bl_lostPages.length > 1)
    {
      var xmlStr = "<lost>" + bl_lostPages + "</lost>";
      bl_mpr_send(xmlStr, window.bl_did, -1, BL_MPR_ASAP, true, -2);
      bl_lostPages = " ";
    }
  }
}

 // Here is the main request handler for sending the flushed MPR string that was created in the cb_sys_mpr_flush function
 // This handles both synchronous and asynchronous requests
function cb_sys_http_request(sendSync, isRetry)
{
  var locStr;
  var req = this.create();

  if (isRetry)
  {
    locStr = this.locStr; 
    this.retryCount++;
  }
  else
  {
    // if the requestObject exists then it means we are doing a synced
    // request with an async request already out.  This means we will have
    // two requests out at the same time. Because of this we will have to handle the stats
    // for them together.  That will require use to compute the time to send and recieve 
    // the syned request/response and store it off so we can tack it on to the next request's 
    // args.  Also because this request's stats are getting folded into the preveous
    // requrest stats than we do not want to send the last request stats with this request
    // hence the only arg on this request is the clients id.
    // NOTE: this means that the asynce pulseTime will include the time it took for this 
    //       synced message to get out of the way.

    if (this.requestObj)
    {
      locStr = bl_runtimepath
               + "?cmd=request&xclientId=" 
               + window.cb_clientId;
      this.syncTimeStart = new Date().getTime();
      this.syncPulseTime = 0;
    }
    else
    {
      //Gather up the previous mpr id's and their times
      locStr = bl_runtimepath
               + "?cmd=request&xclientId=" 
               + window.cb_clientId 
               + "&pulseTime=" 
               + this.pulseTime 
               + "&parseTime=" 
               + this.parseTime 
               + "&pulseId=" 
               + (this.pulseId++)
               + "&retryCnt="
               + this.retryCount;
               
      // we need to tack on the last synced requests time if  it was sent while
      // an asyn request was out.                 
      if (this.syncPulseTime > 0)
      {
        locStr += "&syncPulseTime=" + this.syncPulseTime;
      }               

      this.locStr        = locStr; 
      this.pulseTime     = 0;
      this.parseTime     = 0;
      this.retryCount    = 0;
      this.syncTimeStart = 0;
      this.syncPulseTime = 0;
      this.startTime     = 0;
      
      if (sendSync)
      {
        this.syncTimeStart = new Date().getTime();
      }
      else
      {
        this.startTime = new Date().getTime();
      }
    }
  }
  
  req.open("POST", locStr, !sendSync);
  req.setRequestHeader("Content-type", "text/xml; charset=utf-8");
  req.setRequestHeader("Connection", "Keep-Alive");
  
  if (!sendSync)
  {
    req.onreadystatechange = bl_sys_mpr_http_callback;
    this.requestObj        = req;
  }
  
  bl_sys_mpr_fb_attach(-1);
  
  try
  {
    //send request
    req.send(this.requestStr);
  }
  catch (exception)
  {
    // if this is a sync request we do not want 
    // to set the requestObj to null as that would ste the 
    // pulse time to zero and throw of 
    // the stats
    if (!sendSync)
    {
      this.requestObj = null;
    }
    if (this.handleException)
    {
      bl_sys_handleException(exception);
    }
    else
    {
      throw exception;
    }
  }

  // if callback is null then that means we do not
  // want to handle any response that is coming frome the server
  if (sendSync)
  {
    var reqType = bl_sys_mpr_requestType(req);
    
    if (reqType == 1)
    {
      bl_sys_mpr_fb_dettach();
      delete req;
      req = null;
      this.request(true, true); 
    }
    else
    {
      if (this.requestObj)
      {
        // we need to release the wait curor here
        bl_sys_mpr_fb_dettach();
        
        this.syncPulseTime = new Date().getTime() - this.syncTimeStart;
        this.syncTimeStart = 0;

        // there is a pending async request so we need to wait
        // untill that comes back and process its 
        // response first then this one.  This is because that
        // message got out first and we need to process things in 
        // order.
        this.syncResponseList.push(req);
      }
      else
      {
        this.syncPulseTime = new Date().getTime() - this.syncTimeStart;

        try
        {
          this.response(req);
        }
        catch (exception)
        {
          // catch for we must release the mpr at all cost
        }
        
        delete req;
        this.pulseTime = this.syncPulseTime;
        this.parseTime = (new Date().getTime() - this.syncTimeStart) - this.syncPulseTime;
        this.syncTimeStart = 0;
        this.release();
      }
    }
  }

  req = null;
}

function bl_sys_executeResponse(theWindow, item)
{
  var theDoc = theWindow.document;
  var val    = item.firstChild;
  var name   = val.nodeName;
  
  if (name == "WindowTitleChanged")
  {
    theDoc.title = bl_port_get_text(val);
    return null;
  }
  if (name == "ValidateStrChanged")
  {
    theWindow.bl_validateString = bl_port_get_text(val);
    return null;
  }
  if (name == "CloseWindow")
  {
    theWindow._bl_close_reason = bl_port_get_text(val);
    return theWindow;
  }
 
  var attr = item.attributes.getNamedItem("hdl");
  // get the function handler name
  if (attr)
  {
    var attr_value  = bl_port_get_text(attr);
    var id          = bl_port_get_text(item.attributes.getNamedItem("id"));
    var _bl_element = theDoc.getElementById(id);
  
    try
    {
      if (name == "popup_response")
      {
        theWindow.bl_sys_loadPopup(item);
      }
      else if (_bl_element && theWindow.bl_sys_is_live())
      {
        if (name == "enable" || name == "show")
        {
          theWindow.bl_sys_handleEnableShow(item, _bl_element);
        }
        else if (name == "ddChange")
        {
          theWindow.bl_sys_handleDDChange(item, _bl_element);
        }
        else if (name == "rcChange")
        {
          theWindow.bl_sys_handleRCChange(item, _bl_element);
        }
        else if (name == "set_el_title")
        {
          _bl_element.title = bl_port_get_text(val);
        }
        else if (name == "newBgStyle")
        {
          theWindow.bl_sys_handleNewBgStyle(item, _bl_element);
        }
        else
        {
          var handlerFunc = theWindow[attr_value];
          
          if (handlerFunc)
          {
            handlerFunc(item, _bl_element);
            _bl_element = null;
          }
        }
      }
      else
      {
        var handlerFunc = theWindow[attr_value];
        
        if (handlerFunc)
        {
          handlerFunc(item, _bl_element);
          _bl_element = null;
        }
      }
    }
    catch (exception)
    {
      bl_sys_handleException(exception);
    }
  }
}

function _bl_sys_pingServer()
{
  bl_mpr_send("<pingServer/>", window.bl_did, -1, BL_MPR_ASAP, true);
}




//// Cursor managment

function bl_sys_mpr_fb_handle(event)
{
  if (!event)
  {
    event = this.event;
  }
  
  cb_sys_getTopWindow().bl_sys_mpr_fb_position(event.screenX, event.screenY);
}

function bl_sys_mpr_fb_onTimer()
{
  var feedBackImg = document.getElementById("bl_mpr_fb");
  
  feedBackImg.timer = null;
  bl_sys_mpr_fb_position(feedBackImg.lastScreenX,feedBackImg.lastScreenY);
}

function bl_sys_mpr_fb_position(screenX, screenY)
{
  if (screenX != undefined && screenY != undefined)
  {
    var feedBackImg = document.getElementById("bl_mpr_fb");

    feedBackImg.lastScreenX = screenX;
    feedBackImg.lastScreenY = screenY;
    if (feedBackImg.timer)
    {
      // Don't really show this until a little time has passed.
      // This prevents tiny requests from showing the image.
      return;
    }
    
    var list = window.bl_window_list;
    
    if (feedBackImg && list && list.bl_fb_attachedCount > 0)
    {
      var style = feedBackImg.style;
      var x     = screenX - cb_sys_getScreenLeft();
      var y     = screenY - cb_sys_getScreenTop();

      // Need to brach here as screen X and Y differs between browsers
      if (bl_browserInfo.ie)
      {
        x += 12;
        y -= 3;
      }
      else
      {
        x += 15;
      }

      if (x + 6 > document.body.clientWidth)
      {
        x -= 26;
      }
       
      if (y + 20 >  document.body.clientHeight)
      {
        y = document.body.clientHeight - 20;
      }
      
      style.visibility = "visible";
      style.left       = x+"px";
      style.top        = y+"px";
    }
    else
    {
      bl_sys_mpr_fb_doDetach();
    }
  }
}

function bl_sys_mpr_fb_realHide()
{
  var list = window.bl_window_list;
  
  // we get here because this function was called at the 
  // end of a request or the init of a form
  // so we need to set the flag to false 
  // so that the event hid handling will be active again.
  if (list && list.bl_ignore_fb_hide)
  {
    list.bl_ignore_fb_hide = false;
  }

  var feedBackImg = document.getElementById("bl_mpr_fb");
  
  if (feedBackImg)
  {
    feedBackImg.style.visibility = "hidden";
  }
}

function bl_sys_mpr_fb_hide(event)
{
  var list = window.bl_window_list;
  
  if (list && list.bl_ignore_fb_hide)
  {
    return ;
  }

  if (!event)
  {
    event = window.event;
  }
  
  var offsetX = event.screenX - cb_sys_getScreenLeft();
  var offsetY = event.screenY - cb_sys_getScreenTop();
  var wsize   = cb_sys_getTopWindow().bl_port_windowSize();

  if (offsetX < 0 || offsetX > wsize.width || offsetY < 0 || offsetY > wsize.height)
  {
    bl_sys_mpr_fb_realHide();
  }
}

function bl_sys_mpr_fb_doDetach()
{
  var feedBackImg = document.getElementById("bl_mpr_fb");
  
  if (feedBackImg)
  {
    bl_removeEventListener(document, "mousemove", bl_sys_mpr_fb_handle, true);
    bl_removeEventListener(document, "mouseout", bl_sys_mpr_fb_hide, true);
    bl_removeEventListener(document, "mouseover", bl_sys_mpr_fb_handle, true);

    if (feedBackImg.timer)
    {
      clearTimeout(feedBackImg.timer);
      feedBackImg.timer = null;
    }
    bl_sys_mpr_fb_realHide();
  }
}

function bl_sys_mpr_fb_doAttach()
{
  var feedBackImg = document.getElementById("bl_mpr_fb");
  
  if (feedBackImg)
  {
    bl_addEventListener(document, "mousemove", bl_sys_mpr_fb_handle, true);
    bl_addEventListener(document, "mouseout", bl_sys_mpr_fb_hide, true);
    bl_addEventListener(document, "mouseover", bl_sys_mpr_fb_handle, true);

    if (!feedBackImg.timer)
    {
      // Don't show the pulse indicator until the request has taken longer than 500ms.
      feedBackImg.timer = setTimeout(bl_sys_mpr_fb_onTimer,500);
    }

    feedBackImg.scrollLeft = 0;

    if (bl_browserInfo.ie)
    {
      var event = window.event;
      
      if (event && event.type.toLowerCase().indexOf("mouse") >= 0)
      {
        bl_sys_mpr_fb_position(event.screenX, event.screenY);
      }
    }
  }
}

function bl_sys_mpr_fb_changeType(type)
{
  var feedBackImg = document.getElementById("bl_mpr_fb");
  
  if (feedBackImg)
  {
    feedBackImg.scrollLeft = type;
  }
}

function bl_sys_mpr_fb_callAttach(win, type)
{
  if (type == -1)
  {
    win.bl_sys_mpr_fb_doAttach();
  }
  else if (type == -2)
  {
    win.bl_sys_mpr_fb_doDetach();
  }
  else
  {
    bl_sys_mpr_fb_changeType(type);
  }
}

function bl_sys_mpr_fb_doAttachAction(list, type)
{
  if (list)
  {
    var len = list.length;

    for (var i = 0; i < len; i++)
    {
      var win = list[i];
      
      try
      {
        if (win._bl_sys_last)
        {
          bl_sys_mpr_fb_callAttach(win, type);

          var win_iframes = win.document.getElementsByTagName("IFRAME");
          var win_len     = win_iframes.length;
          
          for (var j = 0; j < win_len; j++)
          {
            var frameElement = win_iframes[j];
            var fwindow      = frameElement.contentWindow;
            
            if (fwindow._bl_sys_last)
            {
              bl_sys_mpr_fb_callAttach(fwindow, type);
            }
          }
        }
      }
      catch (exception)
      {
        // there is a chance that we will try to access
        // an iframe before it is leagle to call into its script
        //(for example if we try to get attibute off it before it's
        // domain has been determing then we will get a permission 
        // denied exception)  (The reason for putting this in is because 
        // we ran in to a permision denied exception on an iframe that 
        // had not loaded its url yet.)It is allright to assume that every thing 
        // is ok and continue on.
      }
    }
  }
}

function bl_sys_mpr_fb_attach(type)
{
  var list = window.bl_window_list;
  
  if (list)
  {
    if (list.bl_fb_attachedCount <= 0)
    {
      list.bl_fb_type = 0;
      
      list.bl_fb_attachedCount = 1;
      bl_sys_mpr_fb_doAttachAction(list, -1);
    }
    else
    {
      list.bl_ignore_fb_hide = true;
      bl_sys_mpr_fb_doAttachAction(list, type);
      list.bl_fb_attachedCount++;
    }
  }
}

function bl_sys_mpr_fb_dettach()
{
  var list = window.bl_window_list;
  
  if (!list)
  {
    list = window.parent.bl_window_list;
  }
  
  if (list)
  {
    if (list.bl_fb_attachedCount == 1)
    {
      list.bl_fb_attachedCount = 0;
      bl_sys_mpr_fb_doAttachAction(list, -2);
    }
    else if (list.bl_fb_attachedCount > 0)
    {
      list.bl_fb_attachedCount--;
    }
  }
}

function bl_sys_findWindow(item)
{
  var searchWindow   = window;
  var pageName       = item.attributes.getNamedItem("pageId");
  var pageName_value = bl_port_get_text(pageName);
    
  if (pageName && pageName_value.length && pageName_value != window.bl_did)
  {
    searchWindow = cb_sys_getWindow(window.bl_window_list, pageName_value);
    
    if (!searchWindow)
    {
      if (typeof bl_lostPages == "undefined")
      {
        bl_lostPages = " ";
      }
      if (bl_lostPages.indexOf(" " + pageName_value + " ") < 0)
      {
        var windowList = window.bl_window_list;
        
        if (bl_sys_findInDeadList(pageName_value, windowList.deadWindowList))
        {
          delete item;
          item = null;
        }
        else
        {
          bl_addMPRITem(pageName_value, windowList.mprWindowList, item);
        }
      }
    }
  }
  
  return searchWindow;
}

function bl_sys_findInDeadList(did, list)
{
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    if (list[i] == did)
    {
      return true;
    }
  }
  
  return false;
}

function bl_sys_removeFromMPRList(did, list)
{
  var ret         = null;
  var currentTime = new Date()
  var timeVal     = currentTime.getTime();
  
  for (var i = list.length - 1; i >= 0; i--)
  {
    var item = list[i];
    
    if (item.did == did)
    {
      list.splice(i, 1);
      ret = item;
    }
    else if (timeVal - item.timeVal > 300000)
    {
      if (typeof bl_lostPages == "undefined")
      {
        bl_lostPages = " ";
      }
      if (bl_lostPages.indexOf(" " + item.did + " ") < 0)
      {
        // this mprItem has been hear to long
        // so lets get rid of it. (5 minutes is long enough)
        bl_lostPages += (item.did + " ");
        bl_cleanMPRItem(item);
        list.splice(i, 1);
      }
    }
  }
  
  return ret;
}

function bl_addMPRITem(did, list, xmlItem)
{
  var mprItem     = null;
  var currentTime = new Date()
  var timeVal     = currentTime.getTime();
  
  for (var i = list.length - 1; i >= 0; i--)
  {
    var item = list[i];
    
    if (item.did == did)
    {
      mprItem = item;  
    }
  }
  
  if (mprItem == null)
  {
    mprItem = { timeVal:timeVal, did:did, list:[] };
    list.push(mprItem);
  }
  
  mprItem.list.push(xmlItem);
}

function bl_cleanMPRItem(mprItem)
{
  var list = mprItem.list;
  var item = list.shift();
  
  while (item)
  {
    delete item;
    item = list.shift();
  }
  
  delete mprItem.list;
  mprItem.list = null;
}

function bl_sys_procesMPRItem(theWindow)
{
  var mprItem = bl_sys_removeFromMPRList(theWindow.bl_did, theWindow.bl_window_list.mprWindowList);

  if (mprItem)
  {
    try
    {
      var list = mprItem.list;
      var item = list.shift();
      
      while (item)
      {
        bl_sys_executeResponse(theWindow, item);
        delete item;
        item = list.shift();
      }
      
      delete mprItem.list;
      mprItem.list = null;
    }
    catch (exception)
    {
    }
  }
}

function bl_sys_serverError(errorType)
{
// error types supported
// 0 - Empty Response (not really an error, just no messages to process)
// 1 - Invalid Command
// 2 - Session already Exists
// 3 - Client Timeout
// 4 - Internal Server Error
// 5 - Pipe Error
// 6 - Session already terminated
// 7 - Invalid Session
// 8 - Exception

  if (errorType > 0)
  {
    var doReload = true;
    var text     = null;
    var mainWin  = bl_sys_get_main(null);
    
    cb_sys_closeAllPopups(2);
    if (errorType == 3)
    {
      text = "Your connection has timed out.";
    }
    else if (errorType == 4)
    {
      text = "An error has been detected.";
    }
    else if (errorType == 7)
    {
      if (mainWin.bl_sys_getSessionTimeoutMsg)
      {
        text = mainWin.bl_sys_getSessionTimeoutMsg();
      }
    }
    else
    {
      text = "Unable to connect to the server.";
      doReload = false;
    }

    if (text)
    {
      var body     = mainWin.document.body;
      var popupArg = { x:0,
                       y:0,
                       w:260,
                       h:75,
                       canDestroy:true,
                       sticky:true,
                       doReload:doReload,
                       msg:text,
                       useVeil:true,
                       formTitle:"",
                       positionType:"center",
                       html:body.getAttribute("bl_messageHTML"),
                       chrome:body.getAttribute("bl_messageChrome")
                    };
      
      if (doReload)
      {
        window.bl_validateString = "";
        bl_sys_get_mpr().sessionClosed = true;
      }

      bl_sys_popupInvoke(popupArg);
    }
  }
}

function cb_sys_eval(funcName, item, element)
{
  eval(funcName + "(item, element);");
}

function cb_sys_getWindow(list, pageName)
{
  if (list)
  {
    var len = list.length;
    for (var i = 0; i < len; i++)
    {
      var child = null;
      try
      {
        child = list[i];
        
        if (child && child.bl_did == pageName)
        {
          return child;
        }
      }
      catch(exception)
      {
        continue;
      }
    }
  }
  
  return null;
}

function cb_sys_closeAllPopups(closeType)
{
  var windowList = window.bl_window_list;

  if (windowList)
  {
    for (var i = windowList.length - 1; i >= 0; i--)
    {
      var win = windowList[i];
      try
      {
        if (!win.bl_is_main && 
            ((win.bl_close_type == undefined || !win.bl_close_type) && (win.opener || bl_port_getDialogArguments(win))))
        {
          // need to send close this window but first set the shutdown type
          win.bl_close_type    = closeType;
          win.bl_sys_goingDown = true;
          win.onunload = null;
          win._bl_sys_closeWindow();
        }
      }
      catch (exception)
      {
      }
      try
      {
        // set the shut down type      
        if (win.bl_close_type != 2)
        {
          win.bl_close_type = closeType;
        }
      }
      catch (exception)
      {
      }
    }
    try
    {
      windowList.splice(0, windowList.length);
    }
    catch (exception)
    {
    }
  }
}



var bl_kb_activePopup   = null;
var bl_kb_popups        = [];
var bl_kb_activeControl = null;
var bl_kb_activeNode    = null;
var bl_kb_activePath    = [];
var bl_kb_shortcuts     = [];
var bl_kb_lastEventType = null;
var bl_kb_firstFocus    = null;

// Tests an element to determine whether or not it's still
// part of its document.
function bl_kb_isElementValid(childEl,parentWin)
{
  try
  {
    while(childEl)
    {
      var childWin = bl_port_docWindow(childEl.ownerDocument);
      var rootNode = childWin.document.documentElement;
      
      if (!bl_port_contains(rootNode, childEl, false))
      {
        return false;
      }
      if (childWin == parentWin)
      {
        return true;
      }
      childEl = childWin.frameElement;
    }
  }
  catch (error)
  {
    // Internet Explorer sometimes has issues with retaining references to elements
    // when the frame containing the element has gone away. (or something like that).
    // This prevents that situation from breaking the rest of the app.
  }
  
  return false;
}

function bl_kb_notifyPopupOpen(popupObj)
{
  for (var i=0; i<bl_kb_popups.length; i++)
  {
    if (bl_kb_popups[i] == popupObj)
    {
      // This popup has already been added.
      return;
    }
  }
  bl_kb_popups.unshift(popupObj);
  
}

function bl_kb_notifyPopupClosed(popupObj)
{
  for (var i=0; i<bl_kb_popups.length; i++)
  {
    if (popupObj == bl_kb_popups[i])
    {
      bl_kb_popups.splice(i,1);
      break;
    }
  }

  if(bl_browserInfo.mac && bl_browserInfo.firefox3)
  {
    // For MAC+FF3, when an overlay is closed with the mouse (by clicking on
    // something within the overlay), focus is not given back to the browser.
    // So we explicitly call focus to try and regain control.
    // Note: Bungee bug #6444: Image button not firing after first time 
    var topWin = cb_sys_getTopWindow();
    topWin.focus();
  }
}

// Note: A null popupObj means the true top level window.
function bl_kb_notifyPopupActive(popupObj)
{
  if (popupObj != bl_kb_activePopup)
  {
    if (popupObj)
    {
      var myZ  = parseInt(popupObj.container.style.zIndex);
      var maxZ = myZ;

      for (var i=0; i<bl_kb_popups.length; i++)
      {
        if (popupObj == bl_kb_popups[i])
        {
          bl_kb_popups.splice(i,1);
        }
        else if (!popupObj.isDead)
        {
          pZ = parseInt(bl_kb_popups[i].container.style.zIndex);
          if (pZ > myZ)
          {
            maxZ = Math.max(maxZ,pZ);
            bl_kb_popups[i].container.style.zIndex = pZ - 2;
          }
        }
      }
      
      popupObj.container.style.zIndex = maxZ;
      bl_kb_popups.unshift(popupObj);
      bl_kb_activePopup = popupObj;

    }
    else
    {
      // A null popupObj means the true top level window.
      bl_kb_activePopup = null;
      
    }
  }
}

// Note: this should be called from the top level window.
function bl_kb_getActiveWindow()
{
  var result = window;
  if (bl_kb_activePopup && bl_kb_activePopup.isOpen)
  {
    result = bl_kb_activePopup.container.iframe.contentWindow;
  }
  return result;
}

function bl_kb_getActiveNode()
{
  var topWin = cb_sys_getTopWindow();
  var activeNode = topWin.bl_kb_activeNode;
  
  try
  {
    if (!activeNode)
    {
      activeNode = null;
    }
    else if (!bl_kb_isElementValid(activeNode,topWin))
    {
      var oldNodeId     = activeNode.id;
      var activeControl = topWin.bl_kb_getActiveElement();
      if (activeControl && oldNodeId)
      {
        activeNode = activeControl.ownerDocument.getElementById(oldNodeId);
      }
      else
      {
        activeNode = activeControl;
      }
      topWin.bl_kb_activeNode = activeNode;
    }
  }
  catch (ex)
  {
    // activeNode is not accesable.  ussually because the system
    // throws "Permision DEnied" exception
    activeNode = null;
  }
  return activeNode;
}

function bl_kb_getActiveElement()
{
  var topWin = cb_sys_getTopWindow();
  var activeEl = topWin.bl_kb_activeControl;
  if (!activeEl)
  {
    return null;
  }
  else if (!bl_kb_isElementValid(activeEl,topWin))
  {
    topWin.bl_kb_activeControl = null;
    try
    {
      // If the actual element has been regenerated, we should be able to find it by it's id.
      // However, IF the 
      var activeDoc   = activeEl.ownerDocument;
      var newActiveEl = activeDoc.getElementById(activeEl.getAttribute("id"));
      if (newActiveEl && bl_kb_isElementValid(newActiveEl,topWin))
      {
        topWin.bl_kb_activeControl = newActiveEl;
      }
    }
    catch (error)
    {
      // Internet Explorer sometimes has issues with retaining references to elements
      // when the frame containing the element has gone away. (or something like that).
      // This prevents that situation from breaking the rest of the app.
    }
    if (!topWin.bl_kb_activeControl)
    {
      // Active element went away or doesn't exist
      topWin.bl_kb_activePath = [];
    }
  }
  
  return topWin.bl_kb_activeControl;
}

// Builds a path to get from the specified window to the element specified by the 'id'
// parameter.
// Note: This should be called from the context of the window where the ID exists.
function bl_kb_buildElementPath(id,toWin)
{
  var path        = bl_kb_buildWindowPath(toWin);
  var elementPath = { path: path, id: id };
  return elementPath;
}

// Builds a path to get from the specified window to the window from which this is called. 
// Note: This should be called from the context of the child window.
function bl_kb_buildWindowPath(toWin)
{
  var win    = window;
  var path   = [];
  while (win != toWin)
  {
    var frameEl = win.frameElement;
    path.unshift(frameEl.id);
    win = bl_port_docWindow(frameEl.ownerDocument);
  }

  return path;
}

// Registers a control with a specific ID as the target for a certain shortcut.
// Param virtualKey: String, in the form of "ctrl a" or "ctrl up" or "alt x", etc.
// Param id: String the ID of the control to be registered.
// Note: This should be called from the context of the window where the ID exists.
function bl_kb_registerShortcut(virtualKey,id)
{
  var win  = cb_sys_getTopLevelWindow();
  var path = bl_kb_buildElementPath(id,win);

  win.bl_kb_shortcuts[virtualKey] = path;
}

// Note: This should be called from the context of the window where the ID exists.
function bl_kb_registerFirstFocus(id)
{
  var win  = cb_sys_getTopLevelWindow();
  var path = bl_kb_buildElementPath(id,win);

  win.bl_kb_firstFocus = path;
}

// Returns the window object refered to by a window path structure. This structure
// can be created using the bl_kb_buildWindowPath function.
// Note: This should be called from the context of the top window.
function bl_kb_resolveWindowPath(path)
{
  var win = window;
  for (var i=0; i<path.length; i++)
  {
    var frameEl = win.document.getElementById(path[i]);
    if (!frameEl || frameEl.tagName != "IFRAME")
    {
      // The element holding the child window must have gone away.
      return null;
    }
    
    win = frameEl.contentWindow;
  }
  return win;
}

// Returns the element refered to by an elementPath structure. See
// bl_kb_buildElementPath for more details.
// Note: This should be called from the context of the top window.
function bl_kb_resolveElementPath(path)
{
  var id  = path.id;
  var win = bl_kb_resolveWindowPath(path.path);

  // If 'win' is null, it means the window associated with the shortcut no
  // longer exists. This is expected when a popup goes away, or when a
  // dynamic form (iframe) is changed out.
  if (!win)
  {
    return null;
  }

  return win.document.getElementById(id);
}

// Note: This should be called from the context of the top level window.
function bl_kb_doFirstFocus(findFirstFocus)
{
  delayMillis = 50;
  if (window != window.parent)
  {
    try
    {
      if (window.frameElement.container.popup_obj.popup_arg.fade)
      {
        delayMillis += 1000;
      }
    }
    catch(e)
    {
    }
  }

  // Let the system finish rendering whatever it has so that first focus can work.
  setTimeout(function(){ bl_kb_finishFirstFocus(findFirstFocus); }, delayMillis );
}
function bl_kb_finishFirstFocus(findFirstFocus)
{
  if (bl_kb_firstFocus)
  {
    var el = bl_kb_resolveElementPath(bl_kb_firstFocus);
    if (el)
    {
      bl_port_focus(el);
    }
    bl_kb_firstFocus = null;
  }
  else if (findFirstFocus)
  {
    var rootEl = bl_contain_findRoot();
    bl_kb_activateFromTab(rootEl,true);
  }
}

// Note: This should be called from the context of the top window.
function bl_kb_doShortcut(virtualKey)
{
  var pathToShortcut = bl_kb_shortcuts[virtualKey];
  if (pathToShortcut)
  {
    var el = bl_kb_resolveElementPath(pathToShortcut);
    if (el)
    {
      var cbTag = el.getAttribute("cb_tag");
      if (cbTag == "IB" || cbTag == "SIB" || cbTag == "BTN")
      {
        bl_port_clickButton(el);
      }
      else
      {
        // TODO: Do something better here than just focusing on the control.
        bl_port_focus(el);
      }
      return true;
    }
    else
    {
      delete bl_kb_shortcuts[virtualKey];
    }
  }
  return false;
}

function bl_kb_buildRootPath()
{
  var path = [];

  var root        = bl_contain_findRoot();
  var strTabOrder = root.getAttribute("bl_tabOrder");
  if (strTabOrder)
  {
    var id  = root.id;
    var mgr = bl_kb_createTabOrderMgr(strTabOrder.split(" "),document);
    var p   = bl_kb_createPathNode(root,id,mgr,-1);

    path = [p];
  }
  return path;
}

function bl_kb_buildActivePath(activeEl)
{
  var id   = activeEl.id;
  var path = [];
  var el   = bl_port_findTrueParent(activeEl);

  var doc;
  var strTabOrder;
  var mgr;

  while (el)
  {
    var doc = el.ownerDocument;

    if (strTabOrder = el.getAttribute("bl_tabOrder"))
    {
      var found    = false;
      var tabOrder = strTabOrder.split(" ");
      if (bl_port_hasAttribute(el,"bl_ctr_isTop"))
      {
        var parentEl = bl_port_findTrueParent(el);
        if (parentEl && parentEl.getAttribute("cb_tag") != "DFL")
        {
          // Move pointer to the container's DynamicForm parent element
          // and use the real ID. If we're inside a FormList, though, we
          // don't want to switch the element.
          el = parentEl;
        }
      }

      for (var i=0; i<tabOrder.length; i++)
      {
        if (id == tabOrder[i])
        {
          found = true;
          id    = el.id;
          mgr   = bl_kb_createTabOrderMgr(tabOrder,doc);
          var p = bl_kb_createPathNode(el,id,mgr,i);
          path.unshift(p);
          break;
        }
      }

    }
    else if ((mgr = el.selectMgr) && bl_port_hasAttribute(el,"bl_allowTabInto"))
    {
      var nodeInDoc = bl_kb_findParentWithin(activeEl,doc);
      if (nodeInDoc)
      {
        var row = mgr.findRow(el, nodeInDoc);
        if (row)
        {
          id    = el.id;
          var i = mgr.computeRowIndex(el, row);
          var p = bl_kb_createPathNode(el,id,mgr,i);
          path.unshift(p);
        }
      }
    }

    
    el = bl_port_findTrueParent(el);
  }

  var strTabOrder = activeEl.getAttribute("bl_tabOrder");
  if (strTabOrder)
  {
    var id       = activeEl.id;
    var mgr      = bl_kb_createTabOrderMgr(strTabOrder.split(" "),activeEl.ownerDocument);
    var p        = bl_kb_createPathNode(activeEl,id,mgr,-1);
    path.push(p);
  }  
  
  //bl_kb_showActivePath(path);
  //bl_port_debugMsg("Built new active path...");
  return path;
}

// Provides a method to find the nearest node which is both parent
// to the leaf node and within the specified document
function bl_kb_findParentWithin(leafNode,doc)
{
  try
  {
    while (leafNode)
    {
      var leafDoc = leafNode.ownerDocument;
      
      if (leafDoc == doc)
      {
        return leafNode;
      }
      
      leafNode = bl_port_docWindow(leafDoc).frameElement;
    }
  }
  catch (ignorable)
  {
    // This protects against exceptions that would occur when the
    // leaf node does not have any parent elements within the specifed
    // document.
  }
  return null;
}

function bl_kb_activate(leafNode,controlEl,source)
{
  var topWin = cb_sys_getTopWindow();

  var currentControl = topWin.bl_kb_activeControl;

  if (currentControl != controlEl)
  {
    if (currentControl)
    {
      try
      {
        //bl_port_debugMsg("Blurring old control element... "+bl_debug_elementId(currentControl),false,false,currentControl);

        var cbTag = currentControl.getAttribute("cb_tag");
        if (cbTag == "SIB")
        {
          bl_sb_hideFocus(currentControl);
        }
        else if (cbTag == "CBX" || cbTag == "RDO")
        {
          bl_rdck_hideFocus(currentControl);
        }
        else if (cbTag == "SCL")
        {
          bl_scl_hideFocus(currentControl);
        }

        var funcName = currentControl.getAttribute("ondeactivate");
        //bl_port_debugMsg( "Deactivate ["+bl_debug_elementId(currentControl)+"] ("+funcName+")",false,false,currentControl);
        if (funcName)
        {
          var func = topWin[funcName];
          func(currentControl);
        }
      }
      catch (error)
      {
        // Internet Explorer sometimes has issues with retaining references to elements
        // when the frame containing the element has gone away. (or something like that).
        // This prevents that situation from breaking the rest of the app.
      }
    }
  
    topWin.bl_kb_activeControl = controlEl;
    //bl_port_debugMsg("New active control ["+bl_debug_elementId(controlEl)+"] ("+source+")",true,false,controlEl);
    if (controlEl)
    {
      var popupObj = null;
      try
      {
        var ctrlWin = bl_port_docWindow(controlEl.ownerDocument);
        var tlw     = ctrlWin.cb_sys_getTopLevelWindow();
        if (tlw.parent != tlw)
        {
          popupObj    = tlw.frameElement.container.popup_obj;
        }
      }
      catch(e)
      {
        // An error here means the current window is not within a popup.
      }
      topWin.bl_kb_notifyPopupActive(popupObj);
    
      //bl_port_outlineEl(controlEl,"1px solid blue");
      topWin.bl_kb_activePath = bl_kb_buildActivePath(controlEl);

      if (bl_port_hasAttribute(controlEl,"bl_default"))
      {
        var win = bl_port_docWindow(controlEl.ownerDocument);
        win.bl_kb_registerShortcut("enter",controlEl.id);
      }

      var cbTag = controlEl.getAttribute("cb_tag");
      if (cbTag == "SIB")
      {
        bl_sb_showFocus(controlEl);
      }
      else if (cbTag == "CBX" || cbTag == "RDO")
      {
        bl_rdck_showFocus(controlEl);
      }
      else if (cbTag == "SCL")
      {
        bl_scl_focus(controlEl);
      }
      
      var funcName     = controlEl.getAttribute("onactivate");
      //bl_port_debugMsg( "Activate ["+bl_debug_elementId(controlEl)+"] ("+funcName+")",false,false,controlEl);
      //bl_port_outlineEl( controlEl, "1px dashed blue");
      if (funcName)
      {
        var func = topWin[funcName];
        func(controlEl);
      }
    }
    else
    {
      topWin.bl_kb_notifyPopupActive(null);
    }
  }
  
  var activeNode = topWin.bl_kb_activeNode;
  if (leafNode != activeNode)
  {
    if (activeNode)
    {
      try
      {
        if (!cb_sys_isInput(leafNode) && cb_sys_isInput(activeNode))
        {
          // ONLY blur the previously active element if it WAS a valid input control
          // and the new focus target is NOT a valid input control.
          //bl_port_debugMsg("Blurring old leaf element... "+bl_debug_elementId(activeNode),false,false,activeNode);
          activeNode.blur();
        }
        if (activeNode.dispatchEvent)
        {
          // - Blur events don't bubble for safari and IE, but do for FF.
          // - IE fires "focusout" events, but safari and FF don't.
          // - This code attempts to bring safari and FF inline with IE.
          var doc = activeNode.ownerDocument;
          var ev  = doc.createEvent("Events");
          ev.initEvent("focusout",true,true);
          bl_moz_dispatchEvent(activeNode, ev, null);
        }
      }
      catch (error)
      {
        // Sometimes the node has already been freed by the browser so we have
        // to catch the "cannot execute freed code" error, and any other error
        // that may occur here.
      }
    }
    topWin.bl_kb_activeNode = leafNode;
    //bl_port_debugMsg("New active control element... "+bl_debug_elementId(controlEl)+".. ",false,false,controlEl);
    //bl_port_debugMsg("New active leaf element... "+bl_debug_elementId(leafNode)+".. Focusable? "+(leafNode&&leafNode.focus?"yes":"no")+"",false,false,leafNode);
    if (leafNode)
    {
      if (leafNode.focus)
      {
        try
        {
          leafNode.focus();
        }
        catch (ex)
        {
          // this can fail for vareous reasons one of which is that the 
          // control's visible flag is set to "hidden"
        }
      }
      if (leafNode.dispatchEvent)
      {
        // - Blur events don't bubble for safari and IE, but do for FF.
        // - IE fires "focusout" events, but safari and FF don't.
        // - This code attempts to bring safari and FF inline with IE.
        var doc = leafNode.ownerDocument;
        var ev  = doc.createEvent("Events");
        ev.initEvent("focusin",true,true);
        bl_moz_dispatchEvent(leafNode, ev, null);
      }
    }
  }
}

function bl_kb_activateFromTab(el,goForward)
{
  var s = bl_port_getComputedStyle(el);
  if (el.disabled || el.isDisabled || s["display"] == "none" || s["visibility"] == "hidden")
  {
    return false;
  }
  
  var cbTag       = el.getAttribute("cb_tag");
  var mgr         = null;
  var strTabOrder = null;

  if (cb_sys_isInput(el) || (cbTag == "DFL" && !bl_port_hasAttribute(el,"bl_allowTabInto")))
  {
    bl_port_focus(el);
    return true;
  }
  else if (cbTag == "SIB" || cbTag == "IB" || cbTag == "RIB")
  {
    bl_port_focus(el);
    return true;
  }
  else if (cbTag == "CBX" || cbTag == "RDO")
  {
    bl_port_focus(el);
    return true;
  }
  else if (cbTag == "SCL")
  {
    bl_scl_focus(el);
    return true;
  }
  else if (cbTag == "EMB")
  {
    var child = el.firstChild;
    if (child && (strTabOrder = child.getAttribute("bl_tabOrder")))
    {
      mgr = bl_kb_createTabOrderMgr(strTabOrder.split(" "),el.ownerDocument);
    }
  }
  else if (cbTag == "IF_EMB")
  {
    var win  = el.contentWindow;
    try
    {
      var root    = win.bl_contain_findRoot();
      if (strTabOrder = root.getAttribute("bl_tabOrder"))
      {
        mgr = bl_kb_createTabOrderMgr(strTabOrder.split(" "),win.document);
      }
    }
    catch (error)
    {
      // We can't really inspect the IFrame if it hasn't been loaded,
      // but we'll try anyway.
    }
  }
  else if (cbTag == "CELL")
  {
    mgr = bl_kb_createChildMgr();
  }
  else if (strTabOrder = el.getAttribute("bl_tabOrder"))
  {
    mgr = bl_kb_createTabOrderMgr(strTabOrder.split(" "),el.ownerDocument);
  }
  else if (el.selectMgr)
  {
    mgr = el.selectMgr;
  }

  if (mgr)
  {
    var len = mgr.getLength(el);
    var i   = goForward ? 0 : len-1;
    var inc = goForward ? 1 : -1;

    for (; i>=0 && i<len; i+=inc)
    {
      var nextEl = mgr.computeRow(el,i);
      if (nextEl && bl_kb_activateFromTab(nextEl,goForward))
      {
        return true;
      }
    }
  }
  return false;
}

// Note: This function must be called from the context of the top window.
function bl_kb_doTab(goForward)
{
  if (bl_kb_activePath.length == 0)
  {
    bl_kb_activePath = bl_kb_buildRootPath();
    if (!goForward)
    {
      // By default the pointer starts at -1, which is good
      // for tabbing forward, but bad for tabbing backwards.
      var p      = bl_kb_activePath[0];
      p.tabIndex = p.mgr.getLength(p.self)+1;
    }
  }
  
  var last = false;
  var inc  = goForward?1:-1;
  
  while (bl_kb_activePath.length > 0)
  {
    var p        = bl_kb_activePath[bl_kb_activePath.length-1];
    var parentEl = p.self;
    var mgr      = p.mgr;
    var len      = mgr.getLength(parentEl);

    for (p.tabIndex += inc; (p.tabIndex >= 0 && p.tabIndex < len); p.tabIndex += inc)
    {
      var el = mgr.computeRow(p.self,p.tabIndex);
      if (el && bl_kb_activateFromTab(el,goForward))
      {
        return true;
      }
    }    

    if (last || bl_kb_activePath.length > 1)
    {
      bl_kb_activePath.pop();
    }
    else
    {
      p.tabIndex = goForward?(-1):(len);
      last       = true;
    }
  }
  
  if (bl_kb_activeControl)
  {
    // Rebuild the path as it was originally
    bl_kb_activePath = bl_kb_buildActivePath(bl_kb_activeControl);
  }
  return false;
}

// This method attempts to find the nearest HTML element representing a control
// within the DOM hierarchy. The element itself can also be a control.
function bl_kb_findNearestControl(el)
{
  while (el)
  {
    if (bl_port_hasAttribute(el,"cb_tag"))
    {
      return el;
    }
    
    el = bl_port_findTrueParent(el);
  }
  return null;
}

function bl_kb_focusOnElement(el,source)
{
  var controlEl = bl_kb_findNearestControl(el);
  if (controlEl)
  {
    if (controlEl.disabled || controlEl.isDisabled)
    {
      // If controlEl is disabled, the leaf node cannot be enabled.
      controlEl = null;
      el        = null;
    }
    else if (el && (el.disabled || el.isDisabled))
    {
      el = controlEl;
    }

    bl_kb_activate(el,controlEl,source);
  }
}

function bl_kb_isFocusInside(parentEl)
{
  var topWin = cb_sys_getTopWindow();
  var el = topWin.bl_kb_activeControl;
  while (el)
  {
    if (el == parentEl)
    {
      return true;
    }
    el = bl_port_findTrueParent(el);
  }
  return false;
}

// Note: Should be called from the context of the top window
function bl_kb_createVirtualKeyEvent(type,event)
{
  var kcode  = bl_port_keyCode(event);
  var srcEl  = bl_kb_getActiveNode();
  var result = bl_port_createSyntheticEvent(type,true,true);

  result.ctrlKey    = event.ctrlKey;
  result.shiftKey   = event.shiftKey;
  result.altKey     = event.altKey;
  result.metaKey    = event.metaKey;
  result.charCode   = event.charCode;
  result.keyCode    = kcode;
  
  if (kcode)
  {
    result.virtualKey = bl_port_getVirtualKey(kcode);
  }
  else
  {
    result.virtualKey = bl_port_getVirtualKey(event.charCode);
  }
  
  result.srcElement = srcEl;

  // If this is set to true, the key event can be used by the shortcut
  // machinery to activate a control. If this is set to false (by a handler),
  // any associated shortcut will be prevented.
  // This allows native controls (text, select, etc) the ability to prevent a
  // shortcut action from firing, while at the same time allowing the native
  // event to occur.
  result.allowShortcuts = true;
  
  return result;
}

// Dispatches the specified type of key event to the currently active element.
// Param keyCode - The actual keyCode represented by the keypress.
// Param virtKey - A string representing the key that was pressed, generally returned from bl_port_getVirtualKey
// Param type - A string representing the type of key event: keydown="d", keyup="u", keypressed=""
// Return - True: allow the default action. False: disallow the default action.
function bl_kb_dispatchVirtual(virtualEvent)
{
  var topWin = cb_sys_getTopWindow();
  var el     = bl_port_getEventTarget(virtualEvent);
  
  if (el && bl_kb_isElementValid(el,topWin))
  {
    var handlerName = virtualEvent.type+"_"+virtualEvent.virtualKey;
    var anykeyName  = virtualEvent.type+"_any";

    //bl_port_debugMsg("dispatching "+handlerName+" to ["+bl_debug_elementId(activeEl)+"]",false,false,activeEl);

    while(el)
    {
      var win = bl_port_docWindow(el.ownerDocument);
      
      win.bl_kb_dispatchInDoc(el,handlerName,anykeyName,virtualEvent);
      if (!virtualEvent.bubbles)
      {
        break;
      }
      if (win == topWin)
      {
        break;
      }
      el = win.frameElement;
    }

    if (virtualEvent.defaultPrevented)
    {
      return false;
    }
  }
  
  return true;
}

// Handler names are in the following format:
//
//                           vkd_x
//                           | | |
//    Virtual Keyboard-------+ | +------key that caused the event
//            key Down---------+ 
//                               
// Param handlerName - The name of the specific handler that should be searched for.
// Param anykeyName - The name of the generic key handler that should be searched for (usually vkX_any)
function bl_kb_dispatchInDoc(targetEl,handlerName,anykeyName,ev)
{
  var funcName = "";
  while (targetEl && targetEl.getAttribute)
  {
    funcName = targetEl.getAttribute(handlerName);
    if (funcName)
    {
      //bl_port_debugMsg("<font color=black>&nbsp; &nbsp; ==&gt; "+funcName+" to ["+bl_debug_elementId(targetEl)+"]",false,false,targetEl);
      var func = window[funcName];
      func(ev,targetEl);
    }
    
    if (ev.bubbles)
    {
      funcName = targetEl.getAttribute(anykeyName);
      if (funcName)
      {
        //bl_port_debugMsg("<font color=black>&nbsp; &nbsp; ==&gt; "+funcName+" to ["+bl_debug_elementId(targetEl)+"]",false,false,targetEl);
        var func = window[funcName];
        func(ev,targetEl);
      }
    }
    
    if (!ev.bubbles)
    {
      //bl_port_debugMsg("<font color=black>&nbsp; &nbsp; ========= cancelBubble");
      return;
    }
    
    targetEl = targetEl.parentNode;
  }
  //bl_port_debugMsg("<font color=black>&nbsp; &nbsp; ========= end of doc");
}

function bl_kb_onKeydown(event)
{
  var topWin = cb_sys_getTopWindow();
  var win    = topWin.bl_kb_getActiveWindow();
  var virtEvent = topWin.bl_kb_createVirtualKeyEvent("vkd",event);
  //var srcEl = bl_port_getEventTarget(event);
  //bl_port_debugMsg(""+virtEvent.virtualKey+" keydown to ["+bl_debug_elementId(srcEl)+"]",false,false,srcEl);

  bl_kb_lastEventType = "down";
  bl_kb_lastDownEvent = event;

  if (!bl_kb_dispatchVirtual(virtEvent))
  {
    bl_port_preventDefault(event);
  }
  else if (virtEvent.allowShortcuts)
  {
    if (virtEvent.virtualKey == "tab")
    {
      // Find the currently focused element, then find the next element in the tab order.
      bl_port_preventDefault(event);
      topWin.bl_kb_doTab(!event.shiftKey);
    }
    else if (virtEvent.virtualKey == "enter")
    {
      if (win.bl_kb_doEnter())
      {
        bl_port_preventDefault(event);
      }
    }
    else if (virtEvent.virtualKey == "esc")
    {
      if (win.bl_kb_doEsc())
      {
        bl_port_preventDefault(event);
      }
    }
    else if ((event.altKey || event.ctrlKey))
    {
      var shortcut = virtEvent.virtualKey;
      if (shortcut != "ctrl" && shortcut != "alt")
      {
        if (event.ctrlKey)
        {
          shortcut = "ctrl "+shortcut;
        }
        if (event.altKey)
        {
          shortcut = "alt "+shortcut;
        }
        if (event.shiftKey)
        {
          shortcut = "shift "+shortcut;
        }

        //bl_port_debugMsg("doing shortcut: "+shortcut);
        if (win.bl_kb_doShortcut(shortcut))
        {
          //bl_port_debugMsg("&nbsp; shortcut: "+shortcut+" succeeded");
          bl_port_killEvent(event);
        }
      }
    }
  }

  bl_port_stopPropagation(event);
}

// Note: This function must be called from the context of the top window.
function bl_kb_doEnter()
{
  if (bl_kb_doShortcut("enter"))
  {
    return true;
  }
  else
  {
    var ac = bl_kb_getActiveElement();
    if (ac)
    {
      var cbTag = ac.getAttribute("cb_tag");
      if (cbTag == "IB" || cbTag == "SIB" || cbTag == "BTN")
      {
        bl_port_clickButton(ac);
        return true;
      }
    }
  
    var defaultEl = bl_port_findDefaultButton();
    if (defaultEl)
    {
      bl_port_clickButton(defaultEl);
      return true;
    }
  }
  return false;
}

// Note: This function must be called from the context of the top window.
function bl_kb_doEsc()
{
  if (bl_kb_doShortcut("esc"))
  {
    return true;
  }
  else
  {
    var cancelEl = bl_port_findCancelButton();
    if (cancelEl)
    {
      bl_port_clickButton(cancelEl);
      return true;
    }
  }
  return false;
}

function bl_kb_onKeyup(event)
{
  var topWin    = cb_sys_getTopWindow();
  var virtEvent = topWin.bl_kb_createVirtualKeyEvent("vku",event);
  //var srcEl = bl_port_getEventTarget(event);
  //bl_port_debugMsg(""+virtEvent.virtualKey+" keyup to ["+bl_debug_elementId(srcEl)+"]",false,false,srcEl);

  bl_kb_lastEventType = "up";

  if (!bl_kb_dispatchVirtual(virtEvent))
  {
    bl_port_preventDefault(event);
  }
  else if (virtEvent.virtualKey == "tab" && virtEvent.allowShortcuts)
  {
    //bl_port_debugMsg("Killing tab keyup");
    // Find the currently focused element, then find the next element in the tab order.
    bl_port_preventDefault(event);
  }
  
  bl_port_stopPropagation(event);
}

function bl_kb_onKeypress(event)
{
  var topWin    = cb_sys_getTopWindow();
  var virtEvent = topWin.bl_kb_createVirtualKeyEvent("vk",event);
  //var srcEl = bl_port_getEventTarget(event);
  //bl_port_debugMsg(""+virtEvent.virtualKey+" keypress to ["+bl_debug_elementId(srcEl)+"]",false,false,srcEl);

  if (bl_kb_lastEventType == "press" && bl_kb_lastDownEvent)
  {
    var keydown  = topWin.bl_kb_createVirtualKeyEvent("vkd",bl_kb_lastDownEvent);
    //var srcEl = bl_port_getEventTarget(bl_kb_lastDownEvent);
    //bl_port_debugMsg(""+keydown.virtualKey+" fake keydown to ["+bl_debug_elementId(srcEl)+"]",false,false,srcEl);
    bl_kb_dispatchVirtual(keydown);
  }
  bl_kb_lastEventType = "press";
  
  if (!bl_kb_dispatchVirtual(virtEvent))
  {
    bl_port_preventDefault(event);
  }
  else if (virtEvent.virtualKey == "tab" && virtEvent.allowShortcuts)
  {
    //bl_port_debugMsg("Killing tab keyup");
    // Find the currently focused element, then find the next element in the tab order.
    bl_port_preventDefault(event);
  }

  bl_port_stopPropagation(event);
}

function bl_kb_createTabOrderMgr(tabOrder,contextDoc)
{
  var result = {};
  
  result.computeRow = bl_kb_mgr_computeRow;
  result.getLength  = bl_kb_mgr_getLength;
  result.contextDoc = contextDoc;
  result.tabOrder   = tabOrder;

  return result;
}

function bl_kb_mgr_computeRow(el,index)
{
  return this.contextDoc.getElementById( this.tabOrder[index] );
}

function bl_kb_mgr_getLength(el)
{
  return this.tabOrder.length;
}


function bl_kb_createChildMgr()
{
  var result = {};
  
  result.computeRow = bl_kb_disc_computeRow;
  result.getLength  = bl_kb_disc_getLength;
  
  return result;
}

function bl_kb_disc_computeRow(el,index)
{
  return el.childNodes[index];
}

function bl_kb_disc_getLength(el)
{
  return el.childNodes.length;
}

function bl_kb_createPathNode(el,id,manager,index)
{
  // Params:
  // el      - The element within the DOM that is associated with the manager.
  // id      - The 'id' of this node within the parent node (so a positional link can be determined).
  // manager - A lightweight selection manager* which will be used to retrieve an element at the specified index.
  // index   - An index to be passed to the manager to retrieve the element this node is pointing at.
  // * See bl_kb_createTabOrderMgr for the definiton of "lightweight selection manager".
  if(!manager) { ASSERT_FAIL_NO_MANAGER; }
  if(!el) { ASSERT_FAIL_NO_SELF; }
  var result = {
    id:       id,
    tabIndex: index,
    mgr:      manager,
    self:     el
  };
  return result;
}

function bl_kb_showAllTabs()
{
  var l = document.getElementsByTagName("*");
  for (var i=0; i<l.length; i++ )
  {
    if (bl_port_hasAttribute(l[i],"bl_tabOrder"))
    {
      bl_port_debugMsg("found tab order on "+l[i].id+":"+l[i].getAttribute("cb_tag")+": "+l[i].getAttribute("bl_tabOrder")+"",0,0,l[i]);
    }
  }
}

function bl_kb_showAllTops()
{
  var l = document.getElementsByTagName("*");
  for (var i=0; i<l.length; i++ )
  {
    if (bl_port_hasAttribute(l[i],"bl_ctr_isTop"))
    {
      bl_port_debugMsg("Found top container "+l[i].id+"",0,0,l[i]);
    }
  }
}

function bl_kb_showActivePath(path)
{
  for (var i=path.length-1; i>=0; i--)
  {
    if (path[i].mgr.tabOrder)
    {
      bl_port_debugMsg("&nbsp; &nbsp; &nbsp;"+path[i].id+", "+path[i].tabIndex+", ("+path[i].mgr.tabOrder.join(",")+")", false,false,path[i].self);
    }
    else
    {
      bl_port_debugMsg("&nbsp; &nbsp; &nbsp;"+path[i].id+", "+path[i].tabIndex+", (handled by selectMgr)", false,false,path[i].self);
    }
  }
}

function bl_kb_enableTrackFocus(win)
{
  if (!win) win = window;
  
  win.addEventListener("focus",bl_kb_trackFocus,true);
  win.addEventListener("blur",bl_kb_trackBlur,true);
}

function bl_kb_trackFocus(event)
{
  var srcEl = bl_port_getEventTarget(event);
  bl_port_debugMsg("Received focus from "+bl_debug_elementId(srcEl)+"!",false,false,srcEl);
}
function bl_kb_trackBlur(event)
{
  var srcEl = bl_port_getEventTarget(event);
  bl_port_debugMsg("Received blur from "+bl_debug_elementId(srcEl)+"!",false,false,srcEl);
}

function bl_kb_clearNativeTabIndex()
{
  var all = document.getElementsByTagName("*");
  for (var i=all.len-1; i>=0; i--)
  {
    var el = all[i];
    el.removeAttribute("tabIndex");
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_kb_last()
{
  var x = 0;
}


function bl_sys_fullMonths()
{
  if (this.bl_fullMonths == undefined)
  {
    this.bl_fullMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
  }
  return this.bl_fullMonths;
}

function bl_sys_months()
{
  if (this.bl_abrevMonths == undefined)
  {
    this.bl_abrevMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
  }
  
  return this.bl_abrevMonths;
}

function bl_sys_days()
{
  if (this.bl_abrevDays == undefined)
  {
    this.bl_abrevDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  }
  
  return this.bl_abrevDays;
}

function bl_sys_fullDays()
{
  if (this.bl_fullDays == undefined)
  {
    this.bl_fullDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  }
  return this.bl_fullDays;
}

function bl_sys_procInitTags(node)
{
  var scriptNode = node.nextSibling;
  
  if (scriptNode && scriptNode.nodeName == "initTags")
  {
    // get the bulk text. FF limits buffer sizes to 4096 and puts additional text in a separate childNode
    var htmlText = "";
    for (var i = 0; i< scriptNode.childNodes.length; i++)
    {
      htmlText += bl_port_get_text(scriptNode.childNodes[i]);
    }
    bl_port_insertAdjacentHTML(window.document.body, "beforeend", htmlText);
    scriptNode = scriptNode.nextSibling;
  }
  
  if (scriptNode && scriptNode.nodeName == "initXMLTags")
  {
    bl_port_insertAdjacentHTML(window.document.body, "afterend", bl_port_get_xml(scriptNode.firstChild));
    scriptNode = scriptNode.nextSibling;
  }
  
  if (scriptNode && scriptNode.nodeName == "initScript")
  {
    eval(bl_port_get_text(scriptNode));
  }
}

function bl_sys_context_menu(event)
{
  if (!event)
  {
    event = window.event;
  }

  if (event)
  {
    var sel = bl_port_get_selection(document);
    
    if (!cb_sys_isInput(bl_port_getEventTarget(event)) && (!sel || sel.type != "Text"))
    {
      bl_port_stop_event(event);
    }
  }
}

function _bl_sys_objectLink(anchorEl, funcName, funcArgs)
{
  var objectInfo = bl_sys_findNearestLinkId(anchorEl);
  
  if (objectInfo)
  {
    window.alert("Object info is " + objectInfo);

    var beg = 0;
    var end = 0;

    if(funcArgs && funcArgs.length > 0)
    {
      beg = 0;
      end = 0;
      
      end = funcArgs.indexOf(',');
      
      while (end >= 0)
      {
        requestStr += '<arg type="string" name="name">' + funcArgs.slice(beg, end) + '</arg>';
        beg = end + 1;
        end = funcArgs.indexOf(',', beg);
      }
      
      if (beg < funcArgs.length)
      {
        // We need to add some method of type determination instead of
        // assuming string here
        requestStr += '<arg type="string" name="name">' + funcArgs.substr(beg) + '</arg>';
      }
    }
    
    requestStr += '</function></object_link>';
    
    var mpr = bl_sys_get_mpr();
    
    if (mpr)
    {
      bl_mpr_send(requestStr, window.bl_did, 10);
    }
  }
}

function bl_sys_findNearestLinkId(elem)
{
  var objectLinkId = elem.getAttribute('cb_objectLinkId');
  
  while (!objectLinkId && elem && elem.getAttribute)
  {
    elem = elem.parentNode;
    objectLinkId = elem.getAttribute('cb_objectLinkId');
  }
  
  return objectLinkId;
}

function cb_sys_outputParseError(parseError)
{
  var text = "Parse error\nReason:  "   
           + parseError.reason       
           + "\nFilepos: "   
           + parseError.filepos      
           + "\nLine:  "     
           + parseError.line         
           + "\nLinePos:  "  
           + parseError.linepos      
           + "\nSrcText:  "  
           + parseError.srcText      
           + "\nUrl:  "      
           + parseError.url          
           + "\nCode:  "     
           + parseError.errorCode    
           + "\n";
  window.alert(text);
}

function cb_sys_printFrame(frame, onfinish)
{
  if (!frame) 
  {
    frame = window;
  }
  
  function execOnFinish()
  {
    switch (typeof(onfinish))
    {
      case "string": execScript(onfinish);
      break;
      case "function": onfinish();
    }
  }
  
  while (frame.document.readyState !== "complete")
  {
    setTimeOut("", 3000);
  }
  
  if (window.print)
  { // IE5
    var focused = bl_port_get_activeElement(document);
    bl_port_focus(frame);
    frame.print();
    execOnFinish();
    return;
  }
  
  var eventScope = printGetEventScope(frame);
  var focused = bl_port_get_activeElement(document);
  
  window._bl_printHelper = function()
  {
    execScript("on error resume next: printWB.ExecWB 6, 1", "VBScript");
    printFireEvent(frame, eventScope, "onafterprint");
    bl_port_setOuterHTML(printWB, "");
    execOnFinish();
    window._bl_printHelper = null;
  }
  
  bl_port_insertAdjacentHTML(document.body, "beforeend", "<object id='printWB' width=0 height=0 classid='clsid:8856F961-340A-11D0-A96B-00C04FD705A2'>");
  printFireEvent(frame, eventScope, "onbeforeprint");
  bl_port_focus(frame);
  window._bl_printHelper = _bl_printHelper;
  setTimeout("window._bl_printHelper()", 0);
}

function bl_sys_printUrl(url, did)
{
  var win = cb_sys_getTopWindow();
  if (win)
  {

    if (did != "")
    {
      if (did && did != "")
      {
        url += "&did=" + did;
      }
    }

    var html = "<iframe printFinished='cb_sys_printFinished(this)' name=printHiddenFrame width=0 src='" 
                + url 
                + "&isprint=true' height=0 onload='_bl_sys_onprintHiddenFrame()'></iframe>";


    bl_port_insertAdjacentHTML(win.document.body, "beforeend", html);
  }
}

function _bl_sys_onprintHiddenFrame()
{
  function onfinish()
  {
    _bl_sys_shutdown_window(printHiddenFrame);
    bl_port_setOuterHTML(printHiddenFrame, "");
  }
  
  cb_sys_printFrame(printHiddenFrame, onfinish);
}

function bl_sys_displayPopupBlockerError()
{
  var message = "A pop-up window was blocked by a Pop-up Blocker, disrupting product functionality.\nYou must turn off all pop-up blockers or set them to allow pop-ups for this site or this product will not function properly.\n\nIf no pop-up blocker is blocking pop-ups, the server connection may have been severed.\nRe-login to ensure proper functionality.  If the problem persists, please contact your System Administrator.";
  
  bl_sys_mpr_fb_dettach();
  window.alert(message);
}

function cb_sys_performBuddyExecution(el)
{
  var buddyList = el.buddyExecutionList;
  
  if (buddyList)
  {
    var len = buddyList.length;
    
    for (var i = 0; i < len; i++)
    {
      var eBuddy = buddyList[i];
      
      var cb_buddy_func = eBuddy.getAttribute("cb_buddy_func");
      if (cb_buddy_func)
      {
        eval(cb_buddy_func);
      }
    }
  }
}

function cb_sys_set_input_state(el, bDisableEl)
{
  if (el.tagName.toLowerCase() == "input" || el.tagName.toLowerCase() == "textarea")
  {
    if (bDisableEl)
    {
      el.setAttribute("disabled", "true");
      el.disabled = true;
    }
    else
    {
      // if the server has set the element to disabled during operation, don't set back to enabled.
      if (el.getAttribute("bl_sys_disabled") != null)
      {
        return;
      }
      else
      {
        el.setAttribute("disabled", "false");
        el.disabled = false;
        el.removeAttribute("disabled");
      }
    }
  }
}

function bl_sys_disable(el)
{
  if (el)
  {
    // check to see if this element has any special handling for enable/disable
    var func = window[el.getAttribute("bl_enable")];
    if (func)
    {
      func(el, false);
      return;
    }
    if (el.tagName == "IMG")
    {
      bl_sys_img_disable(el, (el.getAttribute("bl_selected") != null));
    }
    else
    {
      if (el.getAttribute("bl_cal_type") != null)
      {
        bl_cal_disable(el);
      }
    }
    el.setAttribute("disabled", "true");
    el.disabled = true;
    
    var stepStr = el.getAttribute("bl_fade_step");
    var opStr   = el.getAttribute("bl_fade_opacity");
    if (stepStr && opStr)
    {
      cb_sys_startFilter(el, true, 100, parseInt(opStr), parseFloat(stepStr), el.buddyEl, bl_port_compute_opacity_style(opStr, false), null);
    }
    cb_sys_setDisableInputChildren(el, true);
    el.setAttribute("bl_sys_disabled", true);
  }
}

function bl_sys_enable(el)
{
  if (el)
  {
    // check to see if this element has any special handling for enable/disable
    var func = window[el.getAttribute("bl_enable")];
    if (func)
    {
      func(el, true);
      return;
    }
    
    if (el.tagName == "IMG")
    {
      bl_sys_img_set(el, (el.getAttribute("bl_selected") != null), el.bl_mouseIsIn);
    }
    else
    {
      if (el.getAttribute("bl_cal_type") != null)
      {
        bl_cal_enable(el);
      }
    }
    el.setAttribute("disabled", "false");
    el.disabled = false;
    el.removeAttribute("disabled");
    
    var stepStr = el.getAttribute("bl_fade_step");
    var opStr   = el.getAttribute("bl_fade_opacity");

    if (stepStr && opStr)
    {
      cb_sys_startFilter(el, false, parseFloat(opStr), 100, parseInt(stepStr), el.buddyEl, 100, null);
    }
    cb_sys_setDisableInputChildren(el, false);
    el.removeAttribute("bl_sys_disabled");
  }
}

function bl_sys_hide(el)
{
  if (el)
  {
    var retainSpace = el.getAttribute("bl_retainspace") != null;
    var func        = window[el.getAttribute("bl_showHide")];
    
    if (func)
    {
      func(el, retainSpace, true);
    }
    else
    {
      if (retainSpace)
      {
        el.style.visibility = "hidden";
      }
      else
      {
        if (el.getAttribute("bl_display") == null)
        {
          el.setAttribute("bl_display", el.style.display);
        }
        el.style.display = "none";
      }
    }
  }
}

function bl_sys_show(el)
{
  if (el)
  {
    var retainSpace = el.getAttribute("bl_retainspace") != null;
    var func        = window[el.getAttribute("bl_showHide")];
    
    if (func)
    {
      func(el, retainSpace, false);
    }
    else
    {
      if (retainSpace)
      {
        el.style.visibility = "visible";
      }
      else
      {
        var display = el.getAttribute("bl_display") || "";
        el.style.display = display;
      }
    }
  }
}

function bl_sys_handleDDChange(item, el)
{
  if (bl_port_get_text(item.firstChild) == true)
  {
    el.setAttribute("bl_ddFrozen", true);
  }
  else
  {
    el.removeAttribute("bl_ddFrozen");
  }
}

function bl_sys_handleRCChange(item, el)
{
  if (bl_port_get_text(item.firstChild) == true)
  {
    el.setAttribute("bl_rcFrozen", true);
  }
  else
  {
    el.removeAttribute("bl_rcFrozen");
  }
}

function bl_sys_handleEnableShow(item, el)
{
  var item_text = bl_port_get_text(item.firstChild);

  if (item.firstChild.nodeName == "enable")
  {
    if (item_text == "true")
    {
      bl_sys_enable(el);
      bl_sys_enable(el.buddyEl);
    }
    else
    {
      bl_sys_disable(el);
      bl_sys_disable(el.buddyEl);
    }
  }
  else if (item.firstChild.nodeName == "show")
  {
    if (item_text == "true")
    {
      bl_sys_show(el);
      bl_sys_show(el.buddyEl);
    }
    else
    {
      bl_sys_hide(el);
      bl_sys_hide(el.buddyEl);
    }
  }
}

function bl_sys_handleNewBgStyle(item, el)
{
  var text = bl_port_get_text(item);
  var s    = el.style;
  
  s.background = "";
  
  s.cssText += ";"+text;
}

function cb_sys_focusUpdate()
{
  if (!window.bl_sys_isInPopup())
  {
    var activeEl = (document.readyState == "complete") ? bl_port_get_activeElement(document) : null;
    
    //branch here because firefox doesn't support calling focus on body
    if (bl_browserInfo.ie)
    {
      bl_port_focus(window.document);
    }
    else if (bl_browserInfo.firefox)
    {
      bl_port_focus(window);
    }
    
    bl_port_setActive(activeEl);
  }
}

function bl_doMessage(typeStr, message, suspendId, prompt, visible)
{
  var type = parseInt(typeStr);
  
  var xmlStr = "<MessageBox>";
  if (type == 0)
  {
    if (visible)
    {
      window.alert(message);
    }
  }
  else if (type == 1)
  {
    var confirmVal = true;
    
    if (visible)
    {
      confirmVal = window.confirm(message);
    }
    
    xmlStr += "<confirm>";
    xmlStr += (confirmVal ? "true" : "false");
    xmlStr += "</confirm>";
  }
  else
  {
    var returnPrompt = "";
   
    if (visible)
    {
      returnPrompt = window.prompt(message, prompt);
    }

    if (!returnPrompt)
    {
      xmlStr += "<confirm>false</confirm><prompt><prompt>";
    }
    else
    {
      xmlStr += "<confirm>true</confirm><prompt>"
              + returnPrompt
              + "</prompt>";
    }
  }
  
  xmlStr += "</MessageBox>";
  
  // send the data to the server only if suspendId is
  // a valid one.
  if (suspendId >= 0)
  {  
    bl_mpr_send(xmlStr, window.bl_did, -1, BL_MPR_ASAP, false, suspendId);
  }
}

function _bl_logoutHandler(item, element)
{
  var el = item.firstChild;
  
  if (el.nodeName == "logout")
  {
    var nodes         = el.childNodes;
    var redirectURL   = bl_port_get_text(nodes.item(0));

    if(redirectURL == "")
    {
      redirectURL = bl_deployurl;
    }

    _bl_redirect(redirectURL);
  }

}

function _bl_redirect(url)
{ 
  try
  {
    if (url == "")
    {
      cb_sys_getTopWindow().location.reload(true);
    }
    else if(window.bl_embedded)
    {
      cb_sys_getTopWindow().location = url;
    }
    else
    {
      top.location.href = url;
    }
  }
  catch(exception)
  {
    if (url == "")
    {
      top.location.reload(true);
    }
    else
    {
      top.location.href = url;
    }
  }

}

function _bl_messageHandler(item, element)
{
  var el = item.firstChild;
  
  if (el.nodeName == "message")
  {
    var prompt      = "";
    var nodes       = el.childNodes;
    var message     = bl_port_get_text(nodes.item(0));
    var suspendId   = bl_port_get_text(nodes.item(1));
    var messageType = bl_port_get_text(nodes.item(2));
    var visible     = true;
    
    if (nodes.length > 3)
    {
      var lastItem = nodes.item(3);
      
      if (lastItem.nodeName == "prompt")
      {
        if (messageType == "2")
        {
          prompt = bl_port_get_text(nodes.item(3));
        }
      }
      else
      {
        visible = !(bl_port_get_text(lastItem) == "false");
      }
    }
    bl_doMessage(messageType, message, suspendId, prompt, visible);
  }
}


function _bl_popup(event, el)
{
  if (el)
  {
    var openProp = el.getAttribute("cb_open_prop");
    
    if (openProp)
    {
      if (el.getAttribute("bl_open_is_popup") != null)
      {
      }
      else
      {
        eval(openProp);
      }
    }
  }
}

function bl_sys_handleException(exception)
{
  if (exception)
  {
    var str = "An exception has been thrown. It is possible that the server connection has been severed.\nIf problem persists, please contact your System Administrator.\n";
    
    if (exception.name)
    {
      str += exception.name;
      str += ":";
      if (exception.description)
      {
        str += exception.description;
      }
      if (exception.number)
      {
        str += "\nNumber:";
        str += exception.number;
      }
      if (exception.message)
      {
        str += "\nMessage:";
        str += exception.message;
      }
    }
    else
    {
      str += "Error:" + exception;
    }
    
    window.alert(str);
  }
}

function cb_sys_setDisableInputChildren(el, val)
{
  try
  {
    var list = el.getElementsByTagName("INPUT");
    var len  = list.length;
    
    for (var i = 0; i < len; i++)
    {
      cb_sys_set_input_state(list[i], val);
    }
    
    list = el.getElementsByTagName("TEXTAREA");
    len  = list.length;
    
    for (var i = 0; i < len; i++)
    {
      cb_sys_set_input_state(list[i], val);
    }
  }
  catch (exception)
  {
  }
}

function bl_sys_checkDialogSelect(el)
{
  if (el && el.getAttribute("bl_dialogSelect") != null)
  {
    var current = window.bl_currentSelect;
    
    try
    {
      if (current && current.offsetParent != null)
      {
        if (current != el)
        {
          if (current)
          {
            var func = window[current.getAttribute("bl_dialogSelect")];
            
            if (func)
            {
              func(current);
            }
          }
        }
      }
    }
    catch (ex)
    {
      // it is posible that the current is just not valid any mor and 
      // we nee to protect against that from causing to much trouble.
      // also we need to garentee that the el coming in will be set
      // as the current or we will gert in a bad state.
      
    }    
    window.bl_currentSelect = el;
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_sys_last()
{
  var x = 0;
}


//***********************************************************************
//***********************************************************************
//********                  bl_window.js                        *********
//***********************************************************************
//***********************************************************************

function _bl_sys_initWindow(clientId, id, titleString, validateStr, closeMeansCancel, isMain)
{
  bl_port_retrieveDialogWindowProperties(window);

  if (bl_browserInfo.ie6 && typeof window.dialogArguments != "undefined")
  {
    _bl_sys_fixIE6Size();
  }
    
  if (titleString.length)
  {
    try
    {
      window.document.title = unescape(titleString);
    }
    catch (exception)
    {
    }
  }
  
  if (validateStr.length)
  {
    window.bl_validateString = unescape(validateStr);
  }
  
  window.bl_did                 = id;
  window.cb_clientId            = clientId;
  window.closeMeansCancel       = closeMeansCancel;
  window.document.oncontextmenu = bl_sys_context_menu;
  window.bl_is_main             = isMain;

  var isFrameBased = false;

  if (isMain)
  {
    window.mpr = new cb_sys_mpr_create();
  }
  else if (window.frameElement)
  { // Dynamic Form
    var frm = window.frameElement;
    
    if (frm.getAttribute("cb_tag") == "IF_EMB")
    {
      frm.bl_winName = id;
      isFrameBased   = true;
      
      // bl_close_type = 2 means that the server will handle the shutdown 
      // of this window so don't send a shutdown for this window
      window.bl_close_type = 2;
    }
  }
  
  var list       = null;
  var isPrint    = false;
  var dialogArgs = bl_port_getDialogArguments();  
  
  if (bl_sys_isInPopup())
  {
    list = window.parent.bl_window_list;
  }
  else if (dialogArgs && !isMain)
  {
    isPrint = dialogArgs.isPrint;
    list    = dialogArgs.parent.bl_window_list;
  }
  else if (window.opener && !isMain)
  {
    try
    {
      list = window.opener.bl_window_list;
    }
    catch (exception)
    {
    }
  }
  
  // if frame window then get its parent child list
  if (!list && !isMain)
  {
    try
    {
      list = cb_sys_getTopWindow().bl_window_list;
    }
    catch (exception)
    {
      list = null;
    }
  }
  
  if (!list && !window.bl_window_list)
  {
    list = [];
    list.deadWindowList = [];
    list.mprWindowList  = [];
    list.bl_fb_attachedCount = 0;
  }
  
  if (list && !window.bl_window_list)
  {
    window.bl_window_list = list;
    if (!cb_sys_getWindow(list, id))
    {
      list.push(window);
    }
  }
  
  if (window.isPrint)
  {
    cb_sys_print_loaded();
  }
  
  if (isFrameBased)
  {
    window.parent.bl_inline_checkPending(window.frameElement);
  }
  
  bl_sys_mpr_fb_dettach();
}

function _bl_sys_clearInputBlocker()
{
  var inputBlocker = document.getElementById("bl_inputBlocker_id");

  if (inputBlocker)
  {
    inputBlocker.parentNode.removeChild(inputBlocker);
  }
}

function _bl_sys_startInteraction(id, pingServer)
{
  if (!window.bl_is_main && window.frameElement)
  { 
    var frm = window.frameElement;
    
    if (frm.getAttribute("cb_tag") == "IF_EMB" && frm.getAttribute("bl_state") == "pending")
    {
      return;
    }
    
    // ie will no give the body of the iframe a client width or height if the src is 
    // set while loading so let force a resize of the iframe to force it to do the right 
    // thing
    var body = document.body;
    if (bl_browserInfo.ie && body.clientWidth == 0 && body.clientHeight == 0 )
    {
      frm.style.width = frm.offsetWidth + 1;
      frm.style.width = frm.offsetWidth;
    }
  }

  _bl_geo_doResize();
  window.onresize = _bl_geo_resized;

  // in some context firefox will stop poping up 
  // a dialog on window.open and making that dialog
  // the top dialog.  this is here to alieviate that issue
  // we only want to do this if dialog ars actual exist on the window
  // as that is the indication that this window is the top window and
  // was opened using window.open 
  if (bl_browserInfo.firefox && bl_port_getDialogArguments())
  {
    try
    {
      // don't call 
      window.focus();    
    } catch (e) {}
  }
  
  var findFirstFocus = true;
    
  if (bl_sys_isInPopup())
  {
    var popupArg = null;
    try
    {
      popupArg = window.frameElement.container.popup_obj.popup_arg;
      findFirstFocus = popupArg.sticky;
    } 
    catch(e) 
    {
      findFirstFocus = false;
    }
 }
  
  var tlw = cb_sys_getTopLevelWindow();
  tlw.bl_kb_doFirstFocus(findFirstFocus);

  bl_sys_findAndRemoveTracker(window.bl_did);
  bl_sys_procesMPRItem(window);
  
  if(id > -1)
  {
    bl_mpr_send("<start_interaction>"+id+"</start_interaction>", window.bl_did, -1, BL_MPR_ASAP, true);
  }
  else if (pingServer)
  {
    bl_mpr_send("<pingServer/>", window.bl_did, -1, BL_MPR_ASAP, true);
  }
  
  _bl_sys_clearInputBlocker();
}

function _bl_sys_safari_beforeUnload(event)
{
  if (bl_browserInfo.safari && !window.bl_port_safariUnloaded)
  {
    // Safari doesn't correctly throw the "onunload" event, so this will
    // manually do it. This comes at the loss of the ability to warn the
    // user that they are about to lose their work on other dialogs.
    // (This issue references Webkit bugs #3402 and #12469).

    var unloadEvent = document.createEvent("HTMLEvents");
    unloadEvent.initEvent("unload",true,true);
    document.body.dispatchEvent(unloadEvent);

    window.bl_port_safariUnloaded = true;
  }
}


// adds a dialog close tracker.
// this is needed in order to make sure 
// a shutdown message goes back to the server 
// in the event the dilog never makes it to creattion
function bl_sys_closeTrackerAdd(did, url, suspendId, enableContext, fireCallback)
{
  var tracker = { url:url,
                  did:did,
                  time:new Date(),
                  win:null,
                  blocked:false,
                  enableContext:enableContext,
                  suspendId:suspendId
                };

  if (!this.list)
  {
    this.list = [];
  }

  this.list.push(tracker);
  
  if (fireCallback)
  {
    _bl_sys_checkCloseTrackers();
  }

  return tracker;
}

function bl_sys_is_live()
{
  if (bl_sys_isInPopup())
  {
    var arg = bl_sys_getMyPopupArg();
    
    if (arg && arg.isLive)
    {
      return true;
    }
  }
    
  return !window.closed;
}

function _bl_sys_msg(el)
{
  var msg = el.getAttribute("bl_msg");
  
  if (msg)
  {
    window.alert(msg);
  }
}

function _bl_sys_closeWindow(closeReason)
{
  if (window.bl_sys_isInPopup())
  {
    var arg = bl_sys_getMyPopupArg();
    
    if (closeReason)
    {
      window._bl_close_reason = closeReason;
    }
    
    if (!arg)
    {
      cb_sys_getTopWindow().bl_sys_popupVeilDown();
      if (typeof this.frameElement != "undefined")
      {
        this.frameElement.container.popup_obj.close();
      }
      return;
    }

    bl_sys_closeThisPopup();
  }
  else
  {
    var win = cb_sys_getTopWindow();
    if (closeReason)
    {
      win._bl_close_reason = closeReason;
    }
    win.close()
  }
}

function _bl_sys_toplevel_handler(item, el)
{
}

function _bl_sys_validateClose(event)
{
  var ret = undefined;
  
  if (!event)
  {
    event = window.event;
  }
  
  // bl_close_type undefined or 0 means we are needing to notify the 
  // server that this window is shutdown
  if (window.bl_close_type == undefined || window.bl_close_type == 0)
  {
    bl_port_focus(window);
    
    if (window.bl_is_main)
    {
      ret  = window.bl_validateString;
    }
    else 
    {
      var closeStr = (window.closeMeansCancel ? "Cancel" : "Ok");
      
      if (window._bl_close_reason)
      {
        closeStr = window._bl_close_reason;
      }

      if (closeStr == "Cancel")
      {
        ret = window.bl_validateString;
      }
    }
  }
  if (ret == "")
  {
    ret = undefined;
  }
  return ret;

}

function bl_sys_getWindowName(win)
{
  if (win.bl_sys_isInPopup && win.bl_sys_isInPopup() && win.bl_did)
  {
    return win.bl_did;
  }
  else if (!win.bl_is_main && win.frameElement && win.frameElement.bl_winName)
  {
    return win.frameElement.bl_winName;
  }
  return "-1";
}

function _bl_sys_shutdown_window(win, popupArg)
{
  var mpr = null;
  if (!win.bl_sys_goingDown)
  {
    mpr = bl_sys_get_mpr(win);
  }
  
  win.onunload = null;
  
  if (mpr)
  {
    if (!win.bl_windowHasShutDown)
    {
      if (win.cb_sys_doCleanUp)
      {
        win.cb_sys_doCleanUp();
      }
      win.bl_windowHasShutDown = true;
      
      // bl_close_type = 0 or undefined means that we are going to send the shutdown to the server
      // bl_is_main indicates that we need to force shutdown all child windows seting their
      // bl_close_type to 1 which also means don't send shutdown 1 also means the system is going down
      if (!win.bl_close_type && win.bl_is_main)
      {
        cb_sys_closeAllPopups(1);
      }
      
      // remove child from parent
      try
      {
        if (win.bl_window_list)
        {
          var list = win.bl_window_list;
          
          if (list)
          {
            var len = list.length;
            
            for (var i = 0; i < len; i++)
            {
              try
              {
                var child = list[i];
                
                if (child && child == win)
                {
                  if (list.deadWindowList.length >= 5)
                  {
                    list.deadWindowList.splice(0, 1);
                  }
                  
                  list.deadWindowList.push(child.bl_did);
                  list.splice(i, 1);
                  break;
                }
              }
              catch (exception)
              {
              }
            }
          }
        }
        //  bl_close_type is set to 2 so no need to go any further
        if (win.bl_close_type != undefined && win.bl_close_type == 2)
        {
          return;
        }
        
        //if main win is closing you... don't send shutdown.
        if (!win.bl_sys_goingDown)  
        {
          // need to tell the server done editing
          var closeStr = (win.closeMeansCancel ? "Cancel" : "Ok");
          var idObj    = bl_port_getDialogArguments(win);
          var isPopup  = win.bl_sys_isInPopup();
          var idName   = bl_sys_getWindowName(win);
          var sendType = (win.bl_is_main)? BL_MPR_SYNC:BL_MPR_ASAP;
          
          if (win._bl_close_reason)
          {
            closeStr = win._bl_close_reason;
          }
          
          var suspendId = 0;
          var parentId  = 0;

          win.bl_sys_shutdownPopupList();
          
          if (idObj)
          {
            parentId  = idObj.parentId;
            suspendId = idObj.suspendId;
          }
          else if (isPopup && popupArg)
          {
            suspendId = popupArg.suspendId;

            if (popupArg.deferSend)
            {
              sendType = BL_MPR_DEFER;
            }
          }

          mpr.handleException = false;
          win.bl_mpr_send(bl_sys_shutDownMSG(suspendId, parentId, closeStr), idName, -1, sendType, true, -1);
        }
      }
      catch (exception)
      {
        //in shutdown of window ignore exception
      }
      mpr.handleException = true;
    }
  }
}

function _bl_callModalInvoke()
{
  var mi = window.bl_mi;

  // need to make sure that the function on the modal invoker actauly 
  // exists befroe we start the process
  if (mi && mi.contentWindow._bl_sys_invokeModal)
  {
    if (mi.bl_modalItem)
    {
      mi.contentWindow.setTimeout('_bl_sys_invokeModal()', 10);
    }
  }
  else 
  {
    window.setTimeout('_bl_callModalInvoke()', 10);
  }
}

function bl_sys_processModal(suspendId, m_url, m_features, m_args, m_did)
{
  // Modal windows prevent the parent context from doing anything (including
  // AJAX requests). We get around that by opening a hidden IFRAME which
  // becomes the parent context of modal windows. This IFRAME can be blocked,
  // but the main window is not blocked.
  var mi = window.bl_mi;
  
  if (!mi)
  {
    window.bl_mi = mi = document.getElementById("bl_modalInvoker");
  }

  if (mi && !mi.bl_modalItem)
  {
    mi.bl_modalItem = {url:m_url, features:m_features, args:m_args, did:m_did};
    _bl_callModalInvoke();
  }
  else
  {
    bl_sys_killSuspend(suspendId);
    bl_sys_mpr_fb_dettach();
  }
}

function bl_sys_shutDownMSG(suspendId, parentId, closeStr)
{
  var ret = "<close_request";
  
  if (parentId > 0)
  {
    ret += " parentId='";
    ret += parentId;
    ret += "'";
  }
  
  if (suspendId > 0)
  {
    ret += " suspendId='";
    ret += suspendId;
    ret += "'";
  }
  ret +=  "><reason>" +closeStr+ "</reason></close_request>";
  
  return ret;
}

function bl_sys_shutDownTracker(mpr, tracker, list, i, windowToClose)
{
  try
  {
    list.splice(i, 1);
    bl_sys_mpr_fb_dettach();

    if (windowToClose)
    {
      windowToClose._bl_sys_closeWindow();
    }
    
    var did = tracker.did;
    
    if (tracker.suspendId >= 0)
    {
      if (did && did != "")
      {
        var mprItem = bl_sys_removeFromMPRList(did, window.bl_window_list.mprWindowList);
        
        if (mprItem)
        {
          bl_cleanMPRItem(mprItem);
        }
        mpr.send(did, bl_sys_shutDownMSG(tracker.suspendId, 0, "Cancel"), did, -1, BL_MPR_ASAP, true, -1);
      }
      else
      {
        bl_sys_killSuspend(tracker.suspendId);
      }
    }
    
    if (tracker.enableContext)
    {
      tracker.enableContext.bl_port_enableEvents();
    }
  }
  catch (e)
  {
    // making sure that nothing happens that is not leagle
    // in this context
  }
}

function bl_sys_findAndShutDownTracker(tracker)
{
  var mpr = bl_sys_get_mpr();
  var list = mpr.list;

  if (!list)
  {
    return;
  }
  
  for (var i = list.length - 1; i >= 0; i--)
  {
    if (tracker == list[i])
    {
      bl_sys_shutDownTracker(mpr, tracker, list, i, null);
      break;
    }
  }
}

function bl_sys_findAndRemoveTracker(name)
{
  var mpr = bl_sys_get_mpr();
  var list = mpr.list;

  if (!list)
  {
    return;
  }
  
  for (var i = list.length - 1; i >= 0; i--)
  {
    if (name == list[i].did)
    {
      list.splice(i, 1);
    }
  }
}


// A function to detect when popup windows are closed on the client
// before initialization has occurred.
function _bl_sys_checkCloseTrackers()
{
  var mpr = bl_sys_get_mpr();
  var list = mpr.list;

  if (!list)
  {
    return;
  }
  
  for (var i = list.length - 1; i >= 0; i--)
  {
    var tracker = list[i];
    var twin    = tracker.win
    
    // There are three possible test outcomes: 
    // 1 - The window has initialized loaded. State="ok"
    // 2 - The window is known to have been closed (or failed loading). State="fail"
    // 3 - The state of the window is still unknown. State="unknown"
    
    if (twin)
    {
      try
      {
        if (twin.closed)
        {
          bl_sys_shutDownTracker(mpr, tracker, list, i, null);
        }
      } 
      catch (e)
      {
        bl_sys_shutDownTracker(mpr, tracker, list, i, null);
      }
    }
    else if (tracker.blocked)
    {
      bl_sys_shutDownTracker(mpr, tracker, list, i, null);
    }
    else if ((tracker.time - new Date()) > 300000)
    {
      // Window hasn't loaded after 5 minutes. Assume failure? for now
      bl_sys_shutDownTracker(mpr, tracker, list, i, twin);
    }
  }
  
  if (list.length > 0)
  {
    setTimeout(_bl_sys_checkCloseTrackers, 500);
  }
}

function bl_sys_killSuspend(suspendId)
{
  if (suspendId && suspendId > 0)
  {
    var xmlStr = "<killSuspend><reason killed='1'>Cancel</reason></killSuspend>";
    var idName = bl_sys_getWindowName(window);
    bl_mpr_send(xmlStr, idName, -1, BL_MPR_ASAP, true, suspendId);
  }
}

function bl_wn_findControl(id)
{
  var winList   = bl_moz_listAllWindows(bl_sys_get_main(window));
  var len       = winList.length;
  
  for (var i = 0; i < len; i++)
  {
    var contextEl = winList[i].document.getElementById(id);
    
    if (contextEl)
    {
      return contextEl;
    }
  }
  
  return null;
}

function bl_sys_initCloseTracker(did, url, arg, fireCallback, enableContext)
{
  var suspendId = -1;
  
  if (arg && arg.suspendId != undefined)
  {
    suspendId = arg.suspendId;
  }
  
  return bl_sys_get_mpr().addCloseTracker(did, url, suspendId, enableContext, fireCallback);
}

function _bl_sys_open(did, url, features, windowtype, isPrint, suspendId, rawUrl)
{
  var newWin = null;
  try
  {
    if (!rawUrl && isPrint)
    {
      bl_sys_printUrl(url, did);
    }
    else
    {
      var blocked = false;
      var args    = { parent:window, 
                      parentId:window.bl_did, 
                      suspendId:suspendId, 
                      isPrint:isPrint, 
                      isRaw:rawUrl 
                    };

      if (did != "")
      {
        bl_sys_mpr_fb_attach(0);
        
        if (did && did != "")
        {
          url += "&did=" + did;
        }
      }
      
      features = bl_port_openFeatures(windowtype, features);

      if (windowtype == 0)
      {
        newWin = bl_port_openWindow(window, url, args, did, "_blank", features, false, null);

        if (!newWin)
        {
          blocked = true;
        }
        else if (!rawUrl)
        {
          window.bl_window_list.push(newWin);
        }
      }
      else if (windowtype == 1)
      {
        newWin = bl_port_showModeless(window, url, did, args, features);
        
        if (newWin)
        {
          newWin.isPrint = isPrint;
        }
        else
        {
          blocked = true;
        }
      }
      else
      {
        var modalURL = (rawUrl)? url : (modalURL = document.location.protocol + "//" + document.location.host + url);
        window.bl_sys_processModal(suspendId, modalURL, features, args, did);
      }
    }
  }
  catch (exception)
  {
    blocked = true;
  }

  if (blocked)
  {
    bl_sys_killSuspend(suspendId);
    bl_sys_displayPopupBlockerError();
  }
  return newWin;
}

function _bl_dialogHandler(item, element)
{
  var el = item.firstChild;
  if (el.nodeName == "popup")
  {
    eval(bl_port_get_text(el));
  }
}

function bl_sys_addCleanUpCall(el, func)
{
  if (func)
  {
    var item = { el:el, cleanUp:func };
    var list = window.bl_sys_cleanUpList
    
    if (!list)
    {
      window.bl_sys_cleanUpList = list = [];
    }
    
    list.push(item);
  }
}

function bl_dlg_cleanUpForEl(el)
{
  var list = window.bl_sys_cleanUpList;
  
  if (list)
  {
    var len = list.length;
    
    for (var i = len - 1; i >= 0; i--)
    {
      var item = list[i];
      
      try
      {
        if (item.el.offsetParent == null)
        {
          item.cleanUp(item.el);
          item.cleanUp = null;
          item.el      = null;
          list.splice(i, 1);
        }
      } 
      catch (ex) {}
    }
  }
  bl_btn_cleanUpForEl(el);
}

function cb_sys_doCleanUp()
{
  var list = window.bl_sys_cleanUpList;
  
  if (list)
  {
    var item = list.pop();
    
    while (item != undefined)
    {
      try
      {
        item.cleanUp(item.el);
        item.cleanUp = null;
        item.el      = null;
      } 
      catch (ex) {}
      
      item = list.pop();
    }
    window.bl_sys_cleanUpList = null;
  }
  bl_btn_cleanUpMove();
}


//***********************************************************************
//***********************************************************************
//********                  bl_container.js                     *********
//***********************************************************************
//***********************************************************************

// Globals
var GRID_ROUNDOF_FACTOR          = 1000;
var bl_contain_type_natural      = 0;
var bl_contain_type_horzBox      = 1;
var bl_contain_type_vertBox      = 2;
var bl_contain_type_horizontal   = 3;
var bl_contain_type_vertical     = 4;
var bl_contain_type_2dHorizontal = 5;
var bl_contain_type_2dVertical   = 6;
var bl_contain_type_absolute     = 7;
var bl_contain_type_grid         = 8;

function bl_contain_topParent()
{
  var ret = document.getElementById("bl_layout_parent");
  
  if (!ret)
  {
    ret = document.body;
  }
  
  return ret;
}

// Note: If 'isDrop' is false, this will not compute which half of the child
// the mouse is over, and the consumer of the information will have to.
function bl_contain_v_computeCanDrop(ddObj, el, child, clientx, clienty, isDrop)
{
  var dim       = 2;
  var size      = 30;
  var offsetPar = el.firstChild.offsetParent;
  var elTop     = bl_sys_find_y(offsetPar, null, false);
  var y         = clienty - elTop + offsetPar.scrollTop;
  var len       = this.numChildren(el);
  var index     = 0;

  if (el != child)
  {
    // The mouse is over a specific child. Position the drag hint in relation
    // to this element.
    var childTop   = child.offsetTop;
    var parentNode = child.parentNode;

    if (parentNode.tagName == "TD")
    {
      childTop += parentNode.offsetTop;
    }
    
    index = this.getChildIndex(el, child);
  }
  else if (len > 0)
  {
    // The mouse is not over any specific child. Find the element closest to
    // the mouse. Position the drag hint in relation to this element.

    var curTop = 0;
    var child  = this.getChild(el, 0);

    for (var i = 1; i < len; i++)
    {
      var next       = this.getChild(el, i);
      var childTop   = next.offsetTop;
      var parentNode = next.parentNode;

      if (parentNode.tagName == "TD")
      {
        childTop += parentNode.offsetTop;
      }
      
      if (y < childTop)
      {
        break;
      }
      child = next;
      index++;
    }
  }
  else
  {
    child = el;
  }
  
  if (isDrop)
  {
    if (!ddObj.isTopLeft)
    {
      child = (index < (len - 1))? this.getChild(el, index + 1):el;
    }
    ddObj.setHint(null);
  }
  else
  {
    var hintContext = { el:el,
                        child:child,
                        hintDrop:_bl_ctr_ddHintDrop,
                        x:clientx,
                        y:clienty,
                        dimension:dim,
                        size:size,
                        isVertical:true
                      };
    
    ddObj.setHint(hintContext);
  }
  
  return child;
}

// Note: If 'isDrop' is false, this will not compute which half of the child
// the mouse is over, and the consumer of the information will have to.
function bl_contain_h_computeCanDrop(ddObj, el, child, clientx, clienty, isDrop)
{
  var dim       = 2;
  var size      = 30;
  var offsetPar = el.firstChild.offsetParent;
  var elLeft    = bl_sys_find_x(offsetPar, null, false);
  var x         = clientx - elLeft + offsetPar.scrollLeft;
  var len       = this.numChildren(el);
  var index     = 0;

  if (el != child)
  {
    // The mouse is over a specific child. Position the drag hint in relation
    // to this element.
    var childLeft  = child.offsetLeft;
    var parentNode = child.parentNode;

    if (parentNode.tagName == "TD")
    {
      childLeft += parentNode.offsetLeft;
    }

    index = this.getChildIndex(el, child);
    size  = child.offsetHeight;
  }
  else if (len > 0)
  {
    // The mouse is not over any specific child. Find the element closest to
    // the mouse. Position the drag hint in relation to this element.

    var curLeft = 0;
    
    child = this.getChild(el, 0);

    for (var i = 1; i < len; i++)
    {
      var next    = this.getChild(el, i);
      var childLeft  = next.offsetLeft;
      var parentNode = next.parentNode;

      if (parentNode.tagName == "TD")
      {
        childLeft += parentNode.offsetLeft;
      }
      
      if (x < childLeft)
      {
        break;
      }
      child = next;
      index++;
    }

    size = child.offsetHeight;
  }
  else
  {
    child = el;
  }
  
  if (isDrop)
  {
    if (!ddObj.isTopLeft)
    {
      child = (index < (len - 1))? this.getChild(el, index + 1):el;
    }
    ddObj.setHint(null);
  }
  else
  {
    var hintContext = { el:el,
                        child:child,
                        hintDrop:_bl_ctr_ddHintDrop,
                        x:clientx,
                        y:clienty,
                        dimension:dim,
                        size:size
                      };
    
    ddObj.setHint(hintContext);
  }
  
  return child;
}


// Layout Managers BEGIN

// Natural
function bl_contain_natural_create()
{
  this.type = bl_contain_type_natural;
  this.borderName = "vh";
}

bl_contain_natural_create.prototype.find                = bl_contain_find;
bl_contain_natural_create.prototype.findChild           = bl_contain_findChild;
bl_contain_natural_create.prototype.nextChild           = bl_contain_findNextChild;
bl_contain_natural_create.prototype.prevChild           = bl_contain_findPrevChild;
bl_contain_natural_create.prototype.getChild            = bl_contain_getChild;
bl_contain_natural_create.prototype.numChildren         = bl_contain_numChildren;
bl_contain_natural_create.prototype.getChildIndex       = bl_contain_getChildIndex;
bl_contain_natural_create.prototype.findDropChild       = bl_contain_findDropChild;
bl_contain_natural_create.prototype.cleanup             = bl_contain_n_cleanup;
bl_contain_natural_create.prototype.computeCanDrop      = bl_contain_n_computeCanDrop;
bl_contain_natural_create.prototype.computeDragFeedback = bl_contain_n_computeDragFeedback;
bl_contain_natural_create.prototype.adjustToFlow        = bl_contain_n_adjustToFlow;
bl_contain_natural_create.prototype.layoutChildren      = bl_contain_layoutChildren;
bl_contain_natural_create.prototype.resizeCheck         = bl_contain_resize_check_children;
bl_contain_natural_create.prototype.canEdit             = bl_contain_can_edit;
bl_contain_natural_create.prototype.setCanEdit          = bl_contain_set_can_edit;
bl_contain_natural_create.prototype.setCanEditRecurs    = bl_contain_set_can_edit_recurs;
bl_contain_natural_create.prototype.cleanUpArtifacts    = bl_contain_clean_up_artifacts;
bl_contain_natural_create.prototype.buildUpArtifacts    = bl_contain_build_up_artifacts;
bl_contain_natural_create.prototype.layoutBorder        = bl_contain_layoutBorder;
bl_contain_natural_create.prototype.addChild            = bl_contain_add_child;
bl_contain_natural_create.prototype.childAdded          = bl_contain_child_added;
bl_contain_natural_create.prototype.removeChild         = bl_contain_remove_child;
bl_contain_natural_create.prototype.removeAll           = bl_contain_removeAll;
bl_contain_natural_create.prototype.childRemoved        = bl_contain_child_removed;
bl_contain_natural_create.prototype.childLimitSet       = bl_contain_childLimits;
bl_contain_natural_create.prototype.childReset          = bl_contain_child_reset;
bl_contain_natural_create.prototype.moveChild           = bl_contain_moveChild;
bl_contain_natural_create.prototype.selectChild         = bl_contain_selectChildIndex;
bl_contain_natural_create.prototype.keyCommand          = bl_contain_keyCommand;

function bl_contain_removeAll(el)
{
  var bag = bl_contain_getBag(el);
  bag.parentNode.removeChild(bag);
  el.innerHTML = "";
  bl_port_insertAdjacentElement(el, "AfterBegin", bag);
}

function bl_contain_resize_check_children(el, resizeQueue)
{
  if (this.canEdit(el))
  {
    this.layoutBorder(el);
  }

  if (el.offsetWidth != el.bl_lastWidth || el.offsetHeight != el.bl_lastHeight)
  {
    el.bl_lastWidth  = el.offsetWidth;
    el.bl_lastHeight = el.offsetHeight;
    this.layoutChildren(el, resizeQueue);
  }
}

function bl_contain_selectChildIndex(el, index)
{
  var child = this.getChild(el, index);
  
  if (child)
  {
    bl_contain_selectChild(el, child);
  }
}

function bl_contain_keyCommand(el, child, event, kcode)
{
  var newSelect = null;
  var newParent = el;
  
  switch (kcode)
  {
    case (37): //left
    {
      newSelect = this.prevChild(el, child);
      
      if (!newSelect)
      {
        newSelect = this.getChild(el, this.numChildren(el) - 1);
      }
    }
    break;
    case (39): //right
    {
      newSelect = this.nextChild(el, child);
      
      if (!newSelect)
      {
        // account for the artifact bag that is always generated to the container
        newSelect = this.getChild(el, 0);
      }
    }
    break;
    case (38): //up
    {
      var grandParent = bl_contain_getParent(el);

      if (grandParent)
      {
        if (bl_contain_getLayout(grandParent) == null)
        {
          newSelect = el;
        }
        else 
        {
          newParent = grandParent;
          newSelect = el;
        }
      }
    }
    break;
    case (40): //down
    {
      if (child && child.getAttribute("cb_tag") == "CTR")
      {
        var layout = bl_contain_getLayout(child);
        
        if (layout.numChildren(child) > 0)
        {
          var first = layout.getChild(child, 0);
          
          if (first)
          {
            newSelect = first;
            newParent = child;
          }
        }
      }
    }
    break;
  }  
  
  if (newParent && newSelect)
  {
    bl_contain_performSelect(newParent, newSelect);
  }
}

function bl_contain_moveChild(el, oldIndex, newIndex)
{
  var child = this.getChild(el, oldIndex);
  var len   = el.childNodes.length;
  
  el.removeChild(child);

  if (len > newIndex)
  {
    var insertSpot = this.getChild(el, newIndex);
    
    if (insertSpot)
    {
      bl_port_insertAdjacentElement(insertSpot, "beforebegin", child);
    }
    else
    {
      bl_port_insertAdjacentElement(el, "beforeend", child);
    }
  }
  else
  {
    bl_port_insertAdjacentElement(el, "beforeend", child);
  }
}

function bl_contain_child_reset(el, child, val)
{
  bl_port_insertAdjacentHTML(child, "beforebegin", val);
  
  var ret = child.previousSibling;
  child.parentNode.removeChild(child);

  if (this.type < bl_contain_type_vertical)
  {
    bl_contain_checkForAutoSize(el);
  }

  return ret;
}

function bl_contain_numChildren(el)
{
  // CONTAINER SPAN CASE
  // Subtract 1 for the background artifact.
  return el.childNodes.length - 1;
}

function bl_contain_getChildIndex(el, child)
{
  var list  = el.childNodes;
  var len   = list.length;
  
  if (child)
  {
    for (var i = 1; i < len; i++)
    {
      var temp = list[i];
      
      if (temp == child)
      {
        // account for the artifact bag that is always generated to the container
        return (i - 1);
      }
    }
  }
  return -1;
}

function bl_contain_getChild(el, index)
{
  if (index >= 0)
  {
    var list = el.childNodes;

    if (index + 1 < list.length)
    {
      return list[index + 1]
    }
  }
  
  return null;
}

function bl_contain_findChild(el, src)
{
  var row = src;
  
  while (row && row.parentNode != el)
  {
    row = row.parentNode;
  }
  
  return row;
}

function bl_contain_findNextChild(el, child)
{
  return child.nextSibling;
}

function bl_contain_findPrevChild(el, child)
{
  var ret = child.previousSibling;
  return (ret == el.firstChild)? null:ret;
}

function bl_contain_find(el, src)
{
  el.bl_context = "";
  
  if (src == el)
  {
    // account for the artifact bag that is always generated to the container
    return el;
  }

  var child = src;
  
  while (child && child.parentNode != el)
  {
    child = child.parentNode;
  }

  if (child)
  {
    if (child.getAttribute("bl_bag") != null)
    {
      child = el;
    }
  }
  
  return child;
}

function bl_contain_findDropChild(el, clientx, clienty)
{
  var src = null;
  var win = bl_port_docWindow(el.ownerDocument);
  
  if (win.document.elementFromPoint)
  {
    src = win.document.elementFromPoint(clientx, clienty);
  }
  
  if (!src)
  {
    src = win.bl_contain_findElement(el, clientx, clienty);
  }
  
  var child = this.find(el, src);
  
  if (!child)
  {
    el.bl_context   = "";
    child           = el;
  }
  
  return child;
}

function bl_contain_n_cleanup(el)
{
  this.cleanUpArtifacts(el)
}

function bl_contain_n_computeCanDrop(ddObj, el, child, clientx, clienty, isDrop)
{
  return null;
}

function bl_contain_n_computeDragFeedback(el, feedback, x, y)
{
  bl_contain_computeFeedbackOff(feedback);
}

function bl_contain_n_adjustToFlow(el)
{
  var list = el.childNodes;

  el.style.whiteSpace = "normal";
  
  if (list.length > 1)
  {
    var child = list[1];
  
    while (child)
    {
      with (child.style)
      {
        left     = "auto";
        top      = "auto";
        position = "";
        display  = "block";
      }
      child = child.nextSibling;
    }
  }
}

function bl_contain_layoutChildren(el, resizeQueue)
{
}

function bl_contain_can_edit(el)
{
  return (el.getAttribute("bl_inEdit") != null);
}


function bl_contain_set_can_edit(el, val)
{
  if (val)
  {
    el.setAttribute("bl_inEdit", true);
  }
  else if (el.getAttribute("bl_inEdit") != null)
  {
    el.removeAttribute("bl_inEdit");
    this.cleanUpArtifacts(el);
  }
}

function bl_contain_set_can_edit_recurs(el, val)
{
  this.setCanEdit(el, val);
  
  var list = el.chrildren;
  var len  = list.length;
  
  for (i = 0; i < len ; i++)
  {
    var child = list[i];
    if (child.getAttribute("cb_tag") == "CTR")
    {
      var layout = bl_contain_getLayout(el);
      layout.setCanEditRecurs(child);
    }
  }
}

function bl_contain_clean_up_artifacts(el)
{
  var bag = bl_contain_getBag(bl_contain_getParent(el));
  bl_contain_find_border(el, bag);
  
  if (el.bl_b1)
  {
    el.bl_b1.parentNode.removeChild(el.bl_b1);
    el.bl_b2.parentNode.removeChild(el.bl_b2);
    el.bl_b3.parentNode.removeChild(el.bl_b3);
    el.bl_b4.parentNode.removeChild(el.bl_b4);
    el.bl_b1 = null;
    el.bl_b2 = null;
    el.bl_b3 = null;
    el.bl_b4 = null;
  }
}

function bl_contain_find_border(el, bag)
{
  var id   = el.id;
  var list = bag.childNodes;
  var len  = list.length;
  
  for (var i = 0; i < len; i++)
  {
    var item = list[i];
    
    if (!bl_port_isTextNode(item))
    {
      if (item.getAttribute("bl_container_id") == id)
      {
        el.bl_b1 = item;
        el.bl_b2 = item.nextSibling;
        el.bl_b3 = el.bl_b2.nextSibling;
        el.bl_b4 = el.bl_b3.nextSibling;
        return true;
      }
    }
  }
  return false;
}

function bl_contain_build_up_artifacts(el)
{
  if (!el.bl_b1)
  {
    var bag = bl_contain_getBag(bl_contain_getParent(el));

    if (!bl_contain_find_border(el, bag))
    {
      var horiz = "<div class='border_line_div' ><img src='/" 
                + bl_version 
                + "/res/img/bungee/form/" 
                + this.borderName
                + "_horiz.gif'/></div>";
                
      var vert  = "<div class='border_line_div' ><img src='/" 
                + bl_version
                + "/res/img/bungee/form/" 
                + this.borderName
                + "_vert.gif'></div>";
      
      bl_port_insertAdjacentHTML(bag, "afterbegin", horiz);
      el.bl_b1 = bag.firstChild;
      el.bl_b1.setAttribute("bl_container_id", el.id);
      
      bl_port_insertAdjacentHTML(bag, "afterbegin", vert);
      el.bl_b2 = bag.firstChild;
      el.bl_b2.setAttribute("bl_container_id", el.id);
      
      bl_port_insertAdjacentHTML(bag, "afterbegin", horiz);
      el.bl_b3 = bag.firstChild;
      el.bl_b3.setAttribute("bl_container_id", el.id);
      
      bl_port_insertAdjacentHTML(bag, "afterbegin", vert);
      el.bl_b4 = bag.firstChild;
      el.bl_b4.setAttribute("bl_container_id", el.id);
    }
  }
}

function bl_contain_assignBorder(layout, el, x, y, w, h)
{
  var offsety = ((y % 2 != 0) ? 1 : 0)
  var offsetx = ((x % 2 != 0) ? 1 : 0)
  
  layout.buildUpArtifacts(el);
  
  with (el.bl_b1.style)
  {
    left   = (x + offsetx)+"px";
    top    = y+"px";
    height = "1px";
    width  = Math.max(w - offsetx, 0)+"px";
  }
    
  with (el.bl_b2.style)
  {
    left   = Math.max(x + w - 1, 0)+"px";
    top    = (y + offsety)+"px";
    height = Math.max(h - offsety, 0)+"px";
    width  = "1px";
  }
    
  with (el.bl_b3.style)
  {
    left   = (x + offsetx)+"px";
    top    = Math.max(y + h - 1, 0)+"px";
    height = "1px";
    width  = Math.max(w - offsety, 0)+"px";
  }
    
  with (el.bl_b4.style)
  {
    left   = x+"px";
    top    = (y + offsety)+"px";
    height = Math.max(h - offsety, 0)+"px";
    width  = "1px";
  }
}

function bl_contain_layoutBorder(el)
{
  var left       = el.offsetLeft;
  var top        = el.offsetTop;
  var parentNode = el.parentNode;
  
  if (bl_browserInfo.ie && parentNode.tagName == "TD")
  {
    left += parentNode.offsetLeft;
    top  += parentNode.offsetTop;
  }
  
  bl_contain_assignBorder(this, el, left, top, el.offsetWidth, el.offsetHeight)
}

// Hroizontal Flow
function bl_contain_horizontal_create()
{
  this.type = bl_contain_type_horizontal;
  this.borderName = "vh";
}

bl_contain_horizontal_create.prototype                = new bl_contain_natural_create();
bl_contain_horizontal_create.prototype.computeCanDrop = bl_contain_h_computeCanDrop;
bl_contain_horizontal_create.prototype.adjustToFlow   = bl_contain_h_adjustToFlow;
bl_contain_horizontal_create.prototype.layoutChildren = bl_contain_horizontal_layout;
bl_contain_horizontal_create.prototype.childAdded     = bl_contain_childAddedCheck;

function bl_contain_horizontal_layout(el, resizeQueue)
{
  var list       = el.childNodes;
  var len        = list.length;
  var elHeight   = el.clientHeight;
  var elStyle    = bl_port_getComputedStyle(el);
  var padding    = parseInt(elStyle.paddingTop) + parseInt(elStyle.paddingBottom);
  
  if (elHeight <= 0)
  {
    elHeight = el.offsetHeight;
  }
  
  elHeight -= padding;
  
  // start at 1 beacuse we must
  // account for the artifact bag
  // that is always generated to the container
  for (var i = 1; i < len; i++)
  {
    var child       = list[i];
    var childLayout = bl_contain_getLayout(child);
    
    if (child.getAttribute("bl_natural") == null)
    {
      child.style.height = elHeight+"px";
    }
    
    bl_contain_resizePush(child, resizeQueue);
  }
}

function bl_contain_h_adjustToFlow(el)
{
  var list = el.childNodes;
  var len  = list.length;
  
  el.style.whiteSpace = "nowrap";
  
  // end at 1 because we must
  // account for the artifact bag
  // that is always generated to the container
  for (var i = len - 1; i >= 1; i--)
  {
    with (list[i].style)
    {
      left     = "auto";
      top      = "auto";
      position = "";
      display  = "inline";
    }
  }
}

function bl_contain_child_added(el, index, child, context)
{
  return child;
}

function bl_contain_checkForAutoSize(el)
{
  var container = el;
  var parent    = container.parentNode;
  
  while (parent.id != "bl_layout_parent")
  {
    var layout = bl_contain_getLayout(parent);

    if (layout && layout.type == bl_contain_type_grid)
    {
      break;
    }
    container = parent;
    parent = parent.parentNode;
    
    if (!parent)
    {
      return;
    }
  }
  
  if (container.offsetWidth < container.scrollWidth ||
      container.offsetHeight < container.scrollHeight)
  {
    var win     = bl_contain_getLiveWindow(el);
    var width   = container.scrollWidth;
    var height  = container.scrollHeight;
    var context = "<layout><cmd>autoSize</cmd><containerId>" 
                + el.id 
                + "</containerId><width>"
                + width
                + "</width><height>"
                + height
                + "</height></layout>";
    
    win.bl_mpr_send(context, win.cb_controlContextId, 1);
  } 
}

function bl_contain_childAddedCheck(el, index, child, context)
{
  if (this.canEdit(el))
  {
    bl_contain_checkForAutoSize(el);
  }  

  return child;
}

function bl_contain_add_child(el, index, content, context)
{
  var newEl = null;
  
  index += 1;
  
  if (index <= 0)
  {
    bl_port_insertAdjacentHTML(el, "afterbegin", content);
    newEl = el.firstChild;
  }
  else
  {
    var el_children = el.childNodes;
    if (index < el_children.length)
    {
      var childEl = el_children[index];
      
      bl_port_insertAdjacentHTML(childEl, "beforebegin", content);
      newEl = childEl.previousSibling;
    }
    else
    {
      bl_port_insertAdjacentHTML(el, "beforeend", content);
      newEl = el.lastChild;
    }
  }
  
  return this.childAdded(el, index - 1, newEl, context);
}

function bl_contain_child_removed(el, child, index)
{
}

function bl_contain_remove_child(el, index)
{
  var child = this.getChild(el, index);
  
  if (child)
  {
    bl_contain_cleanupLayout(child);
    el.removeChild(child);
    this.childRemoved(el, child, index);
  }
  
  return child;
}

function bl_contain_childLimits(el, child, name, val)
{
}

//Table Flow
function bl_ht_create()
{
  this.type = bl_contain_type_horzBox;
  this.borderName = "vh";
}

bl_ht_create.prototype                     = new bl_contain_natural_create();
bl_ht_create.prototype.find                = bl_ht_find;
bl_ht_create.prototype.findChild           = bl_ht_findChild;
bl_ht_create.prototype.nextChild           = bl_ht_findNextChild;
bl_ht_create.prototype.prevChild           = bl_ht_findPrevChild;
bl_ht_create.prototype.getChild            = bl_ht_getChild;
bl_ht_create.prototype.numChildren         = bl_ht_numChildren;
bl_ht_create.prototype.getChildIndex       = bl_ht_getChildIndex;
bl_ht_create.prototype.adjustToFlow        = bl_ht_adjustToFlow;
bl_ht_create.prototype.addChild            = bl_ht_addChild;
bl_ht_create.prototype.removeChild         = bl_ht_removeChild;
bl_ht_create.prototype.removeAll           = bl_ht_removeAll;
bl_ht_create.prototype.childReset          = bl_ht_childReset;
bl_ht_create.prototype.moveChild           = bl_ht_moveChild;
bl_ht_create.prototype.keyCommand          = bl_ht_keyCommand;
bl_ht_create.prototype.layoutChildren      = bl_ht_layoutChildren;
bl_ht_create.prototype.computeCanDrop      = bl_contain_h_computeCanDrop;
bl_ht_create.prototype.childAdded          = bl_contain_childAddedCheck;

function bl_ht_removeAll(el)
{
  var childParent = el.lastChild.firstChild.firstChild;
  for (var i = childParent.childNodes.length - 1; i >= 0; i--)
  {
    childParent.deleteCell(i);
  }
}

function bl_ht_findNextChild(el, child)
{
  var pnode = child.parentNode;
  return (pnode && pnode.tagName == "TD" && pnode.nextSibling)? pnode.nextSibling.lastChild:null;
}

function bl_ht_findPrevChild(el, child)
{
  var pnode = child.parentNode;
  return (pnode && pnode.tagName == "TD" && pnode.previousSibling)? pnode.previousSibling.lastChild:null;
}

function bl_ht_find(el, src)
{
  var child      = src;
  var childParent = el.lastChild.firstChild.firstChild;

  if (src != el)
  {
    while (child && child.parentNode != childParent)
    {
      child = child.parentNode;
      if (child == el)
      {  
        break;
      }      
    }
  }

  if (child && child.tagName == "TD")
  {
    child = child.lastChild;
  }
  else
  {
    child = el;
  }
  
  return child;
}

function bl_ht_findChild(el, src)
{
  var child      = null;
  var childParent = el.lastChild.firstChild.firstChild;

  if (src != el)
  {
    child = src;
    
    while (child && child.parentNode != childParent)
    {
      if (child == el)
      {  
        break;
      }      
      child = child.parentNode;
    }
  }

  return (child && child.tagName == "TD")? child.lastChild:null;
}

function bl_ht_addChild(el, index, content, context)
{
  var childParent = el.lastChild.firstChild.firstChild;
  var len         = childParent.childNodes.length;
  
  if (index < 0)
  {
    index = 0;
  }
  else if (index > len)
  {
    index = len;
  }
  
  var newTD   = childParent.insertCell(index);
  var tdStyle = el.lastChild.getAttribute("bl_tdstyle");
  
  if (tdStyle)
  {
    newTD.style.cssTExt = tdStyle;
  }
  newTD.innerHTML = content;
  
  
  return this.childAdded(el, index, newTD.lastChild, context);
}

function bl_ht_removeChild(el, index)
{
  var child = null;
  
  if (index >= 0)
  {
    var childParent = el.lastChild.firstChild.firstChild;
    var len         = childParent.childNodes.length;

    if (index < len)
    {
      child = childParent.childNodes[index].lastChild;
      bl_contain_cleanupLayout(child);
      childParent.deleteCell(index);
    }
  }
  
  return child;
}

function bl_ht_moveChild(el, oldIndex, newIndex)
{
  if (oldIndex >= 0)
  {
    var childParent = el.lastChild.firstChild.firstChild;
    var len         = childParent.childNodes.length;

    if (olIndex < len)
    {
      var child = childParent.childNodes[oldIndex].lastChild;
      childParent.deleteCell(oldIndex);

      if (newIndex > len)
      {
        newIndex = len;
      }
      
      var newTD = childParent.insertCell(newIndex);
      var tdStyle = el.lastChild.getAttribute("bl_tdstyle");

      if (tdStyle)
      {
        newTD.style.cssTExt = tdStyle;
      }
      newTD.appendChild(child);
    }
  }
}

function bl_ht_childReset(el, child, val)
{
  var parentTD = child.parentNode;  
  
  parentTD.innerHTML = val;
  var ret = parentTD.lastChild;

  if (this.type < bl_contain_type_vertical)
  {
    bl_contain_checkForAutoSize(el);
  }

  return ret;
}

function bl_ht_getChild(el, index)
{
  if (index >= 0)
  {
    var list = el.lastChild.firstChild.firstChild.childNodes;

    if (index < list.length)
    {
      return list[index].lastChild;
    }
  }
  
  return null;
}

function bl_ht_numChildren(el)
{
  return el.lastChild.firstChild.firstChild.childNodes.length;
}

function bl_ht_getChildIndex(el, child)
{
  if (child)
  {
    var parent = child.parentNode;
    
    if (parent && parent.tagName == "TD")
    {
      return bl_port_get_cellIndex(parent);
    }
  }
  return -1;
}

function bl_ht_adjustToFlow(el)
{
}

function bl_ht_keyCommand(el, child, event, kcode)
{
  var len   = this.numChildren(el);
  var index = this.getChildIndex(el, child);
  
  if (index >= 0 && index < len && (kcode == 37 || kcode == 39))
  {
    switch (kcode)
    {
      case (37): //left
      {
        index = (index == 0)? (len - 1) : (index - 1);
        bl_contain_performSelect(el, this.getChild(el, index));
      }
      break;
      case (39): //right
      {
        index = (index == len - 1)? 0 : (index + 1);
        bl_contain_performSelect(el, this.getChild(el, index));
      }
      break;
    }  
  }
  else
  {
    bl_contain_natural_create.prototype.keyCommand.call(this, el, child, event, kcode);
  }
}

function bl_ht_layoutChildren(el, resizeQueue)
{
  if (this.canEdit(el))
  {
    var tdEl = el.lastChild.firstChild.firstChild.firstChild;
    
    while (tdEl)
    {
      var child = tdEl.lastChild;
      
      if (child)
      {
        bl_contain_resizePush(tdEl.firstChild, resizeQueue);
      }
      
      tdEl = tdEl.nextSibling;
    }
  }
}

function bl_vt_create()
{
  this.type = bl_contain_type_vertBox;
  this.borderName = "vh";
}

bl_vt_create.prototype                     = new bl_contain_natural_create();
bl_vt_create.prototype.find                = bl_vt_find;
bl_vt_create.prototype.findChild           = bl_vt_findChild;
bl_vt_create.prototype.nextChild           = bl_vt_findNextChild;
bl_vt_create.prototype.prevChild           = bl_vt_findPrevChild;
bl_vt_create.prototype.getChild            = bl_vt_getChild;
bl_vt_create.prototype.numChildren         = bl_vt_numChildren;
bl_vt_create.prototype.getChildIndex       = bl_vt_getChildIndex;
bl_vt_create.prototype.adjustToFlow        = bl_ht_adjustToFlow;
bl_vt_create.prototype.addChild            = bl_vt_addChild;
bl_vt_create.prototype.removeChild         = bl_vt_removeChild;
bl_vt_create.prototype.removeAll           = bl_vt_removeAll;
bl_vt_create.prototype.moveChild           = bl_vt_moveChild;
bl_vt_create.prototype.layoutChildren      = bl_vt_layoutChildren;
bl_vt_create.prototype.computeCanDrop      = bl_contain_v_computeCanDrop;
bl_vt_create.prototype.childAdded          = bl_contain_childAddedCheck;
                           
                           
function bl_vt_removeAll(el)
{
  var childParent = el.lastChild.firstChild;
  
  for (var i = childParent.childNodes.length - 1; i >= 0; i--)
  {
    childParent.deleteRow(i);
  }
}
                           
function bl_vt_findNextChild(el, child)
{
  var pnode = (child && child.parentNode && child.parentNode.parentNode)? child.parentNode.parentNode:null;
  return (pnode && pnode.tagName == "TR" && pnode.nextSibling)? pnode.nextSibling.firstChild.lastChild:null;
}

function bl_vt_findPrevChild(el, child)
{
  var pnode = (child && child.parentNode && child.parentNode.parentNode)? child.parentNode.parentNode:null;
  return (pnode && pnode.tagName == "TR" && pnode.previousSibling)? pnode.previousSibling.firstChild.lastChild:null;
}

function bl_vt_find(el, src)
{
  var child      = src;
  var childParent = el.lastChild.firstChild;

  if (src != el)
  {
    while (child && child.parentNode != childParent)
    {
      child = child.parentNode;
      if (child == el)
      {  
        break;
      }      
    }
  }

  if (child && child.tagName == "TR")
  {
    child = child.firstChild.lastChild;
  }
  else
  {
    child = el;
  }
  
  return child;
}

function bl_vt_findChild(el, src)
{
  var child      = null;
  var childParent = el.lastChild.firstChild;

  if (src != el)
  {
    child = src;
    
    while (child && child.parentNode != childParent)
    {
      if (child == el)
      {  
        break;
      }      
      child = child.parentNode;
    }
  }

  return (child && child.tagName == "TR")? child.firstChild.lastChild:null;
}

function bl_vt_addChild(el, index, content, context)
{
  var childParent = el.lastChild.firstChild;
  var len         = childParent.childNodes.length;
  
  if (index < 0)
  {
    index = 0;
  }
  else if (index > len)
  {
    index = len;
  }
  
  var row   = childParent.insertRow(index);
  var newTD = row.insertCell(0);
  var tdStyle = el.lastChild.getAttribute("bl_tdstyle");

  if (tdStyle)
  {
    newTD.style.cssTExt = tdStyle;
  }
  
  newTD.innerHTML = content;
  return this.childAdded(el, index, newTD.lastChild, context);
}

function bl_vt_removeChild(el, index)
{
  var child = null;
  
  if (index >= 0)
  {
    var childParent = el.lastChild.firstChild;
    var list        = childParent.childNodes;

    if (index < list.length)
    {
      var row = list[index];
      
      child = row.firstChild.lastChild;
      bl_contain_cleanupLayout(child);
      childParent.removeChild(row);
    }
  }
  
  return child;
}

function bl_vt_moveChild(el, oldIndex, newIndex)
{
  if (oldIndex >= 0)
  {
    var childParent = el.lastChild.firstChild;
    var list        = childParent.childNodes;
    var len         = list.length;

    if (olIndex < len)
    {
      var row = list[index];
      var child = row.firstChild.lastChild;
      
      childParent.removeChild(row);
      
      row   = childParent.insertRow(index);
      
      var newTD = row.insertCell(0);
      var tdStyle = el.lastChild.getAttribute("bl_tdstyle");

      if (tdStyle)
      {
        newTD.style.cssTExt = tdStyle;
      }
      newTd.appendChild(child);
    }
  }
}

function bl_vt_getChild(el, index)
{
  if (index >= 0)
  {
    var list = el.lastChild.firstChild.childNodes;

    if (index < list.length)
    {
      return list[index].firstChild.lastChild;
    }
  }
  
  return null;
}

function bl_vt_numChildren(el)
{
  return el.lastChild.firstChild.childNodes.length;
}

function bl_vt_getChildIndex(el, child)
{ 
  // we don't have a valid childIndex if the child is the element
  if (child && child != el)
  {
    var parent = child.parentNode;
    
    if (parent && parent.tagName == "TD")
    {
      return bl_port_get_rowIndex(parent.parentNode);
    }
  }
  return -1;
}

function bl_vt_layoutChildren(el, resizeQueue)
{
  if (this.canEdit(el))
  {
    var trEl = el.lastChild.firstChild.firstChild;
    
    while (trEl)
    {
      var child = trEl.firstChild.lastChild;
      
      if (child)
      {
        bl_contain_resizePush(trEl.firstChild, resizeQueue);
      }
      
      trEl = trEl.nextSibling;
    }
  }
}


//Vertical Flow
function bl_contain_vertical_create()
{
  this.type = bl_contain_type_vertical;
  this.borderName = "vh";
}

bl_contain_vertical_create.prototype                  = new bl_contain_natural_create();
bl_contain_vertical_create.prototype.computeCanDrop   = bl_contain_v_computeCanDrop;
bl_contain_vertical_create.prototype.adjustToFlow     = bl_contain_v_adjustToFlow;
bl_contain_vertical_create.prototype.layoutChildren   = bl_contain_vertical_layout;
bl_contain_vertical_create.prototype.childAdded       = bl_contain_childAddedCheck;

function bl_contain_vertical_layout(el, resizeQueue)
{
  var list       = el.childNodes;
  var len        = list.length;
  var elWidth    = el.clientWidth;
  var elStyle    = bl_port_getComputedStyle(el) || el.style;
  var padding    = parseInt(elStyle.paddingLeft) + parseInt(elStyle.paddingRight);
  
  if (elWidth <= 0)
  {
    elWidth = el.offsetWidth;
  }
  
  if (!isNaN(padding))
  {
    elWidth -= padding;
  }

  if (elWidth <= 0)
  {
    // A width of 0 should be ignored and not propagated.
    // Assume the current width is correct.
    return;
  }

  // start at 1 because we must
  // account for the artifact bag
  // that is always generated to the container
  for (var i = 1; i < len; i++)
  {
    var child  = list[i];
    
    if (child.getAttribute("bl_natural") == null)
    {
      var cStyle = child.style;

      if (cStyle.width != "100%")
      {
        child.style.width = elWidth+"px";
      }
    }
    
    bl_contain_resizePush(child, resizeQueue);
  }
}

function bl_contain_v_adjustToFlow(el)
{
  var list = el.childNodes;
  var len  = list.length;
  
  el.style.whiteSpace = "normal";

  // end at 1 because we must
  // account for the artifact bag
  // that is always generated to the container
  for (var i = len - 1; i >= 1; i--)
  {
    with (list[i].style)
    {
      left     = "auto";
      top      = "auto";
      position = "";
      display  = "block";
    }
  }
}

// Absolute Flow
function bl_contain_absolute_create()
{
  this.type = bl_contain_type_absolute;
  this.borderName = "absolute";
}

bl_contain_absolute_create.prototype                     = new bl_contain_natural_create();
bl_contain_absolute_create.prototype.computeCanDrop      = bl_contain_a_computeCanDrop;
bl_contain_absolute_create.prototype.computeDragFeedback = bl_contain_a_computeDragFeedback;
bl_contain_absolute_create.prototype.adjustToFlow        = bl_contain_a_adjustToFlow;

function bl_contain_a_computeCanDrop(ddObj, el, child, clientx, clienty, isDrop)
{
  var srcContext = ddObj.srcContext;
  var pos        = bl_sys_find_xy(el, null, false);
  var diffX      = srcContext.dragOffsetX;
  var diffY      = srcContext.dragOffsetY;
  var offsetX    = clientx - pos.x - ((diffX)? diffX:0);
  var offsetY    = clienty - pos.y - ((diffX)? diffY:0);
  
  el.bl_context = offsetX + " " + offsetY;
  
  if (isDrop)
  {
    bl_contain_computeFeedbackOff(bl_contain_dragFeedback(cb_sys_getTopWindow()));
  }
  
  ddObj.setHint(null);
  return child;
}

function bl_contain_a_computeDragFeedback(el, feedback, x, y)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    var srcContext = ddObj.srcContext.item;
    var diffX      = srcContext.dragOffsetX;
    var diffY      = srcContext.dragOffsetY;
    
    ddObj.setFeedbackItem(feedback);
    bl_contain_computeFeedbackText(feedback, x - ((diffX)? diffX:0), y - ((diffY)? diffY:0), undefined, undefined);
  }
}

function bl_contain_a_adjustToFlow(el)
{
  var list = el.childNodes;
  
  el.style.whiteSpace = "normal";
  
  // end at 1 because we must
  // account for the artifact bag
  // that is always generated to the container
  for (var i = list.length - 1; i >= 1; i--)
  {
    with (list[i].style)
    {
      left     = child.offsetLeft+"px";
      top      = child.offsetTop+"px";
      position = "absolute";
      display  = "block";
    }
  }
}

// 2d Vertical Flow
function bl_contain_2d_vertical_create()
{
  this.type = bl_contain_type_2dVertical;
  this.borderName = "absolute";
}

bl_contain_2d_vertical_create.prototype                     = new bl_contain_natural_create();
bl_contain_2d_vertical_create.prototype.computeCanDrop      = bl_contain_a_computeCanDrop;
bl_contain_2d_vertical_create.prototype.adjustToFlow        = bl_contain_a_adjustToFlow;
bl_contain_2d_vertical_create.prototype.layoutChildren      = bl_contain_2d_vertical_layout;

function bl_contain_2d_vertical_layout(el, resizeQueue)
{
  if (!el.cb_in_position_elements)
  {
    el.cb_in_position_elements = true;
    
    try
    {
      var parHeight = el.offsetHeight;
      var parWidth  = el.offsetWidth;
      var list      = el.childNodes;
      var len       = list.length;
      
      if (len > 1)
      {
        var imarg         = parseInt(el.getAttribute("bl_in_margin"));
        var omarg         = parseInt(el.getAttribute("bl_out_margin"));
        var currentLeft   = omarg;
        var currentTop    = omarg;
        var currentWidth  = 0;
        var stepDownStart = -1;
        var visibleCount  = 0;
        var minHeight     = 10000;
        var minWidth      = 10000;
        var maxHeight     = 0;
        var maxWidth      = 0;
        
        for (var i = 1; i < len; i++)
        {
          var item       = list[i];
          var itemStyle  = item.style;
          var itemHeight = item.offsetHeight;
          var itemWidth  = item.offsetWidth + imarg;
          
          if (itemHeight + omarg + currentTop > parHeight)
          {
            if (stepDownStart < 0)
            {
              stepDownStart = i;
            }
            
            currentLeft    += currentWidth;
            itemStyle.top   = omarg+"px";
            itemStyle.left  = currentLeft+"px";
            currentTop      = itemHeight + (omarg + imarg);
            currentWidth    = itemWidth;
          }
          else
          {
            itemStyle.top   = currentTop+"px";
            itemStyle.left  = currentLeft+"px";
            currentTop     += (itemHeight + imarg);
            
            if (currentWidth < itemWidth)
            {
              currentWidth = itemWidth + imarg;
            }
          }
          
          bl_contain_resizePush(item, resizeQueue);
          
          if (currentLeft < parWidth)
          {
            minHeight = Math.min(minHeight, itemHeight + imarg);
            maxHeight = Math.max(maxHeight, itemHeight + imarg);
            minWidth  = Math.min(minWidth, itemWidth);
            maxWidth  = Math.max(maxWidth, itemWidth);
            visibleCount++;
          }
        }
        
        var meanWidth  = (minWidth + maxWidth)/2;
        var meanHeight = (minHeight + maxHeight)/2;
        
        if (currentTop < parHeight)
        {
          visibleCount += Math.floor((parHeight - currentTop)/meanHeight);
        }
        if (currentLeft < parWidth)
        {
          var colCount  = Math.ceil((parWidth - currentLeft)/meanWidth);
          var rowCount  = Math.floor(parHeight/meanHeight);
          visibleCount += (colCount * rowCount);
        }
        
        el.setAttribute("bl_stepDownStart", stepDownStart);
        el.setAttribute("bl_visibleCount", visibleCount);
      }
    }
    catch (exception)
    {
    }
    el.cb_in_position_elements = false;
  }
  
  if (window.fireEvent)
  {
    window.fireEvent("layoutcomplete");
  }
}

// 2d Horizontal Flow
function bl_contain_2d_horizontal_create()
{
  this.type = bl_contain_type_2dHorizontal;
  this.borderName = "absolute";
}

bl_contain_2d_horizontal_create.prototype                     = new bl_contain_natural_create();
bl_contain_2d_horizontal_create.prototype.computeCanDrop      = bl_contain_a_computeCanDrop;
bl_contain_2d_horizontal_create.prototype.adjustToFlow        = bl_contain_a_adjustToFlow;
bl_contain_2d_horizontal_create.prototype.layoutChildren      = bl_contain_2d_horizontal_layout;

function bl_contain_2d_horizontal_layout(el, resizeQueue)
{
  if (!el.cb_in_position_elements)
  {
    el.cb_in_position_elements = true;
    
    var elParent = bl_contain_getParent(el);
    var ctrParent = bl_contain_getLayout(elParent);
    var parentIsVerticalFlow = (ctrParent && ctrParent.type == bl_contain_type_vertical);
    
    try
    {
      // When the parent is a vertical box, assume a practically infinite
      // height for the calculations-- because we can expand vertically as
      // needed.
      var parHeight = parentIsVerticalFlow ? 2000000000 : el.offsetHeight;
      var parWidth  = el.offsetWidth;
      var list      = el.childNodes;
      var len       = list.length;
      
      if (len > 1)
      {
        var imarg         = parseInt(el.getAttribute("bl_in_margin"));
        var omarg         = parseInt(el.getAttribute("bl_out_margin"));
        var currentLeft   = omarg;
        var currentTop    = omarg;
        var currentHeight = 0;
        var stepDownStart = -1;
        var visibleCount  = 0;
        var minHeight     = 10000;
        var minWidth      = 10000;
        var maxHeight     = 0;
        var maxWidth      = 0;
        
        for (var i = 1; i < len; i++)
        {
          var item       = list[i];
          var itemStyle  = item.style;
          var itemHeight = item.offsetHeight + imarg;
          var itemWidth  = item.offsetWidth;
          
          if (itemWidth + omarg + currentLeft > parWidth)
          {
            if (stepDownStart < 0)
            {
              stepDownStart = i;
            }
            
            currentTop     += currentHeight;
            itemStyle.top   = currentTop+"px";
            itemStyle.left  = omarg+"px";
            currentLeft     = itemWidth + (omarg + imarg);
            currentHeight   = itemHeight;
          }
          else
          {
            itemStyle.top    = currentTop+"px";
            itemStyle.left   = currentLeft+"px";
            currentLeft     += (itemWidth + imarg);
            
            if (currentHeight < itemHeight)
            {
              currentHeight = itemHeight;
            }
          }
          
          bl_contain_resizePush(item, resizeQueue);
          
          if (currentTop < parHeight)
          {
            minHeight = Math.min(minHeight, itemHeight);
            maxHeight = Math.max(maxHeight, itemHeight);
            minWidth  = Math.min(minWidth, itemWidth + imarg);
            maxWidth  = Math.max(maxWidth, itemWidth + imarg);
            visibleCount++;
          }
        }
        
        if (parentIsVerticalFlow)
        {
          // Explicitly set the height of this control so that controls below
          // it in the list will flow correctly.
          var parHeight = (currentTop + currentHeight + omarg + imarg);
          var computed = bl_port_getComputedStyle(el);
          if (computed)
          {
            if (!isNaN(parseInt(computed.borderTopWidth)))
            {
              parHeight += parseInt(computed.borderTopWidth);
            }
            if (!isNaN(parseInt(computed.borderBottomWidth)))
            {
              parHeight += parseInt(computed.borderBottomWidth);
            }
          }
          el.style.height = parHeight+"px";
        }
        
        var meanWidth  = (minWidth + maxWidth)/2;
        var meanHeight = (minHeight + maxHeight)/2;
        
        if (currentLeft < parWidth)
        {
          visibleCount += Math.floor((parWidth - currentLeft)/meanWidth);
        }
        if (currentTop < parHeight)
        {
          var rowCount  = Math.ceil((parHeight - currentTop)/meanHeight);
          var colCount  = Math.floor(parWidth/meanWidth);
          visibleCount += (colCount * rowCount);
        }
        
        el.setAttribute("bl_stepDownStart", stepDownStart);
        el.setAttribute("bl_visibleCount", visibleCount);
      }
    }
    catch (exception)
    {
    }
    el.cb_in_position_elements = false;
  }
  
  if (window.fireEvent)
  {
    window.fireEvent("layoutcomplete");
  }
}

// Grid Flow
function bl_contain_grid_create()
{
  this.type = bl_contain_type_grid;
  this.borderName = "grid";
}

bl_contain_grid_create.prototype                     = new bl_contain_natural_create();
bl_contain_grid_create.prototype.cleanup             = bl_contain_grid_cleanup;
bl_contain_grid_create.prototype.findDropChild       = bl_contain_grid_findDropChild;
bl_contain_grid_create.prototype.computeCanDrop      = bl_contain_grid_computeCanDrop;
bl_contain_grid_create.prototype.adjustToFlow        = bl_contain_grid_adjustToFlow;
bl_contain_grid_create.prototype.layoutChildren      = bl_contain_grid_layout;
bl_contain_grid_create.prototype.cleanUpArtifacts    = bl_contain_clean_up_grid_artifacts;
bl_contain_grid_create.prototype.buildUpArtifacts    = bl_contain_build_up_grid_artifacts;
bl_contain_grid_create.prototype.childAdded          = bl_contain_grid_child_added;
bl_contain_grid_create.prototype.childRemoved        = bl_contain_grid_child_removed;
bl_contain_grid_create.prototype.childLimitSet       = bl_contain_grid_childLimits;
bl_contain_grid_create.prototype.resizeCheck         = bl_contain_grid_resize_check_children;
bl_contain_grid_create.prototype.setCanEdit          = bl_contain_grid_set_can_edit;

function bl_contain_grid_set_can_edit(el, val)
{
  bl_contain_natural_create.prototype.setCanEdit.call(this, el, val);
  bl_contain_sep_setActive(bl_contain_getRowData(el), !val);
  bl_contain_sep_setActive(bl_contain_getColumnData(el), !val);
}

function bl_contain_sep_setActive(list, val)
{
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    var item = list[i];
    
    if (item.separator)
    {
      var imgList = item.sepList;
      
      if (imgList)
      {
        var imgLen = imgList.length;
        
        for (var j = 0; j < imgLen; j++)
        {
          var img  = imgList[j];
          
          if (val)
          {
            img.setAttribute("bl_active", true);
          }
          else
          {
            img.removeAttribute("bl_active");
          }
        }
      }
    }
  }
}

function bl_contain_grid_resize_check_children(el, resizeQueue)
{
  if (el.offsetWidth != el.bl_lastWidth || el.offsetHeight != el.bl_lastHeight)
  {
    el.bl_lastWidth  = el.offsetWidth;
    el.bl_lastHeight = el.offsetHeight;
    bl_contain_recomputeDims(el);
    this.layoutChildren(el, resizeQueue);
  }
  if (this.canEdit(el))
  {
    this.layoutBorder(el);
  }
}

function bl_contain_grid_cleanup(el)
{
  bl_contain_natural_create.prototype.cleanup.call(this, el);
  bl_contain_clean_row_column_data(el.cb_rowList);
  bl_contain_clean_row_column_data(el.cb_colList);
  bl_contain_clean_cell_data(el.cb_cellList);

  el.cb_current_boundry = null;  
  el.cb_rowList         = null;
  el.cb_colList         = null;
  el.cb_cellList        = null;
}

function bl_contain_grid_findDropChild(el, clientx, clienty)
{
  var pos  = bl_sys_find_xy(el, null, false);
  var cell = bl_ctr_findCell(el, bl_contain_getCellData(el), clientx - pos.x, clienty - pos.y);
  
  if (cell == null || cell.childIndex >= 0)
  {
    return null;
  }
  
  el.bl_context = cell.rowIndex + " " + cell.colIndex;
  
  return el;
}

function bl_contain_grid_computeCanDrop(ddObj, el, child, clientx, clienty, isDrop)
{
  var ret   = null;
  var cell  = null;
  
  if (ddObj.indexCount == 1)
  {
    var pos = bl_sys_find_xy(el, null, false);
    
    cell = bl_ctr_findCell(el, bl_contain_getCellData(el), clientx - pos.x, clienty - pos.y);
    
    if (cell && cell.childIndex < 0)
    {
      ddObj.setDragOverNotify(child, bl_ctr_dragEnd);
      ret = child;
    }
  }

  if (ret == null || isDrop)
  {
    ddObj.setHint(null);
  }
  else if (cell != null)
  {
    var hintContext = { el:el,
                        child:child,
                        hintDrop:_bl_ctr_ddHintDrop,
                        x:cell.x + 2,
                        y:cell.y + 2,
                        dimension:cell.width - (cell.isLastCol? 2:1),
                        size:cell.height - (cell.isLastRow? 2:1),
                        useOffsets:true,
                        color:"#A9D586"
                      };
    
    ddObj.setHint(hintContext);
  }
  
  return ret;
}

function bl_contain_grid_adjustToFlow(el)
{
  var list = el.childNodes;
  
  el.style.whiteSpace = "normal";
  
  // end at 1 because we must
  // account for the artifact bag
  // that is always generated to the container
  for (var i = list.length - 1; i >= 1; i--)
  {
    with (list[i].style)
    {
      position = "absolute";
      display  = "block";
    }
  }
}

function bl_contain_grid_layout(el, resizeQueue)
{
  var computeArtifacts  = (el.getAttribute("bl_inEdit") != null);
  var cells             = bl_contain_getCellData(el);
  var rows              = bl_contain_getRowData(el);
  var cols              = bl_contain_getColumnData(el);
  var rowCount          = rows.length;
  var colCount          = cols.length;
  var childList         = el.childNodes;
  var offset            = 0;
  var len               = childList.length;
  
  for (var i = 0; i < rowCount; i ++)
  {
    bl_contain_place_row_seps(rows[i], cols);
    
    for (var j = 0; j < colCount; j++)
    {
      var cell  = cells[(i * colCount) + j];
      
      if (i == 0)
      {
        bl_contain_place_col_seps(cols[j], rows);
      }
      
      if (cell.childIndex >= 0)
      {
        // account for the artifact bag
        // that is always generated to the container
        var index = cell.childIndex + 1;
        
        if (index < len)
        {
          var child = childList[index];
          
          bl_contain_grid_place_child(el, rows, cols, cell, child, i, j);
          bl_contain_resizePush(child, resizeQueue);
        }
      }
      if (computeArtifacts)
      {
        bl_ctr_gridPositionCell(el, rows, cols, cell, i, j);
      }
    }
  }
}

function bl_contain_place_row_seps(row, cols)
{
  if (row.separator)
  {
    var list = row.sepList;
    
    if (list)
    {
      var len = list.length;
      
      for (var i = 0; i < len; i++)
      {
        var item     = list[i];
        var count    = parseInt(item.getAttribute("bl_count"));
        var start    = parseInt(item.getAttribute("bl_start"));
        var colWidth = bl_ctr_gridDim(cols, start, count);
        
        with (item.style)
        {
          left   = bl_ctr_gridDim(cols, 0, start) + "px";
          width  = Math.max(colWidth, 0) + "px";
          top    = (row.position + row.pixelSize  - 3) + "px";
          height = "6px";
        }
      }
    }
  }
}

function bl_contain_place_col_seps(col, rows)
{
  if (col.separator)
  {
    var list = col.sepList;
    
    if (list)
    {
      var len = list.length;
      
      for (var i = 0; i < len; i++)
      {
        var item      = list[i];
        var count     = parseInt(item.getAttribute("bl_count"));
        var start     = parseInt(item.getAttribute("bl_start"));
        var rowHeight = bl_ctr_gridDim(rows, start, count);
        
        with (item.style)
        {
          left   = (col.position + col.pixelSize - 3) + "px";
          width  = "6px";
          top    = bl_ctr_gridDim(rows, 0, start) + "px";
          height = Math.max(rowHeight, 0) + "px";
        }
      }
    }
  }
}

function bl_contain_send_sizes(el, list, isRow, index, val)
{
  var win     = bl_contain_getLiveWindow(el);
  var len     = list.length;
  var context = "<layout><cmd>setSizes</cmd><containerId>" + el.id + "</containerId><isRow>" + ((isRow) ? "t" : "f") + "</isRow><values>";
  
  for (var i = 0; i < len; i++)
  {
    context += list[i].size;
    context += " ";
    context += list[i].pixelSize;
    
    if (i < len - 1)
    {
      context += " ";
    }
  }
  
  context += "</values>";
  
  if (index >= 0)
  {
    context += '<toggle val="';
    context += val
    context += '">';
    context += index;
    context += '</toggle>';
  }
  context += "</layout>";
  
  win.bl_mpr_send(context, win.cb_controlContextId, 1);
}

function bl_contain_compute_new_sizes(list, size)
{
  list.cb_per_list = [];
  
  var totalSize        = size * GRID_ROUNDOF_FACTOR;
  var len              = list.length;
  var newPerSize       = 0;
  var perList          = list.cb_per_list;
  var currentPixelSize = 0;
  var i;
  var needsToResizeChildren = false;
  
  for (i = 0; i < len; i++)
  {
    var item = list[i];
    
    currentPixelSize += item.pixelSize;
    if (item.isFixed)
    {
      item.size = item.pixelSize;
    }
    else
    {
      newPerSize += item.pixelSize;
      item.computePixelSize = item.pixelSize * GRID_ROUNDOF_FACTOR;
      perList.push(item);
    }
  }

  var perLen = perList.length;

  // this means that a row/col just went to not being fixed
  // and is the only item that could take percentage
  if (currentPixelSize != size && perLen == 1)
  {
    var item = perList[0];
    var diff = (size - currentPixelSize);
    newPerSize += diff;
    item.pixelSize += diff;
    item.computePixelSize = item.pixelSize * GRID_ROUNDOF_FACTOR;
    
    needsToResizeChildren = true;
    
  }

  newPerSize *= GRID_ROUNDOF_FACTOR;

  if (perLen > 0)
  {
    var perTotal = 100;
    
    for (i = 0; i < perLen; i++)
    {
      var item  = perList[i];
      item.size = Math.floor((item.computePixelSize * 100)/newPerSize);
      perTotal -= item.size;
    }
    
    while (perTotal > 0)
    {
      if (i >= perLen)
      {
        i = 0;
      }
      perList[i].size++;
      perTotal--;
    }
  }
  
  
  var currentPos = 0;
  
  for (i = 0; i < len; i++)
  {
    var item = list[i];
    
    item.position = currentPos;
    currentPos += item.pixelSize;
  }
  
  return needsToResizeChildren;
}

function bl_contain_grid_mouse_move(event, el, layout)
{
  if (event.ctrlKey)
  {
    bl_ctr_setGridboundry(el, null)
    bl_ctr_setGridCell(el, null);
  }
  else if (!bl_contain_getOverlayData())
  {
    var pos = bl_sys_find_xy(el, null, false);
    var x   = event.clientX - pos.x;
    var y   = event.clientY - pos.y;
    
    layout.buildUpArtifacts(el);
    
    if (bl_contain_found_row_column_boundry(el, x, y) == null)
    {
      var cell = bl_ctr_findCell(el, bl_contain_getCellData(el), x, y);
      bl_ctr_setGridCell(el, cell);
    }
  }
}

function bl_contain_clean_up_grid_artifacts(el)
{
  bl_contain_natural_create.prototype.cleanUpArtifacts.call(this, el);
  bl_contain_clean_row_column_artifacts(bl_contain_getRowData(el));
  bl_contain_clean_row_column_artifacts(bl_contain_getColumnData(el));
  bl_contain_clean_cell_data_artifacts(bl_contain_getCellData(el));
  
  var body = bl_contain_topParent();
  
  if (body.cb_col_button_bar)
  {
    body.cb_col_button_bar.parentNode.removeChild(body.cb_col_button_bar);
    body.cb_col_button_bar = null;
  }
  
  if (body.cb_row_button_bar)
  {
    body.cb_row_button_bar.parentNode.removeChild(body.cb_row_button_bar);
    body.cb_row_button_bar = null;
  }
  
  el.cb_artifacts_built = false;
  el.cb_current_boundry = null;
}

function bl_contain_build_up_grid_artifacts(el)
{
  bl_contain_natural_create.prototype.buildUpArtifacts.call(this, el);
  
  if (!el.cb_artifacts_built)
  {
    var bag = bl_contain_getBag(el);
    
    bl_contain_collect_cells(el);
    el.cb_artifacts_built = true;
  }
}

function bl_contain_grid_child_added(el, index, child, context)
{
  var list = context.split(" ");
  
  var rows      = bl_contain_getRowData(el);
  var cols      = bl_contain_getColumnData(el);
  var rowIndex  = parseInt(list[0]);
  var colIndex  = parseInt(list[1]);
  var cells     = bl_contain_getCellData(el);
  
  if (rowIndex >= 0 && rowIndex < rows.length && colIndex >= 0 && colIndex < cols.length)
  {
    var cell = cells[(rowIndex * cols.length) + colIndex];
    var len  = cells.length;
    
    for (var i = 0; i < len; i++)
    {
      var item = cells[i];
      
      if (item.childIndex >= index)
      {
        item.childIndex++;
      }
    }

    cell.childIndex = index;
  }
  
  return child;
}

function bl_contain_grid_child_removed(el, child, index)
{
  var cells  = bl_contain_getCellData(el);
  var len    = cells.length;
  
  for (var i = 0; i < len; i++)
  {
    var item = cells[i];
    
    if (item.childIndex == index)
    {
      item.childIndex = -1;
    }
    else if (item.childIndex > index)
    {
      item.childIndex--;
    }
  }
}

function bl_contain_grid_childLimits(el, child, name, val)
{
  bl_contain_natural_create.prototype.childLimitSet.call(this, el, child, name, val);

  var cells      = bl_contain_getCellData(el);
  var rows       = bl_contain_getRowData(el);
  var cols       = bl_contain_getColumnData(el);
  var childIndex = layout.getChildIndex(el, child);
  var cellInfo   = bl_contain_grid_findCellInfo(rows, cols, cells, childIndex);

  if (cellInfo)
  {
    bl_contain_grid_place_child(el, rows, cols, cellInfo.cell, child, cellInfo.rowIndex, cellInfo.colIndex);
    bl_contain_layoutChild(child, true);
  }
}

function bl_contain_grid_findCellInfo(rows, cols, cells, index)
{
  var rowCount = rows.length;
  var colCount = cols.length;
  
  for (var rowIndex = 0; rowIndex < rowCount; rowIndex++)
  {
    for (var colIndex = 0; colIndex < colCount; colIndex++)
    {
      cell = cells[(rowIndex * colCount) + colIndex];
      
      if (cell.childIndex == index)
      {
        return { cell:cell, rowIndex:rowIndex, colIndex:colIndex };
      }
    }
  }
  return null;
}

function bl_contain_grid_child_posCheck(el, child)
{
  var layout = bl_contain_getLayout(el);

  if (layout && layout.type == bl_contain_type_grid && child != null)
  {
    var cells = bl_contain_getCellData(el);
    var rows  = bl_contain_getRowData(el);
    var cols  = bl_contain_getColumnData(el);
    var childIndex = layout.getChildIndex(el, child);
    var cellInfo = bl_contain_grid_findCellInfo(rows, cols, cells, childIndex);

    if (cellInfo)
    {
      var left   = child.offsetLeft;
      var top    = child.offsetTop;
      var width  = child.offsetWidth;
      var height = child.offsetHeight;
      
      bl_contain_grid_place_child(el, rows, cols, cellInfo.cell, child, cellInfo.rowIndex, cellInfo.colIndex);

      if (left != child.offsetLeft   || 
          top  != child.offsetTop    || 
          width != child.offsetWidth || 
          height != child.offsetHeight)
      {
        bl_contain_layoutChild(child, false);
      }
    }
  }
}

// Layout Managers END
function _bl_ctr_ddHintDrop(event, hintImage)
{
  bl_ctr_handleDrop(this.el, event, event.clientX, event.clientY);
}

function bl_ctr_gridPositionCell(el, rows, cols, cell, rowIndex, colIndex)
{
  if (cell.childIndex >= -1)
  {
    var row = rows[rowIndex];
    var col = cols[colIndex];
    var w   = bl_ctr_gridDim(cols, colIndex, cell.columnVal);
    var h   = bl_ctr_gridDim(rows, rowIndex, cell.rowVal);
    var x   = col.position;
    var y   = row.position;
    
    cell.rowIndex = rowIndex;
    cell.colIndex = colIndex;
    cell.width    = w;
    cell.height   = h;
    cell.x        = x;
    cell.y        = y;
    
    if (!cell.bl_b1)
    {
      var bag      = bl_contain_getBag(el);
      var div1     = "<div class='border_line_div'><img src='/" + bl_version + "/res/img/bungee/form/grid_col.gif'></div>";
      var div2     = "<div class='border_line_div'><img src='/" + bl_version + "/res/img/bungee/form/grid_row.gif'></div>";
      
      bl_port_insertAdjacentHTML(bag, "afterbegin", div1);
      cell.bl_b1 = bag.firstChild;
      
      bl_port_insertAdjacentHTML(bag, "afterbegin", div2);
      cell.bl_b2 = bag.firstChild;
    }
    
    if (x + w < el.offsetWidth)
    {
      var offsety  = ((y % 2 != 0) ? 1 : 0);

      with (cell.bl_b1.style)
      {
        left    = (x + w) + "px";
        top     = (y + offsety) + "px";
        height  = Math.max(h - offsety, 0) + "px";
        width   = "1px";
        display = "block";
      }
    }
    else
    {
      cell.bl_b1.style.display = "none";
    }
    
    if (y + h < el.offsetHeight)
    {
      var offsetx = ((x % 2 != 0) ? 1 : 0)

      with (cell.bl_b2.style)
      {
        left    = (x + offsetx) + "px";
        top     = (y + h) + "px";
        width   = Math.max(w - 1 - offsetx, 0) + "px";
        height  = "1px";
        display = "block";
      }
    }
    else
    {
      cell.bl_b2.style.display = "none";
    }
  }
}

function bl_contain_grid_place_child(el, rows, cols, cell, child, rowIndex, colIndex)
{
  var row   = rows[rowIndex];
  var col   = cols[colIndex];
  var style = child.style;
  
  if (row.colapsed  || col.colapsed)
  {
    //style.left     = -100;
    //style.top      = -100;
    //style.width    = 0;
    //style.height   = 0;
    //child.style.display = "none";
    return;
  }
  //else
  //{
  //  child.style.display = "block";
  //}
  
  var erow       = rows[rowIndex + cell.rowVal - 1];
  var ecol       = cols[colIndex + cell.columnVal - 1];
  var cellWidth  = bl_ctr_gridDim(cols, colIndex, cell.columnVal);
  var cellHeight = bl_ctr_gridDim(rows, rowIndex, cell.rowVal);
  var rmargin1   = row.margin1;
  var cmargin1   = col.margin1;
  var rmargin2   = erow.margin2;
  var cmargin2   = ecol.margin2;
  
  if (rowIndex > 0 && rows[rowIndex - 1].separator)
  {
    rmargin1 += 3;
  }
  if (colIndex > 0 && cols[colIndex - 1].separator)
  {
    cmargin1 += 3;
  }
  
  if (erow.separator)
  {
    rmargin2 += 3;
  }
  if (ecol.separator)
  {
    cmargin2 += 3;
  }
  
  var width  = parseInt(child.getAttribute("bl_width"));
  var height = parseInt(child.getAttribute("bl_height"));
  var w      = (width >= 0)  ? width  : child.offsetWidth;
  var h      = (height >= 0) ? height : child.offsetHeight;
  var cw     = cellWidth - (cmargin1 + cmargin2);
  var ch     = cellHeight - (rmargin1 + rmargin2);
  
  var maxWidth  = parseInt(child.getAttribute("bl_max_w"));
  var minWidth  = parseInt(child.getAttribute("bl_min_w"));
  var maxHeight = parseInt(child.getAttribute("bl_max_h"));
  var minHeight = parseInt(child.getAttribute("bl_min_h"));
  
  if (minHeight != maxHeight)
  {
    h = ch;
    
    if (h < minHeight)
    {
      h = minHeight;
    }
    
    if (h > maxHeight)
    {
      h = maxHeight;
    }
  }
  
  if (minWidth != maxWidth)
  {
    w = cw;
    
    if (w < minWidth)
    {
      w = minWidth;
    }
    
    if (w > maxWidth)
    {
      w = maxWidth;
    }
  }
  
  if (h > ch)
  {
    h = ch;
  }
  
  if (w > cw)
  {
    w = cw;
  }
  
  var x = col.position;
  var y = row.position;
  
  switch (cell.hAlign)
  {
    case 'l':
      x += cmargin1;
    break;
    case 'c':
      x += (cmargin1 + Math.floor((cw/2) - (w/2)));
    break;
    case 'r':
      x += (cellWidth - (w + cmargin2));
    break;
  }
  
  switch (cell.vAlign)
  {
    case 't':
      y += rmargin1;
    break;
    case 'm':
      y += (rmargin1 + Math.floor((ch/2) - (h/2)));
    break;
    case 'b':
      y += (cellHeight - (h + rmargin2));
    break;
  }
  
  if (w < 0)
  {
    w = 0;
  }
  if (h < 0)
  {
    h = 0;
  }

  var shaveH = child.getAttribute("bl_shave_h");

  if (shaveH != null)
  {
    h -= parseInt(shaveH);
  }
  
  style.left     = x+"px";
  style.top      = y+"px";
  if (bl_browserInfo.ie)
  {
    // This prevents an IE effect known as the Holly Hack. If either of these
    // is set to zero, IE will override it and let it be as big as it needs.
    // While useful for vertical and horizontal layouts, it's not at all useful
    // for grid layouts.
    h = (h==0)?1:h;
    w = (w==0)?1:w;
  }
  style.width    = w+"px";
  style.height   = h+"px";
}

function bl_contain_getBag(el)
{
  var ret = el.bl_artifact_bag;
  
  if (!ret)
  {
    ret = el.firstChild;
    
    if (!ret || ret.getAttribute("bl_bag") == null)
    {
      var baghtml = "<span style='font-size:0px;width:0px;height:0px;' bl_bag></span>";
      bl_port_insertAdjacentHTML(el, "afterbegin", baghtml);
      ret = el.bl_artifact_bag = el.firstChild;
    }
    
    el.bl_artifact_bag = ret;
  }
  
  return ret;
}

function bl_contain_in_bounds(item, mx, my, o1, o2)
{
  var x1 = item.offsetLeft + o1;
  var y1 = item.offsetTop + o1;
  var x2 = x1 + item.offsetWidth + o2;
  var y2 = y1 + item.offsetHeight + o2;
  
  return (mx > x1 && mx <= x2 && my > y1 && my <= y2);
}

function bl_contain_is_edit_button(event, container)
{
  if (bl_contain_getOverlayData())
  {
    return true;
  }

  var pos = bl_sys_find_xy(container, null, false);
  var x   = event.clientX - pos.x;
  var y   = event.clientY - pos.y;
  
  return (x > 3 && y > 3 && x < container.clientWidth - 3 && y < container.clientHeight - 3);
}

function bl_contain_hide_buttons()
{
  var body = bl_contain_topParent();
  
  if (body.cb_cell_button)
  {
    body.cb_cell_button.style.display = "none";
  }
}

function bl_contain_row_col_hilite_hide()
{
  var hilite = bl_contain_topParent().bl_hilite;
  
  if (hilite)
  {
    hilite.style.display = "none";
  }
}

function bl_contain_get_hilite()
{
  var body   = bl_contain_topParent();
  var hilite = body.bl_hilite;
  
  if (!hilite)
  {
    var imageHTML = "<div class='bl_hilite'></div>";
    bl_port_insertAdjacentHTML(body, "beforeend", imageHTML);
    hilite = body.bl_hilite = body.lastChild;
  }
  return hilite;
}

function bl_contain_cell_hilite_show(props)
{
  var hilite = bl_contain_get_hilite();
  
  if (props.width > 2 && props.height > 1)
  {
    with (hilite.style)
    {
      display = "";
      top     = (props.top    + 1) + "px";
      left    = (props.left   + 1) + "px";
      width   = (props.width  - 1) + "px";
      height  = (props.height - 2) + "px";
    }
  }
}

function bl_contain_row_col_hilite_show(container, item, isRow)
{
  var hilite = bl_contain_get_hilite();
  var topEl  = bl_contain_topParent();
  var elTop  = bl_sys_real_y(container, topEl, false);
  var elLeft = bl_sys_real_x(container, topEl, false);
  
  if (isRow)
  {
    if (container.offsetWidth > 2 && item.pixelSize > 1)
    {
      hilite.style.display = "";
      hilite.style.top     = (elTop + item.position + 1) + "px";
      hilite.style.left    = (elLeft + 1)+"px";
      hilite.style.width   = (container.offsetWidth - 2) + "px";
      hilite.style.height  = (item.pixelSize - 1) + "px";
    }
  }
  else
  {
    if (container.offsetHeight > 2 && item.pixelSize > 1)
    {
      hilite.style.display = "";
      hilite.style.top     = (elTop + 1) + "px";
      hilite.style.left    = (elLeft + item.position + 1) + "px";
      hilite.style.width   = (item.pixelSize - 1) + "px";
      hilite.style.height  = (container.offsetHeight - 2) + "px";
    }
  }
}

function _bl_contain_align_action(event, el)
{
  var parentWindow = bl_sys_popupParent();
  parentWindow.bl_contain_setAlign(el.id, parentWindow.bl_contain_getOverlayData());
}

function _bl_contain_popupAction(event, el)
{
  var parentWindow = bl_sys_popupParent();
  var data         = parentWindow.bl_contain_getOverlayData();
  
  if (data)
  {
    var item  = data.item;
    var index = data.index;
    var cmd   = el.getAttribute("bl_cmd");
    var edEl  = data.el;
    
    if (cmd == "S")
    {
      if (el.getAttribute("bl_selected") == null)
      {
        el.setAttribute("bl_selected", true);
      }
      else
      {
        el.removeAttribute("bl_selected");
      }
      
      parentWindow.bl_contain_sepProcess(data, item, index, data.isRow);
    }
    else if (cmd == "L")
    {
      if (el.getAttribute("bl_selected") == null)
      {
        el.setAttribute("bl_selected", true);
      }
      else
      {
        el.removeAttribute("bl_selected");
      }
      
      parentWindow.bl_contain_lockProcess(data);
    }
    else if (cmd != "E")
    {
      parentWindow._bl_contain_action(el, data.container, item, index, cmd, data.isRow, data.typeName);
    }
    else if (el.id == "EditMargins")
    {
      parentWindow.bl_dialogData = data;
      _bl_sys_popupClose();
      parentWindow.bl_contain_editMargins(event);
      return ;
    }
    else
    {
      parentWindow.bl_dialogData = data;
      _bl_sys_popupClose();
      parentWindow.bl_contain_editDialog(event);
      return ;
    }
  }
  
  _bl_contain_initEditPopup();
}

function bl_contain_popup_cleanup()
{
  var data = bl_contain_getOverlayData();
  
  if (data)
  {
    var el = data.el;
    
    el.bl_mouseIsIn = false;
    el.bl_mouseIsDown = false;
    cb_sys_img_reset(el, false);
    
    if (!bl_contain_getDialogData())
    {
      bl_contain_row_col_hilite_hide();
    }
    
    bl_ctr_setGridCell(data.container, null);
    
    bl_sys_img_thaw(el)
    bl_overlayData = null;
  }
}

function bl_contain_setSelectButton(selected, other1, other2)
{
  selected.setAttribute("bl_selected", true);
  bl_sys_img_freeze(selected);
  bl_sys_img_thaw(other1);
  bl_sys_img_thaw(other2);
  other1.removeAttribute("bl_selected");
  other2.removeAttribute("bl_selected");
  cb_sys_img_buildSrc(selected, "pr")
  bl_sys_img_set(other1, false, other1.bl_mouseIsIn);
  bl_sys_img_set(other2, false, other2.bl_mouseIsIn);
}

function _bl_contain_cell_align_action(event, el)
{
  bl_sys_popupParent().bl_contain_setCellAlign(el.id);
  
  _bl_contain_initCellPopup();
}

function _bl_contain_initCellPopup()
{
  var parentWindow = bl_sys_popupParent();
  var data        = parentWindow.bl_contain_getOverlayData();
  
  if (data)
  {
    var container = data.container;
    var rowIndex  = data.rowIndex;
    var colIndex  = data.colIndex;
    var tButton   = document.getElementById("t");
    var mButton   = document.getElementById("m");
    var bButton   = document.getElementById("b");
    var lButton   = document.getElementById("l");
    var cButton   = document.getElementById("c");
    var rButton   = document.getElementById("r");
    var rows      = parentWindow.bl_contain_getRowData(container);
    var cols      = parentWindow.bl_contain_getColumnData(container);
    var cells     = parentWindow.bl_contain_getCellData(container);
    var rowCount  = rows.length;
    var colCount  = cols.length;
    
    if (rowIndex >= 0 && rowIndex < rowCount &&
        colIndex >= 0 && colIndex < colCount)
    {
      var cell = cells[(rowIndex * colCount) + colIndex];
      
      if (cell.hAlign == "l")
      {
        bl_contain_setSelectButton(lButton, cButton, rButton);
      }
      else if (cell.hAlign == "c")
      {
        bl_contain_setSelectButton(cButton, lButton, rButton);
      }
      else
      {
        bl_contain_setSelectButton(rButton, cButton, lButton);
      }
      
      if (cell.vAlign == "t")
      {
        bl_contain_setSelectButton(tButton, mButton, bButton);
      }
      else if (cell.vAlign == "m")
      {
        bl_contain_setSelectButton(mButton, bButton, tButton);
      }
      else
      {
        bl_contain_setSelectButton(bButton, tButton, mButton);
      }
    }
  }
  _bl_sys_clearInputBlocker();
}

function _bl_contain_initEditPopup()
{
  var parentWindow = bl_sys_popupParent();
  var data         = parentWindow.bl_contain_getOverlayData();
  
  if (data)
  {
    var container = data.container;
    var item      = data.item;
    var index     = data.index;
    var isRow     = data.isRow;
    var ibButton  = document.getElementById("InsertBefore");
    var iaButton  = document.getElementById("InsertAfter");
    var rButton   = document.getElementById("Remove");
    var wButton   = document.getElementById("Size");
    var sButton   = document.getElementById("Separator");
    var lButton   = document.getElementById("Locked");
    var titleText = document.getElementById("Title");
    var sizeText  = document.getElementById("ITEMSIZE");
    var rows      = parentWindow.bl_contain_getRowData(container);
    var cols      = parentWindow.bl_contain_getColumnData(container);
    var cells     = parentWindow.bl_contain_getCellData(container);
    var rowCount  = rows.length;
    var colCount  = cols.length;
    
    if (item.separator)
    {
      sButton.src = "/" + bl_version + "/res/img/bungee/form/popup/type_toggle_pr.gif";
      sButton.setAttribute("bl_selected", true);
    }
    else
    {
      sButton.src = "/" + bl_version + "/res/img/bungee/form/popup/type_toggle_en.gif";
      sButton.removeAttribute("bl_selected");
    }
    
    if (item.isFixed)
    {
      wButton.src = "/" + bl_version + "/res/img/bungee/form/popup/stretchable_toggle_en.gif";
      wButton.removeAttribute("bl_selected");
    }
    else
    {
      wButton.src = "/" + bl_version + "/res/img/bungee/form/popup/stretchable_toggle_pr.gif";
      wButton.setAttribute("bl_selected", true);
    }

    if (item.isLocked)
    {
      lButton.src = "/" + bl_version + "/res/img/bungee/form/popup/locked_toggle_pr.gif";
      lButton.setAttribute("bl_selected", true);
    }
    else
    {
      lButton.src = "/" + bl_version + "/res/img/bungee/form/popup/locked_toggle_en.gif";
      lButton.removeAttribute("bl_selected");
    }
    
    if (isRow)
    {
      bl_port_setInnerText(titleText, "Grid: edit row[" + index + "] ");
      bl_port_setInnerText(sizeText, "size(" + item.pixelSize + "px)");

      if (rowCount >= 20)
      {
        bl_sys_disable(iaButton);
        bl_sys_disable(ibButton);
        ibButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/insert_above_di.gif";
        iaButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/insert_below_di.gif";
      }
      else
      {
        bl_sys_enable(iaButton);
        bl_sys_enable(ibButton);
        ibButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/insert_above_en.gif";
        iaButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/insert_below_en.gif";
      }
      
      
      var disableRemove = (rowCount == 1);
      
      if (!disableRemove)
      {
        var rowIndex = index * colCount;
        
        for (var i = 0; i < colCount; i++)
        {
          if (cells[rowIndex + i].childIndex >= 0)
          {
            disableRemove = true;
            break;
          }
        }
      }
      if (disableRemove)
      {
        rButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/remove_row_di.gif";
        bl_sys_disable(rButton);
      }
      else
      {
        rButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/remove_row_en.gif";
        bl_sys_enable(rButton);
      }
    }
    else
    {
      bl_port_setInnerText(titleText, "Grid: edit column[" + index + "] ");
      bl_port_setInnerText(sizeText, "size(" + item.pixelSize + "px)");
      
      if (colCount >= 20)
      {
        bl_sys_disable(iaButton);
        bl_sys_disable(ibButton);
        ibButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/insert_before_di.gif";
        iaButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/insert_after_di.gif";
      }
      else
      {
        bl_sys_enable(iaButton);
        bl_sys_enable(ibButton);
        ibButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/insert_before_en.gif";
        iaButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/insert_after_en.gif";
      }
      
      var disableRemove = (colCount == 1);
      
      if (!disableRemove)
      {
        for (var i = 0; i < rowCount; i++)
        {
          if (cells[(i * colCount) + index].childIndex >= 0)
          {
            disableRemove = true;
            break;
          }
        }
      }
      if (disableRemove)
      {
        rButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/remove_column_di.gif";
        bl_sys_disable(rButton);
      }
      else
      {
        rButton.src      = "/" + bl_version + "/res/img/bungee/form/popup/remove_column_en.gif";
        bl_sys_enable(rButton);
      }
    }
    
    parentWindow.bl_contain_row_col_hilite_show(container, item, isRow);
  }
  _bl_sys_clearInputBlocker();
}

function _bl_contain_initEdit()
{
  bl_port_retrieveDialogWindowProperties(window);
  
  window.onunload = _bl_contain_shutdown_dialog;
  if (bl_browserInfo.safari)
  {
    // Allows a synthetic onunload event to be fired. See webkit
    // bugs: #3402 and #12469. This handler is normally added by
    // TopLevelForm.cpp, but the edit dialog is a static page.
    window.onbeforeunload = function(event) { _bl_sys_safari_beforeUnload(event); };
  }

  var parentWindow = bl_port_getDialogArguments().parent;
  var data         = parentWindow.bl_contain_getDialogData();
  
  if (data)
  {
    var container     = data.container;
    var item          = data.item;
    var index         = data.index;
    var isRow         = data.isRow;
    var sizeEdit      = document.getElementById("ITEMSIZE");
    var marLeftName   = document.getElementById("MLName");
    var marLeft       = document.getElementById("MELEFT");
    var marLeftD      = document.getElementById("MELEFTD");
    var marRightName  = document.getElementById("MRName");
    var marRight      = document.getElementById("MERIGHT");
    var marRightD     = document.getElementById("MERIGHTD");
    var sCheck        = document.getElementById("Separator");
    var sLocked       = document.getElementById("Locked");
    var sStrtch       = document.getElementById("Stretchable");
    var titleText     = document.getElementById("Title");
    
    var rows          = parentWindow.bl_contain_getRowData(container);
    var cols          = parentWindow.bl_contain_getColumnData(container);
    var cells         = parentWindow.bl_contain_getCellData(container);
    var rowCount      = rows.length;
    var colCount      = cols.length;
    
    sCheck.checked      =  item.separator;
    marLeft.value       = item.margin1;
    marRight.value      = item.margin2;
    marLeftD.innerHTML  = (item.margin1Set)? "&nbsp;":"(Default)";
    marRightD.innerHTML = (item.margin2Set)? "&nbsp;":"(Default)";
    
    
    sizeEdit.value    = item.pixelSize;
    
    marLeft.bl_oval   = marLeft.value;
    marRight.bl_oval  = marRight.value;
    sizeEdit.bl_oval  = sizeEdit.value;

    sStrtch.checked = !item.isFixed;
    sLocked.checked = item.isLocked;
    
    if (isRow)
    {
      bl_port_setInnerText(titleText, "Grid: edit row[" + index + "]");
      bl_port_setInnerText(marLeftName, "Top Margin:");
      bl_port_setInnerText(marRightName, "Bottom Margin:");
    }
    else
    {
      bl_port_setInnerText(titleText, "Grid: edit column[" + index + "]");
      bl_port_setInnerText(marLeftName, "Left Margin:");
      bl_port_setInnerText(marRightName, "Right Margin:");
    }
    
    parentWindow.bl_contain_row_col_hilite_show(container, item, isRow)
  }
}

function _bl_contain_initMargin()
{
  bl_port_retrieveDialogWindowProperties(window);
  window.onunload = _bl_contain_shutdown_dialog;

  if (bl_browserInfo.safari)
  {
    // Allows a synthetic onunload event to be fired. See webkit
    // bugs: #3402 and #12469. This handler is normally added by
    // TopLevelForm.cpp, but the edit dialog is a static page.
    window.onbeforeunload = function(event) { _bl_sys_safari_beforeUnload(event); };
  }
  
  var parentWindow = bl_port_getDialogArguments().parent;
  var data         = parentWindow.bl_contain_getDialogData();
  
  if (data)
  {
    var container     = data.container;
    var outerMargin    = document.getElementById("OUTERMARGIN");
    var innerRowMargin = document.getElementById("INNERROWMARGIN");
    var innerColMargin = document.getElementById("INNERCOLMARGIN");
    var row            = bl_contain_getRowData(container)[0];
    var col            = bl_contain_getColumnData(container)[0];
    
    outerMargin.value    = row.margin1;
    innerRowMargin.value = row.margin2;
    innerColMargin.value = col.margin2;
  }
}

function _bl_contain_editChanged(event, el)
{
  var parentWindow = bl_port_getDialogArguments().parent;

  if (el.id == "Separator")
  {
    parentWindow.bl_contain_sepProcess(parentWindow.bl_contain_getDialogData());
  }
  else if (el.id == "Locked")
  {
    parentWindow.bl_contain_lockProcess(parentWindow.bl_contain_getDialogData());
  }
}

function _bl_contain_sizeTypeChanged(event, el)
{
  var parentWindow = bl_port_getDialogArguments().parent;
  var data         = parentWindow.bl_contain_getDialogData();
  
  if (data)
  {
    var container = data.container;
    var item      = data.item;
    var isRow     = data.isRow;
    var list;
    var size;
    
    if (isRow)
    {
      list = bl_contain_getRowData(container);
      size = container.offsetHeight;
    }
    else
    {
      list = bl_contain_getColumnData(container);
      size = container.offsetWidth;
    }
    
    parentWindow.bl_contain_sizeTypeChange(container, list, size, data.item, data.index, isRow);
  }
}

function _bl_contain_macro_align(event, el)
{
  var parentWindow = bl_port_getDialogArguments().parent;
  parentWindow.bl_contain_setAlign(el.id, parentWindow.bl_contain_getDialogData());
}

function _bl_contain_editBlur(event, el)
{
  bl_contain_editValChanged(el);
}

function _bl_contain_editKeyDown(event, el)
{
  var kcode = bl_port_keyCode(event);
  
  if (kcode == 13)
  {
    bl_contain_editValChanged(el);
    bl_port_stop_event(event);
  }
  else if (kcode > 57 && !event.ctrlKey)
  {
    if (kcode < 96 || kcode > 105)
    {
      bl_port_stop_event(event);
    }
  }
}

function bl_contain_editValChanged(el)
{
  var parentWindow = bl_port_getDialogArguments().parent;
  var data = parentWindow.bl_contain_getDialogData();
  
  if (data)
  {
    var id = el.id;
    
    if (id == "MELEFT" || id == "MERIGHT")
    {
      var val  = el.value;
      
      if (val != el.bl_oval)
      {
        el.bl_oval = val;
        
        if (val == "")
        {
          val = "-1";
        }
        
        parentWindow.bl_contain_sendMargin((id == "MELEFT"), val);
        
        var item = data.item;

        if (id == "MELEFT")
        {
          var dval = document.getElementById("MELEFTD");
          dval.innerHTML  = (item.margin1Set)? "&nbsp;":"(Default)";

          if (val == "-1")
          {
            el.bl_oval = "" + item.margin1;
            el.value = item.margin1;
          }
        }
        else
        {
          var dval = document.getElementById("MERIGHTD");
          dval.innerHTML  = (item.margin2Set)? "&nbsp;":"(Default)";
          
          if (val == "-1")
          {
            el.bl_oval = "" + item.margin2;
            el.value = item.margin2;
          }
        }
      }
    }
    else if (id == "ITEMSIZE")
    {
      var val = el.value;
      
      if (val != el.bl_oval)
      {
        el.bl_oval = val;
        parentWindow.bl_contain_sizeChange(parseInt(val));
      }
    }
    else if (id == "OUTERMARGIN")
    {
      _bl_contain_newMarginSet(el, "outerMargin");
    }
    else if (id == "INNERROWMARGIN")
    {
      _bl_contain_newMarginSet(el, "innerRowMargin");
    }
    else if (id == "INNERCOLMARGIN")
    {
      _bl_contain_newMarginSet(el, "innerColMargin");
    }
  }
}

function _bl_contain_newMarginSet(el, cmd)
{
  var val = el.value;
  
  if (val == "")
  {
    val = "-1";
  }
  bl_port_getDialogArguments().parent.bl_contain_sendSetMargins(cmd, val);
}

function _bl_contain_shutdown_dialog()
{
  var parentWindow  = bl_port_getDialogArguments().parent;
  parentWindow.bl_dialogData = null;
  parentWindow.bl_contain_row_col_hilite_hide();
}

function bl_contain_editDialog(event)
{
  var url     = "/" + bl_version + "/res/htm/bl_form_grid_row_col.htm";
  var feature = (bl_browserInfo.ie)? "resizable:yes;status:no;unadorned:false;help:no;scroll:no":
                                     "resizable:yes;status:no;scrollbars:no";
  _bl_sys_open("", url, bl_port_computeFeature(event, feature, 315, 250), 2, false, -1, false, false);
}

function bl_contain_editMargins(event)
{
  bl_contain_row_col_hilite_hide();
  
  var url     = "/" + bl_version + "/res/htm/bl_form_grid_margin.htm";
  var feature = (bl_browserInfo.ie)? "resizable:yes;status:no;unadorned:false;help:no;scroll:no":
                                     "resizable:yes;status:no;scrollbars:no";
  _bl_sys_open("", url, bl_port_computeFeature(event, feature, 315, 250), 2, false, -1, false, false);
}

function bl_contain_popup_valid(win)
{
  return (win._bl_sys_last && win._bl_contain_last && win._bl_kb_last && win._bl_port_last && win._bl_popup_init);
}

function bl_contain_getOverlayData()
{
  return window.bl_overlayData;
}

function bl_contain_getDialogData()
{
  return window.bl_dialogData;
}

// Brings up a popup menu (and generates the HTML content) necessary to display the cell-allignment menu.
function _bl_contain_cellOverlay(event, el)
{
  var overlayData = bl_contain_getOverlayData();
  
  if (overlayData && overlayData.el == el)
  {
    window.cb_sys_popup_close(false);
    return ;
  }

  var html  = window.bl_cellPopupText;
  var props = el.bl_props;

  if (!html)
  {
    html   = "<script type='text/javascript'>window.bl_version='"
            + bl_version
            + "'</script><div style='background-color:white;overflow:hidden;margin:0px;border:1px solid #9f9f9f'>";
    
    var attrs2 = " bl_absorb_events bl_popup_ignore width='15px' height='15px' bl_is_value ";

    // Title  
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/title.gif' width='63px' height='16px' style='display:block'><img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/vertical_divider.gif' width='63px' height='1px'>";

    // First row of alignment options
    html += "<div style='font-size:1px;height:15px;text-align:right;padding-right:20px;white-space:nowrap;'><img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/vertical.gif' style='width:15px;height:15px'>";
          
    html += bl_sys_button_html("t", 'img/bungee/form/popup/align_top_', "Set to align at top", false, "_bl_contain_cell_align_action", attrs2, false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/horizontal_divider.gif' style='width:1px;height:15px'>";
          
    html += bl_sys_button_html("m", 'img/bungee/form/popup/align_middle_', "Set to align in the middle", false, "_bl_contain_cell_align_action", attrs2, false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/horizontal_divider.gif' style='width:1px;height:15px'>";
          
    html += bl_sys_button_html("b", 'img/bungee/form/popup/align_bottom_', "Set to align at bottom", false, "_bl_contain_cell_align_action", attrs2, false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/horizontal_divider.gif' style='width:1px;height:15px'></div>";
    
    // Second row of alignment options
    html += "<div style='font-size:1;height:15px;text-align:right;padding-right:20px;white-space:nowrap;'><img src='/" 
         + bl_version
         + "/res/img/bungee/form/popup/horizontal.gif' style='width:15px;height:15px'>";
    
    html += bl_sys_button_html("l", 'img/bungee/form/popup/align_left_', "Set to align at left", false, "_bl_contain_cell_align_action", attrs2, false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/horizontal_divider.gif' style='width:1px;height:15px'>";
          
    html += bl_sys_button_html("c", 'img/bungee/form/popup/align_center_', "Set to align in the center", false, "_bl_contain_cell_align_action", attrs2, false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/horizontal_divider.gif' style='width:1px;height:15px'>";
          
    html += bl_sys_button_html("r", 'img/bungee/form/popup/align_right_', "Set to align at right.", false, "_bl_contain_cell_align_action", attrs2, false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/horizontal_divider.gif' style='width:1px;height:15px'></div>";
    
    // Footer
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/divider.gif' width='63px' height='1px'></div><div id='bl_inputBlocker_id' class='bl_inputBlocker' onmousepress='bl_port_killEvent(event)' onmousedown='bl_port_killEvent(event)' onmouseup='bl_port_killEvent(event)'></div><script type='text/javascript'>window._bl_contain_initCellPopup();</script>";
          
    window.bl_cellPopupText = html;
  }
  
  bl_overlayData = { el:el, container:props.container, rowIndex:props.rowIndex, colIndex:props.colIndex }
  bl_contain_cell_hilite_show(props);
  
  var argData = { html:html,
                  customArg:el,
                  doSideCart:true,
                  controlHAlign:"Left",
                  controlVAlign:"Bottom",
                  x:0,
                  y:0,
                  w:63,
                  h:49,
                  el:el,
                  cleanUp:bl_contain_popup_cleanup,
                  canDestroy:true,
                  valid:bl_contain_popup_valid,
                  useVeil:true,
                  positionType:"control"
                };
  
  if (window.bl_sys_popupInvoke(argData) != null) 
  {
    bl_sys_img_freeze(el);
  }
}

function bl_contain_popupHTML(isrow)
{
  var html   = "<script type='text/javascript'>window.bl_version='"
               + bl_version
               + "';</script><div style='background-color:white;overflow:hidden;margin:0px;border:1px solid #9f9f9f;'>";
  
  var attrs  = " bl_absorb_events width=192 height=18 ";
  var align_attrs = " bl_absorb_events bl_popup_ignore style='margin-left:2px;margin-bottom:2px;width:15px;height:15px;'";
  
  html += "<table border='0' cellpadding='0' cellspacing='0' style='width:192px;height:18px;background-image:url(/" 
        + bl_version
        + "/res/img/bungee/form/popup/title_stretch.gif);font-family:tahoma;font-size:11px;color:#c2c2c2'><tbody><tr><td style='padding-left:5px;white-space:nowrap'><span id='Title'></span></td><td style='white-space:nowrap;padding-right:3px;text-align:right'><span id='ITEMSIZE' ></span></td></tr></tbody></table><img src='/" 
        + bl_version
        + "/res/img/bungee/form/popup/divider.gif' width='192px' height='1px'/>";
  
  html += bl_sys_button_html("EditMargins", 'img/bungee/form/popup/edit_margins_', "Edit Margins", false, "_bl_contain_popupAction", attrs + " bl_cmd='E' ", false, null);

  if (isrow)
  {
    html += bl_sys_button_html("Edit", 'img/bungee/form/popup/edit_row_', "Edit row", false, "_bl_contain_popupAction", attrs + " bl_cmd='E' ", false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/divider.gif' width='192px' height='1px'>";
    
    html += bl_sys_button_html("InsertBefore", 'img/bungee/form/popup/insert_above_', "Insert above row", false, "_bl_contain_popupAction", attrs + " bl_cmd='IB' ", false, null);
    html += bl_sys_button_html("InsertAfter", 'img/bungee/form/popup/insert_below_', "Insert below row", false, "_bl_contain_popupAction", attrs + " bl_cmd='IA' ", false, null);
    html += bl_sys_button_html("Remove", 'img/bungee/form/popup/remove_row_', "Remove row", false, "_bl_contain_popupAction", attrs + " bl_cmd='R' ", false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/divider.gif' width='192px' height='1px'>";
    
    html += bl_sys_button_html("Size", 'img/bungee/form/popup/stretchable_toggle_', "Toggle Stretchable", false, "_bl_contain_popupAction", attrs + " bl_cmd='W' bl_is_value", false, null);
    html += bl_sys_button_html("Locked", 'img/bungee/form/popup/locked_toggle_', "Toggle Locked", false, "_bl_contain_popupAction", attrs + " bl_cmd='L' bl_is_value", false, null);
    html += bl_sys_button_html("Separator", 'img/bungee/form/popup/type_toggle_', "Toggle separator row", false, "_bl_contain_popupAction", attrs + " bl_cmd='S' bl_is_value ", false, null);
  }
  else
  {
    html += bl_sys_button_html("Edit", 'img/bungee/form/popup/edit_column_', "Edit column", false, "_bl_contain_popupAction", attrs + " bl_cmd='E' ", false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/divider.gif' width='192px' height='1px'>";
    
    html += bl_sys_button_html("InsertBefore", 'img/bungee/form/popup/insert_before_', "Insert before column", false, "_bl_contain_popupAction", attrs + " bl_cmd='IB' ", false, null);
    html += bl_sys_button_html("InsertAfter", 'img/bungee/form/popup/insert_after_', "Insert after column", false, "_bl_contain_popupAction", attrs + " bl_cmd='IA' ", false, null);
    html += bl_sys_button_html("Remove", 'img/bungee/form/popup/remove_column_', "Remove column", false, "_bl_contain_popupAction", attrs + " bl_cmd='R' ", false, null);
    
    html += "<img src='/" 
          + bl_version
          + "/res/img/bungee/form/popup/divider.gif' width='192px' height='1px'>";
    
    html += bl_sys_button_html("Size", 'img/bungee/form/popup/stretchable_toggle_', "Toggle Stretchable", false, "_bl_contain_popupAction", attrs + " bl_cmd='W' bl_is_value ", false, null);
    html += bl_sys_button_html("Locked", 'img/bungee/form/popup/locked_toggle_', "Toggle Locked", false, "_bl_contain_popupAction", attrs + " bl_cmd='L' bl_is_value", false, null);
    html += bl_sys_button_html("Separator", 'img/bungee/form/popup/type_toggle_', "Toggle separator column", false, "_bl_contain_popupAction", attrs + " bl_cmd='S' bl_is_value ", false, null);
  }
  
  html += "<img src='/" 
        + bl_version
        + "/res/img/bungee/form/popup/divider.gif' width=192 height=1><div style='padding-right:7px;text-align:right;background-image:url(/" 
        + bl_version
        + "/res/img/bungee/form/popup/v-align_en.gif);width:192px;height:18px;'><div style='left:120px'>";
  
  html += bl_sys_button_html("t", 'img/bungee/form/popup/align_top_', "Set to align at top", false, "_bl_contain_align_action", align_attrs, false, null);
  html += bl_sys_button_html("m", 'img/bungee/form/popup/align_middle_', "Set to align in the middle", false, "_bl_contain_align_action", align_attrs, false, null);
  html += bl_sys_button_html("b", 'img/bungee/form/popup/align_bottom_', "Set to align at bottom", false, "_bl_contain_align_action", align_attrs, false, null);
  
  html += "</div></div><div style='text-align:right;padding-right:7px;background-image:url(/" 
        + bl_version
        + "/res/img/bungee/form/popup/h-align_en.gif);width:192px;height:18px;'><div style='left:120px'>";
        
  html += bl_sys_button_html("l", 'img/bungee/form/popup/align_left_', "Set to align at left", false, "_bl_contain_align_action", align_attrs, false, null);
  html += bl_sys_button_html("c", 'img/bungee/form/popup/align_center_', "Set to align in the center", false, "_bl_contain_align_action", align_attrs, false, null);
  html += bl_sys_button_html("r", 'img/bungee/form/popup/align_right_', "Set to align at right", false, "_bl_contain_align_action", align_attrs, false, null);
  
  html += "</div></div><img src='/" 
        + bl_version
        + "/res/img/bungee/form/popup/divider.gif' width='192px' height='1px'></div><div id='bl_inputBlocker_id' class='bl_inputBlocker' onmousepress='bl_port_killEvent(event)' onmousedown='bl_port_killEvent(event)' onmouseup='bl_port_killEvent(event)'></div><script type='text/javascript'>window._bl_contain_initEditPopup();</script>";
  
  return html;
}

function bl_contain_reset_popup_context(list, index)
{
  var data = bl_contain_getOverlayData();
  
  if (data)
  {
    var len = list.length;
    
    if (index >= len)
    {
      index = len - 1;
    }
    
    data.item  = list[index];
    data.index = index;
  }
}

function bl_contain_boundryArtifact(container)
{
  var ret = container.bl_boundryArtifact;
  
  if (!ret)
  {
    var bag  = bl_contain_getBag(container);
    var list = bag.childNodes;
    var len  = list.length;
    
    for (var i = 0; i < len; i++)
    {
      var child = list[i];
      
      if (child.getAttribute("bl_boundry") != null)
      {
        ret = child;
        break ;
      }
    } 
    
    if (!ret)
    {
      var div = "<div bl_boundry style='display:none;' class='border_line_div_hilight' ><img src='/" 
                + bl_version 
                + "/res/img/bungee/form/horiz_wall_ov.gif'></div>";
                
      bl_port_insertAdjacentHTML(bag, "afterbegin", div);
      ret = bag.firstChild;
    }
    
    container.bl_boundryArtifact = ret;
  }
  
  return ret;
}

function bl_contain_showBoundry(boundryItem, el)
{
  var list  = boundryItem.boudryList;
  var isRow = boundryItem.isRow;

  if (!list)
  {
    list = [];
    boundryItem.boudryList = list;
  }
  else
  {
    list.splice(0, list.length);
  }
  
  var hilightDiv = bl_contain_boundryArtifact(el);

  with (hilightDiv.style)
  {
    display = "";
    
    if (isRow)
    {
      hilightDiv.firstChild.src = "/" + bl_version + "/res/img/bungee/form/horiz_wall_ov.gif";
      bl_contain_grid_compute_wall_buttons_row(el, boundryItem, boundryItem.index);
  
      top    = (boundryItem.position + boundryItem.pixelSize) + "px";
      left   = (0) + "px";
      width  = (el.offsetWidth) + "px";
      height = (1) + "px";
    }
    else
    {
      hilightDiv.firstChild.src = "/" + bl_version + "/res/img/bungee/form/vert_wall_ov.gif";
      
      bl_contain_grid_compute_wall_buttons_column(el, boundryItem, boundryItem.index);
      
      top    = (0) + "px";
      left   = (boundryItem.position + boundryItem.pixelSize) + "px";
      width  = (1) + "px";
      height = (el.offsetHeight) + "px";
    }
  }
    
  var len     = list.length;
  var barpos  = boundryItem.cb_boundryPos - 4;
  var dimList = (isRow) ? bl_contain_getColumnData(el) : bl_contain_getRowData(el);
  
  for (var i = 0; i < len; i++)
  {
    var wallBar = list[i];
    var props   = wallBar.bl_props;
    var dimPos  = bl_ctr_gridDim(dimList, 0, props.dimIndex);
    var dim     = Math.floor(bl_ctr_gridDim(dimList, props.dimIndex, props.span)/2);
    
    with (wallBar.style)
    {
      display = "";
      if (isRow)
      {
        left = (dimPos + dim - 8) + "px";
        top  = barpos + "px";
      }
      else
      {
        left = barpos + "px";
        top  = (dimPos + dim - 8) + "px";
      }
    }
  }
}

function bl_contain_hideBoundry(item, el)
{
  var hilightDiv = bl_contain_boundryArtifact(el);
  var list       = item.boudryList;

  hilightDiv.style.display = "none";

  if (list)
  {
    var len  = list.length;
    
    for (var i = 0; i < len; i++)
    {
      list[i].style.display = "none";
    }
  }
}

function bl_contain_clean_row_column_data_atrifacts(item)
{
  if (item.boudryList)
  {
    item.boudryList.splice(0, item.boudryList.length);
  }
  
  bl_contain_clean_up_sep(item);
  
  item.boudryList = null;
}

function bl_contain_clean_row_column_artifacts(list)
{
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    bl_contain_clean_row_column_data_atrifacts(list[i]);
  }
}

function bl_contain_cleanupLayout(el)
{
  var layout = el.bl_layout;
  
  if (layout && layout.canEdit(el))
  {
    var list = el.childNodes;
    var len  = list.length;
    var index;

    for (index = 0; index < len; index++)
    {
      bl_contain_cleanupLayout(list[index]);
    }
    
    layout.cleanup(el);
    el.bl_layout = null;
  }
}

function bl_contain_getLayout(el)
{
  var ret = el.bl_layout;

  if (!ret)
  {
    var layoutTypeStr = el.getAttribute("bl_layout_type");
    
    if (layoutTypeStr)
    {
      var layoutList = window.bl_layoutList;
      var layoutType = parseInt(layoutTypeStr)
      
      if (layoutType < 0 || layoutType > 8)
      {
        layoutType = 0;
      }
      
      if (!layoutList)
      {
        window.bl_layoutList = layoutList = [new bl_contain_natural_create(),
                                             new bl_ht_create(),
                                             new bl_vt_create(),
                                             new bl_contain_horizontal_create(),
                                             new bl_contain_vertical_create(),
                                             new bl_contain_2d_horizontal_create(),
                                             new bl_contain_2d_vertical_create(),
                                             new bl_contain_absolute_create(),
                                             new bl_contain_grid_create()];
      }      
      
      el.bl_layout = ret = layoutList[layoutType];
    }
  }
  
  return ret;
}

function bl_contain_computeDropInfo(el, ddObj, event, clientx, clienty)
{
  var layout   = bl_contain_getLayout(el);
  var feedback = bl_contain_dragFeedback(cb_sys_getTopWindow());
  var target    = bl_port_getEventTarget(event);
  var zoneList = null;
  
  if (layout.canEdit(el) || (el.getAttribute("cb_tag") == "DFL" && !cb_sys_isInput(target)))
  {
    zoneList = el.getAttribute("bl_zone_list");
    
    if (zoneList && ddObj && !bl_port_contains(ddObj.srcContext.item, el, true))
    {
      var child = layout.findDropChild(el, clientx, clienty);
      
      if (!child || layout.computeCanDrop(ddObj, el, child, clientx, clienty, false) == null)
      {
        zoneList = null;
      }
    }
  }
  
  if (zoneList)
  {
    if (bl_dd_checkList(ddObj, event, zoneList))
    {
      var pos = bl_sys_find_xy(el, null, false);
      layout.computeDragFeedback(el, feedback, clientx - pos.x, clienty - pos.y);
      bl_port_killEvent(event);
      
      if (bl_contain_isFormEditor())
      {
        bl_contain_topParent().style.border = "#9DA1A6 1px solid";
      }
      
      return ;
    }
  }

  bl_contain_computeFeedbackOff(feedback);
  ddObj.setHint(null);
  ddObj.clearEffect();
}

function _bl_ctr_ddOver(event, el)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    bl_contain_computeDropInfo(el, ddObj, event, event.clientX, event.clientY);
  }
}

function _bl_ctr_ddOut(event, el)
{
  var ddObj  = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    var clientx = event.clientX;
    var clienty = event.clientY;
    var pos     = bl_sys_find_xy(el, null, false);
    
    if (pos.x <= clientx && 
        clientx <= pos.x + el.offsetWidth && 
        pos.y <= clienty && 
        clienty <= pos.y + el.offsetHeight)
    {
      bl_contain_computeDropInfo(el, ddObj, event, clientx, clienty);
    }
    else
    {
      ddObj.setFeedbackItem(null);
      ddObj.setHint(null);
      ddObj.clearEffect();
    }
  }
}

function bl_contain_getcontextElement(el)
{
  var frameEl = window.frameElement;
  
  if (frameEl)
  {
    var cbTag = frameEl.getAttribute("cb_tag");
    
    if (cbTag && cbTag == "FER")
    {
      return frameEl;
    }
  }
  
  return el;
}

function bl_contain_inFormControl()
{
  var frameEl = window.frameElement;
  
  if (frameEl)
  {
    var cbTag = frameEl.getAttribute("cb_tag");
    
    if (cbTag && cbTag == "FER")
    {
      return true;
    }
  }
  
  return false;
}

function bl_contain_getLiveWindow(el)
{
  var win              = window;
  var controlContextId = null;
  var frameEl          = null;

  if (!win.bl_is_main)
  {
    try
    {
      frameEl = win.frameElement;
    }
    catch (exception)
    {
    }
  }
  
  if (frameEl)
  {
    var cbTag = frameEl.getAttribute("cb_tag");
    
    if (cbTag && cbTag == "FER")
    {
      controlContextId = win.frameElement.id;
      win = win.parent;
    }
  }
  
  if (!controlContextId && el)
  {
    controlContextId = el.id;
  }
  
  var formId = window.bl_formId;
  
  if (!formId)
  {
    formId = win.bl_did;
  }
  
  win.cb_formId           = formId;
  win.cb_controlContextId = controlContextId;
  return win;
}

function bl_ctr_handleDrop(el, event, clientx, clienty)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {
    var layout  = bl_contain_getLayout(el);
    var canEdit = layout.canEdit(el);
    var isDFL   = (el.getAttribute("cb_tag") == "DFL");

    if (canEdit || isDFL)
    {
      var child = layout.findDropChild(el, clientx, clienty);
      
      if (child)
      {
        child = layout.computeCanDrop(ddObj, el, child, clientx, clienty, true);
        
        if (child != null)
        {
          var win     = bl_contain_getLiveWindow(el);
          var context = bl_contain_computeContext(win, child, el);
          var index   = layout.getChildIndex(el, child);

          if(index < 0)
          {
            /* TODO:
             * A negative index means either that the drop was added
             * as the first element (insert), or as a new last element
             * (append). However, specifying "-1" will crash the
             * server. Munge it to be the first element to prevent a
             * the crash.
             */
            index = layout.numChildren(el);
          }

          var target = { id:win.cb_controlContextId, index:index, dropContext:context };
          
          if (isDFL)
          {
            target.aboutToDrop = bl_sel_aboutToDrop;
            target.selectMgr   = el.selectMgr;
          }
          
          win.bl_dd_procDrop(target);
          bl_port_stop_event(event);
        }
      }
    }
  }
}

function _bl_ctr_drop(event, el)
{
  bl_ctr_handleDrop(el, event, event.clientX, event.clientY);
}

function bl_contain_computeContext(win, child, el)
{
  var layout  = bl_contain_getLayout(el);
  var context = "";

  if (layout)
  {
    var context          = (el.getAttribute("bl_meta") != null) ? "contaner;1;" : "contaner;0;";
    var containerContext = (el.bl_context)? el.bl_context:"";
    var index            = layout.getChildIndex(el, child);
    
    if (index < 0)
    {
      index = layout.numChildren(el);
    }
    
    context += win.cb_formId
            + ";"
            + el.id
            + ";"
            + layout.getChildIndex(el, child)
            + ";"
            + child.id
            + ";"
            + containerContext;
  }
  
  return context;
}

function _bl_ctr_dblclk(event, el)
{
  var layout = bl_contain_getLayout(el);
  
  if (el.getAttribute("cb_tag") == "DFL")
  {
    if (!layout.canEdit(el) && el.getAttribute("bl_canSelect") != null)
    {
      bl_dfl_dblclk(event, el);
    }
  }
  else
  {
    var child   = layout.find(el, bl_port_getEventTarget(event));
    var win     = bl_contain_getLiveWindow(el);
    var parent  = bl_contain_resolveParent(el, child);
    var context = "<dblclk>" + bl_contain_computeContext(win, child, parent) + "</dblclk>";
 
    bl_contain_selectChild(parent, child);
    win.bl_mpr_send(context, win.cb_controlContextId, 1);
    bl_port_stop_event(event);
  }
}

function bl_contain_getParent(el)
{
  var ret = el.parentNode;
  
  if (ret.tagName == "TD")
  {
    ret = ret.parentNode.parentNode.parentNode.parentNode;
  }
  
  return ret;
}

function _bl_contain_par_key_down(event, el)
{
  var selected = bl_geo_getSelected();

  if (selected.valid())
  {
    _bl_contain_key_down(event, selected.parent);
    bl_port_stop_event(event);
  }
}

function _bl_contain_par_key_up(event, el)
{
  var selected = bl_geo_getSelected();

  if (selected.valid())
  {
    _bl_contain_key_up(event, selected.parent);
    bl_port_stop_event(event);
  }
}

function _bl_contain_par_mouse_down(event, el)
{
  var topContainer = bl_contain_top_container();
  
  if (topContainer)
  {
    bl_contain_performSelect(topContainer, topContainer);
    bl_port_stop_event(event);
  }
}

function _bl_contain_key_down(event, el)
{
  var drag = window.bl_current_drag;
  
  if (drag)
  {
    _bl_contain_size_key(event, drag);
    return ;
  }
  
  if (el.getAttribute("cb_tag") == "DFL")
  {
    var layout = bl_contain_getLayout(el);
    
    if (!layout.canEdit(el) && el.getAttribute("bl_canSelect") != null)
    {
      _bl_sel_key_down(event, el);
    }
  }
}

function _bl_contain_key_up(event, el)
{
  var layout = bl_contain_getLayout(el);
  
  if (layout.canEdit(el))
  {
    var selected = bl_geo_getSelected();
    var kcode    = bl_port_keyCode(event);
    
    if (!selected.child && (kcode == 37 || kcode == 38 || kcode == 39 || kcode == 40))
    {
      kcode = 36;
    }
    
    switch (kcode)
    {
      case (36): //home
      case (35): //end
      {
        var topContainer = bl_contain_top_container();
        
        if (topContainer)
        {
          bl_contain_performSelect(topContainer, topContainer);
        }
      }
      break;
      case (46): //delete
      case (8):  //backspace
      {
        var selected = bl_geo_getSelected();
        bl_contain_performDelete(selected.parent, selected.child);
      }
      break;
      default:
      {
        var selected = bl_geo_getSelected();

        if (selected.valid())
        {
          layout = bl_contain_getLayout(selected.parent);
          layout.keyCommand(selected.parent, selected.child, event, kcode);
        }
      }
    }
    
    bl_port_stop_event(event);
  }
  else if (el.getAttribute("cb_tag") == "DFL")
  {
    if (el.getAttribute("bl_canSelect") != null)
    {
      _bl_sel_key_up(event, el);
    }
  }
}

function bl_contain_top_container()
{
  var topParent = bl_contain_topParent();
  var list      = topParent.childNodes;
  var len       = list.length;
  
  for (var i = 0; i < len; i++)
  {
    var child = list[i];
    
    if (child.getAttribute("bl_is_top") != null)
    {
      return child;
    }
  }
  return null;
}

function bl_contain_performSelect(el, src)
{
  var layout   = bl_contain_getLayout(el);
  var child    = layout.find(el, src);
  var parent   = bl_contain_resolveParent(el, child);
  var context  = null;
  
  if (child)
  {
    var win = bl_contain_getLiveWindow(el);
    
    context = bl_contain_computeContext(win, child, parent);
    
    var selectContext  = "<select>" + context + "</select>";

    bl_contain_selectChild(parent, child);
    
    win.bl_mpr_send(selectContext, win.cb_controlContextId, 1);
  }
      
  var layout = bl_contain_getLayout(parent);
  return {child:child, index:layout.getChildIndex(parent,child), context:context};
}

function bl_contain_resolveParent(el, child)
{
  var ret = el;
  
  if (el == child)
  {
    var elParent = bl_contain_getParent(el);
    
    if (bl_contain_getLayout(elParent) != null)
    {
       ret = elParent;
     }
  }
  
  return ret;
}

function bl_contain_performDelete(el, src)
{
  if (el)
  {
    var layout  = bl_contain_getLayout(el);
    var child   = layout.find(el, src);
    var win     = bl_contain_getLiveWindow(el);
    
    if (child)
    {
      var childParent = child.parentNode;
      
      if (childParent == document.body || childParent.id == "bl_layout_parent")
      {
        window.alert("You may not delete the top container in this form!");
      }
      else
      {
        var parent   = bl_contain_resolveParent(el, child);
        var context  = "<delete>" + bl_contain_computeContext(win, child, parent) + "</delete>";

        bl_contain_selectChild(parent, child);
        
        win.bl_mpr_send(context, win.cb_controlContextId, 1, BL_MPR_SYNC);
      }
    }
  }
}

function bl_contain_findContainerParent(el)
{
  var container = null;
  var child     = el;
  var p         = el;
  var body      = document.body;
  
  while (p)
  {
    if (p.getAttribute)
    {
      var cbtag = p.getAttribute("cb_tag");
      
      if (cbtag == "CTR" ||  cbtag == "DFL")
      {
        var layout = bl_contain_getLayout(p);
        if (layout && layout.canEdit(p) || cbtag == "DFL")
        {
          break ;
        }
      }
      
      child = p;
      p = p.parentNode;
      
      if (p == body)
      {
        p = null;
      }
    }
    else
    {
      p = null;
    }
  }
  
  return p;
}

function bl_contain_findElement(item, clientx, clienty)
{
  var child = item.firstChild;
  var x;
  var y;
  var right;
  var bottom;

  if (bl_browserInfo.firefox)
  {
    var scroll   = bl_sys_find_scrollOffset(item,null,false);  
    var scrollTop  = scroll.top;
    var scrollLeft = scroll.left;
  }
  
  while (child)
  {
    if (child.getBoundingClientRect)
    {
      var rect = child.getBoundingClientRect();
      
      x      = rect.left;
      y      = rect.top;
      right  = rect.right;
      bottom = rect.bottom;
    }
    else
    {
      var box    = null;
      if (child.nodeType == 1 && child.ownerDocument.getBoxObjectFor)
      {
        // Must be using firefox, and the node MUST be an element node (node type 1)
        // for the box object to be available. Some platforms don't support the
        // box object, though, so the fallback computation method is still available.
        box = child.ownerDocument.getBoxObjectFor(child);
      }
      if (box)
      {
        x      = box.x - scrollLeft;
        y      = box.y - scrollTop;
        right  = x + box.width;
        bottom = y + box.height;
      }
      else
      {
        var pos = bl_sys_find_xy(child, null, false);
        
        x      = pos.x;
        y      = pos.y;
        right  = child.offsetWidth + x;
        bottom = child.offsetHeight + y;
      }
    }
    if (x <= clientx && clientx <= right && y <= clienty && clienty <= bottom)
    {
      item = child;
      child = child.firstChild;

      if (bl_browserInfo.firefox)
      {
        scrollTop  += item.scrollTop;
        scrollLeft += item.scrollLeft;
      }
    }
    else
    {
      child = child.nextSibling;
    }
  }
  return item;
}

function bl_contain_getDragInfo(event)
{
  var ret     = null;
  var clientx = event.clientX;
  var clienty = event.clientY;
  
  var win = window;
  var el  = bl_contain_findElement(document.body, clientx, clienty)
  
  if (el)
  {
    var foundFormEditor = false;
    
    while (el && el.tagName == "IFRAME" && !foundFormEditor)
    {
      foundFormEditor = (el.getAttribute("cb_tag")  == "FER");
      
      win     = el.contentWindow;
      clientx = event.screenX - win.cb_sys_getScreenLeft();
      clienty = event.screenY - win.cb_sys_getScreenTop();
      el      = win.bl_contain_findElement(win.document.body, clientx, clienty);
    }
    
    win = bl_port_docWindow(el.ownerDocument);
    
    var container = bl_contain_findContainerParent(el);
    
    if (container)
    {
      ret = { container:container, x:clientx, y:clienty, win:win };
    }
  }
  
  return ret;
}

function _bl_ctr_ddShadowOver(event, el)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    var dInfo = bl_contain_getDragInfo(event);
    
    if (dInfo)
    {
      dInfo.win.bl_contain_computeDropInfo(dInfo.container, ddObj, event, dInfo.x, dInfo.y);
    }
    else
    {
      bl_contain_computeFeedbackOff(bl_contain_dragFeedback(cb_sys_getTopWindow()));
      ddObj.setHint(null);
      ddObj.clearEffect();
    }
  }
}

function _bl_ctr_ddShadowOut(event, el)
{
}

function _bl_ctr_ddShadowDrop(event, el)
{
  var dInfo = bl_contain_getDragInfo(event);

  if (dInfo)
  {
    dInfo.win.bl_ctr_handleDrop(dInfo.container, event, dInfo.x, dInfo.y);
  }
}

function bl_contain_dragInner(event)
{
  var item     = this.item;
  var innerDiv = window.bl_ctr_innerDragDiv;
  
  if (!window.bl_ctr_innerDragDiv)
  {
    window.bl_ctr_innerDragDiv = innerDiv = document.createElement("div");
  }

  /* This reference to bl_browserInfo.firefox is to ensure
   * that the new html contains a reference to the correct dragged
   * element.
   */
  var html = "<div style='border:1px solid #7BBE42;' ondragover='_bl_ctr_ddShadowOver(event, this)' ondragleave='_bl_ctr_ddShadowOut(event, this)' ondrop='_bl_ctr_ddShadowDrop(event, this)'>"
            + bl_port_getOuterHTML(item)
            + "</div>";
  
  innerDiv.innerHTML = html;
  
  var tmpNode = innerDiv.firstChild;
  
  with (tmpNode.firstChild.style)
  {
    position = "";
    top      = "";
    left     = "";
    width    = item.offsetWidth+"px";
    height   = item.offsetHeight+"px";
  }
  
  bl_contain_removeHandlers(tmpNode.firstChild);
  html = innerDiv.innerHTML;
  
  // cleanup
  innerDiv.innerHTML = ""; 
  
  return html;
}

function bl_contain_removeHandlers(tmpEl)
{
  if (!bl_port_isTextNode(tmpEl))
  {
    tmpEl.id = "";
    
    if (tmpEl.getAttribute("cb_tag") == "CTR")
    {
      tmpEl.ondragover   = null;
      tmpEl.ondragleave  = null;
      tmpEl.ondrop       = null;
      tmpEl.onmousedown  = null;
      tmpEl.onmouseover  = null;
      tmpEl.onmouseleave = null;
      
      tmpEl.removeAttribute("bl_inEdit");
      
      var list = tmpEl.childNodes;
      var len  = list.length;
      
      for (var i = 0; i < len; i++)
      {
        bl_contain_removeHandlers(list[i]);
      }
    }
  }
}

function bl_contain_computeFeedbackOff(el)
{
  with (el.style)
  {
    display = "";
    height  = "2px";
    width   = "2px";
    color   = "red";
  }
  
  el.innerHTML = "x<br>x";
}

function bl_contain_computeFeedbackText(el, x, y, w, h)
{
  with (el.style)
  {
    display = "";
    height  = "15px";
    width   = "auto";
    color   = "black";
  }
  el.innerHTML = "x(" + x + ") y(" + y + ")<br>x(" + x + ") y(" + y + ")";
}

function bl_contain_dragFeedback(topWin)
{
  var doc = topWin.document;
  
  if (!doc.bl_drag_feedBackEl)
  {
    var el = doc.createElement("DIV");
    
    with (el.style)
    {
      position    = "absolute";
      height      = "2px";
      width       = "2px";
      left        = "-2px";
      top         = "-2px";
      zIndex      = 3000;
      overflow    = "hidden";
      color       = "red";
      display     = "none";
      fontSize    = "12px";
      fontFamily  = "Arial";
    }
    
    doc.body.appendChild(el);
    doc.bl_drag_feedBackEl = el;
  }
  
  return doc.bl_drag_feedBackEl;
}

function bl_ctr_shadowUpdate(ddObj, shadow, effect)
{
  shadow.firstChild.style.borderColor = (effect == "none")? "red":"#7BBE42";
}

function bl_ctr_shadowDrag(ddObj, dragEl, x, y)
{
  var topw    = cb_sys_getTopWindow();
  var body    = topw.document.body;
  var wsize   = topw.bl_port_windowSize();
  var child   = dragEl.firstChild;
  var pLeft   = 0;
  var pTop    = 0;
  
  pLeft = x - bl_port_getScreenLeft(topw) - this.dragOffsetX + body.scrollLeft;
  pTop  = y - bl_port_getScreenTop(topw)  - this.dragOffsetY + body.scrollTop;

  var feedback  = bl_contain_dragFeedback(topw);
  var fleft     = pLeft;
  var ftop      = pTop - 27;
  
  if (ftop < 0)
  {
    ftop = pTop + dragEl.offsetHeight;
  }
  
  if (fleft + feedback.offsetWidth > wsize.width)
  {
    fleft = wsize.width - feedback.offsetWidth;
  }
  
  if (fleft < 0)
  {
    fleft = 0;
  }
  
  with (feedback.style)
  {
    left  = fleft+"px";
    top   = ftop+"px";
  }
  
  with (dragEl.style)
  {
    left = pLeft+"px";
    top  = pTop+"px";
  }
}

function bl_ctr_dragEnd(source, item, dragStarted)
{
  var feedback = bl_contain_dragFeedback(cb_sys_getTopWindow());
  feedback.style.display = "none";
}

function _bl_contain_noHandlerMousedown(event,el)
{
  bl_kb_focusOnElement(bl_port_getEventTarget(event));
}

function _bl_ctr_down(event, el)
{
  var layout = bl_contain_getLayout(el);
  
  if (!layout)
  {
    // no layou means do not handle this event
    return ;
  }
  
  var target = bl_port_getEventTarget(event);
  var blTag  = el.getAttribute("cb_tag");

  if (bl_browserInfo.firefox && event.detail > 1)
  {
    if (!cb_sys_isInput(target))
    {
      // This is to prevent the text from being selected by a double click (when inside a dynamic form list)
      bl_port_preventDefault(event);
    }
  }
  
  if (bl_port_point_on_scrollbar(target, event.clientX, event.clientY))
  {
    if ((blTag == "DFL" && el.getAttribute("bl_canSelect") != null) || 
        layout.canEdit(el))
    {
      bl_kb_focusOnElement(target);
    }
    bl_port_stop_event(event);
  }
  else 
  {
    if (blTag == "DFL")
    {
      if (el.getAttribute("bl_canSelect") != null)
      {
        //  bl_kb_focusOnElement(target) is called in here so lets not callit 
        // above
        _bl_sel_down(event, el);
      }
    }
    else if (layout.canEdit(el))
    {
      bl_kb_focusOnElement(target);
      
      if (bl_port_isLeftDown(event))
      {
        var parent = bl_contain_getParent(el);

        if (!(bl_contain_getLayout(parent) != null && bl_port_contains(bl_contain_getBag(el), target, true)))
        {
          var childData = bl_contain_performSelect(el, target);
          
          if (childData.child)
          {
            var contextEl   = bl_contain_getcontextElement(el);
            var win         = bl_contain_getLiveWindow(el);
            var item        = childData.child;
            var childxy     = bl_sys_find_xy(item, null, false);
            var srcContext  = { source: contextEl,
                                item:item, 
                                did:win.cb_formId,
                                indexes:[childData.index], 
                                computeShadow:bl_contain_dragInner,
                                shadowOpacity:40,
                                dragEnd:bl_ctr_dragEnd, 
                                shadowPosition:bl_ctr_shadowDrag,
                                shadowUpdate:bl_ctr_shadowUpdate,
                                dragContext:childData.context,
                                dragOffsetX:event.screenX - (childxy.x + cb_sys_getScreenLeft()),
                                dragOffsetY:event.screenY - (childxy.y + cb_sys_getScreenTop()),
                                updateShadowBorder:true
                              };

            
            win.bl_dd_detect(event, srcContext);
            bl_ctr_setGridboundry(el, null)
            bl_ctr_setGridCell(el, null);
            bl_port_stop_event(event);
          }
        }
      }
      else
      {
        bl_port_stop_event(event);
      }
    }
  }
}

function _bl_ctr_enter(event, el)
{
  el = bl_port_computeEventEl(el);
  
  var layout = bl_contain_getLayout(el);
  
  if (bl_contain_isGridEdit(layout, el))
  {
    var current = window.bl_geo_currentGrid;
    
    if (current != el)
    {
      if (current)
      {
        bl_ctr_setGridboundry(current, null);
        bl_ctr_setGridCell(current, null);
      }
      
      window.bl_geo_currentGrid = el;
    }
    
    bl_port_stop_event(event);
  }
  else if (bl_contain_allowFlyOver(el))
  {
    _bl_sel_enter(event, el);
  }
}

function bl_contain_allowFlyOver(el)
{
  return (el.getAttribute("bl_selectType") == "flyover" || 
          bl_port_hasAttribute(el, "bl_selectOnFlyOver"));
}

function _bl_ctr_leave(event, el)
{
  el = bl_port_computeEventEl(el);

  var layout = bl_contain_getLayout(el);
  
  if (bl_contain_isGridEdit(layout, el))
  {
    // are we flying over one of the shuttle buttons
    if (bl_contain_is_edit_button(event, el))
    {
      bl_port_stop_event(event);
    }
    else
    {
      bl_ctr_setGridboundry(el, null);
      bl_ctr_setGridCell(el, null);
    }
  }
  else if (bl_contain_allowFlyOver(el))
  {
    _bl_sel_leave(event, el);
  }
}

function bl_contain_isGridEdit(layout, el)
{
  return layout && 
         layout.type == bl_contain_type_grid && 
         layout.canEdit(el);
}

function _bl_ctr_move(event, el)
{
  el = bl_port_computeEventEl(el);

  var layout = bl_contain_getLayout(el);
  
  if (bl_contain_isGridEdit(layout, el))
  {
    bl_contain_grid_mouse_move(event, el, layout);
  }
  else if (bl_contain_allowFlyOver(el))
  {
    _bl_sel_move(event, el);
  }
}

function bl_contain_removeAllChildren(container)
{
  if (container)
  {
    var layout   = bl_contain_getLayout(container);
    var clen     = layout.numChildren(container);
    var selected = bl_geo_getSelected();
    
    for (var i = 0; i < clen; i++)
    {
      var index = parseInt(list[i]);
      
      var child = layout.removeChild(container, index);
      
      if (child == selected.child || bl_port_contains(child, selected.parent, true))
      {
        selected.clear();
      }
    }
    
    bl_contain_resetSelects();
  }
}

function bl_contain_removeItem(container, indexes)
{
  if (container)
  {
    var list     = indexes.split(" ");
    var len      = list.length;
    var layout   = bl_contain_getLayout(container);
    var clen     = layout.numChildren(container);
    var selected = bl_geo_getSelected();
    
    for (var i = 0; i < len; i++)
    {
      var index = parseInt(list[i]);
      
      if (index >= 0 && index < clen)
      {
        var child = layout.removeChild(container, index);
        
        if (child == selected.child || bl_port_contains(child, selected.parent, true))
        {
          bl_geo_getSelected().clear();
        }
      }
    }
    
    bl_contain_resetSelects();
  }
}

function bl_contain_addItem(container, indexStr, content, script, context)
{
  if (container)
  {
    var layout = bl_contain_getLayout(container);
    var newEl  = layout.addChild(container, parseInt(indexStr), content, context);
    
    if (newEl)
    {
      if (script != "")
      {
        eval(script);
      }
      
      bl_contain_selectChild(container, newEl);
      layout = bl_contain_getLayout(newEl);
      
      if (layout)
      {
        layout.layoutBorder(newEl);
      }
    }
  }
}

function bl_contain_moveItem(container, oldIndexStr, newIndexStr)
{
  if (container)
  {
    var oldIndex  = parseInt(oldIndexStr);
    var newIndex  = parseInt(newIndexStr);
    var layout    = bl_contain_getLayout(container);
    
    layout.moveChild(container, oldIndex, newIndex)
    bl_contain_resetSelects();
  }
}

function bl_contain_focus(event)
{
  if (!event)
  {
    event = window.event;
  }
  
  var topParent = bl_contain_topParent();
  var body      = document.body;

  window.bl_has_focus = true;
  
  if (topParent.cb_select_bar_1)
  {
    var imgSrc = "/" + bl_version + "/res/img/bungee/form/control_highlight_on.gif";

    topParent.cb_select_bar_1.src = imgSrc;
    topParent.cb_select_bar_2.src = imgSrc;
    topParent.cb_select_bar_3.src = imgSrc;
    topParent.cb_select_bar_4.src = imgSrc;
    topParent.cb_select_bar_5.src = imgSrc;
    topParent.cb_select_bar_6.src = imgSrc;
    topParent.cb_select_bar_7.src = imgSrc;
    topParent.cb_select_bar_8.src = imgSrc;
  }
  
  if (window.bl_rulers)
  {
    window.bl_rulers.setFocus(true);
  }

  body.style.backgroundImage = "url(/" + bl_version + "/res/img/bungee/form/ruler/bkg_en.gif)";
}

function bl_contain_blur(event)
{
  if (!event)
  {
    event = window.event;
  }
  
  var topParent = bl_contain_topParent();
  var body      = document.body;

  window.bl_has_focus = false;
  
  if (topParent.cb_select_bar_1)
  {
    var imgSrc = "/" + bl_version + "/res/img/bungee/form/control_highlight_off.gif";

    topParent.cb_select_bar_1.src = imgSrc;
    topParent.cb_select_bar_2.src = imgSrc;
    topParent.cb_select_bar_3.src = imgSrc;
    topParent.cb_select_bar_4.src = imgSrc;
    topParent.cb_select_bar_5.src = imgSrc;
    topParent.cb_select_bar_6.src = imgSrc;
    topParent.cb_select_bar_7.src = imgSrc;
    topParent.cb_select_bar_8.src = imgSrc;
  }
  
  if (window.bl_rulers)
  {
    window.bl_rulers.setFocus(false);
  }

  body.style.backgroundImage = "url(/" + bl_version + "/res/img/bungee/form/ruler/bkg_di.gif)";
}

function bl_contain_createSelectArt()
{
  var body = bl_contain_topParent();
  
  if (!body.cb_select_1)
  {
    var imagHTMLHead = "<IMG style='position:absolute;z-index:5000;"    
                     + bl_port_compute_opacity_style(25, true)                        
                     + "' width=7 height=7 disabled=true src='/" 
                     + bl_version 
                     + "/res/img/button/container_select_en.gif' ";
                     
    var imagHTML  = imagHTMLHead;
    var imagHTML2  = imagHTMLHead + "/>";
    
    if (bl_browserInfo.ie)
    {
      imagHTML += "onmouseenter='_bl_contain_sel_enter(event, this)' onmouseleave='_bl_contain_sel_leave(event, this)' onmousemove='_bl_contain_sel_move(event, this, false)' onmouseup='_bl_contain_sel_up(event, this)' onmousedown='_bl_contain_sel_down(event, this)'/>";
    }
    else
    {
      imagHTML += "onmouseover='_bl_contain_sel_enter(event, this)' onmouseout='_bl_contain_sel_leave(event, this)' onmousemove='_bl_contain_sel_move(event, this, false)' onmouseup='_bl_contain_sel_up(event, this)' onmousedown='_bl_contain_sel_down(event, this)'/>";
    }

    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML2);
    body.cb_select_1 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML2);
    body.cb_select_2 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML2);
    body.cb_select_3 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_4 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_5 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_6 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML2);
    body.cb_select_7 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML2);
    body.cb_select_8 = body.lastChild;
    
    imagHTML = bl_sys_button_html("Bind",
                                  'img/bungee/form/popup/control_linked_',
                                  "Edit control bindings.",
                                  true,
                                  "_bl_contain_control_popup",
                                  " bl_sideCart bl_absorb_events width=12 height=12 style='position:absolute;z-index:2750;' ",
                                  false, 
                                  null);
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bind = body.lastChild;
    body.cb_select_bind.cb_popup_cleanup = bl_contain_bind_cleanup;
  
    var imgSrc = (window.bl_has_focus)? "/res/img/bungee/form/control_highlight_on.gif" : "/res/img/bungee/form/control_highlight_off.gif";  
    
    imagHTML = "<IMG style='position:absolute;z-index:5000; "  
             + bl_port_compute_opacity_style(50, true)         
             + "' width=7 height=7 src='/"
             + bl_version
             + imgSrc                                          
             + "'>";
    
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bar_1 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bar_2 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bar_3 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bar_4 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bar_5 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bar_6 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bar_7 = body.lastChild;
    bl_port_insertAdjacentHTML(body, "beforeend", imagHTML);
    body.cb_select_bar_8 = body.lastChild;
  }
}

function bl_contain_selectChild(el, childEl)
{
  bl_contain_createSelectArt()
  if (el && childEl)
  {
    var body   = bl_contain_topParent();
    var layout = bl_contain_getLayout(el);
    
    if ((layout && layout.type == bl_contain_type_absolute) || 
        childEl.getAttribute("bl_is_top") != null)
    {
      body.cb_select_4.style.cursor = "e-resize";
      body.cb_select_5.style.cursor = "se-resize";
      body.cb_select_6.style.cursor = "s-resize";
      
      body.cb_select_4.disabled     = false;
      body.cb_select_5.disabled     = false;
      body.cb_select_6.disabled     = false;

      bl_port_set_opacity(body.cb_select_4, 100);
      bl_port_set_opacity(body.cb_select_5, 100);
      bl_port_set_opacity(body.cb_select_6, 100);
    }
    else
    {
      body.cb_select_4.style.cursor = "default";
      body.cb_select_5.style.cursor = "default";
      body.cb_select_6.style.cursor = "default";

      body.cb_select_4.disabled     = true;
      body.cb_select_5.disabled     = true;
      body.cb_select_6.disabled     = true;

      bl_port_set_opacity(body.cb_select_4, 25);
      bl_port_set_opacity(body.cb_select_5, 25);
      bl_port_set_opacity(body.cb_select_6, 25);
    }
  }
  
  with (bl_geo_getSelected())
  {
    parent = el;
    child  = childEl;
  }
  
  bl_contain_resetSelects();
}

function bl_geo_clearSelection()
{
  this.parent = null;
  this.child  = null;
  bl_contain_resetSelects();
}

function bl_geo_validSelection()
{
  return (this.parent != null && this.child  != null);
}

function bl_geo_getSelected()
{
  var ret = window.bl_selected;
  
  if (!ret)
  {
    window.bl_selected = ret = { valid:bl_geo_validSelection,clear:bl_geo_clearSelection, parent:null, child:null };
  }
  
  return ret;
}

function bl_contain_set_bind_button(isBound)
{
  var but = bl_contain_topParent().cb_select_bind;
  
  if (but)
  {
    if (isBound)
    {
      var path = "/" + bl_version + "/res/img/bungee/form/popup/control_linked_";
      but.setAttribute("bl_imgRoot", path);
      but.src = path + "en.gif";
    }
    else
    {
      var path = "/" + bl_version + "/res/img/bungee/form/popup/control_unlinked_";
      but.setAttribute("bl_imgRoot", path);
      but.src = path + "en.gif";
    }
  }
}

function bl_contain_setPos(style, x, y)
{
  with (style)
  {
    display = "";
    left    = x + "px";
    top     = y + "px";
  }
}

function bl_contain_setPosSize(style, x, y, h, w)
{
  with (style)
  {
    display = "";
    left    = x + "px";
    top     = y + "px";
    width   = w + "px";
    height  = h + "px";
  }
}

function bl_contain_resetSelects()
{
  var topEl = bl_contain_topParent();
  
  if (!window.bl_rulers || !topEl.cb_select_1)
  {
    return ;
  }

  var child = bl_geo_getSelected().child;
  var pos   = null;
  
  bl_rulers.select(child);

  if (child)
  {
    if (bl_browserInfo.ie && child.style.position == "relative")
    {
      // When the child is relative, IE sometimes calculates the wrong size/position for
      // the element. This attempts to use a browser specific API to determine the actual
      // size/position of the element so the select hint can be put in the right place.
      var topPos    = bl_sys_find_xy(topEl, null, false);
      var childRect = child.getBoundingClientRect();
      pos = {
        x: childRect.left - topPos.x + topEl.scrollLeft,
        y: childRect.top - topPos.y  + topEl.scrollTop
      };
    }
    else
    {
      pos = bl_sys_find_xy(child, topEl, false);
    }
    
  }
  
  with (topEl)
  {
    if (pos)
    {
      var w     = child.offsetWidth;
      var h     = child.offsetHeight;
      var y     = pos.y;
      var x     = pos.x;
      var ow1   = 3;
      var ow2   = 4;
      var oh1   = 3;
      var oh2   = 4;
      
      if (w <= 14)
      {
        ow1  = 7;
        ow2  = 0;
      }
      if (h <= 14)
      {
        ow1  = 7;
        ow2  = 0;
      }
      
      var halfw = Math.floor(w/2);
      var halfh = Math.floor(h/2);
      
      bl_contain_setPos(cb_select_1.style, x - ow1,       y - oh1);
      bl_contain_setPos(cb_select_2.style, x + halfw - 3, y - oh1);
      bl_contain_setPos(cb_select_3.style, x + w - ow2,   y - oh1);
      bl_contain_setPos(cb_select_4.style, x + w - ow2,   y + halfh - 3);
      bl_contain_setPos(cb_select_5.style, x + w - ow2,   y + h - oh2);
      bl_contain_setPos(cb_select_6.style, x + halfw - 3, y + h - oh2);
      bl_contain_setPos(cb_select_7.style, x - ow1,       y + h - oh2);
      bl_contain_setPos(cb_select_8.style, x - ow1,       y + halfh - 3);
      
      bl_contain_setPosSize(cb_select_bar_1.style, 
                            x - ow1 + 7,       
                            y - oh1,       
                            oh1,                            
                            Math.max(halfw + ow1 - 10, 0));
      
      bl_contain_setPosSize(cb_select_bar_2.style, 
                            x + halfw - 3 + 7, 
                            y - oh1,       
                            oh1, 
                            Math.max((halfw - ow2 - 3), 0));
      
      bl_contain_setPosSize(cb_select_bar_3.style, 
                            x + w,             
                            y - oh1 + 7,   
                            Math.max(halfh + oh1 - 10, 0),
                            7 - ow2);
                            
      bl_contain_setPosSize(cb_select_bar_4.style, 
                            x + w,
                            y + halfh + 4, 
                            Math.max(halfh - oh2 - 3, 0),
                            7 - ow2);
                            
      bl_contain_setPosSize(cb_select_bar_5.style, 
                            x + halfw - 3 + 7, 
                            y + h,
                            7 - oh2, 
                            Math.max(halfw - ow2 - 3, 0));
                            
      bl_contain_setPosSize(cb_select_bar_6.style, 
                            x - ow1 + 7, 
                            y + h,
                            7 - oh2,
                            Math.max(halfw + ow1 - 10, 0));
                            
      bl_contain_setPosSize(cb_select_bar_7.style, 
                            x - ow1,
                            y - oh1 + 7,
                            Math.max(halfh + oh1 - 10, 0),
                            ow1);
                            
      bl_contain_setPosSize(cb_select_bar_8.style, 
                            x - ow1,
                            y + halfh + 4, 
                            Math.max(halfh - oh2 - 3, 0), 
                            ow1);
          
      if (child.getAttribute("cb_tag") != "CTR")
      {
        with (cb_select_bind.style)
        {
          display = "";
          left    = (x + w - 18)+"px";
          top     = (y  - 12)+"px";
        }
        
        bl_contain_set_bind_button(child.getAttribute("bl_bound") != null);
      }
      else
      {
        cb_select_bind.style.display = "none";
      }
    }
    else
    {
      cb_select_1.style.display        = "none";
      cb_select_2.style.display        = "none";
      cb_select_3.style.display        = "none";
      cb_select_4.style.display        = "none";
      cb_select_5.style.display        = "none";
      cb_select_6.style.display        = "none";
      cb_select_7.style.display        = "none";
      cb_select_8.style.display        = "none";
      cb_select_bar_1.style.display    = "none";
      cb_select_bar_2.style.display    = "none";
      cb_select_bar_3.style.display    = "none";
      cb_select_bar_4.style.display    = "none";
      cb_select_bar_5.style.display    = "none";
      cb_select_bar_6.style.display    = "none";
      cb_select_bar_7.style.display    = "none";
      cb_select_bar_8.style.display    = "none";
      cb_select_bind.style.display     = "none";
    }
  }
}

function _bl_contain_sel_enter(event, el)
{
  if (!el.bl_isDown)
  {
    el.src = "/" + bl_version + "/res/img/button/container_select_ov.gif";
  }
  el.bl_isIn = true;
}

function _bl_contain_sel_leave(event, el)
{
  if (!el.bl_isDown)
  {
    el.src = "/" + bl_version + "/res/img/button/container_select_en.gif";
  }
  el.bl_isIn = false;
}

function _bl_contain_sel_down(event, el)
{
  var child = bl_geo_getSelected();
  
  if (child && child.parent != document.body)
  {
    el.bl_isDown  = true;
    
    var screenLeft = cb_sys_getScreenLeft();
    var screenTop  = cb_sys_getScreenTop();
    
    bl_port_setCapture(el);
    
    el.src = "/" + bl_version + "/res/img/button/container_select_do.gif";
  }
  bl_port_stop_event(event);
}

function _bl_contain_sel_up(event, el)
{
  el = bl_port_computeEventEl(el);
  
  _bl_contain_sel_move(event, el, true);
  el.bl_isDown = false;
  el.src = "/" + bl_version + "/res/img/button/container_select_en.gif";
  bl_port_releaseCapture(el);
  bl_port_stop_event(event);
}

function _bl_contain_sel_move(event, el, doSend)
{
  el = bl_port_computeEventEl(el);
  
  if (el.bl_isDown)
  {
    var selected       = bl_geo_getSelected();
    var screenLeft     = cb_sys_getScreenLeft();
    var screenTop      = cb_sys_getScreenTop();
    
    var newTopLeft     = bl_sys_find_xy(selected.child, null, false);
    var parentTopLeft  = bl_sys_find_xy(selected.parent, null, false);

    var newLeft        = newTopLeft.x + screenLeft;
    var newTop         = newTopLeft.y + screenTop;
    var newRight       = newLeft + selected.child.offsetWidth;
    var newBottom      = newTop + selected.child.offsetHeight;
    
    var parentLeft     = parentTopLeft.x + screenLeft;
    var parentTop      = parentTopLeft.y + screenTop;
    
    var pos_x          = event.screenX;
    var pos_y          = event.screenY;
    var cur            = el.style.cursor;
    
    if (cur == "e-resize")
    {
      newRight  = pos_x;
      
      if (newRight < newLeft)
      {
        newRight = newLeft;
      }
    }
    else if (cur == "se-resize")
    {
      newRight  = pos_x;
      newBottom = pos_y;
      
      if (newRight < newLeft)
      {
        newRight = newLeft;
      }
      if (newBottom < newTop + 1)
      {
        newBottom = newTop + 1;
      }
    }
    else if (cur == "s-resize")
    {
      newBottom = pos_y;
      
      if (newBottom < newTop + 1)
      {
        newBottom = newTop + 1;
      }
    }

    var layout = bl_contain_getLayout(selected.parent);
    var style  = selected.child.style;
    var width  = newRight - newLeft;
    var height = newBottom - newTop;
    var left   = -1;
    var top    = -1;
    
    if (layout.type == bl_contain_type_absolute && selected.child != selected.parent)
    {
      var left   = newLeft - parentLeft;
      var top    = newTop - parentTop;
      style.left = left+"px";
      style.top  = top+"px";
    }
    
    if (selected.child.getAttribute("bl_is_top") != null && window.bl_rulers)
    {
      window.bl_rulers.setFormSize(width, height);
      window.setTimeout("_bl_contain_onscroll()", 10);
    }
    
    style.width  = width  + "px";
    style.height = height + "px";
    
    if (doSend)
    {
      var msg = "<setDim><containerId>"
              + selected.parent.id 
              + "</containerId><childId>"
              + selected.child.id     
              + "</childId>";
      
      if (style.position == "absolute")
      {
        msg += "<left>";
        msg += left;
        msg += "</left><top>";
        msg += top;
        msg += "</top>";
      }
      
      msg += "<width>";
      msg += width;
      msg += "</width><height>";
      msg += height;
      msg += "</height></setDim>";
      
      var liveWin = bl_contain_getLiveWindow(selected.parent);
      liveWin.bl_mpr_send(msg, liveWin.cb_controlContextId, 1, BL_MPR_SYNC);
    }
    
    if (selected.child.getAttribute("cb_tag") == "CTR")
    {
      bl_contain_layoutContainer(selected.child, false);
    }
    bl_contain_resetSelects();
  }
  
  bl_port_stop_event(event);
}

function bl_contain_clean_row_column_data(list)
{
  if (list)
  {
    var perList = list.cb_per_list;
    var len     = list.length;
    
    if (perList && perList.length > 0)
    {
      perList.splice(0, perList.length);
    }
    
    list.cb_per_list = null;
    list.splice(0, len);
  }
}

function bl_contain_clean_cell_artifacts(item)
{
  var b1 = item.bl_b1;
  var b2 = item.bl_b2;
  var wb = item.wallBar;
  
  if (b1)
  {
    b1.parentNode.removeChild(b1);
  }
  if (b2)
  {
    b2.parentNode.removeChild(b2);
  }
  if (wb)
  {
    wb.parentNode.removeChild(wb);
  }
  
  item.wallBar = null;
  item.bl_b1   = null;
  item.bl_b2   = null;
}

function bl_contain_clean_cell_data_artifacts(list)
{
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    bl_contain_clean_cell_artifacts(list[i]);
  }
}

function bl_contain_clean_cell_data(list)
{
  if (list)
  {
    bl_contain_clean_cell_data_artifacts(list);
    list.splice(0, list.length);
  }
}

function bl_contain_insertItem(list, item, index)
{
  list.splice(index, 0, item);
  list.cb_per_list = [];
  
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    var item = list[i];
    
    if (!item.isFixed)
    {
      list.cb_per_list.push(item);
    }
  }
}

function bl_contain_removeDataItem(list, index)
{
  var result  = list.splice(index, 1);
  var perList = list.cb_per_list;
  var item  = result[0];
  
  bl_contain_clean_row_column_data_atrifacts(item);
  
  if (perList)
  {
    var len = perList.length;
    
    for (var i = 0; i < len; i++)
    {
      if (item == perList[i])
      {
        perList.splice(i, 1);
        break;
      }
    }
  }
}

function bl_contain_insertColumnData(container, index)
{
  if (container)
  {
    var cols = bl_contain_getColumnData(container);
    
    if (index >= 0 && index <= cols.length)
    {
      bl_contain_insertItem(cols, new bl_contain_create_row_column_default(), index);
      bl_contain_insertColumn_patch(bl_contain_getCellData(container), index, cols.length - 1, bl_contain_getRowData(container).length);
    }
  }
}

function bl_contain_removeColumnData(container, item, index)
{
  if (container)
  {
    var cols   = bl_contain_getColumnData(container);
    
    bl_ctr_setGridCell(container, null);
    bl_ctr_setGridboundry(container, null);
    
    if (index >= 0 && index < cols.length)
    {
      bl_contain_removeDataItem(cols, index);
      
      var len   = cols.length;
      var cells = bl_contain_getCellData(container);
      var rows  = bl_contain_getRowData(container);
      
      // must pass in the old row length
      bl_contain_removeColumn_patch(cells, index, len + 1, rows.length);
    }
  }
}

function bl_contain_removeRowData(container, item, index)
{
  if (container)
  {
    var rows = bl_contain_getRowData(container);
    
    bl_ctr_setGridCell(container, null);
    bl_ctr_setGridboundry(container, null);
    
    if (index >= 0 && index < rows.length)
    {
      bl_contain_removeDataItem(rows, index);
      
      var len   = rows.length;
      var cells = bl_contain_getCellData(container);
      var cols  = bl_contain_getColumnData(container);
      
      // must pass in the old row length
      bl_contain_removeRow_patch(cells, index, len + 1, cols.length);
    }
  }
}

function bl_contain_insertRowData(container, rowIndex)
{
  if (container)
  {
    var rows = bl_contain_getRowData(container);
    
    if (rowIndex >= 0 && rowIndex <= rows.length)
    {
      bl_contain_insertItem(rows, new bl_contain_create_row_column_default(), rowIndex);
      bl_contain_insertRow_patch(bl_contain_getCellData(container), rowIndex, rows.length - 1, bl_contain_getColumnData(container).length);
    }
  }
}

function bl_contain_removeColumn_patch(cells, colIndex, colCount, rowCount)
{
  var rowIndex  = 0;
  var nextCol   = colIndex + 1;
  var checkNext = (nextCol < colCount);
  
  while (rowIndex < rowCount)
  {
    var rowPos = rowIndex * colCount;
    var item   = cells[rowPos + colIndex];
    
    if (item.childIndex == -2)
    {
      var rootItem = cells[(item.rowVal * colCount) + item.columnVal];
      rootItem.columnVal--;
      rowIndex = item.rowVal + rootItem.rowVal;
    }
    else 
    {
      if (checkNext && item.columnVal > 1)
      {
        var childItem = cells[rowPos + nextCol];
        
        childItem.childIndex  = -1;
        childItem.rowVal      = item.rowVal;
        childItem.columnVal   = item.columnVal - 1;
        childItem.colIndex    = colIndex;
        bl_contain_assignCellRefs(cells, rowIndex, rowIndex + childItem.rowVal, nextCol, nextCol + childItem.columnVal, colCount, rowIndex, nextCol);
      }
      
      rowIndex += item.rowVal;
    }
    bl_contain_clean_cell_artifacts(item);
  }

  if (checkNext)
  {  
    bl_contain_adjustToColIndex(nextCol, -1, cells);
  }

  for (rowIndex = rowCount - 1; rowIndex >= 0; rowIndex--)
  {
    cells.splice((rowIndex * colCount) + colIndex, 1);
  }
}

function bl_contain_insertColumn_patch(cells, colIndex, colCount, rowCount)
{
  var rowIndex = 0;
  
  if (colIndex >= 0 && colIndex < colCount)
  {
    while (rowIndex < rowCount)
    {
      var item = cells[(rowIndex * colCount) + colIndex];
      
      if (item.childIndex == -2)
      {
        var rRow     = item.rowVal;
        var rCol     = item.columnVal;
        var rootItem = cells[(rRow * colCount) + rCol];
        
        // need to set the row end to match what the root is before you
        // modify the root
        cellRowEnd = rowIndex + rootItem.rowVal;
        
        item.columnVal     = rootItem.columnVal - (colIndex - rCol);
        item.rowVal        = rootItem.rowVal;
        item.childIndex    = -1;
        rootItem.columnVal = colIndex - rCol;
        bl_contain_assignCellRefs(cells, rowIndex, rowIndex + item.rowVal, colIndex, colIndex + item.columnVal, colCount, rowIndex, colIndex);
        rowIndex = rRow + rootItem.rowVal;
      }
      else
      {
        rowIndex += item.rowVal;
      }
    }

    bl_contain_adjustToColIndex(colIndex, 1, cells);
  }
  
  for (rowIndex = rowCount - 1; rowIndex >= 0; rowIndex--)
  {
    var newCell = new bl_contain_create_cell_default();
    newCell.colIndex = colIndex;
    cells.splice((rowIndex * colCount) + colIndex, 0, newCell);
  }
}

function bl_contain_adjustToColIndex(index, offset, cellList)
{
  var len = cellList.length;

  for (var i = 0; i < len; i++)
  {
    var item = cellList[i];

    if (item.childIndex == -2 && item.columnVal >= index)
    {
      item.columnVal += offset;
    }
  }
}

function bl_contain_adjustToRowIndex(index, offset, cellList)
{
  var len = cellList.length;

  for (var i = 0; i < len; i++)
  {
    var item = cellList[i];

    if (item.childIndex == -2 && item.rowVal >= index)
    {
      item.rowVal += offset;
    }
  }
}

function bl_contain_removeRow_patch(cells, rowIndex, rowCount, colCount)
{
  var colIndex  = 0;
  var pos       = rowIndex * colCount;
  var nextRow   = rowIndex + 1;
  var checkNext = (nextRow < rowCount);
  
  while (colIndex < colCount)
  {
    var item = cells[pos + colIndex];
    
    if (item.childIndex == -2)
    {
      var rootItem = cells[(item.rowVal * colCount) + item.columnVal];
      rootItem.rowVal--;
      colIndex = item.columnVal + rootItem.columnVal;
    }
    else 
    {
      if (checkNext && item.rowVal > 1)
      {
        var childRowPos  = nextRow * colCount;
        var childItem    = cells[childRowPos + colIndex];
        
        childItem.childIndex  = -1;
        childItem.rowVal      = item.rowVal - 1;
        childItem.columnVal   = item.columnVal;
        childItem.rowIndex    = rowIndex;
        bl_contain_assignCellRefs(cells, nextRow, nextRow + childItem.rowVal, colIndex, colIndex + childItem.columnVal, colCount, nextRow, colIndex);
      }
      colIndex += item.columnVal;
    }
    bl_contain_clean_cell_artifacts(item);
  }
  
  if (checkNext)
  {
    bl_contain_adjustToRowIndex(nextRow, -1, cells);
  }
  
  cells.splice(rowIndex * colCount, colCount);
}

function bl_contain_assignCellRefs(cells, rowIndex, rowEnd, colIndex, colEnd, colCount, rowPointer, colPointer)
{
  var firstHit = false;
  
  for (var i = rowIndex; i < rowEnd; i++)
  {
    for (var j = colIndex; j < colEnd; j++)
    {
      if (firstHit)
      {
        var subCellItem  = cells[(i * colCount) + j];
        
        subCellItem.childIndex  = -2;
        subCellItem.rowVal      = rowPointer;
        subCellItem.columnVal   = colPointer;
      }
      else
      {
        firstHit = true;
      }
    }
  }
}

function bl_contain_insertRow_patch(cells, rowIndex, rowCount, colCount)
{
  var pos = rowIndex * colCount;
  
  if (rowIndex >= 0 && rowIndex < rowCount)
  {
    var colIndex = 0;
    
    while (colIndex < colCount)
    {
      var item  = cells[pos + colIndex];
      
      if (item.childIndex == -2)
      {
        var rRow     = item.rowVal;
        var rCol     = item.columnVal;
        var rootItem = cells[(rRow * colCount) + rCol];
        
        item.columnVal  = rootItem.columnVal;
        item.rowVal     = rootItem.rowVal - (rowIndex - rRow);
        item.childIndex = -1;
        rootItem.rowVal = rowIndex - rRow;
        bl_contain_assignCellRefs(cells, rowIndex, rowIndex + item.rowVal, colIndex, colIndex + item.columnVal, colCount, rowIndex, colIndex);
        colIndex = rCol + rootItem.columnVal;
      }
      else
      {
        colIndex += item.columnVal;
      }
    }

    bl_contain_adjustToRowIndex(rowIndex, 1, cells);
  }
  
  for (colIndex = 0; colIndex < colCount; colIndex++)
  {
    var newCell = new bl_contain_create_cell_default();
    newCell.rowIndex = rowIndex;
    cells.splice(pos + colIndex, 0, newCell);
  }
}

function bl_contain_setGridData(container, cellData, rowData, columnData)
{
  if (container)
  {
    var layout = bl_contain_getLayout(container);
    
    layout.cleanup(container);
    
    container.setAttribute("bl_rows", rowData);
    container.setAttribute("bl_cols", columnData);
    container.setAttribute("bl_cells", cellData);
    
    bl_contain_recomputeDims(container);
    bl_contain_rebuild_seps(container);
    bl_contain_layoutContainer(container, true);
    bl_contain_resetSelects();
  }
}

function bl_contain_wallAction(container, name, rowIndex, colIndex, posIndex)
{
  if (container)
  {
    var cells = bl_contain_getCellData(container);
    var cols  = bl_contain_getColumnData(container);
    var rows  = bl_contain_getRowData(container);
    
    if (name == "BreakRowWall")
    {
      bl_contain_grid_handleBreakRowWall(container, cells, rows, cols, rowIndex, colIndex);
    }
    else if (name == "BreakColWall")
    {
      bl_contain_grid_handleBreakColWall(container, cells, rows, cols, rowIndex, colIndex);
    }
    else if (name == "RepairRowWall")
    {
      bl_contain_grid_handleRepairRowWall(container, cells, rows, cols, rowIndex, colIndex, posIndex);
    }
    else if (name == "RepairColWall")
    {
      bl_contain_grid_handleRepairColWall(container, cells, rows, cols, rowIndex, colIndex, posIndex);
    }


    var current = container.cb_current_boundry;
    
    if (current)
    {
      bl_contain_showBoundry(current, container);
    }

    bl_contain_rebuild_seps(container);
    bl_contain_resetSelects();
  }
}

function bl_contain_ChildStyleSet(childId, val)
{
  var child = document.getElementById(childId);
  
  if (child)
  {
    var parent = bl_contain_getParent(child);
    child.style.cssText = val;
    
    if (parent)
    {
      var layout = bl_contain_getLayout(parent);
      
      if (layout && layout.type < bl_contain_type_vertical)
      {
        bl_contain_checkForAutoSize(child);
      }
    }
  }
}

function bl_contain_ChildReset(childId, val, script)
{
  var child = document.getElementById(childId);
  
  if (child)
  {
    var selected   = bl_geo_getSelected();
    var parent     = bl_contain_getParent(child);
    var selectedID = (selected.child)? selected.child.id:null;
    var newChild   = null;
    
    if (parent.getAttribute("cb_tag") == "CTR")
    {
      var layout = bl_contain_getLayout(parent);
      newChild   = layout.childReset(parent, child, val);
    }
    else if (parent && (parent == document.body || parent.id == "bl_layout_parent"))
    {
      bl_port_insertAdjacentHTML(child, "beforebegin", val);
      newChild = child.previousSibling;
      child.parentNode.removeChild(child);
    }
    
    if (script != "")
    {
      eval(script);
    }

    if (newChild.getAttribute("cb_tag") == "CTR")
    {
      var layout = bl_contain_getLayout(newChild);
      layout.layoutBorder(newChild);
    }
    
    if (selectedID)
    {
      var selectedItem = document.getElementById(selectedID);
      
      if (selectedItem)
      {
        var parentEl = bl_contain_getParent(selectedItem);
        
        parent = (parentEl.getAttribute("cb_tag") == "CTR") ? parentEl : newChild;
        bl_contain_selectChild(parent, selectedItem);
      }
      else
      {
        bl_geo_getSelected().clear();
      }
    }
  }
}

function bl_contian_set_vals(list, count, valList, index, isRow)
{
  var plist = [];

  list.cb_per_list = plist;
  
  for (var i = 0; i < count; i++)
  {
    var item = list[i];
    
    item.size      = parseInt(valList[index]);
    index++;
    item.position  = parseInt(valList[index]);
    index++;
    item.pixelSize = parseInt(valList[index]);
    index++;
    
    var fixedVal = valList[index];
    
    item.isFixed   = (fixedVal == "f" || fixedVal == "F"); 
    item.isLocked  = (fixedVal == "F" || fixedVal == "P");
    
    index++;
    
    if (!item.isFixed)
    {
      plist.push(item);
    }
  }
  return index;
}

function bl_contain_extractGridGeo(container, valList, index)
{
  var cells     = bl_contain_getCellData(container);
  var rows      = bl_contain_getRowData(container);
  var cols      = bl_contain_getColumnData(container);
  var rowCount  = rows.length;
  var colCount  = cols.length;
  var inedit    = (container.getAttribute("bl_inEdit") != null);

  index = bl_contian_set_vals(rows, rowCount, valList, index, true);  
  index = bl_contian_set_vals(cols, colCount, valList, index, false);  
    
  for (var i = 0; i < rowCount; i ++)
  {
    bl_contain_place_row_seps(rows[i], cols);
    
    for (var j = 0; j < colCount; j++)
    {
      var cell  = cells[(i * colCount) + j];
      
      if (i == 0)
      {
        bl_contain_place_col_seps(cols[j], rows);
      }
      
      if (inedit)
      {
        bl_ctr_gridPositionCell(container, rows, cols, cell, i, j);
      }
    }
  }
  return index;
}

function bl_contain_set_row_column_sizes(container, val)
{
  var valList = val.split(";");
  var index   = 0;
  bl_contain_extractGridGeo(container, valList, index);

  var layout = bl_contain_getLayout(container);
  
  if (layout)
  {
    bl_contain_layoutContainer(container, true);
  }
  bl_contain_resetSelects();
  
}


function bl_contain_ChildResetGeo(childId, val)
{
  var child = document.getElementById(childId);
  
  if (child)
  {
    var currentEditor = child;
    var valList       = val.split(";");
    var index         = 0;
    var style;
    var layout;
    var nextChild;
     
    try 
    {
      if (currentEditor.getAttribute("bl_is_top") != null && window.bl_rulers)
      {
        window.bl_rulers.setFormSize(parseInt(valList[2]), parseInt(valList[3]));
        window.setTimeout("_bl_contain_onscroll()", 10);
      }

      do
      {
        with (currentEditor.style)
        {
          // DO NOT!!!! set the 'px' posfix on  these as
          // the server is doing it for us.
          
          left   = valList[index];
          index++;
          top    = valList[index];
          index++;
          width  = valList[index];
          index++;
          height = valList[index];
          index++;
        }
                
        layout = bl_contain_getLayout(currentEditor);
        
        if (layout)
        {
          layout.layoutBorder(currentEditor);
          if (layout.type != bl_contain_type_horzBox && layout.type != bl_contain_type_vertBox)
          {
            if (layout.type == bl_contain_type_grid)
            {
              index = bl_contain_extractGridGeo(currentEditor, valList, index);
            }
            
            currentEditor = currentEditor.firstChild;
          }
          else if (currentEditor == child)
          {
            // if this is the original child then there is 
            // no more procesing we need to do
            break ;
          }
        }
        else 
        {
          bl_contain_procChildResize(child);
          
          if (currentEditor == child)
          {
            // if this is the original child then there is 
            // no more procesing we need to do
            break ;
          }
        }
        
        nextChild = currentEditor.nextSibling;
        
        while (!nextChild)
        {
          currentEditor = currentEditor.parentNode;
          nextChild = (currentEditor == child)? currentEditor:currentEditor.nextSibling;
        }
        
        currentEditor = nextChild;
        
      } while(currentEditor != child);
    }
    catch (exception)
    {
      window.alert("layout mismatch!");
    }   

    bl_contain_resetSelects();
  
    if (bl_contain_isFormEditor())
    {
      var parent = bl_contain_getParent(child);
      layout = bl_contain_getLayout(parent);
      
      if (layout && layout.type <= bl_contain_type_vertical)
      {
        bl_contain_checkForAutoSize(parent);
      }
    }  
  }
}

function bl_contain_set_limits(childId, val)
{
  var child = document.getElementById(childId);
  
  if (child)
  {
    var valList = val.split(" ");
    
    if (valList.length >= 6)
    {
      child.setAttribute("bl_max_h",  valList[0]);
      child.setAttribute("bl_min_h",  valList[1]);
      child.setAttribute("bl_height", valList[2]);
      child.setAttribute("bl_max_w",  valList[3]);
      child.setAttribute("bl_min_w",  valList[4]);
      child.setAttribute("bl_width",  valList[5]);
    }
  }
}

function bl_contain_childPathChanged(childId, val, title)
{
  var child = document.getElementById(childId);
  
  if (child)
  {
    var isBound = (val == "bound");
    
    if (isBound)
    {
      child.setAttribute("bl_bound", true);
    }
    else
    {
      child.removeAttribute("bl_bound");
    }
    
    child.title = title;
    
    if (child == bl_geo_getSelected().child)
    {
      bl_contain_set_bind_button(isBound);
    }
  }
}

function bl_contain_setOV(container, val)
{
  if (container)
  {
    var list  = val.split(" ");
    var len   = list.length;
    var style = container.style;
    
    var overflowVal  = "";
    var overflowXVal = "";
    var overflowYVal = "";
    
    for (var i = 0; i < len; i++)
    {
      var sname = list[i];
      
      if (sname == "overflow")
      {
        overflowVal = list[i + 1];
        i++;
      }
      else if (sname == "overflowX")
      {
        overflowXVal = list[i + 1];
        i++;
      }
      else if (sname == "overflowY")
      {
        overflowYVal = list[i + 1];
        i++;
      }
    }
    
    with (container.style)
    {
      if (overflowVal != "")
      {
        overflow  = overflowVal;
        
        if (bl_browserInfo.ie)
        {
          overflowX = overflowY = "";
        }
      }
      else
      {
        overflowX = overflowXVal;
        overflowY = overflowYVal;

        if (bl_browserInfo.ie)
        {
          overflow = "";
        }
      }
    }
        
    bl_contain_resetSelects();
  }
}

function bl_contain_setFlow(container, val)
{
  if (container && container.getAttribute("bl_layout_type") != val)
  {
    container.setAttribute("bl_layout_type", val);
    
    var layout     = el.bl_layout;
    var dimensions = "";
    
    
    // only need to comput child positions if the new flow is absolute.
    if (val == bl_contain_type_absolute)
    {
      var len = layout.numChildren(el);
      
      for (var i = 1; i < len; i++)
      {
        var child = layout.getChild(child, i);
        
        dimensions += child.offsetLeft + " " + child.offsetTop + " " + child.offsetWidth + " " + child.offsetHeight;
        
        if (i < len - 1)
        {
          dimensions += ";";
        }
      }
    }
    
    if (layout)
    {
      layout.cleanup(container);
    }
    el.bl_layout = null;
    layout.cleanUp(container);      
    layout = bl_contain_getLayout(container);
    layout.adjustToFlow(container);
    
    var msg = "<setFlow><containerId>"   +
              container.id               +
              "</containerId><width>"    +
              container.offsetWidth      +
              "</width><height>"         +
              container.offsetHeight     +
              "</height><dimList>"       +
              dimensions                 +
              "</dimList><flow>"         +
              val                        +
              "</flow></setFlow>";
    
    
    var win = bl_contain_getLiveWindow(container);
    win.bl_mpr_send(msg, win.cb_controlContextId, 1, BL_MPR_SYNC);
    bl_contain_resetSelects();
  }
}

function bl_contain_buildList(el, str, itemCreateFunc)
{
  var list = [];
  
  if (str)
  {
    var strItemList = str.split(";");
    var len         = strItemList.length;
    
    for (var i = 0; i < len; i++)
    {
      var item = new itemCreateFunc(list, strItemList[i]);
      list.push(item);
    }
  }
  
  return list;
}

function bl_contain_create_row_column_default()
{
  this.size       = 0;
  this.pixelSize  = 0;
  this.margin1    = 0;
  this.margin2    = 0;
  this.margin1Set = false;
  this.margin2Set = false;
  this.marginSize = 0;
  this.isFixed    = false;
  this.separator  = false;
  this.colapsed   = false;
}

function bl_contain_setMargins(container, str)
{
  var strList = str.split(" ");
  var index   = parseInt(strList[0]);
  var list    = (strList[1] == "t")? bl_contain_getRowData(container):bl_contain_getColumnData(container);
  var item    = list[index];
  item.margin1    = parseInt(strList[2]);
  item.margin2    = parseInt(strList[3]);
  item.margin1Set = strList[4] == "t";
  item.margin2Set = strList[5] == "t";
  item.marginSize = item.margin1 + item.margin2;
}

function bl_contain_procInnerMargins(list, val, margin1Set, margin2Set)
{
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    var item = list[i];

    if (i == 0)
    {
      item.margin2    = val;
      item.margin2Set = margin2Set;
      item.marginSize = item.margin1 + item.margin2;
    }
    else if (i = len - 1)
    {
      item.margin2    = val;
      item.margin2Set = margin2Set;
      item.marginSize = item.margin1 + item.margin2;
      item.margin1    = val;
      item.margin1Set = margin1Set;
      item.marginSize = item.margin1 + item.margin2;
    }
    else
    {
      item.margin1    = val;
      item.margin1Set = margin1Set;
      item.marginSize = item.margin1 + item.margin2;
    }
  }
}

function bl_contain_setInnerMargins(container, str)
{
  var strList    = str.split(" ");
  var val        = parseInt(strList[0]);
  var leftSet    = strList[1] == "t";
  var rightSet   = strList[2] == "t";
  var topSet     = strList[3] == "t";
  var bottomSet  = strList[4] == "t";
  // row vs. column is the 6th element in the set.
  if (strList[5] == "t")
  {
    bl_contain_procInnerMargins(bl_contain_getRowData(container), val, topSet, bottomSet);
  }
  else
  {
    bl_contain_procInnerMargins(bl_contain_getColumnData(container), val, leftSet, rightSet);
  }
}

function bl_contain_setOuterMargins(container, str)
{
  var rows   = bl_contain_getRowData(container);
  var cols   = bl_contain_getColumnData(container);
  var rowLen = rows.length;
  var colLen = cols.length;

  if (rowLen > 0 && colLen > 0)
  {
    var strList    = str.split(" ");
    var val        = parseInt(strList[0]);
    var leftSet    = strList[1] == "t";
    var rightSet   = strList[2] == "t";
    var topSet     = strList[3] == "t";
    var bottomSet  = strList[4] == "t";
    
    var rowFirst = rows[0];
    var rowLast  = rows[rowLen - 1];
    var colFirst = cols[0];
    var colLast  = cols[colLen - 1];

    rowFirst.margin1    = val;
    rowFirst.margin1Set = leftSet;
    rowFirst.marginSize = rowFirst.margin1 + rowFirst.margin2;
    rowLast.margin2    = val;
    rowLast.margin2Set = rightSet;
    rowLast.marginSize = rowLast.margin1 + rowLast.margin2;

    colFirst.margin1    = val;
    colFirst.margin1Set = topSet;
    colFirst.marginSize = rowFirst.margin1 + rowFirst.margin2;
    colLast.margin2     = val;
    colLast.margin2Set  = bottomSet;
    colLast.marginSize  = rowLast.margin1 + rowLast.margin2;

  }
}

function bl_contain_create_row_column_data(list, str)
{
  var strList     = str.split(" ");
  var stretchType = strList[3];
  
  this.size       = parseInt(strList[0]);
  this.margin1    = parseInt(strList[1]);
  this.margin2    = parseInt(strList[2]);
  this.marginSize = this.margin1 + this.margin2;
  this.isFixed    = (stretchType == "f" || stretchType == "F");
  this.isLocked   = (stretchType == "F" || stretchType == "P");
  this.separator  = strList[4] == "t";
  this.colapsed   = strList[5] == "t";
  this.margin1Set = strList[6] == "t";
  this.margin2Set = strList[7] == "t";
  this.pixelSize  = parseInt(strList[8]);
  
  if (!this.isFixed)
  {
    if (!list.cb_per_list)
    {
      list.cb_per_list = [];
    }
    list.cb_per_list.push(this);
  }
}

function bl_contain_create_cell_default()
{
  this.childIndex = -1;
  this.rowVal     = 1;
  this.columnVal  = 1;
  this.vAlign     = "m";
  this.hAlign     = "c";
}

function bl_contain_create_cell_data(cellList, str)
{
  var list = str.split(" ");
  
  this.childIndex = parseInt(list[0]);
  this.rowVal     = parseInt(list[1]);
  this.columnVal  = parseInt(list[2]);
  this.vAlign     = list[3];
  this.hAlign     = list[4];
}

function bl_contain_compute_dims(size, list)
{
  var len      = list.length;
  var perList  = list.cb_per_list;
  var i;
  
  for (i = 0; i < len; i++)
  {
    var item = list[i];
    
    if (item.colapsed)
    {
      item.pixelSize = 0;
    }
    else if (item.isFixed)
    {
      item.pixelSize  = item.size;
      size           -= item.size;
    }
  }
  
  var perSize = Math.max(size, 0);
  
  size *= GRID_ROUNDOF_FACTOR;
  
  var perActual     = 0;
  var colapsedCount = 0;
  
  if (perList && perList.length > 0)
  {
    var perlen = perList.length;
    
    if (perlen > 0)
    {
      for (i = 0; i < perlen; i++)
      {
        var item = perList[i];
        
        if (item.colapsed)
        {
          colapsedCount++;
        }
        else
        {
          var val         = (size * item.size)/100;
          item.pixelSize  = Math.max(Math.floor(val/GRID_ROUNDOF_FACTOR), 0);
          perActual      += item.pixelSize;
        }
      }
      var diff     = perSize - perActual;
      var modifier = (diff > 0) ? 1 : -1;
      
      diff = Math.abs(diff);
      i = 0;
      
      if (perlen > colapsedCount)
      {
        while (diff > 0)
        {
          perList[i].pixelSize += modifier;
          
          i++;
          
          if (i >= perlen)
          {
            i = 0;
          }
          
          diff--;
        }
      }
    }
  }
  
  bl_contain_compute_pos(list, len);
}

function bl_contain_compute_pos(list, len)
{
  var currentPos = 0;
  
  for (i = 0; i < len; i++)
  {
    var item = list[i];
    
    item.position = currentPos;
    currentPos += item.pixelSize;
  }
}

function bl_contain_recomputeDims(el)
{
  bl_contain_compute_dims(el.clientHeight, bl_contain_getRowData(el));
  bl_contain_compute_dims(el.clientWidth, bl_contain_getColumnData(el));
}

function bl_contain_computeIndex(item, list)
{
  var len = list.length;
  
  for (var i = 0; i < len; i ++)
  {
    var data = list[i];
    
    if (data == item)
    {
      return i;
    }
  }
  
  return -1;
}

function bl_contain_bind_cleanup(el)
{
  el.bl_popup_up = false;
  if (el.bl_mouseIsIn)
  {
    cb_sys_img_buildSrc(el, "ov");
  }
  else
  {
    cb_sys_img_buildSrc(el, "en");
  }
  bl_sys_img_thaw(el);
}

function _bl_contain_control_popup(event, el)
{
  var selected = bl_geo_getSelected()
  
  if (!el.bl_popup_up && selected.valid() && selected.child.getAttribute("cb_tag") != "CTR")
  {
    var win = bl_contain_getLiveWindow(selected.parent);
    var mpr = win.bl_sys_get_mpr();
    
    bl_sys_img_freeze(el);
    
    if (mpr)
    {
      var context = new cb_sys_popup_context(el, event, "form-popup", true);
      
      var msg     = "<popup><controlId>"                
                  + selected.child.id
                  + "</controlId><popupId>"
                  + context.id
                  + "</popupId></popup>";
      
      el.bl_popup_up = true;
      win.bl_mpr_send(msg, win.cb_controlContextId, 1000);
      mpr.setPopupContext(context, true);
    }
  }
}

function _bl_contain_wall_action(event, el)
{
  if (el.bl_props)
  {
    var props      = el.bl_props
    var container  = el.parentNode.parentNode;
    var name       = props.contextStr;
    var rowIndex   = props.rowIndex;
    var colIndex   = props.colIndex;
    var posIndex   = props.index;
    
    var msg = "<layout><containerId>"
              + container.id
              + "</containerId><cmd>wallCMD</cmd><wall><"
              + name
              + ">" 
              + rowIndex 
              + " " 
              + colIndex;
    
    if (posIndex >= 0)
    {
      msg += (" " + posIndex);
    }
              
    msg += ("</" + name + "></wall></layout>");
    
    var win = bl_contain_getLiveWindow(container);
    win.bl_mpr_send(msg, win.cb_controlContextId, 1);
    bl_contain_wallAction(container, name, rowIndex, colIndex, posIndex);
  }
}

function bl_contain_rebuild_seps(el)
{
  var cols      = bl_contain_getColumnData(el);
  var rows      = bl_contain_getRowData(el);
  var cells     = bl_contain_getCellData(el);
  var bag       = bl_contain_getBag(el);
  var colCount  = cols.length;
  var rowCount  = rows.length;
  var i;
  
  for (i = 0; i < rowCount; i++)
  {
    var row = rows[i];
    bl_contain_rebuild_sep_row(el, bag, row, i, rowCount, colCount, cells);
    bl_contain_place_row_seps(row, cols);
  }
  
  for (i = 0; i < colCount; i++)
  {
    var col = cols[i];
    bl_contain_rebuild_sep_col(el, bag, col, i, rowCount, colCount, cells);
    bl_contain_place_col_seps(col, rows);
  }
}

function bl_contain_rebuild_sep_row(el, bag, item, index, rowCount, colCount, cells)
{
  bl_contain_clean_up_sep(item);
  
  if (item.separator)
  {
    bl_contain_build_up_row_sep(el, bag, item, index, rowCount, colCount, cells);
  }
}

function bl_contain_rebuild_sep_col(el, bag, item, index, rowCount, colCount, cells)
{
  bl_contain_clean_up_sep(item);
  
  if (item.separator)
  {
    bl_contain_build_up_col_sep(el, bag, item, index, rowCount, colCount, cells);
  }
}

function bl_contain_sepProcess(data)
{
  if (data)
  {
    var container = data.container; 
    var item      = data.item; 
    var index     = data.index; 

    bl_ctr_setGridCell(container, null);
    
    if (index >= 0)
    {
      var cols   = bl_contain_getColumnData(container);
      var rows   = bl_contain_getRowData(container);
      var cells  = bl_contain_getCellData(container);
      var sepVal = !item.separator;
      
      item.separator  = sepVal;
      
      if (item.separator)
      {
        var bag = bl_contain_getBag(container);
        
        bl_contain_get_drag_img(container, bag);
        
        if (data.isRow)
        {
          bl_contain_build_up_row_sep(container, bag, item, index, rows.length, cols.length, cells);
        }
        else
        {
          bl_contain_build_up_col_sep(container, bag, item, index, rows.length, cols.length, cells);
        }
      }
      else
      {
        bl_contain_clean_up_sep(item);
      }
      
      var msg = "<layout><containerId>"                     
              + container.id                                    
              + "</containerId><cmd>setSeparator</cmd><index>"  
              + index                                           
              + "</index><val>"                                 
              + sepVal                                          
              + "</val><type>"                                  
              + data.typeName                       
              + "</type></layout>";
      
      var win = bl_contain_getLiveWindow(container);
      win.bl_mpr_send(msg, win.cb_controlContextId, 1);
      bl_contain_layoutContainer(container, true);
    }
  }
}

function bl_contain_lockProcess(data)
{
  if (data)
  {
    var container = data.container; 
    var item      = data.item; 
    var index     = data.index; 
    var popupEl   = data.el;
    
    bl_ctr_setGridCell(container, null);
    
    if (index >= 0)
    {
      var cols  = bl_contain_getColumnData(container);
      var rows  = bl_contain_getRowData(container);
      var cells = bl_contain_getCellData(container);
      var val   = !item.isLocked;
      
      item.isLocked  = val;

      var itemsizer = popupEl.nextSibling;

      if (val)
      {
        bl_sys_disable(itemsizer);
      }
      else
      {
        bl_sys_enable(itemsizer);
      }
      
      if (index > 0)
      {
        var prevProps = popupEl.previousSibling.bl_props;
        
        if (val)
        {
          prevProps.upperBound = 100000;
          prevProps.nextLocked = true;
          prevProps.currentPosRight  = item.pixelSize;
        }
        else
        {
          prevProps.upperBound = prevProps.origUpperBound;
          prevProps.nextLocked = false;
          prevProps.currentPosRight  = prevProps.currentOrigPosRight;
        }
      }
      
      var msg = "<layout><containerId>"               
              + container.id                              
              + "</containerId><cmd>setLock</cmd><index>" 
              + index                                     
              + "</index><val>"                           
              + val                                       
              + "</val><type>"                            
              + data.typeName                 
              + "</type></layout>";
      
      var win = bl_contain_getLiveWindow(container);
      win.bl_mpr_send(msg, win.cb_controlContextId, 1);
      bl_contain_layoutContainer(container, true);
    }
  }
}

function bl_contain_processCMD(cmd, container, type, index, item)
{
  if (type == "Row")
  {
    if (cmd == "R")
    {
      bl_contain_removeRowData(container, item, index);
      bl_contain_reset_popup_context(bl_contain_getRowData(container), index);
    }
    else if (cmd == "IA")
    {
      bl_contain_insertRowData(container, index + 1)
      bl_contain_reset_popup_context(bl_contain_getRowData(container), index + 1);
    }
    else if (cmd == "IB")
    {
      bl_contain_insertRowData(container, index)
      bl_contain_reset_popup_context(bl_contain_getRowData(container), index);
    }
  }
  else
  {
    if (cmd == "R")
    {
      bl_contain_removeColumnData(container, item, index);
      bl_contain_reset_popup_context(bl_contain_getColumnData(container), index);
    }
    else if (cmd == "IA")
    {
      bl_contain_insertColumnData(container, index + 1)
      bl_contain_reset_popup_context(bl_contain_getColumnData(container), index + 1);
    }
    else if (cmd == "IB")
    {
      bl_contain_insertColumnData(container, index)
      bl_contain_reset_popup_context(bl_contain_getColumnData(container), index);
    }
  }
  bl_contain_rebuild_seps(container);
}

function bl_contin_set_cell_align(el, rows, cols, cell, i, j, isHAlign, val)
{
  if (isHAlign)
  {
    cell.hAlign = val
  }
  else
  {
    cell.vAlign = val
  }
  
  if (cell.childIndex >= 0)
  {
    var child = el.childNodes[cell.childIndex + 1];
    bl_contain_grid_place_child(el, rows, cols, cell, child, i, j);
    bl_contain_layoutChild(child, true);
  }
}

function bl_contain_setAlign(val, data)
{
  if (data)
  { 
    var isRow      = data.isRow;
    var container  = data.container;
    var item       = data.item;
    var index      = data.index
    var isHAlign   = (val == "l"  || val == "c" || val == "r");
    var cells      = bl_contain_getCellData(container);
    var rows       = bl_contain_getRowData(container);
    var cols       = bl_contain_getColumnData(container);
    var rowCount   = rows.length;
    var colCount   = cols.length;
    
    if (isRow)
    {
      var rowPos = index * colCount;
      
      for (var i = 0; i < colCount; i++)
      {
        bl_contin_set_cell_align(container, rows, cols, cells[rowPos + i], index, i, isHAlign, val);
      }
    }
    else
    {
      for (var i = 0; i < rowCount; i++)
      {
        bl_contin_set_cell_align(container, rows, cols, cells[(i * colCount) + index], i, index, isHAlign, val);
      }
    }
    
    bl_contain_resetSelects();
    
    var msg = "<layout><containerId>"                         +
              container.id                                    +
              "</containerId><cmd>setAlignment</cmd><index>"  +
              index                                           +
              "</index><isRow>"                               +
              isRow                                           +
              "</isRow><isHAlign>"                            +
              isHAlign                                        +
              "</isHAlign><val>"                              +
              val                                             +
              "</val></layout>";
    
    var win = bl_contain_getLiveWindow(container);
    win.bl_mpr_send(msg, win.cb_controlContextId, 1);
  }
}

function bl_contain_sizeChange(val)
{
  var data = bl_contain_getDialogData();
  
  if (data)
  {
    var container = data.container;
    var msg = "<layout><containerId>"
            + container.id
            + "</containerId><cmd>setItemSize</cmd><index>"
            + data.index
            + "</index><isRow>"                        
            + data.isRow
            + "</isRow><val>"                                
            + val                                            
            + "</val></layout>";
    var win = bl_contain_getLiveWindow(container);
    
    win.bl_mpr_send(msg, win.cb_controlContextId, 1, BL_MPR_SYNC);
    bl_contain_row_col_hilite_show(container, data.item, data.isRow);
  }
}

function bl_contain_sizeTypeChange(container, list, size, item, index, isRow)
{
  item.isFixed  = !item.isFixed;
  
  if (bl_contain_compute_new_sizes(list, size))
  {
    bl_contain_layoutContainer(container, true);
  }
  
  bl_contain_send_sizes(container, list, isRow, index, item.isFixed);
}

function bl_contain_setCellAlign(val)
{
  var data = bl_contain_getOverlayData();
  
  if (data)
  {
    var container = data.container;
    var rowIndex  = data.rowIndex;
    var colIndex  = data.colIndex;
    var rows      = bl_contain_getRowData(container);
    var cols      = bl_contain_getColumnData(container);
    var cells     = bl_contain_getCellData(container);
    var rowCount  = rows.length;
    var colCount  = cols.length;
    
    if (rowIndex >= 0 && rowIndex < rowCount &&
        colIndex >= 0 && colIndex < colCount)
    {
      var cell     = cells[(rowIndex * colCount) + colIndex];
      var isHAlign = (val == "l" || val == "c" || val == "r");
      
      bl_contin_set_cell_align(container, rows, cols, cell, rowIndex, colIndex, isHAlign, val);
      bl_contain_resetSelects();
        
      var msg = "<layout><containerId>"                                +
                container.id                                           +
                "</containerId><cmd>setCellAlignment</cmd><rowIndex>"  +
                rowIndex                                               +
                "</rowIndex><colIndex>"                                +
                colIndex                                               +
                "</colIndex><isHAlign>"                                +
                isHAlign                                               +
                "</isHAlign><val>"                                     +
                val                                                    +
                "</val></layout>";
      
      var win = bl_contain_getLiveWindow(container);
      win.bl_mpr_send(msg, win.cb_controlContextId, 1);
    }
  }
}

function _bl_contain_action(el, container, item, index, cmd, isRow, type)
{
  var list;
  var size;
  
  bl_ctr_setGridCell(container, null);
  
  if (index >= 0)
  {
    if (isRow)
    {
      list = bl_contain_getRowData(container);
      size = container.offsetHeight;
    }
    else
    {
      list = bl_contain_getColumnData(container);
      size = container.offsetWidth;
    }
    
    if (cmd == "W")
    {
      bl_contain_sizeTypeChange(container, list, size, item, index, isRow);
    }
    else
    {
      bl_contain_processCMD(cmd, container, type, index, item);
      var msg = "<layout><containerId>" +
                container.id            +
                "</containerId><cmd>"   +
                type                    +
                cmd                     +
                "</cmd><index>"         +
                index                   +
                "</index></layout>";
      
      var win = bl_contain_getLiveWindow(container);
      win.bl_mpr_send(msg, win.cb_controlContextId, 1, BL_MPR_SYNC);
    }
  }
}

function bl_contain_sendMargin(isLeft, value)
{
  var data = bl_contain_getDialogData();
  
  if (data)
  {
    var container = data.container;
    var win     = bl_contain_getLiveWindow(container);
    var context = "<layout><cmd>setMargin</cmd><containerId>"
                  + container.id
                  + "</containerId><isRow>"
                  + ((data.isRow) ? "t" : "f")
                  + "</isRow><index>"
                  + data.index
                  + "</index><isLeft>"
                  + ((isLeft) ? "t" : "f")
                  + "</isLeft><val>"
                  + value
                  + "</val></layout>";
                  
                  
    win.bl_mpr_send(context, win.cb_controlContextId, 1, BL_MPR_SYNC);
    bl_contain_row_col_hilite_show(container, data.item, data.isRow)
  }
}

function bl_contain_sendSetMargins(type, value)
{
  var data = bl_contain_getDialogData();
  
  if (data)
  {
    var container = data.container;
    var win     = bl_contain_getLiveWindow(container);
    var context = "<layout><cmd>"
                  + type
                  + "</cmd><containerId>"
                  + container.id
                  + "</containerId><val>"
                  + value
                  + "</val></layout>";
                  
                  
    win.bl_mpr_send(context, win.cb_controlContextId, 1, BL_MPR_SYNC);
  }
}

function bl_contain_collect_cells(el)
{
  if (!el.bl_cells_collected)
  {
    var cells    = bl_contain_getCellData(el);
    var bag      = bl_contain_getBag(el);
    var colCount = bl_contain_getColumnData(el).length
    var list     = bag.childNodes;
    var len      = list.length;
    var clen     = cells.length;
    
    for (var i = 0; i < len; i++)
    {
      var child = list[i];

      if (!bl_port_isTextNode(child))
      {
        var id = child.getAttribute("bl_cell_id");
        
        if (id)
        {
          var idList = id.split(" ");
          var index  = (parseInt(idList[1]) * colCount) + parseInt(idList[2]);
          
          if (index >= 0 && index < clen)
          {
            var cellItem = cells[index];
            
            if (idList[0] == "r")
            {
              cellItem.bl_b2 = child;
            }
            else
            {
              cellItem.bl_b1 = child;
            }
          }
        }
      }
    }
    el.bl_cells_collected = true;
  }
}

function bl_contain_collect_seps(type, list, bag)
{
  var len   = list.length;
  var clist = bag.childNodes;
  var clen  = clist.length;
  
  for (var i = 0; i < len; i++)
  {
    var item = list[i];
    
    if (item.separator)
    {
      item.sepList = [];
      
      for (var j = 0; j < clen; j++)
      {
        var cel  = clist[j];
        var typeVal = cel.getAttribute(type);
        
        if (typeVal && parseInt(typeVal) == i)
        {
          item.sepList.push(cel);
        }
      }
    }
  }
}

function bl_contain_getRowData(el)
{
  if (!el.cb_rowList)
  {
    var bag = bl_contain_getBag(el);
    
    el.cb_rowList = bl_contain_buildList(el, el.getAttribute("bl_rows"), bl_contain_create_row_column_data);
    bl_contain_compute_pos(el.cb_rowList, el.cb_rowList.length);
    bl_contain_collect_seps("bl_row", el.cb_rowList, bag);
  }
  return el.cb_rowList;
}

function bl_contain_getCellData(el)
{
  if (!el.cb_cellList)
  {
    el.cb_cellList = bl_contain_buildList(el, el.getAttribute("bl_cells"), bl_contain_create_cell_data);
  }
  return el.cb_cellList;
}

function bl_contain_getColumnData(el)
{
  if (!el.cb_colList)
  {
    var bag = bl_contain_getBag(el);
    
    el.cb_colList = bl_contain_buildList(el, el.getAttribute("bl_cols"), bl_contain_create_row_column_data);
    bl_contain_compute_pos(el.cb_colList, el.cb_colList.length);
    bl_contain_collect_seps("bl_col", el.cb_colList, bag);
  }
  return el.cb_colList;
}

function bl_contain_find_boundry(el, list, pos, isRow)
{
  var len        = list.length - 1;
  var boundryPos = 0;
  
  for (var i = 0; i < len; i++)
  {
    var item = list[i];
    
    boundryPos += item.pixelSize;
    
    if (pos >= boundryPos - 4 && pos <= boundryPos + 8)
    {
      item.index          = i;
      item.cb_lower_bound = boundryPos - item.pixelSize;
      item.cb_upper_bound = boundryPos + list[i + 1].pixelSize;
      item.isRow          = isRow;
      item.cb_boundryPos  = boundryPos;
      return item;
    }
  }
  
  return null;
}

function bl_contain_grid_handleBreakRowWall(el, cells, rows, cols, rowIndex, colIndex)
{
  var colCount    = cols.length;
  var index       = (rowIndex * colCount) + colIndex;
  var cellCount   = cells.length;
  
  if (index >= 0 && index < cellCount)
  {
    var cell         = cells[index];
    var aRowIndex    = rowIndex + cell.rowVal;
    var adjacentCell = cells[(aRowIndex * colCount) + colIndex];
    
    if (adjacentCell.childIndex >= 0)
    {
      cell.childIndex = adjacentCell.childIndex;
    }
    
    var rowLen = rowIndex + adjacentCell.rowVal + cell.rowVal;
    var colLen = colIndex + cell.columnVal;
    
    cell.rowVal += adjacentCell.rowVal;
    for (var i = aRowIndex; i < rowLen; i++)
    {
      for (var j = colIndex; j < colLen; j++)
      {
        var item        = cells[(i * colCount) + j];
        item.childIndex = -2;
        item.rowVal     = rowIndex;
        item.columnVal  = colIndex;
        bl_contain_clean_cell_artifacts(item);
      }
    }
    
    if (cell.childIndex >= 0)
    {
      // account for the artifact bag that is always generated to the container
      var cindex = cell.childIndex + 1;
      var child  = el.childNodes[cindex];
      
      bl_contain_grid_place_child(el, rows, cols, cell, child, rowIndex, colIndex);
      bl_contain_layoutChild(child, false);
    }
    bl_ctr_gridPositionCell(el, rows, cols, cell, rowIndex, colIndex);
  }
}

function bl_contain_grid_handleBreakColWall(el, cells, rows, cols, rowIndex, colIndex)
{
  var colCount    = cols.length;
  var index       = (rowIndex * colCount) + colIndex;
  var cellCount   = cells.length;
  
  if (index >= 0 && index < cellCount)
  {
    var cell         = cells[index];
    var aColIndex    = colIndex + cell.columnVal;
    var adjacentCell = cells[(rowIndex * colCount) + aColIndex];
    
    if (adjacentCell.childIndex >= 0)
    {
      cell.childIndex = adjacentCell.childIndex;
    }
    
    var colLen = colIndex + adjacentCell.columnVal + cell.columnVal;
    var rowLen = rowIndex + cell.rowVal;
    
    cell.columnVal += adjacentCell.columnVal;
    for (var i = rowIndex; i < rowLen; i++)
    {
      for (var j = aColIndex; j < colLen; j++)
      {
        var item = cells[(i * colCount) + j];
        item.childIndex = -2;
        item.rowVal     = rowIndex;
        item.columnVal  = colIndex;
        bl_contain_clean_cell_artifacts(item);
      }
    }
    
    if (cell.childIndex >= 0)
    {
      // account for the artifact bag that is always generated to the container
      var cindex = cell.childIndex + 1;
      var child  = el.childNodes[cindex];
      
      bl_contain_grid_place_child(el, rows, cols, cell, child, rowIndex, colIndex);
      bl_contain_layoutChild(child, false);
    }
    bl_ctr_gridPositionCell(el, rows, cols, cell, rowIndex, colIndex);
  }
}

function bl_contain_grid_handleRepairRowWall(el, cells, rows, cols, rowIndex, colIndex, rowPos)
{
  var colCount  = cols.length;
  var index     = (rowIndex * colCount) + colIndex;
  var cellCount = cells.length;
  
  if (index >= 0 && index < cellCount)
  {
    var aRowIndex = rowPos + 1;
    var cell      = cells[index];
    var acell     = cells[(aRowIndex * colCount) + colIndex];
    var rowLen    = rowIndex + cell.rowVal;
    var colLen    = colIndex + cell.columnVal;
    
    acell.childIndex  = -1;
    acell.rowVal      = rowLen - aRowIndex;
    acell.columnVal   = cell.columnVal;
    cell.rowVal       = aRowIndex - rowIndex;
    
    for (var i = aRowIndex; i < rowLen; i++)
    {
      for (var j = colIndex; j < colLen; j++)
      {
        if (i != aRowIndex || j != colIndex)
        {
          var childCell = cells[(i * colCount) + j];
          
          childCell.childIndex = -2;
          childCell.rowVal     = aRowIndex;
          childCell.columnVal  = colIndex;
          bl_contain_clean_cell_artifacts(childCell);
        }
      }
    }
    
    if (cell.childIndex >= 0)
    {
      // account for the artifact bag that is always generated to the container
      var cindex = cell.childIndex + 1;
      var child  = el.childNodes[cindex];
      
      bl_contain_grid_place_child(el, rows, cols, cell, child, rowIndex, colIndex);
      bl_contain_layoutChild(child, false);
    }
    bl_ctr_gridPositionCell(el, rows, cols, acell, aRowIndex, colIndex);
    bl_ctr_gridPositionCell(el, rows, cols, cell, rowIndex, colIndex);
  }
}

function bl_contain_grid_handleRepairColWall(el, cells, rows, cols, rowIndex, colIndex, colPos)
{
  var colCount    = cols.length;
  var index       = (rowIndex * colCount) + colIndex;
  var cellCount   = cells.length;
  
  if (index >= 0 && index < cellCount)
  {
    var aColIndex = colPos + 1;
    var cell      = cells[index];
    var acell     = cells[(rowIndex * colCount) + aColIndex];
    var rowLen    = rowIndex + cell.rowVal;
    var colLen    = colIndex + cell.columnVal;
    
    acell.childIndex  = -1;
    acell.rowVal      = cell.rowVal;
    acell.columnVal   = (colIndex + cell.columnVal) - aColIndex;
    cell.columnVal    = aColIndex - colIndex;
    
    for (var i = rowIndex; i < rowLen; i++)
    {
      for (var j = aColIndex; j < colLen; j++)
      {
        if (i != rowIndex || j != aColIndex)
        {
          var childCell = cells[(i * colCount) + j];
          
          childCell.childIndex   = -2;
          childCell.rowVal       = rowIndex;
          childCell.columnVal    = aColIndex;
        }
      }
    }
    
    if (cell.childIndex >= 0)
    {
      // account for the artifact bag that is always generated to the container
      var cindex = cell.childIndex + 1;
      var child  = el.childNodes[cindex];
      
      bl_contain_grid_place_child(el, rows, cols, cell, child, rowIndex, colIndex);
      bl_contain_layoutChild(child, false);
    }
    bl_ctr_gridPositionCell(el, rows, cols, acell, rowIndex, aColIndex);
    bl_ctr_gridPositionCell(el, rows, cols, cell, rowIndex, colIndex);
  }
}

function bl_ctr_gridDim(list, index, span)
{
  var dim = 0;
  var len = index + span;
  
  for (var i = index; i < len; i++)
  {
    dim += list[i].pixelSize;
  }
  
  return dim;
}

function bl_contain_grid_compute_wall_buttons_row(el, item, index)
{
  var cells     = bl_contain_getCellData(el);
  var rows      = bl_contain_getRowData(el);
  var cols      = bl_contain_getColumnData(el);
  var rowCount  = rows.length;
  var colCount  = cols.length;
  var rowPos    = index * colCount;
  var i         = 0;
  
  while (i < colCount)
  {
    var cell   = cells[rowPos + i];
    var offset = bl_contain_grid_compute_repair_row(el, cells, cell, colCount, item, index, i);
    
    if (offset == 0)
    {
      offset = bl_contain_grid_compute_break_row(el, cells, cell, colCount, item, index, i);
    }
    
    i += offset;
  }
}

function bl_contain_grid_compute_break_row(el, cells, cellItem, colCount, item, rowIndex, colIndex)
{
  var adjacentRow  = rowIndex + 1;
  var adjacentCol  = colIndex;
  var adjacentCell = cells[(adjacentRow * colCount) + adjacentCol];
  
  if (cellItem.childIndex == -2)
  {
    rowIndex = cellItem.rowVal;
    colIndex = cellItem.columnVal;
    cellItem = cells[(rowIndex * colCount) + colIndex];
  }
  
  if (adjacentCell.childIndex == -2)
  {
    adjacentRow  = adjacentCell.rowVal;
    adjacentCol  = adjacentCell.columnVal;
    adjacentCell = cells[(adjacentRow * colCount) + adjacentCol];
  }
  
  if (adjacentCell.columnVal == cellItem.columnVal  &&
      adjacentCol == colIndex                       &&
      !(adjacentCell.childIndex >= 0 && cellItem.childIndex >= 0))
  {
    var wallBar = bl_contain_get_cell_boudry_artifacts(el, cellItem, false, true);
    
    wallBar.bl_props = { isrow:true,
                         rowIndex:rowIndex,
                         colIndex:colIndex,
                         index:-1,
                         contextStr:"BreakRowWall",
                         span:cellItem.columnVal,
                         dimIndex:colIndex
                       };

    item.boudryList.push(wallBar);
    
    return cellItem.columnVal;
  }
  return 1;
}

function bl_contain_grid_compute_break_col(el, cells, cellItem, colCount, item, rowIndex, colIndex)
{
  var adjacentRow   = rowIndex;
  var adjacentCol   = colIndex + 1;
  var adjacentCell  = cells[(adjacentRow * colCount) + adjacentCol];
  
  if (cellItem.childIndex == -2)
  {
    rowIndex = cellItem.rowVal;
    colIndex = cellItem.columnVal;
    cellItem = cells[(rowIndex * colCount) + colIndex];
  }
  
  if (adjacentCell.childIndex == -2)
  {
    adjacentRow  = adjacentCell.rowVal;
    adjacentCol  = adjacentCell.columnVal;
    adjacentCell = cells[(adjacentRow * colCount) + adjacentCol];
  }
  
  if (adjacentCell.rowVal == cellItem.rowVal  &&
      adjacentRow == rowIndex                 &&
      !(adjacentCell.childIndex >= 0 && cellItem.childIndex >= 0))
  {
    var wallBar = bl_contain_get_cell_boudry_artifacts(el, cellItem, false, false);
    
    wallBar.bl_props = { isrow:true,
                         rowIndex:rowIndex,
                         colIndex:colIndex,
                         index:-1,
                         contextStr:"BreakColWall",
                         span:cellItem.rowVal,
                         dimIndex:rowIndex
                       };

    item.boudryList.push(wallBar);
    return cellItem.rowVal;
  }
 
  return 1;
}

function bl_contain_getRulerTooltip1()
{
  var topEl = bl_contain_topParent();
  var ret   = topEl.bl_ruler_tooltip1;
  
  if (ret == undefined)
  {
    ret = document.getElementById("bl_ruler_tooltip1");
    
    if (!ret)
    {
      var div = "<div id='bl_ruler_tooltip1' style='display:none;' class='ruler_tooltip' ></div>";
                
      bl_port_insertAdjacentHTML(topEl, "afterbegin", div);
      ret = topEl.firstChild;
    }
    topEl.bl_ruler_tooltip1 = ret;
  }
  
  return ret;
}

function bl_contain_getRulerTooltip2()
{
  var topEl = bl_contain_topParent();
  var ret   = topEl.bl_ruler_tooltip2;
  
  if (ret == undefined)
  {
    ret = document.getElementById("bl_ruler_tooltip2");
    
    if (!ret)
    {
      var div = "<div id='bl_ruler_tooltip2' style='display:none;' class='ruler_tooltip' ></div>";
                
      bl_port_insertAdjacentHTML(topEl, "afterbegin", div);
      ret = topEl.firstChild;
    }
    topEl.bl_ruler_tooltip2 = ret;
  }
  
  return ret;
}

function bl_contain_getRulerHilight()
{
  var topEl = bl_contain_topParent();
  var ret   = topEl.bl_ruler_boundryArtifact;
  
  if (!ret)
  {
    ret = document.getElementById("bl_ruler_boundryArtifact");
    
    if (!ret)
    {
      var div = "<div id='bl_ruler_boundryArtifact' style='display:none;' class='border_line_div_hilight' ><img src='/" 
                + bl_version 
                + "/res/img/bungee/form/horiz_wall_ov.gif' style='display:block'/></div>";
                
      bl_port_insertAdjacentHTML(topEl, "afterbegin", div);
      ret = topEl.firstChild;
    }
    
    topEl.bl_ruler_boundryArtifact = ret;
  }
  
  return ret;
}

function bl_contain_get_cell_boudry_artifacts(el, cell, isRepair, isRow)
{
  if (!cell.wallBar)
  {
    var bag      = bl_contain_getBag(el);
    var attr     = " bl_absorb_events width='1px' height='1px' style='position:absolute;z-index:3500;display:none;' ";
    var barHTML  = bl_sys_button_html("BoundryButton", 'img/button/add_item_', "", true, "_bl_contain_wall_action", attr, false, null);
    
    bl_port_insertAdjacentHTML(bag, "afterbegin", barHTML);
    cell.wallBar = bag.firstChild;
  }
  
  var button  = cell.wallBar;
  var imgName;
  
  
  if (isRow)
  {
    imgName       = (isRepair) ? 'img/bungee/form/add_horiz_wall_' : 'img/bungee/form/delete_horiz_wall_';
    button.width  = 15;
    button.height = 9;
  }
  else
  {
    imgName       = (isRepair) ? 'img/bungee/form/add_vert_wall_' : 'img/bungee/form/delete_vert_wall_';
    button.width  = 9;
    button.height = 15;
  }
 
  var path = "/" + bl_version + "/res/" + imgName; 
  button.setAttribute("bl_imgRoot", path);
  button.src = path + 'en.gif'
  
  return cell.wallBar;
}

function bl_contain_grid_compute_repair_row(el, cells, cellItem, colCount, item, rowIndex, colIndex)
{
  var rowPosIndex = rowIndex;
  
  if (cellItem.childIndex == -2)
  {
    rowIndex = cellItem.rowVal;
    colIndex = cellItem.columnVal;
    cellItem = cells[(rowIndex * colCount) + colIndex];
  }
  
  if (rowIndex + cellItem.rowVal > rowPosIndex + 1)
  {
    var wallBar = bl_contain_get_cell_boudry_artifacts(el, cellItem, true, true);
    
    wallBar.bl_props = { isrow:true,
                         rowIndex:rowIndex,
                         colIndex:colIndex,
                         index:rowPosIndex,
                         contextStr:"RepairRowWall",
                         span:cellItem.columnVal,
                         dimIndex:colIndex
                       };
    
    item.boudryList.push(wallBar);
    return cellItem.columnVal;
  }
  
  return 0;
}

function bl_contain_grid_compute_repair_col(el, cells, cellItem, colCount, item, rowIndex, colIndex)
{
  var colPosIndex = colIndex;
  
  if (cellItem.childIndex == -2)
  {
    rowIndex = cellItem.rowVal;
    colIndex = cellItem.columnVal;
    cellItem = cells[(rowIndex * colCount) + colIndex];
  }
  
  if (colIndex + cellItem.columnVal > colPosIndex + 1)
  {
    var wallBar = bl_contain_get_cell_boudry_artifacts(el, cellItem, true, false);
    
    wallBar.bl_props = { isrow:true,
                         rowIndex:rowIndex,
                         colIndex:colIndex,
                         index:colPosIndex,
                         contextStr:"RepairColWall",
                         span:cellItem.rowVal,
                         dimIndex:rowIndex
                       };

    item.boudryList.push(wallBar);
    return cellItem.rowVal;
  }
  
  return 0;
}

function bl_contain_grid_compute_wall_buttons_column(el, item, index)
{
  var cells     = bl_contain_getCellData(el);
  var rows      = bl_contain_getRowData(el);
  var cols      = bl_contain_getColumnData(el);
  var rowCount  = rows.length;
  var colCount  = cols.length;
  var i         = 0;
  
  while (i < rowCount)
  {
    var cell   = cells[(i * colCount) + index];
    var offset = bl_contain_grid_compute_repair_col(el, cells, cell, colCount, item, i, index);
    
    if (offset == 0)
    {
      offset = bl_contain_grid_compute_break_col(el, cells, cell, colCount, item, i, index);
    }
    
    i += offset;
  }
}

function bl_ctr_setGridboundry(el, item)
{
  var current = el.cb_current_boundry;
  
  if (item != current)
  {
    if (current)
    {
      bl_contain_hideBoundry(current, el);
    }
    
    el.cb_current_boundry = item;
    
    if (item)
    {
      bl_ctr_setGridCell(el, null);
      bl_contain_showBoundry(item, el);
    }
  }
}

function bl_contain_found_row_column_boundry(container, x, y)
{
  var boundryItem1 = bl_contain_find_boundry(container, bl_contain_getRowData(container), y, true);
  var boundryItem2 = bl_contain_find_boundry(container, bl_contain_getColumnData(container), x, false);
  var item         = null;
  
  if (boundryItem1 && boundryItem2)
  {
    if (boundryItem1 == container.cb_current_boundry)
    {
      item = boundryItem1;
    }
    else if (boundryItem2 == container.cb_current_boundry)
    {
      item = boundryItem2;
    }
    else
    {
      item = boundryItem1;
    }
  }
  else
  {
    item = (boundryItem1) ? boundryItem1 : boundryItem2;
  }

  if (item)
  {
    bl_ctr_setGridboundry(container, item);
  }
  
  return item;
}

function bl_ctr_findCell(el, cellList, x, y)
{
  var rows        = bl_contain_getRowData(el);
  var cols        = bl_contain_getColumnData(el);
  var rowCount    = rows.length;
  var colCount    = cols.length;
  var rowIndex    = -1;
  var colIndex    = -1;
  var currentPosX = 0;
  var currentPosY = 0;
  var currentPosH = 0;
  var currentPosW = 0;
  var i;
  
  for (i = 0; i < rowCount; i++)
  {
    currentPosH = rows[i].pixelSize;
    
    if (y < currentPosY + currentPosH)
    {
      rowIndex = i;
      break ;
    }
    currentPosY += currentPosH;
  }
  
  currentPos = 0;
  
  for (i = 0; i < colCount; i++)
  {
    currentPosW = cols[i].pixelSize;
    
    if (x < currentPosX + currentPosW)
    {
      colIndex = i;
      break ;
    }
    currentPosX += currentPosW;
  }
  
  if (colIndex >= 0 && rowIndex >= 0)
  {
    i = (rowIndex * colCount) + colIndex;
    
    if (i < cellList.length)
    {
      var cell = cellList[i];
      
      if (cell.childIndex == -2)
      {
        rowIndex = cell.rowVal;
        colIndex = cell.columnVal;
        cell     = cellList[(rowIndex * colCount) + colIndex];
      }
      
      cell.isLastRow = (rowIndex == rowCount - 1);
      cell.isLastCol = (colIndex == colCount - 1);
      cell.rowIndex  = rowIndex;
      cell.colIndex  = colIndex;
      cell.x         = bl_ctr_gridDim(cols, 0, colIndex);
      cell.y         = bl_ctr_gridDim(rows, 0, rowIndex);
      cell.width     = bl_ctr_gridDim(cols, colIndex, cell.columnVal);
      cell.height    = bl_ctr_gridDim(rows, rowIndex, cell.rowVal);
      return cell;
    }
  }
  
  return null;
}

function bl_contain_cellShow(item, container)
{
  var rowIndex = item.rowIndex; 
  var colIndex = item.colIndex;
  var rows     = bl_contain_getRowData(container);
  var cols     = bl_contain_getColumnData(container);
  
  if (rowIndex >= 0 && rowIndex < rows.length &&
      colIndex >= 0 && colIndex < cols.length)
  {
    var topEl    = bl_contain_topParent();
    var elTop    = bl_sys_real_y(container, topEl, false);
    var elLeft   = bl_sys_real_x(container, topEl, false);
    var row      = rows[rowIndex];
    var col      = cols[colIndex];
    var body     = bl_contain_topParent();
    var bCell    = body.cb_cell_button;
    var cells    = bl_contain_getCellData(container);
    
    if (!bCell)
    {
      var imageHTML = bl_sys_button_html("CELLALIGNMENT",
                                         'img/bungee/form/popup/align_flyout_button_',
                                         "Edit Cell Attributes",
                                         true,
                                         "_bl_contain_cellOverlay",
                                          " bl_sideCart bl_absorb_events width=10 height=10 style='position:absolute;z-index:2750;' ",
                                          false, 
                                          null);
      
      bl_port_insertAdjacentHTML(body, "beforeend", imageHTML);
      bCell = body.cb_cell_button = body.lastChild;
    }
    
    var cell    = cells[(rowIndex * cols.length) + colIndex];
    var cwidth  = bl_ctr_gridDim(cols, colIndex, cell.columnVal);
    var cheight = bl_ctr_gridDim(rows, rowIndex, cell.rowVal);
    
    with (bCell.style)
    {
      left     = (elLeft + col.position + cwidth - ((cwidth > 30) ? 27 : 13))+"px";
      top      = (elTop + row.position + cheight - 13)+"px";
      display  = "";
    }
    
    bCell.bl_props = { container:container, 
                       rowIndex:rowIndex, 
                       colIndex:colIndex, 
                       left:elLeft + col.position, 
                       width:cwidth, 
                       top:elTop + row.position, 
                       height:cheight
                     };
  }
}

function bl_contain_cellHide(el)
{
  var bCell = bl_contain_topParent().cb_cell_button;
  
  if (bCell)
  {
    bCell.style.display = "none";
    bCell.bl_props      = null;
  }
}

function bl_contain_sep_genSeparatorImg(bag, list, type, index, start, count, cursorStr, imgStr)
{
  var img = "<img style='position:absolute;cursor:" 
            + cursorStr 
            + "' src='" 
            + imgStr
            + "' " 
            + type 
            + "=" 
            + index 
            + " bl_count=" 
            + count 
            + " bl_start=" 
            + start 
            + " onmousedown='_bl_contain_sep_down(event, this)' onmousemove='_bl_contain_sep_move(event, this)' onmouseup='_bl_contain_sep_up(event, this)' ";

  if (bl_browserInfo.ie)
  {
    img += " onmouseleave='_bl_contain_sep_leave(event, this);' onmouseenter='_bl_contain_sep_enter(event, this);'";
  }
  else
  {
    img += " onmouseout='_bl_contain_sep_leave(event, this);' onmouseover='_bl_contain_sep_enter(event, this);'";
  }
  
  img += "/>";
  
  bl_port_insertAdjacentHTML(bag, "afterbegin", img);
  list.push(bag.firstChild);
}

function bl_contain_get_drag_img(el, bag)
{
  var ret = bag.bl_sep_drag_img;
  
  if (!ret)
  {
    var html = "<img class='bl_container_sep_img' src='/" + bl_version + "/res/img/blank.gif'>";
    
    bl_port_insertAdjacentHTML(bag, "afterbegin", html);
    ret = bag.bl_sep_drag_img = bag.firstChild;
  }
  
  return ret;
}

function bl_contain_compute_boundries(sep, el, container)
{
  var indexStr = sep.getAttribute("bl_row");
  
  if (indexStr != null)
  {
    var index = parseInt(indexStr);
    var rows  = bl_contain_getRowData(container);
    
    if (index >= 0 && index < rows.length - 1)
    {
      var item1   = rows[index];
      var item2   = rows[index + 1];
      var sepList = item1.sepList;
      
      if (sepList && sepList.length > 0)
      {
        var img1  = sepList[0];
        var img2  = sepList[sepList.length - 1];
        var style = el.style;
        
        el.src            = bl_contain_sep_get(container, true);
        el.bl_is_vert     = false;
        el.bl_lower_bound = item1.position + 3;
        el.bl_upper_bound = item2.position + item2.pixelSize - 3;
        
        with (el.style)
        {
          left   = img1.offsetLeft+"px";
          width  = ((img2.offsetLeft - img1.offsetLeft) + img2.offsetWidth)+"px";
          top    = img1.offsetTop+"px";
          height = "6px";
          cursor = "row-resize";
        }
        
        el.bl_index = index;
        return true
      }
    }
  }
  else
  {
    indexStr = sep.getAttribute("bl_col");
    
    if (indexStr != null)
    {
      var index = parseInt(indexStr);
      var cols  = bl_contain_getColumnData(container);
      
      if (index >= 0 && index < cols.length - 1)
      {
        var item1   = cols[index];
        var item2   = cols[index + 1];
        var sepList = item1.sepList;
        
        if (sepList && sepList.length > 0)
        {
          var img1  = sepList[0];
          var img2  = sepList[sepList.length - 1];
          var style = el.style;
          
          el.src            = bl_contain_sep_get(container, false);
          el.bl_is_vert     = true;
          el.bl_lower_bound = item1.position + 3;
          el.bl_upper_bound = item2.position + item2.pixelSize - 3;

          with (el.style)
          {
            left   = img1.offsetLeft+"px";
            width  = "6px";
            top    = img1.offsetTop+"px";
            height = ((img2.offsetTop - img1.offsetTop) + img2.offsetHeight)+"px";
            cursor = "col-resize";
          }
          
          el.bl_index = index;
          return true
        }
      }
    }
  }
  
  return false;
}

function bl_contain_sep_get(el, isRow)
{
  var ret = "";
  
  if (isRow)
  {
    ret = el.getAttribute("h_ov");
    
    if (ret == "")
    {
      ret = el.getAttribute("h_en")
    }
  }
  else
  {
    ret = el.getAttribute("v_ov");
    
    if (ret == "")
    {
      ret = el.getAttribute("v_en")
    }
  }
  
  return ret;
}

function _bl_contain_sep_leave(event, el)
{
  if (el.getAttribute("bl_active") != null && !el.bl_down)
  {
    var container = el.parentNode.parentNode;
    var isRow     = el.getAttribute("bl_row") != null;
    
    el.bl_in = false;
    el.src = (isRow)? container.getAttribute("h_en"):container.getAttribute("v_en");
  }
}

function _bl_contain_sep_enter(event, el)
{
  if (el.getAttribute("bl_active") != null)
  {
    var container = el.parentNode.parentNode;
    var isRow     = el.getAttribute("bl_row") != null;
    
    el.bl_in = true;
    el.src = bl_contain_sep_get(container, isRow);
  }
}

function _bl_contain_sep_down(event, el)
{
  if (el.getAttribute("bl_active") != null)
  {
    var container = el.parentNode.parentNode;
    var image     = bl_contain_get_drag_img(container, bl_contain_getBag(container));
    
    if (bl_contain_compute_boundries(el, image, container))
    {
      el.bl_down  = true;
      bl_port_setCapture(el);
      
      if (bl_browserInfo.firefox || bl_browserInfo.safari)
      {
        bl_port_coverDialog();
      }      
      bl_port_killEvent(event);
    }
  }
}

function bl_contain_sep_compute_pos(container, image, isVert, event)
{
  var win = bl_port_docWindow(container.ownerDocument);

  if (isVert)
  {
    var containX   = bl_sys_find_x(container, null, false);
    var screenLeft = bl_port_getScreenLeft(win);
    var x          = event.screenX - (containX + screenLeft) - 3;
    
    if (x < image.bl_lower_bound)
    {
      x = image.bl_lower_bound;
    }
    if (x > image.bl_upper_bound)
    {
      x = image.bl_upper_bound;
    }
    
    return  x;
  }
  var containY  = bl_sys_find_y(container, null, false);
  var screenTop = bl_port_getScreenTop(win);
  var y         = event.screenY - (containY + screenTop) - 3;
  
  if (y < image.bl_lower_bound)
  {
    y = image.bl_lower_bound;
  }
  if (y > image.bl_upper_bound)
  {
    y = image.bl_upper_bound;
  }
  
  return  y;
}

function _bl_contain_sep_move(event, el)
{
  el = bl_port_computeEventEl(el);
  
  if (el.bl_down)
  {
    var container = el.parentNode.parentNode;
    var image     = bl_contain_get_drag_img(container, bl_contain_getBag(container));
    
    if (image.bl_is_vert)
    {
      image.style.left = (bl_contain_sep_compute_pos(container, image, true, event)-3)+"px";
    }
    else
    {
      image.style.top = (bl_contain_sep_compute_pos(container, image, false, event)-3)+"px";
    }
  }
}

function _bl_contain_sep_up(event, el)
{
  el = bl_port_computeEventEl(el);
  
  if (el.bl_down)
  {
    el.bl_down    = false;
    
    var container = el.parentNode.parentNode;
    var image     = bl_contain_get_drag_img(container, bl_contain_getBag(container));
     
    // No CSS unit of measurement specified-- Not needed for zeroes.
    with (image.style)
    {
      left   = 0;
      top    = 0;
      width  = 0;
      height = 0;
    }
        
    var list      = null;
    var size      = 0;
    var pos       = 0;
    
    if (image.bl_is_vert)
    {
      el.src = container.getAttribute("v_en");
      list   = bl_contain_getColumnData(container);
      pos    = bl_contain_sep_compute_pos(container, image, true, event);
      size   = container.offsetWidth;
    }
    else
    {
      el.src          = container.getAttribute("h_en");
      list            = bl_contain_getRowData(container);
      pos             = bl_contain_sep_compute_pos(container, image, false, event);
      image.style.top = pos+"px";
      size            = container.offsetHeight;
    }
    
    var index  = image.bl_index;
    var item1  = list[index];
    var item2  = list[index + 1];
    
    item1.pixelSize = pos - image.bl_lower_bound + 3;
    item2.pixelSize = image.bl_upper_bound - pos + 3;
    bl_contain_compute_new_sizes(list, size);
    
    bl_contain_send_sizes(container, list, !image.bl_is_vert, -1, false);
    bl_contain_layoutContainer(container, true);
  }

  if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    bl_port_uncoverDialog();
  }     
   
  bl_port_releaseCapture(el);
}

function bl_contain_build_up_row_sep(el, bag, item, index, rowCount, colCount, cells)
{
  var start    = 0;
  var end      = 0;
  var count    = 0;
  var j        = 0;
  var sepList  = [];
  var imgStr   = el.getAttribute("h_en");
  
  item.sepList = sepList;
  
  for (; j < colCount; j++)
  {
    var cell = cells[(index * colCount) + j];
    var canHaveSeparator = (cell.rowVal == 1);
    
    if (cell.childIndex == -2)
    {
      var rootCell = cells[(cell.rowVal * colCount) + cell.columnVal];
      canHaveSeparator = ((cell.rowVal + rootCell.rowVal) == (index + 1));
    }
    
    if (canHaveSeparator)
    {
      count++;
    }
    else
    {
      if (count)
      {
        bl_contain_sep_genSeparatorImg(bag, sepList, "bl_row", index, j - count, count, "row-resize", imgStr);
      }
      count = 0;
    }
  }
  if (count)
  {
    bl_contain_sep_genSeparatorImg(bag, sepList, "bl_row", index, j - count, count, "row-resize", imgStr);
  }
}

function bl_contain_build_up_col_sep(el, bag, item, index, rowCount, colCount, cells)
{
  var start    = 0;
  var end      = 0;
  var count    = 0;
  var j        = 0;
  var sepList  = [];
  var imgStr   = el.getAttribute("v_en");
  
  item.sepList = sepList;
  
  for (; j < rowCount; j++)
  {
    var cell = cells[(j * colCount) + index];
    var canHaveSeparator = (cell.columnVal == 1);
    
    if (cell.childIndex == -2)
    {
      var rootCell     = cells[(cell.rowVal * colCount) + cell.columnVal];
      canHaveSeparator = ((cell.columnVal + rootCell.columnVal) == (index + 1));
    }
    
    if (canHaveSeparator)
    {
      count++;
    }
    else
    {
      if (count)
      {
        bl_contain_sep_genSeparatorImg(bag, sepList, "bl_col", index, j - count, count, "col-resize", imgStr);
      }
      count = 0;
    }
  }
  if (count)
  {
    bl_contain_sep_genSeparatorImg(bag, sepList, "bl_col", index, j - count, count, "col-resize", imgStr);
  }
}

function bl_contain_clean_up_sep(item)
{
  var list = item.sepList;
  
  if (list)
  {
    var len = list.length;
    
    for (var i = 0; i < len; i++)
    {
      var imgItem = list[i];
      imgItem.parentNode.removeChild(imgItem);
    }
    list.splice(0, len);
    item.sepList = null;
  }
}

function bl_ctr_setGridCell(el, cell)
{
  var current = el.cb_current_cell;
  
  if (cell != current)
  {
    if (current)
    {
      bl_contain_cellHide(el);
    }
    
    el.cb_current_cell = cell;
    
    if (cell)
    {
      bl_ctr_setGridboundry(el, null);
      bl_contain_cellShow(cell, el);
    }
  }
}

function _bl_geo_deferResize()
{
  var body = document.body;
  
  if (body.bl_resizeChanged)
  {
    body.bl_resizeChanged = false;
    window.setTimeout('_bl_geo_deferResize()', 100);
  }
  else
  {
    body.bl_lastWidth  = body.clientWidth;
    body.bl_lastHeight = body.clientHeight;
    
    _bl_geo_doResize();
    body.bl_resize = false;
    
    if (window.bl_rulers)
    {
      window.bl_rulers.position();
    }
  }
}

function _bl_contain_initFormEditor_final(topContainerId)
{
  var topRuler     = document.getElementById("bl_top_ruler");
  var leftRuler    = document.getElementById("bl_left_ruler");
  var topContainer = document.getElementById(topContainerId);
  var layoutParent = document.getElementById("bl_layout_parent");
  
  window.bl_rulers = new bl_contain_createRuler(topContainer, topRuler, leftRuler, false);


  window.bl_rulers.top.style.width   = Math.max((layoutParent.offsetWidth - 2), 0)+"px";
  window.bl_rulers.left.style.height = Math.max((layoutParent.offsetHeight - 2), 0)+"px";
  
  window.bl_rulers.setFormSize(topContainer.offsetWidth, topContainer.offsetHeight);
  window.onresize = _bl_contain_controlResize;

  window.document.oncontextmenu = bl_sys_context_menu;
  
  if (bl_browserInfo.ie)
  {
    document.body.onfocusin  = bl_contain_focus; 
    document.body.onfocusout = bl_contain_blur;
  }
  else
  {
    window.onfocus = bl_contain_focus; 
    window.onblur  = bl_contain_blur; 
  }
}

function _bl_contain_initFormEditor(topContainerId)
{
  if (bl_browserInfo.firefox)
  {
    window.setTimeout('_bl_contain_initFormEditor_final('+topContainerId+')', 1);
  }
  else
  {
    _bl_contain_initFormEditor_final(topContainerId);
  }
}

function _bl_contain_controlResize()
{
  var rulers = window.bl_rulers;
  
  if (rulers)
  {
    var topParent = document.getElementById("bl_layout_parent");
    
    rulers.top.style.width   = (topParent.offsetWidth - 2)+"px";
    rulers.left.style.height = (topParent.offsetHeight - 2)+"px";
    rulers.top.scrollLeft    = topParent.scrollLeft;
    rulers.left.scrollTop    = topParent.scrollTop;
  }
}

function _bl_contain_onscroll()
{
  var rulers = window.bl_rulers;
  
  if (rulers)
  {
    var topParent = document.getElementById("bl_layout_parent");

    rulers.top.scrollLeft = topParent.scrollLeft;
    rulers.left.scrollTop = topParent.scrollTop;
  }
}

function _bl_geo_resized()
{
  var body = document.body;
  
  body.bl_resizeChanged = false;
  
  if (body.clientWidth != body.bl_lastWidth || body.clientHeight != body.bl_lastHeight)
  {
    // bl_resize allows us to defer the computation of the geometry while
    // a user is resizing a window.  Its purpuse is to make sure that we do
    // not swamp the browser with TOO much computation while this is taking place
    // it works by waiting to do the resize computation so we call 
    // _bl_geo_deferResize 100 milliseconds later to determin if we can dothe 
    // actual computation.  if a resize comes in after that then we mark the
    // bl_resizeChanged so that when _bl_geo_deferResize finaly does get calle that 
    // it will know to defer another 100 milliseconds.  the algorythm will continue to do this 
    // untill the resize event slow down enough to make it worth doing the comutation 
    if (body.bl_resize)
    {
      body.bl_resizeChanged = true;
    }
    else
    {
      body.bl_resize = true;
      window.setTimeout('_bl_geo_deferResize()', 100);
    }
  }
}

function bl_contain_findRoot()
{
  var node = document.body.firstChild;
  
  while (node)
  {
    if (node.getAttribute && node.getAttribute("cb_tag") == "CTR")
    {
      return node;
    }
    node = node.nextSibling;
  }
  return null;
}

function _bl_geo_doResize()
{
  var body = document.body;
  
  if (body.clientWidth == 0 || body.clientHeight == 0)
  {
    window.setTimeout("_bl_geo_deferResize()", 1);
    return null;
  }

  var child = bl_contain_findRoot();

  if (child)
  {
    var computed      = bl_port_getComputedStyle(body);
    var bmarginLeft   = parseInt(computed.marginLeft);
    var bmarginRight  = parseInt(computed.marginRight);
    var bmarginTop    = parseInt(computed.marginTop);
    var bmarginBottom = parseInt(computed.marginBottom);
    var windowSize    = bl_port_windowSize();

    windowSize.width  -= (bmarginLeft + bmarginRight);
    windowSize.height -= (bmarginTop + bmarginBottom);
    
    if (windowSize.width != child.offsetWidth || windowSize.height != child.offsetHeight)
    {
      with (child.style)
      {
        width  = windowSize.width + "px";
        height = windowSize.height + "px";
      }
          
      var msg = "<resize><width>"    
              + windowSize.width     
              + "</width><height>"   
              + windowSize.height    
              + "</height></resize>";
              
      var win = bl_contain_getLiveWindow(child);
      
      // we are defer ing to send assuming that the very next mpr interaction
      // will be timely enough for this message to make it to the server
      win.bl_mpr_send(msg, win.cb_controlContextId, -1, BL_MPR_DEFER);
          
      //var start = new Date();
      bl_contain_layoutContainer(child, false);
      
      //var mid = new Date();
      if (bl_browserInfo.firefox)
      {
        var cnt = bl_contain_removeEmptySpace(document);
      }
      
      return windowSize;
    }
  }
  
  return null;
}

function bl_contain_removeEmptySpace(doc)
{
  // Fix for bug #3264 (erroneous bad scrolling)
  // Finds all grid layouts and verifies that they don't have extra scroll space.
  // If extra scroll space is found, an empty text node is added to the DOM to
  // cause it to re-layout, and the element is scrolled to the top.
  var cnt = 0;
  var divs = doc.getElementsByTagName("DIV");
  var len = divs.length;
  
  var tmpNode;
  
  for(var i = 0; i < len; i++)
  {
    var el = divs[i];
    
    if(el.getAttribute("bl_layout_type") == bl_contain_type_grid)
    {
      var sh = el.scrollHeight;
      var oh = el.offsetHeight;
      
      if(sh > oh)
      {
        cnt++;
        
        if(!tmpNode)
        {
          tmpNode = doc.createTextNode("");
        }
        
        el.scrollTop = 0;
        el.appendChild(tmpNode);
      }
    }
  }
  
  if (tmpNode)
  {
    // If tmpNode is not null, it WILL have a parent node.
    tmpNode.parentNode.removeChild(tmpNode);
  }
  return cnt;
}

function bl_contain_layoutContainer(container, layoutTop)
{
  var resizeQueue = [];
  var layout      = bl_contain_getLayout(container)
//  var start       = new Date();
  
  if (layout)
  {
    if (layoutTop)
    {
      layout.layoutChildren(container, resizeQueue);

      if (layout.canEdit(container))
      {
        layout.layoutBorder(container);
      }
    }
    else
    {
      layout.resizeCheck(container, resizeQueue);
    }
    
    var item = resizeQueue.shift();

    while (item)
    {
      layout = bl_contain_getLayout(item);
      
      if (layout)
      {
        layout.resizeCheck(item, resizeQueue);
      }
      
      item = resizeQueue.shift();
    }
  }
  
  //  var end       = new Date();
  //  window.status = " layout time - " + (end.getTime() - start.getTime());
}

function _bl_contain_embResize(el, resizeQueue)
{
  // there should only ever be one child in an 'Inline' or 'EmbeddedForm'
  // and that child should always be a container. Should you find
  // that this is ever not true then whatever is puting the extra element
  // into this control is broken so you need to find where that is
  // happening and fix it there.  If there is no first child then
  // all I can say is ... thats odd. There should always be a child.
  // However, we will check to make sure it is there just in case.
  var container = el.firstChild;
  
  if (container)
  {
    if (container.getAttribute("bl_natural") == null)
    {
      var elStyle  = bl_port_getComputedStyle(el);
      var style    = container.style;

      if (style.width != "width:100%")
      {
        if (el.style.width == "")
        {
          style.width = "";
        }
        else
        {
          var cwidth   = Math.max((el.clientWidth - parseInt(elStyle.paddingLeft) - parseInt(elStyle.paddingRight)), 0);
          style.width  = cwidth + "px";
        }
      }

      if (el.style.height == "")
      {
        style.height = "";
      }
      else
      {
        var cheight  = Math.max((el.clientHeight - parseInt(elStyle.paddingTop) - parseInt(elStyle.paddingBottom)), 0);
        style.height = cheight + "px";
      }
    }
    
    resizeQueue.push(container);
  }
}

function bl_contain_resizeChild(child, resizeQueue)
{
  var resizeFunc = child.bl_resizeFunc;
  
  if (resizeFunc == undefined)
  {
    resizeFunc = window[child.getAttribute("bl_resize")];
    child.bl_resizeFunc = resizeFunc
  }
  
  if (resizeFunc)
  {
    resizeFunc(child, resizeQueue);
  }
}

function bl_contain_procChildResize(child)
{
  var resizeQueue = [];
  bl_contain_resizeChild(child, resizeQueue);
  
  var len = resizeQueue.length;
  
  for (var cindex = 0; cindex < len; cindex++)
  {
    bl_contain_layoutContainer(resizeQueue[cindex], false);
  }
}

function bl_contain_layoutChild(child, layoutTop)
{
  var layout = bl_contain_getLayout(child);
  
  if (layout)
  {
    bl_contain_layoutContainer(child, layoutTop);
  }
  else
  {
    bl_contain_procChildResize(child);
  }
}

function bl_contain_resizePush(child, resizeQueue)
{
  var layout = bl_contain_getLayout(child);
  
  if (layout)
  {
    resizeQueue.push(child);
  }
  else
  {
    bl_contain_resizeChild(child, resizeQueue);
  }
}

function bl_page_handleMessage(item, name, cmd)
{
}

function bl_contain_handleMessage(item, name, cmd, container)
{
  var ret     = true;
  var chNode1 = cmd.firstChild;
  
  if (name == "form_popup")
  {
    var selected = bl_geo_getSelected();
    var win      = bl_contain_getLiveWindow(selected.parent);
    win.bl_sys_loadPopup(item, win.bl_sys_get_mpr());
  }
  else
  {
    if (!container)
    {
      container = document.getElementById(bl_port_get_text(chNode1));
    }
    
    if (container)
    {
      if (name == "removeAll")
      {
        bl_contain_removeAllChildren(container);
      }
      else if (name == "removeItem")
      {
        bl_contain_removeItem(container, bl_port_get_text(chNode1.nextSibling));
      }
      else if (name == "addItem")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        var chNode4 = chNode3.nextSibling;
        var chNode5 = chNode4.nextSibling;
        bl_contain_addItem(container, bl_port_get_text(chNode2), bl_port_get_text(chNode3), bl_port_get_text(chNode4), bl_port_get_text(chNode5));
      }
      else if (name == "selectItem")
      {
        var layout = bl_contain_getLayout(container);
        layout.selectChild(container, parseInt(bl_port_get_text(chNode1.nextSibling)));
      }
      else if (name == "setItem")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        var chNode4 = chNode3.nextSibling;
        var chNode5 = chNode4.nextSibling;
        var arg2    = bl_port_get_text(chNode2);
        
        bl_contain_removeItem(container, arg2);
        bl_contain_addItem(container, arg2, bl_port_get_text(chNode3), bl_port_get_text(chNode4), bl_port_get_text(chNode5));
      }
      else if (name == "moveItem")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        bl_contain_moveItem(container, bl_port_get_text(chNode2), bl_port_get_text(chNode3));
      }
      else if (name == "ovval")
      {
        bl_contain_setOV(container, bl_port_get_text(chNode1.nextSibling));
      }
      else if (name == "flow")
      {
        bl_contain_setFlow(container, bl_port_get_text(chNode1.nextSibling));
      }
      else if (name == "setGridData")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        var chNode4 = chNode3.nextSibling;
        bl_contain_setGridData(container, bl_port_get_text(chNode2), bl_port_get_text(chNode3), bl_port_get_text(chNode4));
      }
      else if (name == "dim_limits")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        bl_contain_set_limits(bl_port_get_text(chNode2), bl_port_get_text(chNode3));
      }
      else if (name == "resetChildGeometry")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        bl_contain_ChildResetGeo(bl_port_get_text(chNode2), bl_port_get_text(chNode3));
      }
      else if (name == "resetChild")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        var chNode4 = chNode3.nextSibling;
        bl_contain_ChildReset(bl_port_get_text(chNode2), bl_port_get_text(chNode3), bl_port_get_text(chNode4));
      }
      else if (name == "setStyle")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        bl_contain_ChildStyleSet(bl_port_get_text(chNode2), bl_port_get_text(chNode3));
      }
      else if (name == "editFlag")
      {
        _bl_contain_setEditFlag(container.id, bl_port_get_text(chNode1.nextSibling));
      }
      else if (name == "pathBind")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        var chNode4 = chNode3.nextSibling;
        bl_contain_childPathChanged(bl_port_get_text(chNode2), bl_port_get_text(chNode3), bl_port_get_text(chNode4));
      }
      else if (name == "setInternalMargin")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        bl_contain_setMargins(container, bl_port_get_text(chNode3));
      }
      else if (name == "setOuterMargin")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        bl_contain_setOuterMargins(container, bl_port_get_text(chNode3));
      }
      else if (name == "setInnerMargin")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        bl_contain_setInnerMargins(container, bl_port_get_text(chNode3));
      }
      else if (name == "setSizes")
      {
        var chNode2 = chNode1.nextSibling;
        var chNode3 = chNode2.nextSibling;
        bl_contain_set_row_column_sizes(container, bl_port_get_text(chNode3));
      }
      else
      {
        ret = false;
      }
    }
    else
    {
      ret = false;
    }
  }
  
  return ret;
}

function bl_contain_row_col_colapse(container, rowIndex, colIndex, rowVal, colVal)
{
  if (container)
  {
    var rows    = bl_contain_getRowData(container);
    var cols    = bl_contain_getColumnData(container);
    var row     = rows[rowIndex];
    var col     = cols[colIndex];
    var layout  = bl_contain_getLayout(container);
    var changed = (row.colapsed != rowVal || col.colapsed != colVal);
    
    
    row.colapsed = rowVal;
    col.colapsed = colVal;
    
    if (changed)
    {
      bl_contain_recomputeDims(container);
      bl_contain_layoutContainer(container, true);
    }
  }
}

function _bl_contain_posFinish()
{
  if (window.bl_rulers && bl_rulers.isPageLayout)
  {
    var topContainer = window.bl_rulers.topContainer;
    var x = bl_sys_real_x(topContainer, null, false);
    var y = bl_sys_real_y(topContainer, null, false);
    
    with (window.bl_rulers.left.style)
    {
      left   = (x - 18)+"px";
      top    = (y - 20)+"px";
      width  = "17px";
      height = (topContainer.offsetHeight + 40)+"px";
    }
    
    window.bl_rulers.left.firstChild.style.height = (topContainer.offsetHeight)+"px";
    
    with (window.bl_rulers.top.style)
    {
      left   = (x - 20)+"px";
      top    = (y - 18)+"px";
      height = "17px";
      width  = (topContainer.offsetWidth + 40)+"px";
    }
    
    window.bl_rulers.top.firstChild.style.width = topContainer.offsetWidth+"px";
    bl_contain_resetSelects();
  }
}

function bl_contain_position()
{
  if (this.isPageLayout)
  {
    window.setTimeout('_bl_contain_posFinish()', 10);
  }
}

function bl_contain_setFormSize(width, height)
{
  var topParent = bl_contain_topParent();
  var leftChild = this.left.firstChild;
  var topChild  = this.top.firstChild;

  leftChild.style.height             = height+"px";
  topChild.style.width               = width+"px";
  leftChild.nextSibling.style.height = (height + 60)+"px";
  topChild.nextSibling.style.width   = (width + 60)+"px";
}

function bl_contain_setFocus(val)
{
  if (!this.isPageLayout)
  {
    var bkcolor = (val) ? "#003177":"#646464";
    bl_port_setBGColor(this.left.childNodes[2].style, bkcolor);
    bl_port_setBGColor(this.left.childNodes[3].style, bkcolor);
    bl_port_setBGColor(this.top.childNodes[2].style, bkcolor);
    bl_port_setBGColor(this.top.childNodes[3].style, bkcolor);
  }
}

function bl_contain_hideButtons()
{
  var children = this.left.childNodes;
  var len      = children.length;
  var index    = len - 50;
  
  for (;index < len; index++)
  {
    children[index].style.display = "none";
  }  
  
  children = this.top.childNodes;
  len      = children.length;
  index    = len - 50;
  
  for (;index < len; index++)
  {
    children[index].style.display = "none";
  }  
}

function _bl_contain_menuAction(event, el)
{
  var container = bl_contain_currentSelect();
  
  if (container && el.bl_props)
  {
    var props       = el.bl_props;
    var index       = props.index;
    var isRow       = props.isRow;
    var list        = (isRow)? bl_contain_getRowData(container):bl_contain_getColumnData(container);
    var overlayData = bl_contain_getOverlayData();
      
    bl_contain_hide_buttons();
    
    if (overlayData && overlayData.el == el && item == overlayData.item)
    {
      window.cb_sys_popup_close(false);
      return ;
    }
    
    var html;

    if (isRow)
    {
      html = window.bl_rowPopupText;
      
      if (!html)
      {
        html = window.bl_rowPopupText = bl_contain_popupHTML(true);
      }
    }
    else
    {
      html = window.bl_colPopupText;
      
      if (!html)
      {
        html = window.bl_colPopupText = bl_contain_popupHTML(false);
      }
    }
    
    var typeName   = (isRow)? "Row":"Col";
    var vAlign     = (isRow)? "Bottom":"Top";
    bl_overlayData = { el:el, container:container, index:index, item:list[index], isRow:isRow, typeName:typeName }

    var argData = { html:html,
                    customArg:el,
                    x:0,
                    y:0,
                    w:192,
                    h:203,
                    el:el,
                    doSideCart:!isRow,
                    cleanUp:bl_contain_popup_cleanup,
                    controlHAlign:"Right",
                    controlVAlign:vAlign,
                    canDestroy:true,
                    valid:bl_contain_popup_valid,
                    useVeil:true,
                    positionType:"control"
                  };

    if (window.bl_sys_popupInvoke(argData) != null) 
    {
      bl_sys_img_freeze(el);
    }
  }  
}

function _bl_contain_menuFlyover(event, el, isLeaving)
{
  if (isLeaving)
  {
    bl_contain_row_col_hilite_hide();
  }
  else
  {
    var container = bl_contain_currentSelect();

    if (container && el.bl_props)
    {
      var props = el.bl_props;
      var list  = (props.isRow)? bl_contain_getRowData(container):bl_contain_getColumnData(container);

      window.cb_sys_popup_close(false);
      bl_contain_row_col_hilite_show(container, list[props.index], props.isRow);
    }  
  }
}

function bl_contain_size_computeRow(container, style, pos)
{
  var topEl  =  bl_contain_topParent();
  var elLeft = bl_sys_real_x(container, topEl, false);

  if (window.bl_rulers && window.bl_rulers.isPageLayout)
  {
    with (style)
    {
      left   = (elLeft - 4)+"px";
      top    = (pos + bl_sys_real_y(container, topEl, false) - 20)+"px";
      height = "1px";
      width  = (container.offsetWidth + 3)+"px";
    }
  }
  else
  {
    with (style)
    {
      left   = 0;
      top    = pos+"px";
      height = "1px";
      width  = (elLeft + container.offsetWidth)+"px";
    }
  }
}

function bl_contain_size_computeColumn(container, style, pos)
{
  var topEl  =  bl_contain_topParent();
  var elTop  = bl_sys_real_y(container, topEl, false);

  if (window.bl_rulers && window.bl_rulers.isPageLayout)
  {
    with (style)
    {
      left   = (pos + bl_sys_real_x(container, topEl, false) - 20)+"px";
      top    = (elTop - 4)+"px";
      height = (container.offsetHeight + 3)+"px";
      width  = "1px";
    }
  }
  else
  {
    with (style)
    {
      left   = pos+"px";
      top    = 0;
      height = (elTop + container.offsetHeight)+"px";
      width  = "1px";
    }
  }
}

function bl_contain_size_computeTooltip(el, props)
{
  if (props)
  {
    var tooltip1 = bl_contain_getRulerTooltip1();
    var tooltip2 = (props.notLast)? bl_contain_getRulerTooltip2():null;
    
    if (tooltip1)
    {
      var body     = document.body;
      var tx1      = 0;
      var ty1      = 0;
      var tx2      = 0;
      var ty2      = 0;
      var x        = bl_sys_find_x(el, null, false);
      var y        = bl_sys_find_y(el, null, false);

      bl_port_setInnerText(tooltip1, props.currentPosLeft + "px");
      
      if (tooltip2)
      {
        bl_port_setInnerText(tooltip2, props.currentPosRight + "px");
        
        tooltip1.style.width = "";
        tooltip2.style.width = "";
        if (tooltip2.offsetWidth > tooltip1.offsetWidth)
        {
          tooltip1.style.width = tooltip2.offsetWidth;
        }
        else
        {
          tooltip2.style.width = tooltip1.offsetWidth;
        }
      }
      
      if (props.isRow)
      {
        ty1 = y - tooltip1.offsetHeight - 5;
        tx1 = x + el.offsetWidth + 10;
        
        if (tx1 < 0)
        {
          tx1 = 0;
        }
        if (tx1 + tooltip1.offsetWidth > body.clientWidth)
        {
          tx1 = body.clientWidth - tooltip1.offsetWidth;
        }
        if (ty1 < 0)
        {
          ty1 = 0;
        }
        var clientBound = body.clientHeight - 10;
        if (ty1 + tooltip1.offsetHeight > clientBound)
        {
          ty1 = clientBound - tooltip1.offsetHeight;
        }
        
        if (tooltip2)
        {
          tx2 = tx1;
          ty2 = y + el.offsetHeight + 5;
          
          if (ty2 < 0)
          {
            ty2 = 0;
            
          }
          if (ty2 + tooltip2.offsetHeight > body.clientHeight)
          {
            ty2 = body.clientHeight - tooltip2.offsetHeight;
            
          }
          if (ty2 < ty1 + tooltip1.offsetHeight)
          {
            tx2 = tx1 + tooltip1.offsetWidth + 5;
            
            if (ty2 < ty1 + 10)
            {
              ty2 = ty1 + 10;
            }
          }
        }
      }
      else
      {
        tx1 = x - tooltip1.offsetWidth - 5;
        ty1 = y + el.offsetHeight;
        
        if (tx1 < 0)
        {
          tx1 = Math.max(x, 0) + el.offsetWidth + 5;
          ty1 -= 10;
        }

        var clientBound = body.clientWidth - 10;

        if (tx1 + tooltip1.offsetWidth > clientBound)
        {
          tx1 = clientBound - tooltip1.offsetWidth;
        }

        if (ty1 < 0)
        {
          ty1 = 0;
        }
        if (ty1 + tooltip1.offsetHeight > body.clientHeight)
        {
          ty1 = body.clientHeight - tooltip1.offsetHeight;
        }
        if (tooltip2)
        {
          ty2 = ty1;
          tx2 = x + el.offsetWidth + 5;
          
          if (tx2 + tooltip2.offsetWidth > body.clientWidth)
          {
            tx2 = body.clientWidth - tooltip2.offsetWidth;
          }
          if (tx2 < tx1 + tooltip1.offsetWidth)
          {
            ty2 = ty1 + tooltip1.offsetHeight + 5;
            
            if (tx2 < tx1 + 10)
            {
              tx2 = tx1 + 10;
            }
          }
        }
      }

      var style1   = tooltip1.style;
      style1.left = tx1 + "px";
      style1.top  = ty1 + "px";
      
      if (tooltip2)
      {
        var style2   = tooltip2.style;
        style2.left = tx2 + "px";
        style2.top  = ty2 + "px";
      }
    }
  }
}

function bl_contain_size_showTooltip(el, props)
{
  var tooltip1 = bl_contain_getRulerTooltip1();

  if (tooltip1)
  {
    var tooltip2 = (props.notLast)? bl_contain_getRulerTooltip2():null;
    
    tooltip1.style.display = "";
    bl_contain_size_computeTooltip(el, props);
    cb_sys_startFilter(tooltip1, false, 0, 60, 3, null, 60, null);
    
    if (tooltip2)
    {
      tooltip2.style.display = "";
      cb_sys_startFilter(tooltip2, false, 0, 60, 3, null, 60, null);
    }
  }
}

function bl_contain_size_hideDone(tooltip)
{
  tooltip.style.display = "none";
}

function _bl_contain_size_flyover(event, el, isLeaving)
{
  var props = el.bl_props;
  
  if (props)
  {
    var hilight = bl_contain_getRulerHilight();
    var style   = hilight.style;
    if (isLeaving)
    {
      style.display = "none";
      var tooltip1 = bl_contain_getRulerTooltip1();
      
      if (tooltip1)
      {
        var tooltip2 = (props.notLast)? bl_contain_getRulerTooltip2():null;
        cb_sys_startFilter(tooltip1, true, 60, 0, 3, null, 0, bl_contain_size_hideDone);

        if (tooltip2)
        {
          cb_sys_startFilter(tooltip2, true, 60, 0, 3, null, 0, bl_contain_size_hideDone);
        }
      }
    }
    else
    {
      var container = bl_contain_currentSelect();
      
      if (container)
      {
        style.display = "";
        
        bl_contain_size_showTooltip(el, props)
        
        if (props.isRow)
        {
          bl_contain_size_computeRow(container, style, props.currentPos);
          hilight.firstChild.src = "/" + bl_version + "/res/img/bungee/form/horiz_wall_ov.gif";
        }
        else
        {
          bl_contain_size_computeColumn(container, style, props.currentPos);
          hilight.firstChild.src = "/" + bl_version + "/res/img/bungee/form/vert_wall_ov.gif";
        }
      }  
    }
  }
}

function bl_contain_size_move_compute(el, x, y, send)
{
  var container = bl_contain_currentSelect();
  
  if (container && el.bl_props)
  {
    var props   = el.bl_props;
    var hilight = bl_contain_getRulerHilight();
    var style   = hilight.style;
    var topEl   = bl_contain_topParent();
    var pos     = 0;
        
    if (props.isRow)
    {
      pos = y - bl_sys_real_y(topEl, null, false) + topEl.scrollTop;
      
      if (props.lowerBound > pos)
      {
        pos = props.lowerBound;
      }
      if (props.upperBound < pos)
      {
        pos = props.upperBound;
      }

      var offset = (window.bl_rulers && window.bl_rulers.isPageLayout)? (bl_sys_real_y(container, topEl, false) - 20):0;
      
      style.top                     =  pos+"px";
      pos                          -= offset;
      el.style.top                  =  (pos - 4)+"px";
      el.previousSibling.style.top  =  (pos - 4)+"px";
    }
    else
    {
      pos = x - bl_sys_real_x(topEl, null, false) + topEl.scrollLeft;

      if (props.lowerBound > pos)
      {
        pos = props.lowerBound;
      }
      if (props.upperBound < pos)
      {
        pos = props.upperBound;
      }

      var offset = (window.bl_rulers && window.bl_rulers.isPageLayout)? (bl_sys_real_x(container, topEl, false) - 20):0;

      style.left                    =  pos+"px";
      pos                           -= offset;
      el.style.left                 =  (pos - 4)+"px";
      el.previousSibling.style.left =  (pos - 4)+"px";
    }

    props.currentPosLeft  = pos - props.lowerBound;
    
    if (!props.nextLocked && props.notLast)
    {
      props.currentPosRight = props.upperBound - pos;
    }
    
    bl_contain_size_computeTooltip(el, props);

    if (send)
    {
      var msg = null;
      
      if (props.notLast && !props.nextLocked)
      {
        msg = "<layout><containerId>"                            
            + container.id                                       
            + "</containerId><cmd>setAjacentItemsSize</cmd><index>" 
            + props.index                                        
            + "</index><isRow>"                                  
            + props.isRow                                        
            + "</isRow><val1>"                                   
            + props.currentPosLeft                               
            + "</val1><val2>"                                    
            + props.currentPosRight                              
            + "</val2></layout>";
      }
      else
      {
        msg = "<layout><containerId>"                              
            + container.id                                   
            + "</containerId><cmd>setItemSize</cmd><index>"  
            + props.index                                          
            + "</index><isRow>"                              
            + props.isRow                                          
            + "</isRow><val>"                                
            + props.currentPosLeft                           
            + "</val></layout>";
      }
      
      var win = bl_contain_getLiveWindow(container);
      win.bl_mpr_send(msg, win.cb_controlContextId, 1, BL_MPR_SYNC);
    }
  }  
}

function _bl_contain_size_move(event, el)
{
  var clientX = event.clientX;
  var clientY = event.clientY;

  el = bl_port_computeEventEl(el);
  
  var doc = el.ownerDocument;
  var win = bl_port_docWindow(doc);

  if (event.view != win)
  {
    // Sometimes the element is delivered from the top window context, so we have
    // to provide corrected clientX and clientY coordinates. Adjust the coordinates
    // to the perspective of the target element's window
    clientX = event.screenX - bl_port_getScreenLeft(win);
    clientY = event.screenY - bl_port_getScreenTop(win);
  }

  if (el.bl_mouseIsDown)
  {
    bl_contain_size_move_compute(el, clientX - 3, clientY - 3, false);
  }
}

function _bl_contain_size_key(event, el)
{
  var container = bl_contain_currentSelect();
  
  if (bl_port_keyCode(event) == 27 && container && el.bl_props)
  {
    var props   = el.bl_props;
    var hilight = bl_contain_getRulerHilight();
    var pos     = props.currentPos;
        
    hilight.style.display = "none";
    
    if (props.isRow)
    {
      el.style.top                 = (pos - 4)+"px";
      el.previousSibling.style.top = (pos - 4)+"px";
    }
    else
    {
      el.style.left                 = (pos - 4)+"px";
      el.previousSibling.style.left = (pos - 4)+"px";
    }
    
    el.bl_mouseIsDown = false;
    el.bl_mouseIsIn   = false;
    bl_port_releaseCapture(el);
    bl_sys_img_thaw(el);
    bl_sys_img_set(el, false, el.bl_mouseIsIn);
    window.bl_current_drag = null;
  }  
  
  bl_port_stop_event(event);
}

function _bl_contain_size_up(event, el)
{
  if (!el.disabled)
  {
    var clientX   = event.clientX - 3;
    var clientY   = event.clientY - 3;
    var topParent = bl_contain_topParent();
    var isin      = (clientX < topParent.clientWidth && clientY < topParent.clientHeight && el.bl_mouseIsIn);
    
    _bl_contain_size_flyover(event, el, !isin);
    bl_sys_img_thaw(el);
    bl_contain_size_move_compute(el, clientX, clientY, true);
    window.bl_current_drag = null;
  }
}

function _bl_contain_size_action(event, el)
{
  var container = bl_contain_currentSelect();
  
  if (container && el.bl_props)
  {
    var props   = el.bl_props;
    var hilight = bl_contain_getRulerHilight();
    var style   = hilight.style;
    
    if (props.isRow)
    {
      bl_contain_size_computeRow(container, style, props.currentPos);
      hilight.firstChild.src = "/" + bl_version + "/res/img/bungee/form/horiz_wall_do.gif";
    }
    else
    {
      bl_contain_size_computeColumn(container, style, props.currentPos);
      hilight.firstChild.src = "/" + bl_version + "/res/img/bungee/form/vert_wall_do.gif";
    }
    
    bl_sys_img_freeze(el);
    window.bl_current_drag = el;
  }  
}

function bl_contain_positionButtons(itemPosition, list, current, isRow)
{
  var len       = Math.min(list.length, 25);
  var titleQual = (isRow)? "row":"col";
  
  for (var i = 0; i < len; i++)
  {
    var data = list[i];
    var pos  = itemPosition + data.position + data.pixelSize - 4;
    var titleQual;
     
    with (current.style)
    {
      display = "";
      
      if (isRow)
      {
        top = pos + "px";
      }
      else
      {
        left = pos + "px";
      }
    }
        
    current.title    = "Grid: edit " + titleQual + "[" + i + "] - size(" + data.pixelSize + "px)";
    current.bl_props = { index:i, isRow:isRow };
    
    // get the companiniopn button to this
    current = current.nextSibling;

    with (current.style)
    { 
      display = "";

      if (isRow)
      {
        top = pos + "px";
      }
      else
      {
        left = pos + "px";
      }
    }
    
    if (data.isLocked)
    {
      bl_sys_disable(current);
    }
    else
    {
      bl_sys_enable(current);
    }

    var currentPos     = pos + 4;
    var lowerBound     = itemPosition + data.position;
    var currentPosLeft = currentPos - lowerBound;
    var props = { isRow:isRow,
                  index:i,
                  currentPos:currentPos,
                  lowerBound:lowerBound,
                  currentPosLeft:currentPosLeft,
                  notLast:(i < len - 1)
                };

    if (i < len - 1)
    {
      var next = list[i + 1];
      
      props.origUpperBound      = itemPosition + next.position + next.pixelSize;
      props.currentOrigPosRight = props.origUpperBound - props.currentPos;
      
      if (next.isLocked)
      {
        props.upperBound = 100000;
        props.nextLocked = true;
        props.currentPosRight  = next.pixelSize;
      }
      else
      {
        props.upperBound      = props.origUpperBound;
        props.nextLocked      = false;
        props.currentPosRight = props.currentOrigPosRight;
      }
    }
    else
    {
      props.upperBound = 100000;
    }

    current.bl_props = props;
    
    // move to the next set of buttons
    current = current.nextSibling;
  }
  
  while (current)
  {
    current.style.display = "none";
    current = current.nextSibling;
  }
}

function bl_contain_procButtons(selectedItem, left, top)
{
  var layout = bl_contain_getLayout(selectedItem);
  
  if(!layout || layout.type != bl_contain_type_grid)
  {
    this.hideButtons();
  }
  else
  {
    var children = this.left.childNodes;
    var index    = children.length - 50;

    bl_contain_positionButtons(top, bl_contain_getRowData(selectedItem), children[index], true);
    
    children = this.top.childNodes;
    index    = children.length - 50;
    
    bl_contain_positionButtons(left, bl_contain_getColumnData(selectedItem), children[index], false);
  }
}

function bl_contain_selectItem(item)
{
  var leftShadow1 = this.left.childNodes[2];
  var leftShadow2 = this.left.childNodes[3];
  var topShadow1  = this.top.childNodes[2];
  var topShadow2  = this.top.childNodes[3];

  if (this.isPageLayout)
  {
    item = this.topContainer;
  }

  if (item)
  {
    var itemHeight  = item.offsetHeight;
    var itemWidth   = item.offsetWidth;
    var elTop       = 20;
    var elLeft      = 20;
    
    if (!this.isPageLayout)
    {
      var topEl = bl_contain_topParent();
      
      elTop  = bl_sys_real_y(item, topEl, false);
      elLeft = bl_sys_real_x(item, topEl, false);
    }
    
    with (leftShadow1.style)
    {
      left   = "2px";
      top    = "20px";
      height = Math.max(elTop - 20, 3) + "px";
      width  = "13px";
    }
    
    with (leftShadow2.style)
    {
      left   = "2px";
      top    = (elTop + itemHeight) + "px";
      height = Math.max((this.left.firstChild.offsetHeight - (elTop + itemHeight) + 20), 3) + "px";
      width  = "13px";
    }
    
    with (topShadow1.style)
    {
      left   = "20px";
      top    = "2px";
      height = "13px";
      width  = Math.max(elLeft - 20, 3) + "px";
    }
        
    with (topShadow2.style)
    {
      left   = (elLeft + itemWidth) + "px";
      top    = "2px";
      height = "13px";
      width  = Math.max((this.top.firstChild.offsetWidth - (elLeft + itemWidth) + 20), 3) + "px";
    }
        
    this.procButtons(item, elLeft, elTop);
  }    
  else
  {
    with (leftShadow1.style)
    {
      left   = "-2px";
      top    = "-2px";
      height = 0;
      width  = 0;
    }
        
    with (leftShadow2.style)
    {
      left   = "-2px";
      top    = "-2px";
      height = 0;
      width  = 0;
    }
    
    with (topShadow1.style)
    {
      left   = "-2px";
      top    = "-2px";
      height = 0;
      width  = 0;
    }

    with (topShadow2.style)
    {
      left   = "-2px";
      top    = "-2px";
      height = 0;
      width  = 0;
    }
    
    this.hideButtons();
  }
}

function bl_contain_createRuler(topContainer, topRuler, leftRuler, isPageLayout)
{
  this.topContainer  = topContainer;
  this.left          = leftRuler;
  this.top           = topRuler;
  this.isPageLayout  = isPageLayout;
  this.position      = bl_contain_position;
  this.setFormSize   = bl_contain_setFormSize;
  this.select        = bl_contain_selectItem;
  this.setFocus      = bl_contain_setFocus;
  this.hideButtons   = bl_contain_hideButtons;
  this.procButtons   = bl_contain_procButtons;
}

function bl_contain_currentSelect()
{
  return (window.bl_rulers && window.bl_rulers.isPageLayout)? window.bl_rulers.topContainer:bl_geo_getSelected().child;
}

function bl_contain_genButtons(type, istop)
{
  var ret      = "";
  var popupStr = (istop)? ":0px;' bl_sideCart" : ":0px;'";
  var dim1Str  = (istop)? "_menu_' width='9px' height='7px' src='/" : "_menu_' width='7px' height='9px' src='/";
  var dim2Str  = (istop)? "_margin_' width='9px' height='7px' src='/" : "_margin_' width='7px' height='9px' src='/";

  // 25 is tha max count allowed for rows/columns
  for (var i = 0; i < 25; i++)
  {
    ret += "<img unselectable='on' hidefocus='true' onmouseout='_bl_sys_img_leave(event, this)' onmouseover='_bl_sys_img_enter(event, this)' onmousedown='_bl_sys_img_down_exe(event, this)' bl_flyover='_bl_contain_menuFlyover' onmouseup='_bl_sys_img_up_exe(event, this)' bl_absorb_events bl_function='_bl_contain_menuAction'  bl_imgRoot='/";
    ret += bl_version;
    ret += "/res/img/bungee/form/ruler/";
    ret += type;
    ret += dim1Str;
    ret += bl_version;
    ret += "/res/img/bungee/form/ruler/";
    ret += type;
    ret += "_menu_en.gif' style='display:none;position:absolute;z-index:100;";
    ret += type;
    ret += popupStr;
    ret += "'/><img unselectable='on' hidefocus='true' onmouseout='_bl_sys_img_leave(event, this)' onmouseover='_bl_sys_img_enter(event, this)' onmousedown='_bl_sys_img_down_exe(event, this)' bl_flyover='_bl_contain_size_flyover' onmouseup='_bl_sys_img_up_exe(event, this)' bl_absorb_events onmousemove='_bl_contain_size_move(event, this)' bl_function='_bl_contain_size_action' bl_function_up='_bl_contain_size_up' bl_imgRoot='/";
    ret += bl_version;
    ret += "/res/img/bungee/form/ruler/";
    ret += type;
    ret += dim2Str;
    ret += bl_version;
    ret += "/res/img/bungee/form/ruler/";
    ret += type;
    ret += "_margin_en.gif' style='display:none;position:absolute;z-index:100;";
    ret += type;
    ret += ":10px'/>";
  }
  return ret;
}

function bl_contain_addRulers(container)
{
  var body = document.body;
  var html = window.bl_ruler_html;

  if (!html)
  {
    html  = "<div id='bl_top_ruler' class='bl_top_ruler_div'><div class='bl_top_ruler_img'></div><img src='/"
          + bl_version
          + "/res/img/blank.gif' height='1px' /><div class='bl_ruler_shade'></div><div class='bl_ruler_shade'></div>"
          + bl_contain_genButtons("top", true)
          + "</div><div id='bl_left_ruler' class='bl_left_ruler_div'><div class='bl_left_ruler_img' ></div><img src='/"
          + bl_version
          + "/res/img/blank.gif' width='1px'/><div class='bl_ruler_shade'></div><div class='bl_ruler_shade'></div>"
          + bl_contain_genButtons("left", false)
          + "</div>";
          
    window.bl_ruler_html = html;
  }
  
  bl_port_insertAdjacentHTML(body, "beforeend", html);
  
  var leftRuler = body.lastChild;
  var topRuler  = leftRuler.previousSibling;
  
  window.bl_rulers = new bl_contain_createRuler(container, topRuler, leftRuler, true);
  bl_contain_createSelectArt();
  window.bl_rulers.position();
}

function bl_contain_removeRulers()
{
  var rulers = window.bl_rulers;
  rulers.left.parentNode.removeChild(rulers.left);
  rulers.top.parentNode.removeChild(rulers.top);

  rulers.left = null;
  rulers.top  = null;
  bl_rulers   = null;
}

function _bl_contain_setEditFlag(containerId, val)
{
  container = document.getElementById(containerId);
   
  if (container)
  {
    var body   = document.body;
    var color  = null;
    var child  = bl_contain_findRoot();
    var layout = bl_contain_getLayout(container);
    
    if (val == "on")
    {
      layout.setCanEdit(container, true);
    
      with (body.style)
      {  
        container.origBackgroundImage = backgroundImage;
        margin = "20px";
        backgroundImage = "url(/" + bl_version + "/res/img/bungee/form/grid-bg.gif)";
      }
      
      if (child)
      {
        with (child.style)
        {
          body.bl_lastColor = backgroundColor;
          backgroundColor   = "white";
        }
      }
      
      bl_contain_addRulers(container);
    }
    else
    {
      layout.setCanEdit(container, false);
      bl_contain_hide_buttons();
      
      with (body.style)
      {  
        margin = "0px";
        
        if (container.origBackgroundImage && container.origBackgroundImage != backgroundImage)
        {
          backgroundImage = container.origBackgroundImage;
        }
      }
           
      if (body.bl_lastColor || body.bl_lastColor == "")
      {
        if (child)
        {
          with (child.style)
          {
            backgroundColor = body.bl_lastColor;
          }
        }
      }
      
      bl_contain_removeRulers()
    }
    
    _bl_geo_doResize();
  }
}

function _bl_contain_handler(item, el)
{
  var cmd  = item.firstChild;
  var name = cmd.nodeName;
  
  if (name == "row_col_colapse")
  {
    var chNode1 = cmd.firstChild;
    var chNode2 = chNode1.nextSibling;
    var chNode3 = chNode2.nextSibling;
    var chNode4 = chNode3.nextSibling;
    bl_contain_row_col_colapse(el, 
                               parseInt(bl_port_get_text(chNode1)), 
                               parseInt(bl_port_get_text(chNode2)), 
                               bl_port_get_text(chNode3) == "t", 
                               bl_port_get_text(chNode4) == "t");
  }
  else if (name == "invalidate")
  {
    bl_sel_invalidate(el,cmd);
  }
}

function _bl_form_ddOver(event, el)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    var zoneList = el.getAttribute("bl_zone_list");
    bl_contain_computeFeedbackOff(bl_contain_dragFeedback(cb_sys_getTopWindow()));
    ddObj.setHint(null);
    if (zoneList && ddObj.srcContext.item != el)
    {
      if (bl_dd_checkList(ddObj, event, zoneList))
      {
        bl_contain_topParent().style.border = "#7BBE42 1px solid";
        bl_port_killEvent(event);
        return ;
      }
    }

    bl_contain_topParent().style.border = "#9DA1A6 1px solid";
    ddObj.clearEffect();
  }
}

function _bl_form_ddOut(event, el)
{
  bl_contain_topParent().style.border = "#9DA1A6 1px solid";
  bl_contain_computeFeedbackOff(bl_contain_dragFeedback(cb_sys_getTopWindow()));
}

function _bl_form_drop(event, el)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    bl_contain_topParent().style.border = "#9DA1A6 1px solid";

    ddObj.setHint(null);

    if (ddObj.srcContext.item != el)
    {
      var zoneList = el.getAttribute("bl_zone_list");
      
      if (zoneList && bl_dd_checkList(ddObj, event, zoneList))
      {
        var win    = bl_contain_getLiveWindow(el);
        var target = { id:win.cb_controlContextId, index:-1 };
        
        win.bl_dd_procDrop(target);
        bl_port_killEvent(event);
      }
    }
  }
}

function bl_contain_isFormEditor()
{
  try
  {
    var cbTag = window.frameElement.getAttribute("cb_tag");
    return (cbTag && cbTag == "FER");
  }
  catch (exception)
  {
  }
  
  return false;
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_contain_last()
{
  var x = 0;
}

// popup editor states
var cb_pe_down        = 0;
var cb_pe_requestUp   = 1;
var cb_pe_requestDown = 2;
var cb_pe_up          = 3;


function cb_button_focus(el)
{
  if (!el.cb_noSetaFocus && !el.isDisabled && el.style.display != "none")
  {
    try
    {
      var actEl = bl_port_get_activeElement(document);
      
      if (actEl && actEl.tagName == "IFRAME")
      {
        actEl = bl_port_get_activeElement(actEl.contentWindow.document);
      }
      if (cb_sys_isInput(actEl))
      {
        bl_port_focus(el);
        if (actEl)
        {
          bl_port_focus(actEl);
        }
      }
    }
    catch (exception)
    {
    }
  }
}

function _bl_close_pressed(event, el)
{
  if (el.getAttribute("bl_absorb_events") != null && event)
  {
    bl_port_stop_event(event);
  }

  if (el.disabled == "true")
  {
    return;
  }

  window._bl_sys_closeWindow(el.getAttribute("bl_close_reason"));
}

function _bl_button_pressed(event, el)
{
  if (el.getAttribute("bl_absorb_events") != null && event)
  {
    bl_port_stop_event(event);
  }

  if (el.disabled == "true")
  {
    return;
  }
  
  if (!el.bl_pending)
  {
    el.bl_pending = true;
    
    if (!el.tabIndex)
    {
      el.tabIndex = -1;
    }
    
    cb_button_focus(el);
    
    var xmlStr;
    var systemMsg = true;
    
    if (el.cb_timerFired)
    {
      xmlStr = "<timer/>";
    }
    else
    {
      systemMsg = false;
      xmlStr = "<changed/>";
    }
    
    cb_sys_performBuddyExecution(el);
    
    bl_mpr_send(xmlStr, el.id, 0, BL_MPR_ASAP, systemMsg);
    
    //now see if custom down image exists, then swap it out for system button, hiding the system button.
    
    if (el.tagName.toLowerCase() == "input")
    {
      cb_sys_set_input_state(el, true);
    }
    else
    {
      if (el.style.visibility != "hidden" && el.style.display != "none")
      {
        bl_sys_img_freeze(el);
        cb_sys_img_down_set(el, false);
        
        var hbuddy = el.getAttribute("bl_hilite_buddy");
        
        if (hbuddy)
        {
          var bel = document.getElementById(hbuddy);
          
          if (bel)
          {
            cb_sys_img_down_set(el, false);
          }
        }
      }
      else
      {
        bl_sys_img_thaw(el);
      }
    }
  }
}

function cb_sys_img_buildSrc(el, imgType)
{
  if (el.getAttribute("cb_tag") == "SIB")
  {
    var imgs = el.getAttribute(imgType);
    
    if (imgs != null)
    {
      var list      = imgs.split(";");
      var bcap      = bl_sb_getBeginCap(el);
      var ecap      = bl_sb_getEndCap(el);
      var center    = bl_sb_getCenter(el);
      var padTop   = 1;
      var padLeft  = 1;
      var padRight = 1;

      if (imgType == "do" || imgType == "pr")
      {
        padTop   = 2;
        padLeft  = 2;
        padRight = 0;
      }
      else if (imgType == "pd")
      {
        padTop   = 3;
        padLeft  = 2;
        padRight = 0;
      }
      
      bcap.src = list[0];
      
      with (center.style)
      {
        backgroundImage  = "url(" + list[1] + ")";
        paddingTop       = padTop + "px";
        paddingLeft      = padLeft + "px";
        paddingRight     = padRight + "px";
      }
      
      ecap.src = list[2];
      return true;
    }
  }
  else
  {
    var name = el.getAttribute("bl_imgRoot");
    
    if (name)
    {
      el.src = name + imgType + ".gif";
      return true;
    }
    else
    {
      var imgName = el.getAttribute(imgType);
      
      if (imgName)
      {
        if (el.getAttribute("bl_alphaLoad") != null)
        {
          el.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" 
                            + imgName 
                            + "',  sizingMethod='scale')";
        }
        else
        {
          el.src = imgName;
        }
        
        return true;
      }
    }
  }
  return false;
}

function cb_sys_disabled(el)
{
  while (el)
  {
    if (el.getAttribute && el.getAttribute("disabled"))
    {
      return true;
    }
    el = el.parentNode;
  }
  return false;
}

function bl_sys_iframeDisabled(iframeEl)
{
  return (cb_sys_disabled(iframeEl) || (iframeEl.container && iframeEl.container.style.display == "none"));
}

function cb_sys_img_down_set(el, selected)
{
  if (el.getAttribute("cb_just_ov") != null)
  {
    cb_sys_img_buildSrc(el, "ov");
  }
  else if (el.getAttribute("cb_just_do") != null || !selected || el.getAttribute("bl_is_value") == null || !cb_sys_img_buildSrc(el, "pd"))
  {
    cb_sys_img_buildSrc(el, "do");
  }
}

function bl_sys_img_disable(el, selected)
{
  var origIn    = el.bl_mouseIsIn;
  var origDown  = el.bl_mouseIsDown;
  
  el.bl_mouseIsIn   = false;
  el.bl_mouseIsDown = false;
  if (!selected && el.getAttribute("cb_just_en") != null)
  {
    cb_sys_img_buildSrc(el, "en");
  }
  else if (selected && el.getAttribute("cb_just_pr") != null)
  {
    cb_sys_img_buildSrc(el, "pr");
  }
  else
  {
    if (!selected || el.getAttribute("bl_is_value") == null || !cb_sys_img_buildSrc(el, "pi"))
    {
      if (!cb_sys_img_buildSrc(el, "di"))
      {
        cb_sys_img_buildSrc(el, "en");
      }
    }
  }

  el.bl_mouseIsIn   = origIn;
  el.bl_mouseIsDown = origDown;
}

function bl_sys_img_set(el, selected, mouseIn)
{
  if (selected)
  {
    if (mouseIn)
    {
      if (el.getAttribute("bl_is_value") == null || !cb_sys_img_buildSrc(el, "po"))
      {
        cb_sys_img_buildSrc(el, "do");
      }
    }
    else
    {
      if (el.getAttribute("bl_is_value") == null || !cb_sys_img_buildSrc(el, "pr"))
      {
        cb_sys_img_buildSrc(el, "do");
      }
    }
  }
  else
  {
    if (!mouseIn || !cb_sys_img_buildSrc(el, "ov"))
    {
      cb_sys_img_buildSrc(el, "en");
    }
  }
}

function cb_sys_img_leave_set(el, selected)
{
  if (selected)
  {
    if (el.getAttribute("bl_is_value") == null)
    {
      cb_sys_img_buildSrc(el, "do");
    }
    else
    {
      if (!el.bl_mouseIsDown || !cb_sys_img_buildSrc(el, "po"))
      {
        if (!cb_sys_img_buildSrc(el, "pr"))
        {
          cb_sys_img_buildSrc(el, "do");
        }
      }
    }
  }
  else
  {
    if (!el.bl_mouseIsDown || !cb_sys_img_buildSrc(el, "ov"))
    {
      cb_sys_img_buildSrc(el, "en");
    }
  }
}

function cb_sys_img_enter_set(el, selected)
{
  if (selected)
  {
    if (el.bl_mouseIsDown)
    {
      if (el.getAttribute("cb_just_do") != null || el.getAttribute("bl_is_value") == null || !cb_sys_img_buildSrc(el, "pd"))
      {
        cb_sys_img_buildSrc(el, "do");
      }
    }
    else
    {
      if (el.getAttribute("bl_is_value") == null || !cb_sys_img_buildSrc(el, "po"))
      {
        cb_sys_img_buildSrc(el, "ov");
      }
    }
  }
  else
  {
    if (el.getAttribute("cb_just_ov") != null || !el.bl_mouseIsDown || !cb_sys_img_buildSrc(el, "do"))
    {
      cb_sys_img_buildSrc(el, "ov");
    }
  }
}

function cb_sys_img_reset(el)
{
  if (!el.bl_mouseIsIn || !cb_sys_img_buildSrc(el, "ov"))
  {
    cb_sys_img_buildSrc(el, "en");
  }
}

function bl_sys_img_freeze(el)
{
  var hbuddy = el.getAttribute("bl_hilite_buddy");
  
  el.setAttribute("bl_frozen", true);
  if (hbuddy)
  {
    var bel = document.getElementById(hbuddy);
    
    if (bel)
    {
      bel.setAttribute("bl_frozen", true);
    }
  }
}

function bl_sys_img_thaw(el)
{
  var hbuddy = el.getAttribute("bl_hilite_buddy");
  
  el.removeAttribute("bl_frozen");
  if (hbuddy)
  {
    var bel = document.getElementById(hbuddy);
    
    if (bel)
    {
      bel.removeAttribute("bl_frozen");
    }
  }
}

function _bl_sys_img_up_exe(event, el)
{
  el = bl_port_computeEventEl(el);
  
  bl_port_releaseCapture(el);
  el.bl_mouseIsDown = false;

  var func = window[el.getAttribute("bl_function_up")];
  if (func)
  {
    func(event, el);
  }
  if (!cb_sys_disabled(el) && (el.getAttribute("bl_frozen") == null))
  {
    var selected = (el.getAttribute("bl_selected") != null);
    
    bl_sys_img_set(el, selected, el.bl_mouseIsIn);
    
    var hbuddy = el.getAttribute("bl_hilite_buddy");
    
    if (hbuddy)
    {
      var bel = document.getElementById(hbuddy);
      
      if (bel)
      {
        bl_sys_img_set(bel, selected, el.bl_mouseIsIn);
      }
    }
  }
  
  if (el.getAttribute("bl_absorb_events") != null && event)
  {
    bl_port_stop_event(event);
  }
}

function _bl_sys_img_down_exe(event, el)
{
  if (!cb_sys_disabled(el) && (el.getAttribute("bl_frozen") == null))
  {
    bl_kb_focusOnElement(bl_port_getEventTarget(event));
    bl_port_setCapture(el);

    if (el.getAttribute("bl_absorb_events") != null && event)
    {
      bl_port_stop_event(event);
    }
    
    var resetImage = true;
    var selected   = (el.getAttribute("bl_selected") != null);
    
    cb_sys_img_down_set(el, selected);
    
    var hbuddy = el.getAttribute("bl_hilite_buddy");
    var bel    = null;
    
    if (hbuddy)
    {
      bel = document.getElementById(hbuddy);
      
      if (bel)
      {
        cb_sys_img_down_set(bel, selected);
      }
    }
    
    el.bl_mouseIsDown = true;
    
    var func = window[el.getAttribute("bl_function")];
    if (func)
    {
      func(event, el);
    }
  }
}

function _bl_verify_img(event, el)
{
  if (el.readyState == "uninitialized")
  {
    el.title = "Image path: '" 
             + el.src 
             + "' could not be resolved. \n" 
             + el.title;
    el.src   = "/" 
             + bl_version 
             + "/res/img/agent.gif";
  }
}

 function _bl_sys_img_leave(event, el)
 {
   window.bl_w3c_overImg = null;
   el.bl_mouseIsIn       = false;
   
   if (!cb_sys_disabled(el) && (el.getAttribute("bl_frozen") == null))
   {
     var selected = (el.getAttribute("bl_selected") != null);
     
     cb_sys_img_leave_set(el, selected);
     
     var hbuddy = el.getAttribute("bl_hilite_buddy");
     
     if (hbuddy)
     {
       var bel = document.getElementById(hbuddy);
       
       if (bel)
       {
         cb_sys_img_leave_set(bel, selected);
       }
     }
     
     var func = window[el.getAttribute("bl_flyover")];
     if (func)
     {
       func(event, el, true);
     }
   }
   if (el.getAttribute("bl_absorb_events") != null && event)
   {
     bl_port_stop_event(event);
   }
 }
 
 function _bl_sys_img_enter(event, el)
 {
   if (bl_port_contains(el, bl_port_getEventTarget(event), true))
   {
     window.bl_w3c_overImg = el;
     el.bl_mouseIsIn       = true;
     
     if (!cb_sys_disabled(el) && (el.getAttribute("bl_frozen") == null))
     {
       var funcName = el.getAttribute("bl_flyover");
       var selected = (el.getAttribute("bl_selected") != null);
       
       cb_sys_img_enter_set(el, selected);
       
       var hbuddy = el.getAttribute("bl_hilite_buddy");
       
       if (hbuddy)
       {
         var bel = document.getElementById(hbuddy);
         
         if (bel)
         {
           cb_sys_img_enter_set(bel, selected);
         }
       }
       
       var timerDelay = el.getAttribute("bl_down_timer");
       if (timerDelay != null)
       {
         window.setTimeout('_bl_sys_img_timer_down("' + el.id + '");', parseInt(timerDelay));
       }
       
       var func = window[el.getAttribute("bl_flyover")];
       if (func)
       {
         func(event, el, false);
       }
     }
   }
   if (el.getAttribute("bl_absorb_events") != null && event)
   {
     bl_port_stop_event(event);
   }
 }
 
function _bl_sys_img_up(event, el)
{
  el = bl_port_computeEventEl(el);

  var wasDown = el.bl_mouseIsDown;
  bl_port_releaseCapture(el);
  el.bl_mouseIsDown = false;
  
  if (!el.bl_mouseIsIn)
  {
    var func = window[el.getAttribute("bl_flyover")];
    
    if (func)
    {
      func(el, event, true);
    }
  }
  
  if (!cb_sys_disabled(el) && (el.getAttribute("bl_frozen") == null))
  {
    if (el.bl_mouseIsIn && wasDown)
    {
      var func = window[el.getAttribute("bl_function")];
      
      if (func)
      {
        func(event, el);
      }
    }
    
    // checking again as it could have ben set in the eval above.
    if (!cb_sys_disabled(el) && (el.getAttribute("bl_frozen") == null))
    {
      var selected = (el.getAttribute("bl_selected") != null);
      
      bl_sys_img_set(el, selected, el.bl_mouseIsIn);
      
      var hbuddy = el.getAttribute("bl_hilite_buddy");
      
      if (hbuddy)
      {
        var bel = document.getElementById(hbuddy);
        
        if (bel)
        {
          bl_sys_img_set(bel, selected, el.bl_mouseIsIn);
        }
      }
    }
  }
  
  if (el.getAttribute("bl_absorb_events") != null && event)
  {
    bl_port_stop_event(event);
  }
}

function _bl_sys_img_timer_down(id)
{
  var el = document.getElementById(id);
  if (el && el.bl_mouseIsIn && el.bl_mouseIsDown)
  {
    var func = window[el.getAttribute("bl_function")];
    
    if (func)
    {
      func(null, el);
      window.setTimeout('_bl_sys_img_timer_down("' + el.id + '");', parseInt(el.getAttribute("bl_down_timer")));
    }
  }
}

function _bl_sys_imgKeyDown(event, el)
{
  if (event.virtualKey == "space")
  {
    bl_port_clickButton(el);
    bl_port_killEvent(event);
  }
  else if (event.virtualKey == "enter")
  {
    // If there IS a default "enter" action, do it and cancel the event.
    // If there is NOT a default "enter" action, click this button and cancel the event.
    var topWin = cb_sys_getTopWindow();
    if (!topWin.bl_kb_doEnter())
    {
      bl_port_clickButton(el);
    }
    bl_port_killEvent(event);
  }
}

function _bl_sys_img_down(event, el)
{
  if (!cb_sys_disabled(el) && (el.getAttribute("bl_frozen") == null))
  {
    bl_kb_focusOnElement(bl_port_getEventTarget(event));
    bl_port_setCapture(el);
    if (!el.tabIndex)
    {
      el.tabIndex = -1;
    }
    if (el.getAttribute("cb_tag") != null)
    {
      cb_sys_focusUpdate();
    }
    el.bl_mouseIsDown = true;
    
    var selected = (el.getAttribute("bl_selected") != null);
    cb_sys_img_down_set(el, selected);
    
    var hbuddy = el.getAttribute("bl_hilite_buddy");
    
    if (hbuddy)
    {
      var bel = document.getElementById(hbuddy);
      
      if (bel)
      {
        cb_sys_img_down_set(bel, selected);
      }
    }
  }
  
  if (el.getAttribute("bl_absorb_events") != null && event)
  {
    bl_port_stop_event(event);
  }
  
  var timerDelay = el.getAttribute("bl_down_timer");
  if (timerDelay != null)
  {
    window.setTimeout('_bl_sys_img_timer_down("' + el.id + '");', parseInt(timerDelay));
  }
}
function _bl_sys_absorbEvent(event, el)
{
  if (event)
  {
    bl_port_stop_event(event);
  }
}

function bl_sys_button_html(id, name, toolTip, downEx, action, attrs, inEdit, images)
{
  var html = (inEdit)? "<img hidefocus='true' title='":"<img unselectable='on' hidefocus='true' title='"  
           + toolTip
           + "' id='"
           + id
           + "' ";
  
  if (!inEdit)
  {
    if (bl_browserInfo.ie)
    {
      html += "onmouseleave='_bl_sys_img_leave(event, this)' onmouseenter='_bl_sys_img_enter(event, this)'";
    }
    else
    {
      html += "onmouseout='_bl_sys_img_leave(event, this)' onmouseover='_bl_sys_img_enter(event, this)'";
    }
    
    if (images)
    {
      html += " en='"
            + images.enable
            + "' ov='"
            + images.over
            + "' do='"
            + images.down
            + "' di='"
            + images.disable
            + "' ";
    }
    else
    {
      html += " bl_imgRoot='/" 
            + bl_version 
            + "/res/"
            + name
            + "' ";
    }
    
    html += (downEx) ? "onmousedown='_bl_sys_img_down_exe(event, this)' onmouseup='_bl_sys_img_up_exe(event, this)' " :
                       "onmousedown='_bl_sys_img_down(event, this)' onmouseup='_bl_sys_img_up(event, this)' ";
  }
    
  if (attrs)
  {
    html += attrs;
  }
  
  html += " bl_function='" + action + "'";

  if (images)
  {
    html += " src='" + images.enable + "'/>";
  }
  else
  {
    html += " src='/" + bl_version + "/res/" + name + "en.gif'/>";
  }
  
  return html;
}

function bl_btn_cleanUpForEl(el)
{
  var list = window.bl_btn_moveList;
  
  if (list)
  {
    var len = list.length;
    
    for (var i = len - 1; i >= 0; i--)
    {
      var item = list[i];
      
      if (!item.el.parentNode)
      {
        item.move = null;
        item.el   = null;
        list.splice(i, 1);
      }
    }
  }
}

function bl_btn_cleanUpMove()
{
  var list = window.bl_btn_moveList;

  if (list)
  {
    var item = list.pop();
    
    while (item != undefined)
    {
      item.move = null;
      item.el   = null;
      item      = list.pop();
    }
    
    window.bl_btn_moveList = null;
  }
}

function bl_btn_registerMoves(el, func)
{
  if (func)
  {
    var item = { el:el, move:func };
    var list = window.bl_btn_moveList;
    
    if (!list)
    {
      window.bl_btn_moveList    = list = [];
      document.body.onmousemove = bl_btn_move;
    }
    
    list.push(item);
  }
}

function bl_btn_move(event)
{
  var list = window.bl_btn_moveList;
  
  if (list)
  {
    var len = list.length;

    if (!event)
    {
      event = window.event;
    }
    
    for (var i = 0; i < len; i++)
    {
      item = list[i];
      item.move(event, item.el);
    }
  }
}

// this function is for handling the up action foe and image control
// it gets invoked by the image button functionality (in particular
// it gets called when the onmouseup event triggers for the <IMG> tag.)
function _bl_image_action(event, el)
{
  if (!el.bl_pending)
  {
    el.bl_pending = true;
    
    cb_sys_performBuddyExecution(el);
    
    if (!el.cb_noSetaFocus && !el.isDisabled && el.style.display != "none")
    {
      bl_port_focus(el);
    }
    
    var func = window[el.getAttribute("bl_img_action")];
    if (func)
    {
      func(el);
    }
    else
    {
      bl_mpr_send("<execute />", el.id, 0);
    }
    
    if (el.style.visibility != "hidden" && el.style.display != "none")
    {
      bl_sys_img_freeze(el);
      cb_sys_img_down_set(el, false);
      var hbuddy = el.getAttribute("bl_hilite_buddy");
      
      if (hbuddy)
      {
        var bel = document.getElementById(hbuddy);
        
        if (bel)
        {
          cb_sys_img_down_set(el, false);
        }
      }
    }
    else
    {
      bl_sys_img_thaw(el);
    }
  }
}

function bl_set_image(cmd, el)
{
  var list = cmd.childNodes;

  el.src = bl_port_get_text(list.item(0));

  if (list.length > 3)
  {
    el.setAttribute("en", bl_port_get_text(list.item(1)));
    el.setAttribute("ov", bl_port_get_text(list.item(2)));
    el.setAttribute("do", bl_port_get_text(list.item(3)));

    if (list.length > 4)
    {
      el.setAttribute("di", bl_port_get_text(list.item(4)));
    }
  }
}

function _bl_img_handler(item, el)
{
  var cmd  = item.firstChild;
  var name = cmd.nodeName;
  
  if (name == "srcChanged")
  {
    bl_set_image(cmd, el);
  }
  else if (name == "done")
  {
    window.setTimeout("_bl_img_clear(" + el.id + ")", 10);
  }
}

function _bl_img_clear(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    if (el.getAttribute("bl_frozen") != null)
    {
      cb_img_clear_state(el);
    }
    el.bl_pending = false;
  }
}

function _bl_stringHandler(item, el)
{
  var cmd = item.firstChild;
  
  if (cmd.nodeName == "srcChanged")
  {
    var parentID = cmd.firstChild;
    var imgEl    = document.getElementById(bl_port_get_text(parentID));
    
    imgEl.src  = bl_port_get_text(cmd.childNodes.item(1));
  }
}

function _bl_radimg_handler(item, el)
{
  var cmd = item.firstChild;
  var cmdName = cmd.nodeName;
  
  if (cmdName == "isSelected")
  {
    var selected = (bl_port_get_text(cmd) == "true");
    
    if (selected)
    {
      el.setAttribute("bl_selected", true);
      if (el.getAttribute("bl_toggle") == null)
      {
        bl_sys_img_freeze(el);
      }
      bl_sys_img_set(el, true, false);
    }
    else
    {
      el.removeAttribute("bl_selected");
      if (el.getAttribute("bl_toggle") == null)
      {
        bl_sys_img_thaw(el);
      }
      bl_sys_img_set(el, false, el.bl_mouseIsIn);
    }
  }
  else if (cmdName == "label")
  {
    bl_sb_setLabel(el, bl_port_get_text(cmd));
  }
}

function bl_sb_setLabel(el, text)
{
  // we are going to replace the contents of all of the middle part of the style button. <img><span></span>
  // sometimes it is the <div><img/><span></span></div>
  var textEl = el.childNodes[1];
  
  textEl.innerHTML = text;
  
  if (bl_kb_activeControl == el)
  {
    bl_sb_showFocus(el);
  }
}
/*return the span that has the text for the stylebutton*/
function bl_sb_getText(el)
{
  var item = el.childNodes[1].lastChild;
  
  if (item.tagName == "DIV")
  {
    item = item.lastChild;
  }
  
  return item;
}

function bl_sb_getEndCap(el)
{
  return el.lastChild;
}

function bl_sb_getBeginCap(el)
{
  return el.firstChild;
}

function bl_sb_getCenter(el)
{
  return el.childNodes[1];
}

function bl_sb_showFocus(el)
{
  var span = bl_sb_getText(el);
  var cs   = bl_port_getComputedStyle(span);
  var cssText =  "overflow:hidden;padding-left:1px;padding-bottom:1px;padding-right:1px;border: 1px dotted "+cs["color"]+";";

  if (bl_browserInfo.ie)
  {
    cssText += "display:inline-block;"    
  }
  else if (bl_browserInfo.safari)
  {
    cssText += "vertical-align:middle;";
  }
  else
  {
    cssText += "";
  }
  
  span.style.cssText = cssText;
}

function bl_sb_hideFocus(el)
{
  var span = bl_sb_getText(el);
  var cs   = bl_port_getComputedStyle(span);
  var cssText = "overflow:hidden;padding-left:2px;padding-bottom:2px;padding-right:2px;padding-top:1px;";
  
  if (bl_browserInfo.ie)
  {
    cssText += "display:inline-block;"    
  }
  else if (bl_browserInfo.safari)
  {
    cssText += "vertical-align:middle;";
  }
  else
  {
    cssText += "";
  }
  
  span.style.cssText = cssText;
}


function _bl_radimg_action(event, el)
{
  var selected = (el.getAttribute("bl_selected") != null);
  var response = null;
  var toggle   = (el.getAttribute("bl_toggle") != null);
  var buddyId  = el.getAttribute("cb_exe_buddy_id");

  if (!selected || toggle)
  {
    var xmlStr = "<isSelected>";
    if (selected)
    {
      if (!toggle)
      {
        bl_sys_img_thaw(el);
      }
      
      el.removeAttribute("bl_selected");
      xmlStr  += "false";
    }
    else
    {
      el.setAttribute("bl_selected", true);
      xmlStr  += "true";
      
      if (!toggle)
      {
        bl_sys_img_freeze(el);
        bl_sys_img_set(el, true, false);
      }
    }
    
    xmlStr += "</isSelected>";
    
    bl_mpr_send(xmlStr, el.id, -1, bl_sys_readSendType(el));
  }
}

function _bl_img_timer_fire(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    if (!el.getAttribute("disabled"))
    {
      el.cb_timeout_id  = null;
      el.cb_noSetaFocus = true;
      el.cb_timerFired  = true;
      _bl_button_pressed(null, el);
      el.cb_timerFired  = false;
      el.cb_noSetaFocus = false;
    }
  }
}

function cb_radimg_callTimer(el)
{
  if (el)
  {
    var freq = 60000;
    if (el.cb_timeout_id)
    {
      window.clearTimeout(el.cb_timeout_id);
    }
    
    var bl_interval = el.getAttribute("bl_interval");
    if (bl_interval)
    {
      freq = parseInt(bl_interval);
      if (isNaN(freq) || !freq)
      {
        el.cb_timeout_id = null;
        return ;
      }
    }
    else
    {
      el.cb_timeout_id = null;
      return ;
    }
    el.cb_timeout_id = window.setTimeout("_bl_img_timer_fire(" + el.id + ")", freq);
  }
}

function _bl_radimgInit(id, buddyName)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    el.cb_timeout_id = null;
    cb_radimg_callTimer(el);
  }
  
  if (buddyName)
  {
    _bl_sys_funcBuddyInit(id, buddyName);
  }
}

function cb_img_clear_state(el)
{
  var selected = (el.getAttribute("bl_selected") != null);
  
  bl_sys_img_thaw(el);
  
  var hbuddy = el.getAttribute("bl_hilite_buddy");
  var bel = null;
  
  if (hbuddy)
  {
    bel = document.getElementById(hbuddy);
  }
  if (cb_sys_disabled(el))
  {
    bl_sys_img_disable(el, selected);
    
    if (bel)
    {
      bl_sys_img_disable(bel, selected);
    }
  }
  else
  {
    if (el.bl_mouseIsIn)
    {
      cb_sys_img_enter_set(el, selected)
      
      if (bel)
      {
        cb_sys_img_enter_set(bel, selected);
      }
    }
    else
    {
      cb_sys_img_leave_set(el, selected);
      
      if (bel)
      {
        cb_sys_img_leave_set(bel, selected);
      }
    }
  }
}

function _bl_img_clearButton(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    if (el.tagName.toLowerCase() == "input")
    {
      cb_sys_set_input_state(el, false);
    }
    else
    {
      if (el.getAttribute("bl_frozen") != null)
      {
        cb_img_clear_state(el);
      }
    }
    
    if (el.getAttribute("bl_interval") != null)
    {
      cb_radimg_callTimer(el);
    }
    el.bl_pending = false;
  }
}

function _bl_button_handler(item, el)
{
  var item = item.firstChild;
  var name = item.nodeName;
  
  if (name == "close")
  {
    var closeReason = bl_port_get_text(item);
    
    if (bl_browserInfo.firefox)
    {
      // Gecko seems to use a deferred closing mechanism-- If we call
      // win.close() directly, the window will not actually close until
      // the the user performs an interaction (mouse event, keyboard
      // event, etc).
      //
      // Fix for bug #5038 - http://bugger/bug.php?op=show&bugid=5098
      window.setTimeout("window._bl_sys_closeWindow('" +closeReason+ "')",0);
    }
    else
    {
      window._bl_sys_closeWindow(closeReason);
    }
  }
  else if (name == "srcChanged")
  {
    bl_set_image(item, el);
  }
  else if (name == "interval")
  {
    var nfreq = parseInt(bl_port_get_text(item))
    var freq  = parseInt(el.getAttribute("bl_interval"));
    if (isNaN(nfreq) || !nfreq)
    {
      el.removeAttribute("bl_interval");
    }
    else
    {
      el.setAttribute("bl_interval", bl_port_get_text(item));
    }
    cb_radimg_callTimer(el);
  }
  else if (name == "done")
  {
    window.setTimeout("_bl_img_clearButton(" + el.id + ")", 10);
  }
  else if (name == "text")
  {
    var tagName = el.tagName.toLowerCase();
    
    if (tagName == "input")
    {
      el.value = bl_port_get_text(item)
    }
    else 
    {
      bl_port_setInnerText(el, bl_port_get_text(item));
    }
  }
  else if (name == "label")
  {
    bl_sb_setLabel(el, bl_port_get_text(item));
  }
}

// popup editor
function _bl_pe_pressed(event, el)
{
  bl_port_stop_event(event);
  
  if (el.cb_state != cb_pe_up)
  {
    cb_sys_performBuddyExecution(el);
    cb_pe_open(event, el);
  }
}

function _bl_pe_click(event, el)
{
  bl_port_stop_event(event);
}

function cb_pe_cleanup(el)
{
  el.bl_mouseIsDown = false;
  
  var hbuddy = el.getAttribute("bl_hilite_buddy");
  var bel    = null;
  
  if (hbuddy)
  {
    bel = document.getElementById(hbuddy);
  }
  if (el.bl_mouseIsIn)
  {
    cb_sys_img_buildSrc(el, "ov");
    if (bel)
    {
      cb_sys_img_buildSrc(bel, "ov");
    }
  }
  else
  {
    cb_sys_img_buildSrc(el, "en");
    if (bel)
    {
      cb_sys_img_buildSrc(bel, "en");
    }
  }
  
  bl_sys_img_thaw(el);
  el.cb_state = cb_pe_down;
}


// this juction is for clossing the existing popup on this
// popup editors window.
function cb_pe_close(el)
{
  var doit  = true;
  var popit = bl_sys_getPopupObj();
  
  if (popit)
  {
    var doc  = bl_port_getOverLayDocument(popit);
    var list = doc.images;
    var len  = list.length;
    
    for (var i = 0; i < len; i++)
    {
      if (list[i].bl_mouseIsIn)
      {
        doit        = false;
        el.cb_state = cb_pe_up
        break;
      }
    }
  }
  
  if (el.bl_mouseIsIn)
  {
    doit        = false;
    el.cb_state = cb_pe_up
  }
  
  if (doit)
  {
    cb_sys_popup_close(false);
  }
}

// this function is for making a popup context
// for the popup button and making the call to the server
// for retrieving the popups html
function cb_pe_open(event, el)
{
  bl_sys_img_freeze(el);
  if (el.cb_state == cb_pe_requestUp || el.cb_state == cb_pe_requestDown)
  {
    window.clearTimeout(el.bl_timerID);
  }
  
  el.cb_state = cb_pe_up;
  el.cb_popup_cleanup = cb_pe_cleanup;
  
  var func = window[el.getAttribute("bl_img_action")];
  if (func)
  {
    func(el);
  }
  else
  {
    var mpr          = bl_sys_get_mpr();
    var cascadeClose = (el.getAttribute("bl_pe_no_cascade") == null);
    var context      = new cb_sys_popup_context(el, event, "popup-editor", cascadeClose);
    
    bl_mpr_send("<popup>" + context.id + "</popup>", el.id, 0);
    
    mpr.setPopupContext(context, true);
  }
}

function _bl_peFlyout(event, el)
{
  var delayStr = el.getAttribute("bl_pe_delay");
  var delay    = (delayStr) ? parseInt(delayStr) : 500;
  if (el.cb_state == cb_pe_up)
  {
    el.cb_state = cb_pe_requestDown;
    if (delay)
    {
      el.bl_timerID = window.setTimeout('_bl_peFlyAction("' + el.id + '");', delay);
    }
    else
    {
      cb_pe_close(el);
    }
  }
  else if (el.cb_state == cb_pe_requestUp)
  {
    el.cb_state = cb_pe_down;
    window.clearTimeout(el.bl_timerID);
  }
}

function _bl_pe_handler(item,el)
{
  var cmd = item.firstChild;
  var cmdName = cmd.nodeName;
  
  if (cmdName == "label")
  {
    bl_sb_setLabel(el, bl_port_get_text(cmd));
  }
}

function _bl_pe_flyover(event, el, isLeaving)
{
  if (!el.cb_not_registered)
  {
    el.cb_not_registered = true;
    bl_btn_registerMoves(el, _bl_peFlyout)
  }
  
  if (el.cb_state != cb_pe_up && !isLeaving)
  {
    var delayStr = el.getAttribute("bl_pe_delay");
    var delay    = (delayStr) ? parseInt(delayStr) : 500;
    
    if (el.cb_state == cb_pe_requestDown)
    {
      window.clearTimeout(el.bl_timerID)
    }
    el.cb_state = cb_pe_requestUp;
    
    if (delay)
    {
      el.bl_timerID = window.setTimeout('_bl_peFlyAction("' + el.id + '");', delay);
    }
    else
    {
      cb_pe_open(null, el);
    }
  }
}

function _bl_peFlyAction(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    if (el.cb_state == cb_pe_requestDown)
    {
      cb_pe_close(el);
    }
    else
    {
      cb_pe_open(null, el);
    }
  }
}

var bl_apt_srtTester      = null;
var bl_apt_content        = null;
var bl_apt_factory        = null;
var bl_apt_bgMap          = null;
var bl_apt_olMap          = null;
var bl_apt_unusedSideBars = null;
var bl_apt_fadedFilt      = null;
var bl_apt_normFilt       = null;
var bl_apt_itemHeight     = 20;
var bl_apt_aptText        = null;
var bl_apt_crossList      = null;
var bl_apt_auotScroll     = null;
var bl_apt_autoScrollFunc = null;
var bl_apt_autoScrollArg  = null;

function bl_apt_sanitizeText(txt)
{
  return txt.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;").split("\"").join("&#34;");
}

function bl_apt_computeData(val)
{
  var ret;
  eval("ret = " + bl_port_get_text(val) + ";");
  return ret;
}

function _bl_apt_handler(item, el)
{
  var val  = item.firstChild;
  var name = val.nodeName;
  
  if (name == "value")
  {
    val = val.firstChild;
    var selectBy = bl_port_get_text(val);
    val = val.nextSibling;
    var date = bl_port_get_text(val);
    val = val.nextSibling;
    var apts = bl_apt_computeData(val);

    bl_apt_removeAll(el, false);
    bl_apt_clearSelect(el, false);

    bl_apt_selectByChange(el, selectBy, val.nextSibling);
    bl_apt_procValue(el, date, apts);
    _bl_apt_resize(el, null);
  }
  else if (name == "removePending")
  {
    bl_apt_removePend(el, bl_port_get_text(val));
  }
  else if (name == "remove")
  {
    var idlist = bl_port_get_text(val).split(" ");
    var len    = idlist.length;
    
    for (var i = 0; i < len; i++)
    {
      bl_apt_removeItem(el, idlist[i], len == 1);
    }
    
    if (len > 1)
    {
      bl_apt_recomputeApts(el);
    }
  }
  else if (name == "showTitles")
  {
    var ptr = bl_apt_findTitleParentRow(el.firstChild);
    ptr.style.display = (bl_port_get_text(val) == "0")? "none":"";
  }
  else if (name == "controlReadOnly")
  {
    if (bl_port_get_text(val) == "0")
    {
      el.removeAttribute("bl_readOnly");
    }
    else
    {
      el.setAttribute("bl_readOnly", true);
    }
    bl_apt_setEditSelect(el);
  }
  else if (name == "done")
  {
    window.setTimeout("_bl_apt_image_clear('" + el.id + "','" + bl_port_get_text(val) + "')", 10);
  }
  else if (name == "removeselect")
  {
    bl_apt_removeItem(el, el.selectedId, true);
  }
  else if (name == "add")
  {
    var pend = val.attributes.getNamedItem("pendid");
    var dataItem = bl_apt_computeData(val);
    
    if (pend)

    {
      bl_apt_handlePend(el, dataItem, pend);
    }
    else
    {
      bl_apt_addItem(el, dataItem);
    }
  }
  else if (name == "set")
  {
    var dataItem = bl_apt_computeData(val);
    bl_apt_addSet(el, dataItem);
  }
  else if (name == "removeall")
  {
    bl_apt_removeAll(el, true);
  }
  else if (name == "interval")
  {
    var text = bl_port_get_text(val);
    var list = text.split(" ");

    el.setAttribute("bl_interval", list[0]);
    el.setAttribute("bl_legend", list[1]);
    el.setAttribute("bl_on", list[2]);
    el.setAttribute("bl_off", list[3]);
    bl_apt_setInterval(el, el.getAttribute("bl_interval"));
  }
  else if (name == "timeType")
  {
    bl_apt_changeTimeType(el, bl_port_get_text(val));
  }
  else if (name == "allowAllDay")
  {
    el.removeAttribute("bl_noAllday");
  }
  else if (name == "noAllDay")
  {
    el.setAttribute("bl_noAllday", true);
  }
  else if (name == "defaultColor")
  {
    bl_apt_setDefaultColor(el, val);
  }
  else if (name == "tooltipLabel")
  {
    el.setAttribute("bl_tooltipLabel", bl_port_get_text(val));
  }
  else if (name == "no_filter_images")
  {
    bl_apt_change_imageFilter(el, false);
  }
  else if (name == "filter_images")
  {
    bl_apt_change_imageFilter(el, true);
  }
  else if (name == "adjust_pos")
  {
    bl_apt_adjustPosition(el);
    bl_apt_setEditSelect(el);
  }
  else
  {
    bl_apt_change(el, name, val);
  }
}

function bl_apt_setDefaultColor(el, val)
{
  var color = bl_port_get_text(val);
  
  el.setAttribute("bl_defaultColor", color);
  
  if (el.getAttribute("bl_useDefault") != null)
  {
    var dObj = el.firstChild.cbApt;
    var len  = dObj.length();
    
    for (var i = 0; i < len; i++)
    {
      bl_port_setBGColor(dObj.getDay(i).selEl.style, color);
    }
  }
}

function bl_apt_change_imageFilter(el, val)
{
  var currVal = (el.getAttribute("bl_filterImage") != null);
  
  if (val != currVal)
  {
    if (val)
    {
      el.setAttribute("bl_filterImage", true);
    }
    else
    {
      el.removeAttribute("bl_filterImage");
    }
        
    var list = el.cbAptList;
    var len  = el.cbAptLen;
    
    for (var i = 0; i < len; i++)
    {
      list[i].filterImage(val);
    }
  }
}

function bl_apt_cleanView(d)
{
  var v = d.view;
  bl_apt_setViewVisibility(v, "hidden");
  
  if (v.parentNode != null)
  {
    v.parentNode.removeChild(v);
  }
  var sb = d.sideBar;
  
  if (sb)
  {
    bl_apt_gleanSideBars(sb);
    sb.style.visibility = "hidden";
    
    if (sb.parentNode != null)
    {
      sb.parentNode.removeChild(sb);
    }
  }
  return d.dIndex;
}

function bl_apt_clearDataView(dObj, d, list)
{
  if (dObj && d)
  {
    var ld = d.linkData;

    dObj.remove(d, true);
    
    bl_apt_cleanView(d);

    if (list)
    {
      list.push(d);
    }
    
    if (ld)
    {
      bl_apt_cleanView(ld);
      
      if (list)
      {
        list.push(ld);
      }
    }
  }
}

function bl_apt_extractApt(d, doUpdate, list)
{
  if (d.dIndex != undefined && d.dIndex >= 0)
  {
    var ap = d.controlEl.firstChild;
    
    bl_apt_clearDataView(ap.cbApt, d, list);
    
    if (doUpdate)
    {
      bl_apt_updateData(ap, d);
    }
  }
}

function bl_apt_updateData(ap, d)
{
  if (d.dIndex != undefined && d.dIndex >= 0)
  {
    var ld = d.linkData;
    
    bl_apt_updateDay(ap, d.dIndex, d.isAllDay);
    if (ld)
    {
      bl_apt_updateDay(ap, ld.dIndex, ld.isAllDay);
    }
  }
}

function bl_apt_changeTimeType(el, val)
{
  var list    = el.cbAptList;
  var len     = el.cbAptLen;
  var valList = val.split(" ");

  el.setAttribute("bl_timeType", valList[0]);
  el.setAttribute("bl_legend", valList[1]);
  bl_apt_setInterval(el, el.getAttribute("bl_interval"));

  for (var i = 0; i < len; i++)
  {
    bl_apt_setContentStr(list[i], false, false);
  }
}

function bl_apt_change(el, name, val)
{
  var id = val.getAttribute("id");
  if (id)
  {
    var list = el.cbAptList;
    var i    = bl_apt_findIndex(list, el.cbAptLen, id);
    
    if (i >= 0)
    {
      var d = list[i];
      
      if (d.dIndex != undefined && d.dIndex >= 0 && d.dIndex < el.firstChild.cbApt.length())
      {
        if (name == "content")
        {
          bl_apt_setItemContent(d, bl_port_get_text(val));
        }
        else if (name == "qualifier")
        {
          bl_apt_setItemLocation(d, bl_port_get_text(val));
        }
        else if (name == "remind")
        {
          d.remind = (bl_port_get_text(val) == "true");
          bl_apt_setContentStr(d, false, false);
        }
        else if (name == "border")
        {
          bl_apt_setBorder(d, bl_port_get_text(val));
        }
        else if (name == "background")
        {
          d.back = parseInt(bl_port_get_text(val));
          if (d.back < 0 || d.back > bl_apt_bgMap.length)
          {
            d.back = 0;
          }
          d.bgClass = bl_apt_bgMap[d.back];
          bl_apt_setDay(d, d.view.isSelected);
          if (d.linkData != null)
          {
            var ld     = d.linkData;
            ld.back    = d.back;
            ld.bgClass = d.bgClass;
            bl_apt_setDay(ld, d.view.isSelected);
          }
        }
        else if (name == "color")
        {
          if (bl_port_get_text(val) != "")
          {
            bl_apt_setColorRaw(d, bl_port_get_text(val));
          }
          else
          {
            bl_apt_setBorder(d, d.origBorder);
          }
        }
        else if (name == "tooltip")
        {
          d.setTooltip(bl_port_get_text(val), true);
        }
        else if (name == "meeting")
        {
          d.isMeeting = (bl_port_get_text(val) == "true");
          if (d.linkData != null)
          {
            d.linkData.isMeeting = d.isMeeting;
          }
          bl_apt_setContentStr(d, false, false);
        }
        else if (name == "readonly")
        {
          d.readonly = (bl_port_get_text(val) == "true");
        }
        else if (name == "recurType")
        {
          d.recurType = bl_port_get_text(val);
          if (d.linkData != null)
          {
            d.linkData.recurType = d.recurType;
          }
          bl_apt_setContentStr(d, false, false);
        }
        else if (name == "idChange")
        {
          d.id = bl_port_get_text(val);
        }
        else if (name == "image")
        {
          d.setImage(bl_apt_computeData(val.firstChild));
          bl_apt_positionImage(d);
        }
        else if (name == "meetingImage")
        {
          d.meetingImage = bl_port_get_text(val);
          if (d.linkData != null)
          {
            d.linkData.meetingImage = d.meetingImage;
          }
          bl_apt_setContentStr(d, false, false);
        }
        else if (name == "image_filter")
        {
          var elFiltered = (d.controlEl.getAttribute("bl_filterImage") != null);
          
          if (elFiltered == undefined)
          {
            elFiltered = 0;
          }
          d.imageFiltered = (bl_port_get_text(val) == "true");
          d.filterImage(elFiltered)
        }
      }
    }
  }
}

function bl_apt_setColorRaw(d, text)
{
  d.computeColor(text, true);
  d.setColor(true);
  bl_apt_positionImage(d);
  bl_apt_setDay(d, d.view.isSelected);
  bl_apt_redoSideBarStyle(d);
  
  if (d.linkData != null)
  {
    var ld = d.linkData;
    bl_apt_setDay(ld, d.view.isSelected);
    bl_apt_redoSideBarStyle(ld);
  }
}

function bl_apt_setBorder(d, text)
{
  if (d.color && d.color != "")
  {
    d.origBorder = text;
    if (d.linkData != null)
    {
      d.linkData.origBorder = text;
    }
  }
  else
  {
    d.bord = parseInt(text);
    if (d.bord < 0 || d.bord > bl_apt_olMap.length)
    {
      d.bord = 0;
    }
    d.origBorder  = text;
    d.olClass     = bl_apt_olMap[d.bord];
    bl_apt_setDay(d, d.view.isSelected);
    bl_apt_redoSideBarStyle(d);
    
    if (d.linkData != null)
    {
      var ld         = d.linkData;
      ld.bord        = d.bord;
      ld.origBorder  = text;
      ld.olClass     = bl_apt_olMap[d.bord];
      bl_apt_setDay(ld, d.view.isSelected);
      bl_apt_redoSideBarStyle(ld);
    }
  }
}

function bl_apt_setSideBarStyle(d, sb)
{
  if (d.bord == 4)
  {
    bl_port_setBGColor(sb.style, d.color);
  }
  
  sb.className = sb.getAttribute("bl_class") + d.olClass
}

function bl_apt_redoSideBarStyle(d)
{
  if (d)
  {
    var sb = d.sideBar;
    
    while (sb)
    {
      bl_apt_setSideBarStyle(d, sb);
      sb = sb.nextSB
    }
  }
}

function bl_apt_removePend(el, pendId)
{
  var alist = el.cbAptList;
  var plist = el.pendingAptList;
  var len   = plist.length;
  
  for (var i = 0; i < len; i++)
  {
    var pItem = plist[i];
    
    if (pItem.id == pendId)
    {
      plist.splice(i);
      bl_apt_extractApt(pItem, true, alist);
      break;
    }
  }
}

function _bl_apt_image_clear(id, dataId)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    var list = el.cbAptList;
    var i = bl_apt_findIndex(list, el.cbAptLen, dataId);
    
    if (i >= 0)
    {
      var d     = list[i];
      var ld    = d.linkData;
      var image = bl_apt_imageItem(d.view);
      
      if (image.getAttribute("bl_frozen") != null)
      {
        cb_img_clear_state(image);
      }
      image.bl_pending = false;
      
      if (ld)
      {
        image = bl_apt_imageItem(ld.view);
        
        if (image.getAttribute("bl_frozen") != null)
        {
          cb_img_clear_state(image);
        }
        image.bl_pending = false;
      }
    }
  }
}

function bl_apt_removeAll(el, updateView)
{
  var list = el.cbAptList;
  var len  = el.cbAptLen;
  var ap   = el.firstChild;
  if (!ap) 
  { 
    return; 
  }
  var dObj = ap.cbApt;
  var sel  = el.selectedEl;
  
  if (sel != null)
  {
    bl_apt_deselectItem(sel, false);
  }
  
  for (var i = 0; i < len; i++)
  {
    bl_apt_clearDataView(dObj, list[i], null);
  }
  
  el.cbAptLen = 0;
  if (updateView)
  {
    bl_apt_recomputeApts(el);
  }
}

function bl_apt_removeItem(el, id, doUpdate)
{
  var list = el.cbAptList;
  var index = bl_apt_findIndex(list, el.cbAptLen, id);
  
  if (index >= 0)
  {
    var d  = list[index];
    var ld = d.linkData;
    
    list.splice(index, 1);
    el.cbAptLen--;
    
    if (id == el.selectedId)
    {
      bl_apt_clearSelect(el, true);
    }
    
    bl_apt_extractApt(d, doUpdate, list);
  }
}

function bl_apt_handlePend(el, data, pendId)
{
  if (data)
  {
    var aList = el.cbAptList;
    var aLen  = aList.length;
    var val   = pendId.nodeValue;
    var plist = el.pendingAptList;
    var plen  = plist.length;
    var d     = null;
    var id    = data.id;

    
    for (var i = plen - 1; i >= 0; i++)
    {
      if (val == plist[i].id)
      {
        d = plist[i];
        plist.splice(i, 1);
        break ;
      }
    }
    
    if (d != null)
    {
      d.id = id;
      if (el.cbAptLen >= aLen)
      {
        aList.push(d)
      }
      else
      {
        aList.splice(el.cbAptLen, 0, d);
      }
      el.cbAptLen++;
      
      bl_apt_addSet(el, data);
      
      if (el.selectedEl == d.view)
      {
        bl_apt_selectItem(d.view, true);
      }
    }
  }
}

function bl_apt_addSet(el, dataItem)
{
  var id     = dataItem.id;
  var list   = el.cbAptList;
  var i      = bl_apt_findIndex(list, el.cbAptLen, id);
  
  if (i >= 0)
  {
    var d         = list[i];
    var ld        = d.linkData;
    var ap        = d.controlEl.firstChild;
    var dObj      = ap.cbApt;
    var oldI      = d.dIndex;
    var oldLI     = -1;
    var oldAllDay = d.isAllDay;
    var oldLD     = ld;
    
    if (ld)
    {
      oldLI = ld.dIndex;
    }
  
    bl_apt_clearDataView(dObj, d, null)  
    bl_apt_setAptData(dataItem, d);
    bl_apt_placeData(dObj, d, new Date(), el.bl_interval_tlt);
    bl_apt_updateData(ap, d);
    
    if (oldI >= 0 && d.dIndex != oldI && (!ld || ld.dIndex != oldI))
    {
      bl_apt_updateDay(ap, oldI, oldAllDay);
    }

    if (oldLI >= 0 && d.dIndex != oldLI && (!ld || ld.dIndex != oldLI))
    {
      bl_apt_updateDay(ap, oldLI, oldAllDay);
    }
  }
  else
  {
    bl_apt_addItem(el, dataItem);
  }
}

function bl_apt_addItem(el, dataItem)
{
  var ap    = el.firstChild;
  var dObj  = ap.cbApt;
  var aList = el.cbAptList;
  var aLen  = aList.length;
  var d;
  
  if (el.cbAptLen >= aLen)
  {
    d = new bl_apt_createAptData(el);
    aList.push(d)
  }
  else
  {
    d = aList[el.cbAptLen];
  }
  
  el.cbAptLen++;
  bl_apt_setAptData(dataItem, d);
  bl_apt_placeData(dObj, d, new Date(), el.bl_interval_tlt);
  bl_apt_updateData(ap, d);
  if (d.id == el.selectedId)
  {
    bl_apt_selectItem(d.view, true)
  }
}

function bl_apt_sendUpdate(d, force)
{
  if (force || d.id)
  {
    var el     = d.controlEl;
    var pendid = null;
    var cmd    = "update";
    if (!d.id)
    {
      if (d.content == "")
      {
        bl_apt_extractApt(d, true, el.cbAptList);
        
        var sel = el.selectedEl;
        if (sel != null)
        {
          bl_apt_deselectItem(sel, false);
        }
        return ;
      }
      pendid = "pend_" + el.pendIdGen;
      el.pendingAptList.push(d);
      el.pendIdGen++;
      cmd  = "new";
      d.id = pendid;
      if (d.linkData != null)
      {
        d.linkData.id = pendid;
      }
    }
    var isAllDay = ((d.sYear != d.eYear || d.sMonth != d.eMonth || d.sDay != d.eDay) &&
                    d.sHour == 0 && d.sMinute == 0 && d.eMinute == 0 && d.eHour == 0);
    var xmlStr = '<' 
               + cmd 
               +  '><allDay>'
               + ((isAllDay) ? 'true' : 'false')
               + '</allDay><content><![CDATA['
               + d.content
               + ']]></content><start>'
               + d.sYear + ' ' + d.sMonth + ' ' + d.sDay + ' ' + d.sHour + ' ' + d.sMinute
               + '</start><end>'
               + d.eYear + ' ' + d.eMonth + ' ' + d.eDay + ' ' + d.eHour + ' ' + d.eMinute
               + '</end><id>'
               + d.id
               + '</id>';
    if (pendid != null)
    {
      xmlStr += '<pendId>' + pendid + '</pendId>';
    }
    
    xmlStr += '</' + cmd +  '>';
    
    bl_mpr_send(xmlStr, el.id, -1, BL_MPR_SYNC);
  }
  else if (!d.readonly)
  {
    bl_apt_content.cbData = d;
    _bl_apt_edit_content();
  }
}

function bl_apt_findIndex(list, len, id)
{
  for (var i = 0; i < len; i++)
  {
    if (list[i].id == id)
    {
      return i;
    }
  }
  return -1;
}

function bl_apt_setInterval(el, itv, type)
{
  itv = (!itv) ? 30 : parseInt(itv);
  
  if (itv != 5 && itv != 6 && itv != 10 && itv != 15 && itv != 30 && itv != 60)
  {
    itv = 30;
  }
  el.bl_interval_val = itv;
  el.bl_interval_cnt = 60/itv;
  
  el.setAttribute("bl_timeType", type);
  el.bl_interval_tlt = (60 / itv) * 24;
  el.cbImgHeight     = (el.bl_interval_tlt * bl_apt_itemHeight) + 1;
  el.cbImgSrc        = el.getAttribute("bl_legend");
  
  var dObj              = el.firstChild.cbApt;
  var imgTd             = dObj.imageEl;
  var img               = imgTd.firstChild;
  imgTd.height          = el.cbImgHeight;
  img.height            = el.cbImgHeight;
  img.src               = el.cbImgSrc;
  dObj.dayTop.height    = (el.bl_interval_cnt * 160) + 1;
  dObj.dayMiddle.height = el.bl_interval_cnt * 180;
  dObj.dayBottom.height = (el.bl_interval_cnt * 140) - 1;
}

function bl_apt_procValue(el, date, apts)
{
  if (date != null)
  {
    el.cbDate = new Date();
    if (date != "0 0 0")
    {
      var dl = date.split(" ");
      el.cbDate.setFullYear(parseInt(dl[0]), parseInt(dl[1]), parseInt(dl[2]));
    }
    
    el.firstChild.cbHeaderType = -1;
    bl_apt_dateChange(el, el.cbDate, el.getAttribute("bl_selectby"));
  }
  
  if (bl_apt_content)
  {
    document.body.appendChild(bl_apt_content);
    with (bl_apt_content.style)
    {
      display = "none";
      left = "-100px";
      top  = "-100px";
      width = 0;
      height = 0;
    }
  }
  bl_apt_loadData(el, apts);
  bl_apt_assignData(el);
  bl_apt_recomputeApts(el);
  bl_apt_setEditSelect(el);
  bl_apt_computeEditTimes(el, 2);
}

function bl_apt_centerHTML()
{
  var ret = window.bl_centerStr;
  
  if (!ret)
  {
    ret = "<center id='content' unselectable='on'></center>";
    window.bl_centerStr = ret;
  }
  
  return ret;
}

function bl_apt_spanHTML()
{
  var ret = window.bl_spanStr;
  
  if (!ret)
  {
    ret = "<span id='content' style='";

    if (bl_browserInfo.firefox2)
    {
      ret += "display:-moz-inline-box;";
    }
    else
    {
      ret += "display:inline-block;";
    }
    
    ret += "'></span>";
    window.bl_spanStr = ret;
  }
  
  return ret;
}

function bl_apt_swapContentTag(d, doActive)
{
  var v      = d.view;
  var div    = bl_apt_getContentDiv(v);
  var cp     = div.lastChild;
  var cpHTML = cp.innerHTML;
  
  div.removeChild(cp);

  if (d.isAllDay)
  {
    bl_port_insertAdjacentHTML(div, "beforeend", bl_apt_centerHTML());
  }
  else
  {
    bl_port_insertAdjacentHTML(div, "beforeend", bl_apt_spanHTML());
  }
  
  div.lastChild.innerHTML = (cpHTML == "")? "&nbsp;":cpHTML;
  
  if (doActive)
  {
    bl_apt_setActiveDay(d);
  }
  else
  {
    bl_apt_setDay(d, v.isSelected);
  }
  
}

function bl_apt_addAllDaySet(d, day, i, date, len)
{
  d.duration = d.aDuration = -1;
  d.dIndex   = i;
  d.isAllDay = true;
  var v      = d.view;
  day.add(d, false);
  
  bl_apt_swapContentTag(d, false);
  
  if (d.sideBar == null)
  {
    d.sideBar = bl_apt_createSideBar();
  }
  
  var dcnt  = 1;
  var curSB = d.sideBar;
  var done  = false;
  
  bl_apt_setSideBarStyle(d, curSB);
  while (!done)
  {
    if (bl_apt_less(d.eYear, date.getFullYear(), d.eMonth, date.getMonth(), d.eDay, date.getDate()))
    {
      break;
    }
    if (bl_apt_equal(d.eYear, date.getFullYear(), d.eMonth, date.getMonth(), d.eDay, date.getDate()))
    {
      if (d.eMark == 0)
      {
        break;
      }
      done = true;
    }
    dcnt++;
    if (curSB.nextSB == null)
    {
      curSB.nextSB = bl_apt_createSideBar();
    }
    curSB = curSB.nextSB;
    bl_apt_setSideBarStyle(d, curSB);
    date.setDate(date.getDate() + 1);
    if (!done)
    {
      done = ((i + dcnt) >= len);
    }
  }
  bl_apt_gleanSideBars(curSB);
  d.dayCnt = (dcnt == 0) ? 1 : dcnt;
  
  if (i + d.dayCnt > len)
  {
    d.dayCnt = len - i;
  }
  
  bl_apt_allDayCnt(date, d, day);
}

function bl_apt_allDayCnt(date, d, day)
{
  date.setFullYear(d.sYear, d.sMonth, d.sDay);
  var dcnt = 0;
  
  while (bl_apt_less(date.getFullYear(), d.eYear, date.getMonth(), d.eMonth, date.getDate(), d.eDay))
  {
    if (date.getDate() == day.day    &&
        date.getMonth() == day.month &&
        date.getFullYear() == day.year)
    {
      d.sIndex = dcnt;
    }
    dcnt++;
    date.setDate(date.getDate() + 1);
  }
  
  if (d.eMark > 0)
  {
    dcnt++;
  }
  d.tDayCnt = dcnt;
}

function bl_apt_addDaySet(d, day, i)
{
  d.dIndex    = i;
  d.aDuration = d.duration = d.eMark - d.sMark;
  d.isAllDay  = false;
  v = d.view;
  day.add(d, false);
  bl_apt_swapContentTag(d, false);
  
  if (d.sideBar == null)
  {
    d.sideBar = bl_apt_createSideBar();
  }
  var sb = d.sideBar;
  bl_apt_setSideBarStyle(d, sb);
  bl_apt_gleanSideBars(sb);
  
  d.dayCnt  = 1;
  d.sIndex  = 0;
  d.tDayCnt = 1;
}

function bl_apt_createLink(d, el)
{
  var l;
  var aList = el.cbAptList;
  var aLen  = aList.length;
  
  if (el.cbAptLen < aLen)
  {
    l = aList.pop();
  }
  else
  {
    l = new bl_apt_createAptData(el);
  }
  
  l.isLink         = true;
  l.linkData       = d;
  l.id             = d.id;
  l.sYear          = d.sYear;
  l.sMonth         = d.sMonth;
  l.sDay           = d.sDay;
  l.sHour          = d.sHour;
  l.sMinute        = d.sMinute;
  l.eYear          = d.eYear;
  l.eMonth         = d.eMonth;
  l.eDay           = d.eDay;
  l.eHour          = d.eHour;
  l.eMinute        = d.eMinute;
  l.content        = d.content;
  l.qual           = d.qual;
  l.contentDisplay = d.contentDisplay;
  l.qualDisplay    = d.qualDisplay;
  l.allDay         = d.allDay;
  l.bord           = d.bord;
  l.back           = d.back;
  l.bgClass        = d.bgClass;
  l.olClass        = d.olClass;
  l.sMark          = d.sMark;
  l.eMark          = d.eMark;
  l.remind         = d.remind;
  l.recurType      = d.recurType;
  l.isMeeting      = d.isMeeting;
  l.readonly       = d.readonly;
  l.color          = d.color;
  l.tooltip        = d.tooltip;
  l.aDuration      = d.aDuration;
  l.sIndex         = d.sIndex;
  l.tDayCnt        = d.tDayCnt;
  l.isAllDay       = d.isAllDay;
  l.sOffset        = d.sOffset;
  l.sOffMark       = d.sOffMark;
  l.eOffset        = d.eOffset;
  l.eOffMark       = d.eOffMark;
  l.imageSrc       = d.imageSrc;
  l.imageTitle     = d.imageTitle;
  l.meetingImage   = d.meetingImage;
  
  bl_apt_setAPTColor(l.view, (l.bord == 4) ? l.color : "");
  l.imageTitle        = d.imageTitle;
  l.imageEN           = d.imageEN;
  l.imagePopup        = d.imagePopup;
  l.imageFiltered     = d.imageFiltered;
  l.imageOV           = d.imageOV;
  l.imageDO           = d.imageDO;
  l.imageDI           = d.imageDI;
  
  bl_apt_setDataImage(l);
  
  if (l.sideBar == null)
  {
    if (d.linkSB)
    {
      l.sideBar = d.linkSB;
      d.linkSB  = null;
    }
    else
    {
      l.sideBar = bl_apt_createSideBar();
    }
  }
  bl_apt_setContentStr(l, true, false);
  bl_port_copy_opacity(d.view, l.view)
  return l;
}

function bl_apt_greq(y1, y2, m1, m2, d1, d2)
{
  return ((y1 > y2) || (y1 == y2 && m1 > m2) || (y1 == y2 && m1 == m2 && d1 >= d2));
}

function bl_apt_great(y1, y2, m1, m2, d1, d2)
{
  return ((y1 > y2) || (y1 == y2 && m1 > m2) || (y1 == y2 && m1 == m2 && d1 > d2));
}

function bl_apt_less(y1, y2, m1, m2, d1, d2)
{
  return ((y1 < y2) || (y1 == y2 && m1 < m2) || (y1 == y2 && m1 == m2 && d1 < d2));
}

function bl_apt_lesseq(y1, y2, m1, m2, d1, d2)
{
  return ((y1 < y2) || (y1 == y2 && m1 < m2) || (y1 == y2 && m1 == m2 && d1 <= d2));
}

function bl_apt_equal(y1, y2, m1, m2, d1, d2)
{
  return (y1 == y2 && m1 == m2 && d1 == d2);
}

function bl_apt_placeData(dObj, aData, date, itvTlt)
{
  var v;
  var j   = 0;
  var day = dObj.getDay(j);
  var len = dObj.length();
  aData.linkData = null;
  var ys  = aData.sYear;
  var ms  = aData.sMonth;
  var ds  = aData.sDay;
  var ye  = aData.eYear;
  var me  = aData.eMonth;
  var de  = aData.eDay;
  
  aData.dIndex = undefined;
  
  if (bl_apt_less(ys, day.year, ms, day.month, ds, day.day) &&
      bl_apt_greq(ye, day.year, me, day.month, de, day.day))
  {
    if (ye == day.year && me == day.month && de == day.day && aData.eHour == 0 && aData.eMinute == 0)
    {
      return ;
    }
    
    date.setFullYear(day.year, day.month, day.day - 1);
    
    if ((ys == date.getFullYear() && ms == date.getMonth() && ds == date.getDate()) &&
        (ye == day.year && me == day.month && de == day.day)                        &&
        (aData.eMark < aData.sMark))
    {
      bl_apt_addDaySet(aData, day, j);
      aData.aDuration = aData.eMark + (itvTlt - aData.sMark);
      aData.duration  = aData.eMark;
      aData.sMark     = 0;
      return;
    }
    date.setFullYear(day.year, day.month, day.day + 1);
    bl_apt_addAllDaySet(aData, day, j, date, len);
  }
  else
  {
    for (; j < len; j++)
    {
      day = dObj.getDay(j);
      if (day.year == ys  && day.month == ms  && day.day == ds)
      {
        if (aData.allDay)
        {
          date.setFullYear(day.year, day.month, day.day + 1);
          bl_apt_addAllDaySet(aData, day, j, date, len);
          break;
        }
        else if (day.year  == aData.eYear   &&
                 day.month == aData.eMonth  &&
                 day.day   == aData.eDay)
        {
          bl_apt_addDaySet(aData, day, j);
          break;
        }
        else
        {
          date.setFullYear(day.year, day.month, day.day + 1);
          if (aData.eYear  == date.getFullYear()  &&
              aData.eMonth == date.getMonth()     &&
              aData.eDay   == date.getDate()      &&
              aData.eMark < aData.sMark)
          {
            var k  = j + 1;
            var em = aData.eMark;
            bl_apt_addDaySet(aData, day, j);
            
            aData.eMark     = itvTlt;
            aData.duration  = itvTlt - aData.sMark;
            aData.aDuration = aData.duration + em;
            if (k < len && em > 0)
            {
              var ld = bl_apt_createLink(aData, aData.controlEl);
              aData.linkData = ld;
              bl_apt_addDaySet(ld, dObj.getDay(k), k);
              ld.sMark     = 0;
              ld.eMark     = em;
              ld.duration  = em;
              ld.aDuration = aData.aDuration;
            }
            break;
          }
          else
          {
            bl_apt_addAllDaySet(aData, day, j, date, len);
            break;
          }
        }
      }
    }
  }
}

function bl_apt_emptyList(l)
{
  var d = l.pop();
  while (d != undefined)
  {
    bl_apt_setViewVisibility(d.view, "hidden");
    
    var sb = d.sideBar;
    while (sb != null)
    {
      sb.style.visibility = "hidden";
      sb = sb.nextSB;
    }
    
    d = l.pop();
  }
}

function bl_apt_clearData(cleanup)
{
  lst = this.list;
  var len = lst.length;
  for (var i = 0; i < len; i++)
  {
    lst[i].empty(cleanup);
  }
  
  if (cleanup)
  {
    lst.splice(0, len);
    this.divEl     = null;
    this.list      = null;
    this.imageEl   = null;
    this.dayTop    = null;
    this.dayMiddle = null;
    this.dayBottom = null;
    this.length    = null;
    this.getDay    = null;
    this.sort      = null;
    this.remove    = null;
    this.add       = null;
    this.findIndex = null;
  }
}

function bl_apt_sortData()
{
  lst = this.list;
  var len = lst.length;
  for (var i = 0; i < len; i++)
  {
    var day = lst[i];
    day.sortAllDay();
    day.sortDay();
  }
}

function bl_apt_assignData(el)
{
  var aList = el.cbAptList;
  var aLen  = el.cbAptLen;
  var dObj  = el.firstChild.cbApt;
  var date  = new Date();
  
  dObj.clear();
  for (var i = 0; i < aLen; i++)
  {
    bl_apt_placeData(dObj, aList[i], date, el.bl_interval_tlt);
  }
  dObj.sort();
}

function bl_apt_evalAllDay(o1, o2)
{
  return o2.dayCnt - o1.dayCnt;
}

function bl_apt_evalDay(o1, o2)
{
  var diff = o1.sMark - o2.sMark;
  if (!diff)
  {
    return  o2.duration - o1.duration;
  }
  return diff;
}

function bl_apt_recomputeApts(el)
{
  var ap   = el.firstChild;
  var max  = 28;
  var dObj = ap.cbApt;
  var len  = dObj.length();
  
  for (var i = 0; i < len; i++)
  {
    max = Math.max(bl_apt_computeAllDayList(ap, i), max);
    bl_apt_computeDayList(ap, i, false);
  }
  
  dObj.getDay(0).allDayEl.style.height = max+"px";
}

function bl_apt_positionImage(d)
{
  if (d)
  {
    var v    = d.view;
    var offy = (d.isAllDay) ? 18 : 24;
    
    if (v.parentNode)
    {
      var imageChildStyle = bl_apt_imageItem(v).style;
      var vStyle, vWidth, vHeight;
      vWidth          = v.offsetWidth;
      vHeight         = v.offsetHeight;
      
      imageChildStyle.left = (vWidth - 20)+"px";
      imageChildStyle.top  = (vHeight - offy)+"px";
      
      if (d.linkData != null)
      {
        var ld = d.linkData;
        v = ld.view
        
        if (v.parentNode)
        {
          vWidth               = v.offsetWidth;
          vHeight              = v.offsetHeight;
          imageChildStyle      = bl_apt_imageItem(v).style;
          imageChildStyle.left = (vWidth - 20)+"px";
          imageChildStyle.top  = (vHeight - offy)+"px";
        }
      }
    }
  }
}

function bl_apt_computeAllDayList(ap, index)
{
  var dObj  = ap.cbApt;
  var day   = dObj.getDay(index);
  var div   = dObj.divEl;
  var aList = day.allDayList;
  var aLen  = aList.length;
  
  if (aLen > 0)
  {
    var el  = ap.parentNode;
    var del = day.topEl;
    var sel = day.sepEl;
    var sep = 6;
    var hel = day.allDayEl;
    // "hel" references the table cell (TD element) representing the space for
    // all day appointments. The offset from the top of the appointment object
    // is used here for positioning. However, webkit has a bug wherein the
    // offsetTop property for "hel" is returning an incorrect value.
    // Fortunately, the parentNode of "hel" (a TR element) contains the correct
    // size.
    var top = hel.parentNode.offsetTop;
    var y   = top + 2;
    var x   = hel.offsetLeft + 4;
    var w   = hel.offsetWidth;
    var h   = bl_apt_itemHeight;
    var i;
    var dHeight = el.cbImgHeight;
    var itvTlt  = el.bl_interval_tlt;
    
    for (i = 0; i < aLen; i++)
    {
      var d     = aList[i];
      var v     = d.view;
      var cp    = bl_apt_contentPanel(v);
      var cps   = cp.style;
      var cw    = w * d.dayCnt - 8;
      cps.width = "100%";
      cps.left  = 0;
      cps.top   = 0;
      v.childNodes[1].style.height = h+"px";
      s         = v.style;
      s.left    = x+"px";
      
      if (cw < 0)
      {
        cw = 0;
      }
      
      var visVal = (cw) ? "visible" : "hidden";
      
      s.width  = cw+"px";
      s.height = h+"px";
      bl_apt_setViewVisibility(v, visVal);
      cp.parentNode.style.whiteSpace = "nowrap";
      
      for (var j = 0; j < index; j++)
      {
        var subList = dObj.getDay(j).allDayList;
        var subLen  = subList.length;
        for (var k = 0; k < subLen; k++)
        {
          var ad = subList[k];
          if (y == parseInt(ad.view.style.top))
          {
            if ((j + ad.dayCnt) < (index + 1))
            {
              break;
            }
            else
            {
              y += (parseInt(ad.view.style.height) + 2);
              j = -1;
              break;
            }
          }
        }
      }
      
      if (!d.ismoving)
      {
        var sbHeight = dHeight;
        var end      = index + d.dayCnt - 1;
        var sb       = d.sideBar;
        for (var k = index; k <= end && sb; k++)
        {
          var sbs = sb.style;
          
          sel        = dObj.getDay(k).sepEl;
          sbs.left   = (sel.offsetLeft + bl_port_clientLeft(sel))+"px";
          sbs.width  = (sel.clientWidth)+"px";
          sbs.zIndex = d.bord + 1;
          if (k == index && d.sIndex == 0)
          {
            var t      = d.sMark * h;
            sbs.top    = t+"px";
            sbs.height = (sbHeight - t)+"px";
          }
          else if (k == end)
          {
            var sm     = (d.eMark == 0) ? itvTlt : d.eMark;
            sbs.top    = del.offsetTop+"px";
            sbs.height = (sm * h)+"px";
          }
          else
          {
            sbs.top    = del.offsetTop+"px";
            sbs.height = sbHeight+"px";
          }
          sbs.visibility = (d.color && d.color != "") ? "hidden" : visVal;
          
          if (sb.parentNode != div)
          {
            div.appendChild(sb);
          }
          sb = sb.nextSB;
        }
      }
      s.top = y+"px";
      y += (h + 2);
      
      if (v.parentNode != ap.parentNode)
      {
        ap.parentNode.appendChild(v);
      }
      bl_apt_positionImage(d);
    }
    
    return y - top + 5;
  }
  return 28;
}

function bl_apt_computeDayCnt(list)
{
  var len = list.length;
  
  if (len >= 2)
  {
    var d1;
    var sm;
    var d2;
    var cnt;
    
    list[0].cbCnt = list[1].cbCnt = 2;
    
    for (var i = 2; i < len; i++)
    {
      d1 = list[i];
      sm = list[i].sMark;
      for (var j = 0; j < i; j++)
      {
        var d2 = list[j]
        if (sm < list[j].eMark)
        {
          bl_apt_crossList.push(d2);
        }
      }
      var cnt  = bl_apt_crossList.length + 1;
      d1.cbCnt = cnt;
      d2       = bl_apt_crossList.pop();
      while (d2 != undefined)
      {
        d2.cbCnt = Math.max(d2.cbCnt, cnt);
        d2 = bl_apt_crossList.pop();
      }
    }
  }
}

function bl_apt_setViewVisibility(view, val)
{
  view.style.visibility = val;
}

function bl_apt_computeDayList(ap, index, sortIt)
{
  var dObj  = ap.cbApt;
  var day   = dObj.getDay(index);
  var dList = day.dayList;
  var dLen  = dList.length;
  
  if (dLen > 0)
  {
    if (sortIt)
    {
      day.sortDay();
    }
    
    var div            = dObj.divEl;
    var itvTlt         = ap.parentNode.bl_interval_tlt;
    var del            = day.topEl;
    var sel            = day.sepEl;
    var sep            = 6;
    var selClientLeft  = bl_port_clientLeft(sel);
    var selClientWidth = sel.clientWidth;
    var list           = new Array();
    var left           = sel.offsetLeft;
    var w              = del.offsetWidth;
    var right          = left + w + 5;
    var h              = bl_apt_itemHeight;
    var i              = 1;
    var j;
    var k;
    var d1;
    var d2;
    var elw;
    var x;
    var v;
    var v2;
    var v2w;
    var v2x;
    var s;
    var curEnd;
    var lLen;
    var cnt;
    var mcnt;
    
    list.push(dList[0]);
    while (list.length > 0)
    {
      d1       = list[0];
      curEnd   = d1.eMark;
      d1.cbCnt = 1;
      for (; i < dLen; i++)
      {
        d2 = dList[i];
        
        if (d2.sMark >= curEnd)
        {
          break;
        }
        list.push(d2);
        curEnd =  Math.max(((d2.linkView == null) ? d2.eMark : itvTlt), curEnd);
      }
      
      lLen = list.length;
      bl_apt_computeDayCnt(list);
      
      var minsize = Math.floor(w/6)
      for (j = 0; j < lLen; j++)
      {
        d1  = list[j];
        v   = d1.view;
        s   = v.style;
        x   = left;
        elw = Math.floor(w/Math.min(d1.cbCnt, 6));
        
        var hit    = true;
        var hitcnt = 1;
        while (hit)
        {
          hit = false;
          
          for (k = 0; k < j; k++)
          {
            d2  = list[k];
            v2  = d2.view;
            v2w = v2.offsetWidth + 1;
            v2x = v2.offsetLeft;
            
            if (d2.eMark > d1.sMark)
            {
              if (x < v2x && x + elw > v2x)
              {
                if (v2x - x >= minsize)
                {
                  elw = v2x - x - 1;
                }
                else
                {
                  hit = true;
                  hitcnt++;
                  x = v2x + v2w + 1;
                  break;
                }
              }
              else if (x >= v2x && x <= v2x + v2w)
              {
                hit = true;
                hitcnt++;
                x = v2x + v2w + 1;
                break;
              }
            }
          }
        }
        if (hitcnt == d1.cbCnt)
        {
          elw = left + w - x;
        }
        
        if (d1.view.parentNode != div)
        {
          div.appendChild(d1.view);
        }
        
        var elh = d1.duration * h;
        var top = d1.sMark * h;
        
        elw -= 1;
        
        if (elw >= sep)
        {
          s.left   = x+"px";
          s.top    = (top - sep)+"px";
          s.height = (elh + (sep * 2))+"px";
          s.width  = elw+"px";
          
          if (x + elw > right)
          {
            if ((right - x) > 10)
            {
              elw = right - x - 5;
              bl_apt_setViewVisibility(v, "visible");
            }
            else
            {
              bl_apt_setViewVisibility(v, "hidden");
            }
          }
          else
          {
            bl_apt_setViewVisibility(v, "visible");
          }
          
          var itemDiv          = v.childNodes[1];
          var cp               = bl_apt_contentPanel(v);
          var cps              = cp.style;
          var itemDivStyle     = itemDiv.style;
          
          itemDivStyle.height  = elh+"px";
          cps.width            = (elw - sep)+"px";
          cps.left             = (itemDiv.offsetLeft + sep)+"px";
          cps.top              = itemDiv.offsetTop+"px";
          if (!v.isAllDay)
          {
            cps.height = (v.offsetHeight-12)+"px";
          }
          
          itemDivStyle.whiteSpace = (d1.duration <= 1)? "nowrap":"normal";
          
          if (!d1.ismoving)
          {
            var sbs        = d1.sideBar.style;
            sbs.left       = (left + selClientLeft)+"px";
            sbs.top        = top+"px";
            sbs.width      = selClientWidth+"px";
            sbs.height     = elh+"px";
            sbs.zIndex     = d1.bord + 1;
            sbs.visibility = "visible";
            if (d1.sideBar.parentNode != div)
            {
              div.appendChild(d1.sideBar);
            }
          }
          bl_apt_positionImage(d1);
        }
        else
        {
          bl_apt_setViewVisibility(v, "hidden");
        }
        
      }
      list.splice(0, list.length);
      if (i < dLen)
      {
        list.push(dList[i]);
        i++;
      }
    }
  }
}

function bl_apt_filterImage(val)
{
  var ld    = this.linkData;
  var image = bl_apt_imageItem(this.view);
  
  if (val == 0 && !this.imageFiltered)
  {
    image.style.visibility = "visible";
  }
  else
  {
    image.style.visibility = "hidden";
  }
  
  if (ld)
  {
    image = bl_apt_imageItem(ld.view);
    
    if (val == 0 && !ld.imageFiltered)
    {
      image.style.visibility = "visible";
    }
    else
    {
      image.style.visibility = "hidden";
    }
  }
}

function bl_apt_cleanupAppointment()
{
  this.view.cbData  = null;
  this.view         = null;
  this.isLink       = false;
  this.linkData     = null;
  this.controlEl    = null;
  this.computeSMark = null;
  this.computeEMark = null;
  this.computeSTime = null;
  this.computeETime = null;
  this.computeMarks = null;
  this.computeColor = null;
  this.setImage     = null;
  this.setColor     = null;
  this.setTooltip   = null;
  this.setSOffset   = null;
  this.setEOffset   = null;
  this.isZero       = null;
  this.newView      = null;
  this.filterImage  = null;
  this.cleanup      = null;
}

function bl_apt_setDataImage(d)
{
  var image      = bl_apt_imageItem(d.view);
  var elFiltered = (d.controlEl.getAttribute("bl_filterImage") != null);
  
  if (elFiltered == 0 && !d.imageFiltered)
  {
    image.style.visibility = "visible";
  }
  else
  {
    image.style.visibility = "hidden";
  }
  
  image.title = d.imageTitle;
  image.src   = d.imageEN;
  image.setAttribute("en", d.imageEN);
  image.setAttribute("bl_img_action", "_bl_apt_imageAction");
  
  if (d.imagePopup)
  {
    image.setAttribute("bl_function", "_bl_pe_pressed");
  }
  else
  {
    image.setAttribute("bl_function", "_bl_image_action");
  }
  
  if (d.imageOV)
  {
    image.setAttribute("do", d.imageDO);
    image.setAttribute("ov", d.imageOV);
    image.removeAttribute("disabled");
  }
  else
  {
    image.setAttribute("disabled", "true");
  }
  
  if (d.imageDI)
  {
    image.setAttribute("di", d.imageDI);
  }
}

function bl_apt_setImage(dataItem)
{
  if (dataItem)
  {
    this.imageTitle    = unescape(dataItem.tooltip);
    this.imageEN       = dataItem.src;
    this.imagePopup    = dataItem.popup;
    this.imageFiltered = dataItem.filter;
    this.imageOV       = dataItem.over;
    this.imageDO       = dataItem.down;
    this.imageDI       = dataItem.disabled;
    bl_apt_setDataImage(this);
  }
}

function bl_apt_createNewView()
{
  this.view.cbData  = null;
  this.view         = null;
  
  var v = bl_apt_factory.createApt();
  
  v.cbData       = this;
  v.isSelected   = false;
  v.mouseIn      = false;
  v.mouseDown    = false;
  v.isDraging    = false;
  v.style.zIndex = 100;
  
  this.view = v;
}

function bl_apt_createAptData(el)
{
  var v = bl_apt_factory.createApt();
  
  v.cbData       = this;
  v.isSelected   = false;
  v.mouseIn      = false;
  v.mouseDown    = false;
  v.isDraging    = false;
  v.style.zIndex = 100;
  
  this.view         = v;
  this.isLink       = false;
  this.linkData     = null;
  this.controlEl    = el;
  this.computeSMark = bl_apt_computeSMark;
  this.computeEMark = bl_apt_computeEMark;
  this.computeSTime = bl_apt_computeSTime;
  this.computeETime = bl_apt_computeETime;
  this.computeMarks = bl_apt_computeMarks;
  this.computeColor = bl_apt_computeColor;
  this.setImage     = bl_apt_setImage;
  this.setColor     = bl_apt_setColor;
  this.setTooltip   = bl_apt_setTooltip;
  this.setSOffset   = bl_apt_setSOffset;
  this.setEOffset   = bl_apt_setEOffset;
  this.isZero       = bl_apt_zeroDuration;
  this.newView      = bl_apt_createNewView;
  this.cleanup      = bl_apt_cleanupAppointment;
  this.filterImage  = bl_apt_filterImage;
}

function bl_apt_topPanel(el)
{
  return el.firstChild;
}

function bl_apt_imageItem(el)
{
  return el.childNodes[2];
}

function bl_apt_bottomPanel(el)
{
  return el.childNodes[3];
}

function bl_apt_getContentDiv(el)
{
  return el.childNodes[1];
}

function bl_apt_sidePanel(el)
{
  return el.childNodes[1].firstChild;
}

function bl_apt_contentPanel(el)
{
  return el.childNodes[1].childNodes[1];
}

function bl_apt_computeColor(color, setLink)
{
  this.color = color;
  
  if (color && color != "")
  {
    var list    = color.split(";");
    var type    = (list.length > 1) ? 5 : 4;
    
    this.bord    = type;
    this.olClass = bl_apt_olMap[type];
  }
  else
  {
    this.bord    = parseInt(this.origBorder);
    this.olClass = bl_apt_olMap[this.bord];
  }
  
  this.cb_compute_tooltip = true;
  
  if (this.linkData && setLink)
  {
    var ld                = this.linkData;
    ld.bord               = this.bord;
    ld.olClass            = this.olClass;
    ld.color              = this.color;
    ld.cb_compute_tooltip = true;
  }
}

function bl_apt_setColor(setLink)
{
  var colorStr = (this.bord == 4) ? this.color : "";
  
  bl_apt_setAPTColor(this.view, colorStr);
  if (this.linkData && setLink)
  {
    bl_apt_setAPTColor(this.linkData.view, colorStr);
  }
}

function bl_apt_setAPTColor(view, color)
{
  var top    = bl_apt_topPanel(view);
  var bottom = bl_apt_bottomPanel(view);
  var side   = bl_apt_sidePanel(view).firstChild;
  
  bl_port_setBGColor(top.style, color);
  bl_port_setBGColor(bottom.style, color);
  bl_port_setBGColor(side.style, color);
}

function bl_apt_setTooltip(tooltip, setLink)
{
  this.tooltip = tooltip;
  
  if (this.linkData && setLink)
  {
    this.linkData.tooltip = this.tooltip;
  }
  this.cb_compute_tooltip = true;
}

function bl_apt_computeMarks()
{
  this.computeSMark();
  this.computeEMark();
  
}

function bl_apt_setSOffset(val)
{
  var ld = this.linkData;
  this.sOffset  = val;
  this.sOffMark = Math.ceil((bl_apt_itemHeight * val)/this.controlEl.bl_interval_val);
  if (ld)
  {
    ld.sOffset  = val;
    ld.sOffMark = this.sOffMark;
  }
}

function bl_apt_setEOffset(val)
{
  var ld = this.linkData;
  
  this.eOffset = val;
  
  if (this.isZero())
  {
    this.eOffMark = 0;
  }
  else
  {
    this.eOffMark = Math.ceil((bl_apt_itemHeight * val)/this.controlEl.bl_interval_val);
  }
  if (ld)
  {
    ld.eOffset  = val;
    ld.eOffMark = this.eOffMark;
  }
}

function bl_apt_computeSMark()
{
  var el     = this.controlEl;
  var itvCnt = el.bl_interval_cnt;
  var itv    = el.bl_interval_val;
  this.sMark = (this.sHour * itvCnt) + Math.floor(this.sMinute/itv);
  this.setSOffset(this.sMinute%itv);
}

function bl_apt_zeroDuration()
{
  return (this.sYear   == this.eYear    &&
          this.sMonth  == this.eMonth   &&
          this.sDay    == this.eDay     &&
          this.sHour   == this.eHour    &&
          this.sMinute == this.eMinute);
}

function bl_apt_computeEMark()
{
  var el     = this.controlEl
  var itvCnt = el.bl_interval_cnt;
  var itv    = el.bl_interval_val;
  var o      = 0;
  
  if (this.isZero())
  {
    o = 0;
    this.eMark = (this.eHour * itvCnt) + Math.ceil((this.eMinute + itv)/itv);
  }
  else
  {
    o = this.eMinute%itv;
    if (o)
    {
      o = itv - o;
    }
    this.eMark = (this.eHour * itvCnt) + Math.ceil(this.eMinute/itv);
  }
  this.setEOffset(o);
}

function bl_apt_computeSTime(cnt)
{
  var el     = this.controlEl;
  var ld     = this.linkData;
  var itvCnt = el.bl_interval_cnt;
  var itv    = el.bl_interval_val;
  
  this.sMinute = ((cnt%itvCnt) * itv) + this.sOffset;
  this.sHour   = Math.floor(cnt/itvCnt);
  if (ld)
  {
    ld.sMinute = this.sMinute;
    ld.sHour   = this.sHour;
  }
}

function bl_apt_computeETime(cnt)
{
  var el     = this.controlEl;
  var ld     = this.linkData;
  var itvCnt = el.bl_interval_cnt;
  var itv    = el.bl_interval_val;
  
  this.eMinute = ((cnt%itvCnt) * itv) - this.eOffset;
  this.eHour   = Math.floor(cnt/itvCnt);
  if (this.eOffset &&  ((cnt%itvCnt) == 0))
  {
    this.eHour--;
    if (this.eHour < 0)
    {
      this.eHour = 23;
    }
  }
  if (this.eMinute < 0)
  {
    this.eMinute = (itvCnt * itv) + this.eMinute;
  }
  
  if (ld)
  {
    ld.eMinute = this.eMinute;
    ld.eHour   = this.eHour;
  }
}

function bl_apt_setAptData(dataItem, d)
{
  var dtList = dataItem.start.split(" ");

  d.id       = dataItem.id;
  d.sYear    = parseInt(dtList[0]);
  d.sMonth   = parseInt(dtList[1]);
  d.sDay     = parseInt(dtList[2]);
  d.sHour    = parseInt(dtList[3]);
  d.sMinute  = parseInt(dtList[4]);
  dtList     = dataItem.end.split(" ");
  d.eYear    = parseInt(dtList[0]);
  d.eMonth   = parseInt(dtList[1]);
  d.eDay     = parseInt(dtList[2]);
  d.eHour    = parseInt(dtList[3]);
  d.eMinute  = parseInt(dtList[4]);
  d.content  = unescape(dataItem.content);
  d.qual     = unescape(dataItem.location);
  
  d.contentDisplay = bl_apt_sanitizeText(d.content);
  d.qualDisplay    = bl_apt_sanitizeText(d.qual);
  
  d.allDay   = dataItem.isAllDay;
  d.bord     = dataItem.borderType;
  d.back     = dataItem.backgroundType;
  
  if (d.back < 0 || d.back > bl_apt_bgMap.length)
  {
    d.back = 0;
  }
  if (d.bord < 0 || d.bord > bl_apt_olMap.length)
  {
    d.bord = 0;
  }
  
  d.origBorder  = d.bord;
  d.bgClass     = bl_apt_bgMap[d.back];
  d.olClass     = bl_apt_olMap[d.bord];
  
  d.computeMarks();
  
  d.remind      = dataItem.remind;
  d.recurType   = dataItem.recurType;
  d.isMeeting   = dataItem.meeting;
  
  d.computeColor(dataItem.color, false);
  d.setColor(false);
  d.setTooltip(unescape(dataItem.tooltip), false);
  
  d.readonly   = dataItem.readOnly;
  
  d.setImage(dataItem.imageData);
  
//  if (chList[len - 1].nodeName == "MI")
//  {
//    d.meetingImage = bl_port_get_text(chList[len - 1]);
//  }
  
  bl_apt_setContentStr(d, false, false);
}

function bl_apt_loadData(el, data)
{
  el.cbAptLen = 0;

  if (el && data)
  {
    var newLen = data.length;
    var aList = el.cbAptList;
    var aLen  = aList.length;
    var min   = Math.min(newLen, aLen);
    var i     = 0;
    
    for (; i < min; i++)
    {
      var d = aList[i];
      bl_apt_setAptData(data[i], d);
    }
    
    for (; i < newLen; i++)
    {
      var aData = new bl_apt_createAptData(el);
      bl_apt_setAptData(data[i], aData);
      aList.push(aData);
    }
    el.cbAptLen = newLen;
  }
}

function bl_apt_createTempData(sDate, eDate, isAllDay, el)
{
  var d     = new bl_apt_createAptData(el);
  var today = new Date();
  
  d.id = null;
  
  d.sYear          = sDate.getFullYear();
  d.sMonth         = sDate.getMonth();
  d.sDay           = sDate.getDate();
  d.sHour          = sDate.getHours();
  d.sMinute        = sDate.getMinutes();
  d.eYear          = eDate.getFullYear();
  d.eMonth         = eDate.getMonth();
  d.eDay           = eDate.getDate();
  d.eHour          = eDate.getHours();
  d.eMinute        = eDate.getMinutes();
  d.content        = "";
  d.qual           = "";
  d.contentDisplay = "";
  d.qualDisplay    = "";
  d.allDay         = isAllDay;
  d.origBorder     = 2;
  d.bord           = 2;
  d.back           = 0;
  d.bgClass        = bl_apt_bgMap[d.back];
  d.olClass        = bl_apt_olMap[d.bord];
  
  d.computeMarks();
  
  d.remind       = false;
  d.imageSrc     = null;
  d.imageTitle   = null;
  d.meetingImage = "";
  d.isMeeting    = false;
  d.readonly     = false;
  
  d.computeColor(el.getAttribute("bl_defaultColor"), false);
  d.setColor(false);
  d.setTooltip(el.getAttribute("bl_tooltipLabel"), false);
  
  d.recurType = "n"
  bl_apt_setContentStr(d, false, false);
  
  return d;
}

function bl_apt_dateChange(el, date, sel)
{
  var ap = el.firstChild;
  if (sel == "day")
  {
    bl_apt_ChangeDayDates(el, ap, date, 1);
  }
  else
  {
    var d = new Date();
    
    d.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
    if (sel == "workweek")
    {
      var day = date.getDate() - date.getDay() + 1;
      d.setDate(day);
      bl_apt_ChangeDayDates(el, ap, d, 5);
    }
    else if (sel == "month")
    {
      d.setDate(1);
    }
    else if (sel == "fullweek")
    {
      var day = date.getDate() - date.getDay();
      d.setDate(day);
      bl_apt_ChangeDayDates(el, ap, d, 7);
    }
    else 
    {
      bl_apt_ChangeDayDates(el, ap, date, 1);
    }
  }
}

function bl_apt_willFit(str, width)
{
  bl_apt_srtTester.innerHTML = str;
  return (bl_apt_srtTester.offsetWidth+16 < width);
}

function bl_apt_getStringWidth(str)
{
  bl_apt_srtTester.innerHTML = str;
  return bl_apt_srtTester.offsetWidth;
}

function bl_apt_computeStr(dt, type)
{
  var fw_list = bl_sys_fullDays();
  var w_list  = bl_sys_days();
  var m_list  = bl_sys_months();
  var fm_list = bl_sys_fullMonths();
  
  switch (type)
  {
    case (0) : return fw_list[dt.getDay()] + ', '  + fm_list[dt.getMonth()] + ' '  + dt.getDate();
    case (1) : return fw_list[dt.getDay()] + ', '  + m_list[dt.getMonth()] + ' '  + dt.getDate();
    case (2) : return w_list[dt.getDay()] + ', '  + m_list[dt.getMonth()] + ' '  + dt.getDate();
    case (3) : return w_list[dt.getDay()] + ' '  + dt.getDate();
  }
  return (dt.getMonth() + 1) + '/'  + dt.getDate();
}

function bl_apt_ChangeDayDates(el, ap, date, cnt)
{
  // Safari doesn't support table-layout:fixed, so the table cell sizing
  // is done manually. Each column is set the same width, and safari then
  // figures out how to divide the remaining space.
  var dObj  = ap.cbApt;
  var dt    = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  var ct    = 0;
  var width = 0;

  if (bl_browserInfo.safari)
  {
    // Reset all sizes to zero, so the browser won't use them as minimum
    // widths for the cells.
    for (var i=0; i<cnt; i++)
    {
      var d = dObj.getDay(i);
      d.headerText.firstChild.style.width = "";
    }
    var totalWidth = 0;
    for (var i=0; i<cnt; i++)
    {
      var d = dObj.getDay(i);
      totalWidth += d.headerText.firstChild.offsetWidth;
    }
    width = Math.floor(totalWidth / cnt);
  }
  else
  {
    width = dObj.getDay(0).headerText.offsetWidth;
  }

  var str = "";

  // Try date formats in the following order:  
  // Wednesday, September 5
  // Wednesday, Sep 5
  // Wed, Sep 5
  // Wed 5
  // 9/5
  for (var i = 0; i < cnt; i++)
  {
    if (i > 0)
    {
      dt.setDate(dt.getDate() + 1);
    }
    inner:
    for (; ct<=4; ct++)
    {
      if (bl_apt_willFit(bl_apt_computeStr(dt, ct), width))
      {
        break inner;
      }
    }
  }
    
  if (ap.cbHeaderType != ct)
  {
    ap.cbHeaderType = ct;
    dt.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
    for (var i = 0; i < cnt; i++)
    {
      var dow = dt.getDay();
      var day = dObj.getDay(i);
      
      bl_port_setInnerText(day.headerText.firstChild, bl_apt_computeStr(dt, ct));
      day.year  = dt.getFullYear();
      day.month = dt.getMonth();
      day.day   = dt.getDate();
      dt.setDate(dt.getDate() + 1);
      
      var offImage  = "url(" + el.getAttribute("bl_off") + ")";
      var backImage = (dow > 0 && dow < 6)? ("url(" + el.getAttribute("bl_on") + ")"):offImage;
      
      day.topEl.style.background = offImage;
      day.middleEl.style.background = backImage;
      day.bottomEl.style.background = offImage;
    }
  }
  
  if (bl_browserInfo.safari)
  {
    // Now that we know how wide each column should be, we will set
    // the appropriate column sizes.
    for (var i = 0; i < cnt; i++)
    {
      dObj.getDay(i).headerText.firstChild.style.width = width+"px";
    }
  }
}

function _bl_apt_resize(el, resizeQueue)
{
  var w = el.offsetWidth;
  var h = el.offsetHeight;
  
  bl_apt_controlInit(el);

  var ap     = el.firstChild;
  var apBody = bl_apt_findBodyDiv(ap);
  var apHead = bl_apt_findHeadDiv(ap);
  
  var headHeight = parseInt(apHead.offsetHeight);
  
  ap.style.height     = h+"px";
  ap.style.width      = w+"px";
  apBody.style.height = Math.max(h-headHeight, 0)+"px";
  apBody.style.width  = w+"px";
  
  if (h > 0 && w > 0 && (el.oldWidth != w || el.oldHeight != h))
  {
    el.oldWidth  = w;
    el.oldHeight = h;
    bl_apt_dateChange(el, el.cbDate, el.getAttribute("bl_selectby"));
    bl_apt_recomputeApts(el);
    bl_apt_setEditSelect(el);
  }
}

function bl_apt_adjustPosition(el)
{
  el.sDind = 0;
  el.sCnt  = (8 * el.bl_interval_cnt);
  el.eDind = 0;
  el.eCnt  = el.sCnt + 1;
  
  var child = el.firstChild;
  
  child.cbApt.divEl.scrollTop = (el.bl_interval_cnt * bl_apt_itemHeight) * 7;
}

function bl_apt_selectByChange(el, selectBy, controlData)
{
  if (selectBy != "day" && selectBy != "fullweek" && selectBy != "month" && selectBy != "workweek")
  {
    selectBy = "day";
  }

  if (el.getAttribute("bl_selectby") != selectBy && controlData)
  {
    el.setAttribute("bl_selectby", selectBy);

    var ap = el.firstChild;
    if (ap != null)
    {
      ap.cbApt.clear(true);
      ap.cbApt           = null;
      ap.dragItem        = null;
      ap.keyInputHandler = null;
    }
    el.innerHTML = bl_port_get_text(controlData);
    bl_apt_factory.attachControl(el.firstChild, selectBy);
    bl_apt_setInterval(el, el.bl_interval_val);
    bl_apt_adjustPosition(el);
  }
}

function bl_apt_appointmentParent(item)
{
  var ap = item.parentNode;
  
  while (ap.id != "appointment")
  {
    ap = ap.parentNode;
  }
  return ap;
}

function bl_apt_attachAP(ap, cnt)
{
  ap.cbApt           = new bl_apt_createElementData(ap, cnt);
  ap.dragItem        = null;
  ap.keyInputHandler = bl_apt_findKeyInputElement(ap);

  return ap;
}

function bl_apt_findDayIndex(x)
{
  var lst = this.list;
  var len = lst.length;
  for (var i = 0; i < len; i ++)
  {
    var day = lst[i];
    var el = day.topEl;
    if (x >= day.sepEl.offsetLeft && x < el.offsetLeft + el.offsetWidth)
    {
      return i;
    }
  }
  return -1;
}

function bl_apt_createElementData(ap, cnt)
{
  var ls = new Array();
  this.divEl = ap.firstChild.lastChild.firstChild.firstChild;
  
  for (var i = 0 ; i < cnt; i++)
  {
    ls.push(new bl_apt_createDayData(ap, this.divEl, i));
  }
  
  var el         = ls[0].sepEl;
  this.list      = ls;
  this.imageEl   = el.previousSibling;
  this.dayTop    = el;
  el             = el.parentNode.nextSibling;
  this.dayMiddle = el.firstChild;
  this.dayBottom = el.nextSibling.firstChild;
  this.length    = bl_apt_ListLength;
  this.getDay    = bl_apt_getDayItem;
  this.clear     = bl_apt_clearData;
  this.sort      = bl_apt_sortData;
  this.remove    = bl_apt_extractData;
  this.add       = bl_apt_addInData;
  this.findIndex = bl_apt_findDayIndex;
}

function bl_apt_getDayItem(i)
{
  if (i != undefined && i >= 0 && i < this.list.length)
  {
    return this.list[i];
  }
  return null;
}

function bl_apt_ListLength()
{
  return this.list.length;
}

function bl_apt_addInData(d, sortIt)
{
  if (d.dIndex != undefined && d.dIndex >= 0 && d.dIndex < this.list.length)
  {
    this.list[d.dIndex].add(d, sortIt);
  }
}

function bl_apt_addData(d, sortIt)
{
  var list = (d.isAllDay) ? this.allDayList : this.dayList;
  list.push(d);
  
  if (sortIt)
  {
    list.sort(((d.isAllDay) ? bl_apt_evalAllDay : bl_apt_evalDay))
  }
}

function bl_apt_createDayData(ap, div, i)
{
  this.allDayList = new Array();
  this.dayList    = new Array();
  var el          = ap.firstChild.firstChild.firstChild.firstChild.firstChild;
  this.allDayEl   =   el.lastChild.childNodes[i + 1];
  if (bl_browserInfo.ie)
  {
    this.headerText = el.firstChild.childNodes[i +  1];
    el              = div.firstChild.firstChild.firstChild;
  }
  else
  {
    this.headerText = el.childNodes[1].childNodes[i + 1];
    el              = div.firstChild.firstChild.firstChild.nextSibling;
  }
  this.sepEl      = el.childNodes[(i*2) + 1];
  this.topEl      = el.childNodes[(i*2) + 2];
  this.selEl      = div.childNodes[i + 1];
  this.middleEl   = el.nextSibling.childNodes[(i*2) + 1];
  this.bottomEl   = el.nextSibling.nextSibling.childNodes[(i*2) + 1];
  this.sortAllDay = bl_apt_sortAllDay;
  this.sortDay    = bl_apt_sortDay;
  this.empty      = bl_apt_emptyData;
  this.remove     = bl_apt_removeData;
  this.add        = bl_apt_addData;
}

function bl_apt_sortAllDay()
{
  this.allDayList.sort(bl_apt_evalAllDay);
}

function bl_apt_sortDay()
{
  this.dayList.sort(bl_apt_evalDay);
}

function bl_apt_emptyData()
{
  bl_apt_emptyList(this.allDayList);
  bl_apt_emptyList(this.dayList);
}

function bl_apt_getLinkDataView(el)
{
  var ret = null;
  var d   = el.cbData;
  
  if (d.linkData != null)
  {
    ret = d.linkData.view;
  }
  return ret;
}

function bl_apt_computeDayType(detectMove, x, y, d, height)
{
  var type = -1;
  var day = d.controlEl.firstChild.cbApt.getDay(d.dIndex);
  
  if (day)
  {
    if (x > 6 && y <= 6)
    {
      type = (bl_apt_less(d.sYear, day.year, d.sMonth, day.month, d.sDay, day.day)) ? 0 : 1;
    }
    else if (x > 6 && (y >= (height - 6)))
    {
      type = (bl_apt_great(d.eYear, day.year, d.eMonth, day.month, d.eDay, day.day)) ? 0 : 2;
    }
    else
    {
      type = 0;
    }
    
    if (x > 6 && detectMove && type == 0)
    {
      type = -1;
    }
  }
  return type;
}

function bl_apt_computeAllDayType(detectMove, x, d, width)
{
  type     = -1;
  var dObj =  d.controlEl.firstChild.cbApt;
  if (x <= 6)
  {
    var day = dObj.getDay(0);
    type = (bl_apt_less(d.sYear, day.year, d.sMonth, day.month, d.sDay, day.day)) ? 0 : 1;
  }
  else if (x >= (width - 6))
  {
    var day = dObj.getDay(dObj.length() - 1);
    type    = (bl_apt_great(d.eYear, day.year, d.eMonth, day.month, d.eDay, day.day) && d.eMark > 0) ? 0 : 2;
  }
  else
  {
    type = 0;
  }
  if (detectMove && type == 0)
  {
    type = -1;
  }
  return type;
}

function bl_apt_computeMoveType(item, d, detectMove, event)
{
  var src    = bl_port_getEventTarget(event);
  var offPos = bl_port_offsetToItem(event, src);
  var type = -1;

  if (!d.readonly)
  {
    if (src != item)
    {
      if (src.id == "content")
      {
        if (d.isAllDay)
        {
          type = bl_apt_computeAllDayType(detectMove, offPos.x, d, src.offsetWidth);
        }
        else
        {
          type = bl_apt_computeDayType(detectMove, offPos.x, offPos.y, d, src.offsetHeight);
        }
      }
      else if (src.id == "side")
      {
        type = 0;
      }
      else if (src.id == "top")
      {
        type = 1;
      }
      else if (src.id == "bottom")
      {
        type = 2;
      }
      else if (src.getAttribute("bl_ignore_me") != null)
      {
        type = -2;
      }
    }
    else
    {
      if (d.isAllDay)
      {
        type = bl_apt_computeAllDayType(detectMove, offPos.x, d, item.offsetWidth);
      }
      else
      {
        type = bl_apt_computeDayType(detectMove, offPos.x, offPos.y, d, item.offsetHeight);
      }
    }
    
    if (d.linkData)
    {
      var dind = d.dIndex;
      var lind = d.linkData.dIndex;
      if ((type == 1 && dind > lind) || (type == 2 && dind < lind))
      {
        type = (detectMove) ? -1 : 0;
      }
    }
  }    
  return type;
}

function bl_apt_compute_tt(d)
{
  if (d.cb_compute_tooltip)
  {
    var cont     = bl_apt_contentPanel(d.view);
    var tlabel   = d.controlEl.getAttribute("bl_apt_tooltip_label");
    var str      = "";
    var showText = (cont.offsetWidth < cont.scrollWidth   ||
                    cont.offsetHeight < cont.scrollHeight ||
                    (d.tooltip && d.tooltip != ""));
    var sepdone  = false;
    var labdone  = false;
    
    if (showText)
    {
    
      str += "<div><div style='white-space:nowrap;'>";
      
      var isMilt = (d.controlEl.getAttribute("bl_timeType") == "military");
      str += bl_apt_computeTimeStr(d.sHour, d.sMinute, isMilt);
      str += "-";
      
      if (!d.isZero())
      {
        str += bl_apt_computeTimeStr(d.eHour, d.eMinute, isMilt);
      }
      str += "</div>";
      str += d.contentDisplay;
      
      if (d.qual != "")
      {
        str += "(" + d.qualDisplay + ")\u200F";
      }
      
      str += "</div>";
    }
    
    if (d.tooltip && d.tooltip != "")
    {
      str += "<hr style='width:100px'>";
      
      if (d.imageSrc)
      {
        var text = d.imageTitle.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;");
        
        str += "<div align=left ><img src='" + d.imageSrc + "'unselectable='on' style='vertical-align:middle;'/>" + d.imageTitle + "</div>";
      }
      if (tlabel && tlabel != "")
      {
        str += tlabel;
        str += "<br>"
      }
      
      var tList = d.tooltip.split(";");
      var tLen  = tList.length;
      var cList = null;
      var cLen  = 0;
      
      if (d.color)
      {
        cList = d.color.split(";");
        cLen  = cList.length;
      }
      
      for (i = 0; i < tLen; i ++)
      {
        var rec   = tList[i];
        var color = (cList && i < cLen) ? cList[i] : "#FFFFFF";
        var text = rec.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;");
        
        str += "<SPAN style='padding-left:4px'><IMG src='/"
             + bl_version
             + "/res/img/apt_color_tooltip.gif' style='vertical-align:middle;background-color:"
             + color + ";' UNSELECTABLE='on'/>" + text + "</SPAN>";
        
        if (i < tLen - 1)
        {
          str += "<br>"
        }
      }
    }
    if (d.readonly)
    {
      str += "<div style='color:#0080FF;font-weight:bold;font-size:9px;text-align:right'>(read only)</div>";
    }
    d.ttHTML = str;
    
    d.cb_compute_tooltip = false;
  }
}

function bl_apt_done_tt_fade(ttDiv)
{
  ttDiv.goDown = undefined;
  ttDiv.style.visibility = "hidden";
}

function bl_apt_start_tt_filter(ttDiv, goingDown)
{
  if (goingDown)
  {
    ttDiv.style.visibility = "hidden";
  }
  else
  {
    ttDiv.style.visibility = "visible";
  }
}

function bl_apt_show_tt(d)
{
  var el    = d.controlEl;
  var ttDiv = el.cb_ttDiv;

  if (!ttDiv)
  {
    ttDiv = document.createElement("div");
    ttDiv.setAttribute("unselectable", "on");
    ttDiv.className  = "bl_apt_ttDiv";
    bl_port_insertAdjacentElement(document.body, "afterBegin", ttDiv);
    ttDiv.style.left = 0;
    ttDiv.style.top  = 0;
    el.cb_ttDiv      = ttDiv;
  }
  
  if (d.ttHTML && d.ttHTML != "")
  {
    ttDiv.innerHTML = d.ttHTML;
    
    var fwidth = ttDiv.firstChild.offsetWidth;
    
    ttDiv.cb_current_tt = d;
    
    if (fwidth > 300)
    {
      ttDiv.firstChild.style.width = "300px";
    }

    var view    = d.view;
    var left    = bl_sys_find_x(view, null, false);
    var top     = bl_sys_find_y(view, null, false);
    var vheight = view.offsetHeight;
    var vwidth  = view.offsetWidth;
    var width   = ttDiv.offsetWidth;
    var height  = ttDiv.offsetHeight;
    var x       = left + Math.floor(view.offsetWidth / 2) - width;
    var y       = top - height - 2;
    
    if (y < 0)
    {
      y = 0;
    }
    if (x < 0)
    {
      x = 0;
    }
    
    if (y + height > top)
    {
      y = top + vheight + 2;
    }
    
    ttDiv.style.left = x+"px";
    ttDiv.style.top  = y+"px";
    bl_apt_start_tt_filter(ttDiv, false);
  }
}

function bl_apt_hide_tt(el, d)
{
  var ttDiv = el.cb_ttDiv;
  
  bl_apt_tt_clear_timeout();
  if (ttDiv && ttDiv.style.visibility == "visible")
  {
    if (el.cb_tt_data == d)
    {
      el.cb_tt_data = null;
    }
    
    ttDiv.cb_current_tt = null;
    bl_apt_start_tt_filter(ttDiv, true);
  }
}

function _bl_apt_mouse_move(event, item)
{
  if (bl_port_getEventTarget(event).getAttribute("bl_ignore_me") != null)
  {
    return;
  }
  
  var d = item.cbData;
  
  if (item.isDraging)
  {
    var x = event.screenX;
    var y = event.screenY;
    
    if (item.moveType == 0)
    {
      d.ismoving = true;
      if (d.linkData)
      {
        d.linkData.ismoving = true;
      }
      
      if (!item.moved)
      {
        item.style.cursor = "move";
      }
    }
    else
    {
      d.ismoving = false;
    }
    
    if (item.moved)
    {
      bl_apt_move(item, x, y, false);
    }
    else if (Math.abs(item.cbx - x) > 3 || Math.abs(item.cby - y) > 3)
    {
      item.moved = true;
    }
  }
  else
  {
    var type   = bl_apt_computeMoveType(item, d, true, event);
    var target = bl_port_getEventTarget(event);
    
    if (type == -2)
    {
      target.style.cursor = "text";
    }
    else
    {
      if (d.isAllDay)
      {
        target.style.cursor = (type > 0) ? "e-resize" : "default";
      }
      else
      {
        if (type == 0)
        {
          target.style.cursor = "move";
        }
        else if (type > 0)
        {
          target.style.cursor = "n-resize";
        }
        else
        {
          target.style.cursor = "default";
        }
      }
    }
  }
  bl_port_killEvent(event);
}

function bl_apt_dragAnchore(item, d, ap, dind, cind, done)
{
  var dObj = ap.cbApt;
  if (d.isAllDay)
  {
    bl_apt_swapViewParent(item, dObj.divEl, d, dObj);
    d.isAllDay = false;
    bl_apt_swapContentTag(d, true);
    bl_apt_gleanSideBars(d.sideBar);
    bl_apt_setHeadH(ap, bl_apt_recomputeAllDays(ap), done);
    d.dIndex = dind;
    dObj.add(d, true);
  }
  else if (d.linkData)
  {
    var ld = d.linkData;
    var li = ld.dIndex;
    
    if (li == dind)
    {
      if (li < d.dIndex)
      {
        d.sMark = ld.sMark;
      }
      else if (li > d.dIndex)
      {
        d.eMark = ld.eMark;
      }
    }
    dObj.remove(ld, false);
    bl_apt_removeLink(d);
    bl_apt_gleanSideBars(d.sideBar);
    if (dind != li)
    {
      bl_apt_computeDayList(ap, li, true);
    }
  }
  
  var d      = item.cbData;
  var el     = d.controlEl;
  var itvCnt = el.bl_interval_cnt;
  var itv    = el.bl_interval_val
  var itvTlt = el.bl_interval_tlt;
  var day    = dObj.getDay(dind);
  
  if (item.moveType == 1)
  {
    if (d.sMark == d.anchorMark)
    {
      if (d.anchorMark == itvTlt)
      {
        if (cind > d.anchorIndex)
        {
          dind++;
          day     = dObj.getDay(dind);
          d.sMark = 0;
          d.eMark = 1;
          d.eHour = d.eMinute = d.sHour = d.sMinute = 0;
        }
        else
        {
          var date  = new Date(day.year, day.month, day.day + 1);
          d.eMark   = d.anchorMark;
          d.sMark   = d.anchorMark - 1;
          d.sHour   = Math.floor(d.sMark/itvCnt);
          d.sMinute = (d.sMark%itvCnt) * itv;
          d.eHour   = Math.floor(d.eMark/itvCnt);
          d.eMinute = (d.eMark%itvCnt) * itv;
          d.eYear   = date.getFullYear();
          d.eMonth  = date.getMonth();
          d.eDay    = date.getDate();
        }
      }
      else
      {
        if (d.isZero())
        {
          d.sMark = d.eMark - 1;
        }
        else
        {
          if (d.eOffset)
          {
            d.sMark--;
            d.sOffset = itv - d.eOffset;
          }
          else
          {
            d.eMark = d.sMark + 1;
          }
          d.sHour   = d.eHour;
          d.sMinute = d.eMinute;
        }
      }
    }
    else
    {
      d.sHour   = Math.floor(d.sMark/itvCnt);
      d.sMinute = (d.sMark%itvCnt) * itv;
      if (d.eMark != d.anchorMark)
      {
        d.eMark = d.anchorMark;
      }
    }
    d.sYear  = day.year;
    d.sMonth = day.month;
    d.sDay   = day.day;
  }
  else if (item.moveType == 2)
  {
    if (d.sMark == d.eMark)
    {
      d.eMark++;
      if (d.eOffset)
      {
        d.eOffset = itv - d.sOffset;
      }
      d.eHour   = d.sHour;
      d.eMinute = d.sMinute;
    }
    else
    {
      d.eHour   = Math.floor(d.eMark/itvCnt);
      d.eMinute = (d.eMark%itvCnt) * itv;
    }
    d.eYear  = day.year;
    d.eMonth = day.month;
    d.eDay   = day.day;
  }
  d.duration = d.aDuration = d.eMark - d.sMark;
  
  if (dind != d.dIndex)
  {
    dObj.remove(d, false);
    d.dIndex = dind;
    dObj.add(d, true);
  }
  
  bl_apt_computeDayList(ap, dind, true);
}

function bl_apt_setHeadH(ap, max, justMax)
{
  var item = ap.cbApt.getDay(0).allDayEl;
  item.style.height = ((justMax) ? max : Math.max(max, item.offsetHeight))+"px";
}

function bl_apt_switchDataToLink(d, ld)
{
  var el       = d.controlEl;
  var list     = el.cbAptList;
  var len      = el.cbAptLen;
  var tempView = ld.view;
  
  ld.view        = d.view;
  d.view         = tempView;
  ld.view.cbData = ld;
  d.view.cbData  = d;
  
  ld.origIndex     = d.origIndex;
  ld.origAllDay    = d.origAllDay;
  ld.origDuration  = d.origDuration;
  ld.origSMark     = d.origSMark;
  ld.origEMark     = d.origEMark;
  ld.origWidth     = d.origWidth;
  ld.origHeight    = d.origHeight;
  ld.origLeft      = d.origLeft;
  ld.origTop       = d.origTop;
  ld.origADuration = d.origADuration;
  ld.origSIndex    = d.origSIndex;
  ld.origTDayCnt   = d.origTDayCnt;
  ld.origDayCnt    = d.origDayCnt;
  ld.origHasLink   = d.origHasLink;
  ld.origLIndex    = d.origLIndex;
  ld.origLAllDay   = d.origLAllDay;
  ld.origLDuration = d.origLDuration;
  ld.origLSMark    = d.origLSMark;
  ld.origLEMark    = d.origLEMark;
  ld.origLWidth    = d.origLWidth;
  ld.origLHeight   = d.origLHeight;
  ld.origLLeft     = d.origLLeft;
  ld.origLTop      = d.origLTop;
  ld.origLSIndex   = d.origLSIndex;
  ld.origLTDayCnt  = d.origLTDayCnt;
  ld.origLDayCnt   = d.origLDayCnt;
  ld.anchorMark    = d.anchorMark;
  ld.anchorIndex   = d.anchorIndex;
  
  bl_apt_replaceLinkData(ld, d, list, len);
}


function bl_apt_dragLink(item, d, ap, dind, done)
{
  var itvTlt = ap.parentNode.bl_interval_tlt;
  var dObj   = ap.cbApt;
  var div    = dObj.divEl;
  var dday   = dObj.getDay(dind);
  var aday   = dObj.getDay(d.anchorIndex);
  
  if (dday && aday)
  {
    if (d.isAllDay)
    {
      bl_apt_swapViewParent(item, div, d, dObj);
      d.isAllDay = false;
      bl_apt_swapContentTag(d, true);
      bl_apt_setHeadH(ap, bl_apt_recomputeAllDays(ap), done);
      d.dIndex = d.anchorIndex;
      aday.dayList.push(d);
      bl_apt_gleanSideBars(d.sideBar);
    }
    
    var ld = d.linkData;
    if (ld == null)
    {
      bl_apt_addLink(d, div, dind);
      ld = d.linkData;
      dday.dayList.push(ld);
      bl_apt_switchDataToLink(d, ld);
    }
    
    if (d.dIndex < ld.dIndex)
    {
      d.eMark  = itvTlt;
      ld.sMark = 0;
    }
    else
    {
      ld.eMark = itvTlt;
      d.sMark  = 0;
    }
  }
  bl_apt_dragComputeTimes(item);
  bl_apt_computeDayList(ap, d.anchorIndex, true);
  bl_apt_computeDayList(ap, dind, true);
}

function bl_apt_dragAllDay(item, d, ap, dind, done)
{
  var dObj = ap.cbApt;
  
  if (!d.isAllDay)
  {
    var di  = d.dIndex;
    var ld  = d.linkData;
    var ldi = (ld != null) ? d.linkData.dIndex : -1;
    
    bl_apt_swapViewParent(item, ap.parentNode, d, dObj);
    d.isAllDay = true;
    bl_apt_swapContentTag(d, true);
    bl_apt_computeDayList(ap, di, false);
    
    if (ldi >= 0)
    {
      bl_apt_removeLink(d);
      bl_apt_computeDayList(ap, ldi, false);
      
      if (di > ldi)
      {
        d.sMark = ld.sMark;
      }
      else
      {
        d.eMark = ld.eMark;
      }
    }
    d.dIndex = -1;
  }
  
  var sind = (dind > d.anchorIndex) ? d.anchorIndex : dind;
  d.dayCnt = Math.abs(dind - d.anchorIndex) + 1;
  
  bl_apt_setSideBarCnt(d, d.dayCnt);
  if (d.dIndex != sind)
  {
    if (d.dIndex != undefined && d.dIndex >= 0)
    {
      dObj.remove(d, false);
    }
    d.dIndex = sind;
    dObj.add(d, true);
  }
  
  bl_apt_dragComputeTimes(item);
  bl_apt_setActiveDay(d);
  bl_apt_setHeadH(ap, bl_apt_recomputeAllDays(ap), done);
}


function bl_apt_dragComputeTimes(item)
{
  var d      = item.cbData;
  var el     = d.controlEl;
  var itvTlt = el.bl_interval_tlt;
  var itvCnt = el.bl_interval_cnt;
  var itv    = el.bl_interval_val
  var ap     = el.firstChild;
  var dObj   = ap.cbApt;
  var day    = dObj.getDay(d.dIndex);
  var date   = new Date();
  
  if (day)
  {
    if (item.moveType == 1)
    {
      if (d.linkData != null)
      {
        var ld = d.linkData;
        
        ld.sYear   = d.sYear   = day.year;
        ld.sMonth  = d.sMonth  = day.month;
        ld.sDay    = d.sDay    = day.day;
        ld.sHour   = d.sHour   = Math.floor(d.sMark/itvCnt);
        ld.sMinute = d.sMinute = (d.sMark%itvCnt) * itv;
      }
      else
      {
        d.sYear    = day.year;
        d.sMonth   = day.month;
        d.sDay     = day.day;
        d.sHour    = Math.floor(d.sMark/itvCnt);
        d.sMinute  = (d.sMark%itvCnt) * itv;
        d.duration = d.aDuration = (d.isAllDay) ? -1 : d.eMark - d.sMark;
      }
    }
    else if (item.moveType == 2)
    {
      if (d.linkData != null)
      {
        var ld = d.linkData;
        
        ld.eYear   = d.eYear   = day.year;
        ld.eMonth  = d.eMonth  = day.month;
        ld.eDay    = d.eDay    = day.day;
        ld.eHour   = d.eHour   = Math.floor(d.eMark/itvCnt);
        ld.eMinute = d.eMinute = (d.eMark%itvCnt) * itv;
      }
      else
      {
        var newd = day.day;
        if (d.isAllDay)
        {
          newd +=  d.dayCnt;
          if (d.eMark > 0)
          {
            newd--;
          }
          d.duration = d.aDuration = -1;
        }
        else
        {
          d.duration = d.aDuration = d.eMark - d.sMark;
        }
        date.setFullYear(day.year, day.month,  newd);
        d.eYear   = date.getFullYear();
        d.eMonth  = date.getMonth();
        d.eDay    = date.getDate();
        d.eHour   = Math.floor(d.eMark/itvCnt);
        d.eMinute = (d.eMark%itvCnt) * itv;
      }
    }
    
    if (d.sHour >= 24)
    {
      date.setFullYear(d.sYear, d.sMonth, d.sDay + 1);
      d.sYear   = date.getFullYear();
      d.sMonth  = date.getMonth();
      d.sDay    = date.getDate();
      d.sHour   = 0;
      d.sMinute = 0;
    }
    if (d.eHour >= 24)
    {
      date.setFullYear(d.eYear, d.eMonth, d.eDay + 1);
      d.eYear   = date.getFullYear();
      d.eMonth  = date.getMonth();
      d.eDay    = date.getDate();
      d.eHour   = 0;
      d.eMinute = 0;
    }
    
    if (d.linkData != null)
    {
      var ld = d.linkData;
      
      if (d.dIndex < ld.dIndex)
      {
        d.duration  = itvTlt - d.sMark;
        ld.duration = ld.eMark;
      }
      else
      {
        d.duration  = d.eMark;
        ld.duration = itvTlt - ld.sMark;
      }
      d.aDuration = ld.aDuration = ld.duration + d.duration;
    }
  }
}

function bl_apt_dragDayPos(item, d, ap, dind, cnt, done)
{
  var itvTlt = d.controlEl.bl_interval_tlt;
  
  if (item.moveType == 1)
  {
    d.setSOffset(0);
    if (dind == d.anchorIndex - 1 && (d.anchorMark + (itvTlt - cnt)) < itvTlt)
    {
      if (d.linkData && d.linkData.dIndex < d.dIndex)
      {
        d.linkData.sMark = cnt;
      }
      else
      {
        d.sMark = cnt;
      }
      bl_apt_dragLink(item, d, ap, dind, done);
    }
    else if (dind < d.anchorIndex || (dind == d.anchorIndex && Math.abs(d.anchorMark - cnt) == itvTlt))
    {
      if (cnt >= itvTlt)
      {
        d.sMark = 0;
        dind++;
      }
      else
      {
        d.sMark = cnt;
      }
      bl_apt_dragAllDay(item, d, ap, dind, done);
    }
    else
    {
      d.sMark = ((dind == d.anchorIndex && cnt > d.anchorMark) || dind > d.anchorIndex) ? d.anchorMark : cnt;
      bl_apt_dragAnchore(item, d, ap, d.anchorIndex, dind, done);
    }
  }
  else if (item.moveType == 2)
  {
    d.setEOffset(0);
    if (dind == d.anchorIndex + 1 && (cnt + (itvTlt - d.anchorMark)) < itvTlt)
    {
      if (d.linkData && d.linkData.dIndex > d.dIndex)
      {
        d.linkData.eMark = cnt;
      }
      else
      {
        d.eMark = cnt;
      }
      bl_apt_dragLink(item, d, ap, dind, done);
    }
    else if (dind > d.anchorIndex || (dind == d.anchorIndex && Math.abs(d.anchorMark - cnt) == itvTlt))
    {
      d.eMark = cnt;
      if (cnt == 0)
      {
        dind--;
      }
      bl_apt_dragAllDay(item, d, ap, dind, done);
    }
    else
    {
      d.eMark = (cnt < d.anchorMark || dind < d.anchorIndex) ? d.anchorMark : cnt;
      bl_apt_dragAnchore(item, d, ap, d.anchorIndex, dind, done);
    }
  }
  
  bl_apt_setContentStr(d, false, true);
  bl_apt_activateItem(item);
}

function bl_apt_setSideBarCnt(d, cnt)
{
  if (cnt > 0)
  {
    var sb = d.sideBar;
    
    if (sb == null)
    {
      sb = d.sideBar = bl_apt_createSideBar();
      bl_apt_setSideBarStyle(d, sb);
    }
    
    
    cnt--;
    while (sb.nextSB != null && cnt > 0)
    {
      cnt--;
      sb = sb.nextSB;
    }
    
    if (cnt > 0)
    {
      while (cnt > 0)
      {
        sb.nextSB = bl_apt_createSideBar();
        sb = sb.nextSB;
        bl_apt_setSideBarStyle(d, sb);
        cnt--;
      }
    }
    else if (sb.nextSB != null)
    {
      bl_apt_gleanSideBars(sb);
    }
  }
}

function bl_apt_computeMoveTimes(item)
{
  var d      = item.cbData;
  var di     = d.dIndex;
  var el     = d.controlEl;
  var ap     = el.firstChild;
  var dObj   = ap.cbApt;
  var date   = new Date();
  var day    = dObj.getDay(di);
  var itv    = el.bl_interval_val;
  var itvCnt = el.bl_interval_cnt;
  var itvTlt = el.bl_interval_tlt;
  
  if (day)
  {
    date.setFullYear(day.year, day.month, day.day);
    
    if (d.isAllDay)
    {
      date.setDate(date.getDate() - d.sIndex);
      
      d.sHour   = 0
      d.sMinute = 0;
      d.eHour   = 0
      d.eMinute = 0;
      
      d.duration = -1;
      d.sYear    = date.getFullYear();
      d.sMonth   = date.getMonth();
      d.sDay     = date.getDate();
      
      var diff = (d.eHour == 0 && d.eMinute == 0) ? d.tDayCnt : d.tDayCnt - 1;
      date.setDate(date.getDate() + diff);
      d.eYear  = date.getFullYear();
      d.eMonth = date.getMonth();
      d.eDay   = date.getDate();
      d.computeMarks();
    }
    else
    {
      if (d.linkData != null)
      {
        var ld = d.linkData;
        
        ld.ismoving = false;
        if (ld.dIndex > di)
        {
          d.sYear  = ld.sYear  = date.getFullYear();
          d.sMonth = ld.sMonth = date.getMonth();
          d.sDay   = ld.sDay   = date.getDate();
          d.computeSTime(d.lastCnt);
          d.computeSMark();
          d.eMark = itvTlt;
          date.setDate(date.getDate() + 1);
          ld.sMark = 0;
          ld.eMark = (ld.duration < 0) ? 1 : ld.duration;
          d.eYear  = ld.eYear  = date.getFullYear();
          d.eMonth = ld.eMonth = date.getMonth();
          d.eDay   = ld.eDay   = date.getDate();
          d.computeETime(ld.eMark);
        }
        else
        {
          d.sMark = 0;
          d.eMark = (d.duration < 0) ? 1 : d.duration;
          
          d.eYear  = ld.eYear  = date.getFullYear();
          d.eMonth = ld.eMonth = date.getMonth();
          d.eDay   = ld.eDay   = date.getDate();
          d.computeETime(d.eMark);
          date.setDate(date.getDate() - 1);
          ld.sMark = itvTlt - ((ld.duration < 0) ? 1 : ld.duration);
          ld.eMark = itvTlt;
          d.sYear  = ld.sYear  = date.getFullYear();
          d.sMonth = ld.sMonth = date.getMonth();
          d.sDay   = ld.sDay   = date.getDate();
          d.computeSTime(ld.sMark);
        }
      }
      else if (d.duration < d.aDuration)
      {
        if (d.dIndex == 0)
        {
          var ecnt   = d.duration;
          var scnt   = itvTlt - (d.aDuration - d.duration);
          d.eYear    = date.getFullYear();
          d.eMonth   = date.getMonth();
          d.eDay     = date.getDate();
          d.computeETime(ecnt);
          d.eMark    = ecnt;
          date.setDate(date.getDate() - 1);
          d.sYear    = date.getFullYear();
          d.sMonth   = date.getMonth();
          d.sDay     = date.getDate();
          d.computeSTime(scnt);
          d.sMark    = 0;
          d.duration = d.eMark;
        }
        else if (d.dIndex == (dObj.length() - 1))
        {
          var ecnt = d.aDuration - d.duration;
          d.sYear  = date.getFullYear();
          d.sMonth = date.getMonth();
          d.sDay   = date.getDate();
          d.computeSTime(d.lastCnt);
          d.sMark  = d.lastCnt;
          date.setDate(date.getDate() + 1);
          d.eMark  = itvTlt;
          d.eYear  = date.getFullYear();
          d.eMonth = date.getMonth();
          d.eDay   = date.getDate();
          d.computeETime(ecnt);
          d.duration = itvTlt - d.sMark;
        }
      }
      else
      {
        var zero = d.isZero();
        
        d.sYear  = date.getFullYear();
        d.sMonth = date.getMonth();
        d.sDay   = date.getDate();
        d.computeSTime(d.lastCnt);
        d.computeSMark();
        d.eMark  = d.sMark + ((d.duration < 0) ? 1 : d.duration);
        d.eYear  = date.getFullYear();
        d.eMonth = date.getMonth();
        d.eDay   = date.getDate();
        d.computeETime((zero) ? d.lastCnt : d.eMark);
        d.duration = d.eMark - d.sMark;
      }
    }
  }
}

function bl_apt_clearSB(sb)
{
  if (sb)
  {
    sb.style.visibility = "hidden";
    
    if (sb.parentNode != null)
    {
      sb.parentNode.removeChild(sb);
    }
    sb.nextSB = null;
    bl_apt_unusedSideBars.push(sb);
  }
}

function bl_apt_moveDone(item, x, y)
{
  item.style.cursor = "wait";
  
  if (bl_apt_move(item, x, y, true))
  {
    var d  = item.cbData;
    var di = d.dIndex;
    var oi = d.origIndex;
    var el = d.controlEl;
    var ap = el.firstChild;
    var allDay = d.isAllDay;
    
    d.ismoving = false;
    if (d.isAllDay)
    {
      bl_apt_setSideBarCnt(d, d.dayCnt);
    }
    else
    {
      bl_apt_gleanSideBars(d.sideBar);
    }
    
    bl_apt_clearSB(d.linkSB)
    d.linkSB = null;
    
    if ((allDay && !d.origAllDay) || (!allDay  && !d.origAllDay && di != oi))
    {
      bl_apt_computeDayList(ap, oi, true);
    }
    if (allDay)
    {
      bl_apt_recomputeAllDays(ap);
    }
    else
    {
      bl_apt_computeDayList(ap, di, true);
      
      if (d.linkData != null)
      {
        bl_apt_computeDayList(ap, d.linkData.dIndex, true);
      }
    }
    
    if (d.id)
    {
      bl_apt_clearSelect(el, true);
    }
    bl_apt_sendUpdate(d, false);
  }
}

function bl_apt_clearSelect(el, setRange)
{
  var sel = el.selectedEl;
  if (sel != null)
  {
    bl_apt_deselectItem(sel, true);
    if (setRange)
    {
      var d = sel.cbData;
      bl_apt_setSelectRange(el, d, d.linkData);
    }
    bl_mpr_send('<clearSelect/>', el.id, 0); 
  }
}

function bl_apt_move(item, x, y, done)
{
  var d  = item.cbData;
  var ap = d.controlEl.firstChild;
  var yoffset = (item.moveType == 0) ? item.yhit : 0;
  
  if (!d.readonly && bl_apt_computePos(ap, yoffset, x, y, -1, item.moveType, 0, 0))
  {
    var cnt = ap.cb_cnt;
    var dind = ap.cb_dind;
    
    if (ap.cb_inAllDay)
    {
      if (item.moveType == 0)
      {
        bl_apt_moveAllDayPos(item, dind, d, ap);
      }
      else
      {
        if (item.moveType == 2 && dind > d.anchorIndex || (dind == d.anchorIndex && d.anchorMark == 0))
        {
          dind++;
        }
        bl_apt_dragDayPos(item, d, ap, dind, 0, done);
      }
    }
    else
    {
      if (d.lastCnt != cnt || item.lastIndex != dind || d.isAllDay)
      {
        if (item.moveType == 0)
        {
          if (cnt < 0)
          {
            if (d.aDuration < 0)
            {
              cnt = 0;
            }
            else if (cnt + d.aDuration < 1)
            {
              cnt = 1 - d.aDuration;
            }
          }
          bl_apt_moveDayPos(item, cnt, ap, dind);
        }
        else
        {
          bl_apt_dragDayPos(item, d, ap, dind, cnt, done);
        }
      }
    }
    item.lastIndex = dind;
    return true;
  }
  else
  {
    bl_apt_restoreItem(ap, item, false);
  }
  return false;
}

function bl_apt_filterDone(view)
{
}

function bl_apt_cancleFilter(d)
{
}

function bl_apt_startFilter(d, goingDown)
{
  var view = d.view;
  var linkView = null;
  
  if (d.linkData)
  {
    linkView = d.linkData.view;
  }
  
  if (goingDown)
  {
    cb_sys_startFilter(view, false, 65, 100, 5, linkView, "", bl_apt_filterDone);
  }
  else
  {
    cb_sys_startFilter(view, true, 100, 65, 5, linkView, bl_apt_fadedFilt, null);
  }
}

function bl_apt_restoreItem(ap, item, force)
{
  if (item.moveType == 0)
  {
    var d  = item.cbData;
    var oi = d.origIndex;
    
    if (d.origAllDay)
    {
      bl_apt_moveAllDayPos(item, item.origScIndex, d, ap);
    }
    else
    {
      bl_apt_moveDayPos(item, d.origCnt, ap, oi);
    }
    if (force)
    {
      bl_apt_startFilter(d, true);
    }
  }
  else
  {
    if (force)
    {
      bl_apt_dragDayPosDone(item, 0, 0, false);
    }
  }
}

function bl_apt_moveAllDayPos(item, dind, d, ap)
{
  if (dind != item.lastIndex || !d.isAllDay)
  {
    var index = dind - item.indexDiff - d.sIndex;
    d.sIndex  = 0;
    
    if (index < 0)
    {
      d.sIndex = -index;
      index    = 0;
    }
    var dObj = ap.cbApt;
    var dcnt = dObj.length();
    
    d.dayCnt = d.tDayCnt - d.sIndex;
    
    if (index + d.dayCnt > dcnt)
    {
      d.dayCnt = dcnt - index;
    }
    
    
    if (!d.isAllDay)
    {
      bl_apt_swapViewParent(item, ap.parentNode, d, dObj);
      bl_apt_removeLink(d);
      d.isAllDay = true;
      bl_apt_swapContentTag(d, true);
    }
    else
    {
      dObj.remove(d, false);
    }
    
    d.dIndex = index;
    item.indexDiff = dind - d.dIndex;
    dObj.add(d, true);
    bl_apt_setActiveDay(d);
    dObj.getDay(0).allDayEl.style.height = bl_apt_recomputeAllDays(ap)+"px";
    bl_apt_computeMoveTimes(item);
    bl_apt_setContentStr(d, false, true);
  }
}

function bl_apt_updateDay(ap, index, allDay)
{
  if (allDay)
  {
    var day = ap.cbApt.getDay(index);
    
    if (day)
    {
      day.sortAllDay();
      day.allDayEl.style.height = bl_apt_recomputeAllDays(ap)+"px";
    }
  }
  else
  {
    bl_apt_computeDayList(ap, index, true);
  }
}

function bl_apt_recomputeAllDays(ap)
{
  var max = 28;
  var len = ap.cbApt.length();
  
  for (var i = 0; i < len; i++)
  {
    max = Math.max(bl_apt_computeAllDayList(ap, i), max);
  }
  
  return max;
}

function bl_apt_extractData(d, removeLink)
{
  if (d.dIndex != undefined && d.dIndex >= 0 && d.dIndex < this.length())
  {
    this.list[d.dIndex].remove(d);
    if (removeLink && d.linkData != null)
    {
      d = d.linkData
      this.list[d.dIndex].remove(d);
    }
  }
}

function bl_apt_removeData(d)
{
  var list = (d.isAllDay) ? this.allDayList : this.dayList;
  var len  = list.length;
  
  for (var i = 0; i < len; i++)
  {
    if (list[i] == d)
    {
      list.splice(i, 1);
      break;
    }
  }
}

function bl_apt_swapViewParent(v, p, d, dObj)
{
  bl_port_releaseCapture(v);
  p.appendChild(v);
  bl_port_setCapture(v);
  dObj.remove(d, true);
}

function bl_apt_moveDayPos(item, cnt, ap, dind)
{
  var d      = item.cbData;
  var ad     = false;
  var itvTlt = ap.parentNode.bl_interval_tlt;
  var dObj   = ap.cbApt;
  var div    = dObj.divEl;
  var day    = dObj.getDay(dind);
  
  if (d.isAllDay)
  {
    bl_apt_swapViewParent(item, div, d, dObj);
    d.isAllDay = false;
    bl_apt_swapContentTag(d, true);
    dObj.getDay(0).allDayEl.style.height = bl_apt_recomputeAllDays(ap)+"px";
  }
  else
  {
    dObj.remove(d, true);
  }
  
  var sw   = 6;
  var swx2 = sw * 2;
  var ex   = false;
  var s    = item.style;
  
  d.dIndex = dind;
  dObj.add(d, false);
  if (d.origCnt == cnt && dind == d.origIndex && !d.origAllDay)
  {
    d.duration = d.origDuration;
    s.height   = d.origHeight+"px";
    s.top      = d.origTop+"px";
    s.left     = d.origLeft+"px";
    s.width    = d.origWidth+"px";
    bl_apt_contentPanel(item).style.width = (d.origWidth - sw)+"px";
    item.childNodes[1].style.height = (d.origHeight - swx2)+"px";
    
    if (d.origHasLink)
    {
      bl_apt_addLink(d, div, d.origLIndex);
      
      var ld = d.linkData;
      var lv = ld.view;
      var ls = lv.style;
      
      ld.isAllDay   = false;
      ld.duration   = d.origLDuration;
      dObj.add(ld, false);
      ls.visibility = "visible";
      ls.height     = d.origLHeight+"px";
      ls.top        = d.origLTop+"px";
      ls.left       = d.origLLeft+"px";
      ls.width      = d.origLWidth+"px";
      bl_apt_contentPanel(lv).style.width = (d.origLWidth - sw)+"px";
      lv.childNodes[1].style.height       = (d.origLHeight - swx2)+"px";
      bl_apt_setDay(ld, false);
    }
    else
    {
      bl_apt_removeLink(d);
    }
    
    bl_apt_setDay(d, false);
  }
  else
  {
    var h = bl_apt_itemHeight;
    var w = day.topEl.offsetWidth;
    
    if (cnt < 0)
    {
      if (dind > 0)
      {
        var li = dind - 1;
        bl_apt_addLink(d, div, li);
        
        var ld = d.linkData;
        var lv = ld.view;
        var ls = lv.style;
        
        ld.duration = -cnt;
        dObj.add(ld, false);
        
        elh           = ld.duration * h;
        ls.visibility = "visible";
        ls.height     = (elh + swx2)+"px";
        ls.top        = (((itvTlt + cnt) * h) - sw)+"px";
        ls.left       = dObj.getDay(li).sepEl.offsetLeft+"px";
        ls.width      = w+"px";
        bl_apt_contentPanel(lv).style.width = (w - sw)+"px";
        lv.childNodes[1].style.height       = elh+"px";
      }
      else
      {
        bl_apt_removeLink(d);
      }
      d.duration = Math.abs(cnt + d.aDuration);
      cnt = 0;
    }
    else if (cnt + d.aDuration > itvTlt)
    {
      if (dind < dObj.length() - 1)
      {
        var li = dind + 1;
        bl_apt_addLink(d, div, li);
        
        var ld = d.linkData;
        var lv = ld.view;
        var ls = lv.style;
        
        ld.duration = cnt + d.aDuration - itvTlt;
        dObj.add(ld, false);
        elh           = ld.duration * h;
        ls.visibility = "visible";
        ls.height     = (elh + swx2)+"px";
        ls.top        = 0;
        ls.left       = dObj.getDay(li).sepEl.offsetLeft+"px";
        ls.width      = w+"px";
        bl_apt_contentPanel(lv).style.width = (w - sw)+"px";
        lv.childNodes[1].style.height       = (elh)+"px";
      }
      else
      {
        bl_apt_removeLink(d);
      }
      d.duration = itvTlt - cnt;
    }
    else
    {
      d.duration = (d.aDuration < 0) ? 1 : d.aDuration;
      bl_apt_removeLink(d);
    }
    elh      = d.duration * h;
    s.height = (elh + swx2)+"px";
    s.top    = ((cnt * h) - sw) + "px";
    s.left   = day.sepEl.offsetLeft + "px";
    s.width  = w+"px";
    
    with (bl_apt_contentPanel(item).style)
    {
      left   = sw + "px";
      top    = sw + "px";
      width  = (w - sw)+"px";
      height = elh + "px";
    }
    
    item.childNodes[1].style.height       = elh+"px";
    bl_apt_activateItem(item);
  }
  d.lastCnt = cnt;
  bl_apt_computeMoveTimes(item);
  bl_apt_setContentStr(d, false, true);
}

function bl_apt_addLink(d, p, dind)
{
  var ld = d.linkData;
  
  if (ld == null)
  {
    var ld = bl_apt_createLink(d, d.controlEl);
    bl_apt_swapContentTag(ld, true);
  }
  ld.ismoving  = d.ismoving;
  var v        = ld.view;
  v.isSelected = d.view.isSelected;
  ld.dIndex    = dind;
  
  if (v.parentNode != p)
  {
    p.appendChild(v);
  }
  
  d.linkData = ld;
}

function bl_apt_replaceLinkData(d, ld, list, len)
{
  if (d.isLink)
  {
    var i = bl_apt_findIndex(list, len, d.id);
    if (i >= 0)
    {
      list.splice(i, 1, d);
    }
  }
  
  d.isLink   = false;
  d.linkData = ld;
  if (ld != null)
  {
    ld.isLink = true;
  }
}

function bl_apt_removeLink(d)
{
  if (d.linkData != null)
  {
    var el   = d.controlEl;
    var list = el.cbAptList;
    var len  = el.cbAptLen;
    var ld   = d.linkData;
    
    bl_apt_replaceLinkData(d, null, list, len);
    
    var v = ld.view;
    bl_apt_setViewVisibility(v, "hidden");
    
    if (v.parentNode != null)
    {
      v.parentNode.removeChild(ld.view);
    }
    var sb     = ld.sideBar;
    ld.sideBar = null;
    if (d.ismoving)
    {
      d.linkSB = sb;
    }
    else
    {
      bl_apt_clearSB(sb)
    }
    list.push(ld);
  }
}

function _bl_apt_tt_timmer(id, dataId)
{
  var el = document.getElementById(id);
  
  window.bl_apt_tt_timer_id = undefined;
  
  if (el)
  {
    var ttData = el.cb_tt_data;
    
    el.cb_tt_data = null;
    if (ttData && ttData.view.mouseIn)
    {
      bl_apt_show_tt(ttData);
    }
  }
}

function _bl_apt_enter(event, item)
{
  var target       = bl_port_getEventTarget(event);
  var offPos       = bl_port_offsetToItem(event, target);
  var isContained  = false;

  if (bl_browserInfo.ie)
  {
    isContained = (target == item);
  }
  else
  {
    // I know this seems odd but we realy only want to 
    // to be notified once while we are with in the item
    isContained = !item.mouseIn;
  }
  
  if (isContained &&
      offPos.x >= 0                   &&
      offPos.y >= 0                   &&
      offPos.x <= item.offsetWidth    &&
      offPos.y <= item.offsetHeight   &&
      !item.isDraging)
  {
    var d     = item.cbData
    var el    = d.controlEl;
    var ttDiv = d.controlEl.cb_ttDiv;
    
    item.mouseIn = true;
    bl_apt_activateItem(item);

    if (ttDiv && ttDiv.goDown)
    {
      cb_sys_setOpFilter(ttDiv, "", true);
    }
    
    el.cb_tt_data = d;
    bl_apt_compute_tt(d);
    bl_apt_tt_clear_timeout();
    window.bl_apt_tt_timer_id = window.setTimeout('_bl_apt_tt_timmer("' + el.id + '","' + d.id + '")', 250);
  }
  bl_port_killEvent(event);
}

function bl_apt_tt_clear_timeout()
{
  if (window.bl_apt_tt_timer_id)
  {
    window.clearTimeout(window.bl_apt_tt_timer_id);
  }
  window.bl_apt_tt_timer_id = undefined;
}

function bl_apt_setSideStyle(inside, d, extra)
{
  var ld = d.linkData;
  var em = d.eOffMark;
  var sm = d.sOffMark;
  
  if (ld)
  {
    if (ld.dIndex < d.dIndex)
    {
      sm = 0;
    }
    else
    {
      em = 0;
    }
  }
  
  var s = inside.style;
  if (d.isZero())
  {
    s.top = s.height = "";
    inside.className = "bl_apt_dInSideZero " + extra;
    inside.firstChild.style.display = "inline";
  }
  else if (em || sm)
  {
    inside.firstChild.style.display = "none";
    
    var cName = "bl_apt_dInSideO ";
    if (!em)
    {
      cName = "bl_apt_dInSideOT "
    }
    else if (!sm)
    {
      cName = "bl_apt_dInSideOB "
    }
    
    inside.className = cName + extra;
    var h = (bl_apt_itemHeight * d.duration) - (em + sm);
    
    s.top = ((sm >= 2) ? sm - 2 : sm)+"px";
    if (h <= 2)
    {
      h = 0;
    }
    else if (sm >= 2)
    {
      h += 2;
    }
    s.height = h+"px";
  }
  else
  {
    s.top                           = s.height = "";
    inside.firstChild.style.display = "none";
    inside.className                = "bl_apt_dInSide " + extra;
  }
}

function bl_apt_setActiveDay(d)
{
  var os      = d.olClass;
  var bg      = d.bgClass;
  var item    = d.view;
  var top     = bl_apt_topPanel(item);
  var bottom  = bl_apt_bottomPanel(item);
  var side    = bl_apt_sidePanel(item);
  var inside  = side.firstChild;
  var content = bl_apt_contentPanel(item);
  
  if (item.isSelected)
  {
    if (d.isAllDay)
    {
      top.className     = "bl_apt_aTop";
      bottom.className  = "bl_apt_aBottom";
      inside.className  = side.className = "bl_apt_aSide";

      if (d.bord == 4)
      {
        content.style.borderColor = "#C0C0C0";
        content.className = "bl_apt_aContent " + bg;
      }
      else
      {
        content.className = "bl_apt_aContent " + bg + os + "AB";
      }
    }
    else
    {
      top.className     = "bl_apt_dTopActive " + os + " "  + os + "AB";
      bottom.className  = "bl_apt_dBottomActive " + os + " "  + os + "AB";
      bl_apt_setSideStyle(inside, d, os + " "  + os + "AB");
      side.className    = "bl_apt_dSide " + os + "AB";
      content.className = "bl_apt_dContent " + bg + " " + os + "AB";
    }
  }
  else
  {
    if (d.isAllDay)
    {
      top.className     = "bl_apt_aTop";
      bottom.className  = "bl_apt_aBottom";
      inside.className  = side.className = "bl_apt_aSide";

      if (d.bord == 4)
      {
        content.style.borderColor = "#C0C0C0";
        content.className = "bl_apt_aContent " + bg;
      }
      else
      {
        content.className = "bl_apt_aContent " + bg + os + "AB";
      }
    }
    else
    {
      top.className     = "bl_apt_dTop " + os + " "  + os + "AB";
      bottom.className  = "bl_apt_dBottom " + os + " "  + os + "AB";
      bl_apt_setSideStyle(inside, d, os + " "  + os + "AB");
      side.className    = "bl_apt_dSide " + os + "AB";
      content.className = "bl_apt_dContent " + bg + " " + os + "AB";
    }
  }
}

function bl_apt_setDay(d, sel)
{
  var os      = d.olClass;
  var bg      = d.bgClass;
  var item    = d.view;
  var top     = bl_apt_topPanel(item);
  var bottom  = bl_apt_bottomPanel(item);
  var side    = bl_apt_sidePanel(item);
  var inside  = side.firstChild;
  var content = bl_apt_contentPanel(item);
  
  
  if (sel)
  {
    if (d.isAllDay)
    {
      top.className     = "bl_apt_aTop bl_apt_BorderC";
      bottom.className  = "bl_apt_aBottom bl_apt_BorderC";
      inside.className  = side.className = "bl_apt_aSide";
      
      if (d.bord == 4)
      {
        content.style.borderColor = d.color;
        content.className = "bl_apt_aContent " + bg;
      }
      else
      {
        content.className = "bl_apt_aContent bl_apt_BorderC " + bg;
      }
    }
    else
    {
      top.className     = "bl_apt_dTopActive bl_apt_BorderC " + os;
      bottom.className  = "bl_apt_dBottomActive bl_apt_BorderC " + os;
      bl_apt_setSideStyle(inside, d, " bl_apt_BorderC " + os);
      side.className    = "bl_apt_dSide bl_apt_BorderC";
      content.className = "bl_apt_dContent bl_apt_BorderC " + bg;
    }
  }
  else
  {
    if (d.isAllDay)
    {
      top.className     = "bl_apt_aTop bl_apt_BorderC";
      bottom.className  = "bl_apt_aBottom bl_apt_BorderC";
      inside.className  = side.className = "bl_apt_aSide";

      if (d.bord == 4)
      {
        content.style.borderColor = d.color;
        content.className = "bl_apt_aContent " + bg;
      }
      else
      {
        content.className = "bl_apt_aContent bl_apt_BorderC " + bg;
      }
    }
    else
    {
      top.className     = "bl_apt_dTop bl_apt_BorderC " + os;
      bottom.className  = "bl_apt_dBottom bl_apt_BorderC " + os;
      bl_apt_setSideStyle(inside, d, " bl_apt_BorderC " + os);
      side.className    = "bl_apt_dSide bl_apt_BorderC";
      content.className = "bl_apt_dContent bl_apt_BorderC " + bg;
    }
  }
}

function _bl_apt_leave(event, item)
{
  var target      = bl_port_getEventTarget(event);
  var isContained = false;
  
  if (bl_browserInfo.ie)
  {
    isContained = bl_port_contains(item, target, false) && item != target;
  }
  else
  {
    with (bl_port_offsetToItem(event, item))
    {
      isContained = (x >= 0 && y >= 0 && x <= item.offsetWidth && y <= item.offsetHeight);
    }
  }
  
  if (!isContained && !item.isDraging)
  {
    var d = item.cbData;
    item.mouseIn = false;
    bl_apt_deactivateItem(item);
    bl_apt_hide_tt(d.controlEl, d);
  }
  
  bl_port_killEvent(event);
}

function bl_apt_activateItem(item)
{
  var d = item.cbData;
  bl_apt_setActiveDay(d);
  
  if (d.linkData != null)
  {
    bl_apt_setActiveDay(d.linkData);
  }
}

function bl_apt_deactivateItem(item)
{
  var d = item.cbData;
  bl_apt_setDay(d, item.isSelected);
  
  if (d.linkData != null)
  {
    var v = d.linkData.view;
    bl_apt_setDay(d.linkData, v.isSelected);
  }
}

function bl_apt_setSelectRange(el, d, ld)
{
  if (el.getAttribute("bl_readonly") == null)
  {
    if (ld != null)
    {
      if (d.dIndex < ld.dIndex)
      {
        el.sDind = d.dIndex
        el.eDind = ld.dIndex;
        el.sCnt  = d.sMark;
        el.eCnt  = ld.eMark;
      }
      else
      {
        el.sDind = ld.dIndex
        el.eDind = d.dIndex;
        el.sCnt  = ld.sMark;
        el.eCnt  = d.eMark;
      }
    }
    else
    {
      el.sDind = el.eDind = d.dIndex;
      el.sCnt  = d.sMark;
      el.eCnt  = d.eMark;
    }
    
    bl_apt_setEditSelect(el);
    bl_apt_computeEditTimes(el, 2);
  }
}

function bl_apt_selectItem(item, send)
{
  var d  = item.cbData;
  var ld = d.linkData;
  var el = d.controlEl;
  item.isSelected = true;
  el.selectedEl   = item;
  el.selectedId   = d.id;
  
  bl_apt_setActiveDay(d);
  item.style.zIndex = 101;
  
  if (ld != null)
  {
    var v = d.linkData.view;
    v.isSelected   = true;
    v.style.zIndex = 101;
    bl_apt_setActiveDay(ld);
  }
  bl_apt_setSelectRange(el, d, ld);
  
  if (send)
  {
    bl_mpr_send('<select><id>' + d.id + '</id></select>', el.id, 0);
  }
}

function bl_apt_deselectItem(item, send)
{
  var d  = item.cbData;
  var el = d.controlEl;
  item.isSelected = false;
  el.selectedEl   = null;
  el.selectedId   = null;
  bl_apt_setDay(d, false);
  item.style.zIndex = 100;
  
  if (d.linkData != null)
  {
    var v          = d.linkData.view;
    v.isSelected   = false;
    v.style.zIndex = 100;
    bl_apt_setDay(d.linkData, false);
  }
  
  if (!d.id && send)
  {
    bl_apt_sendUpdate(d, true);
  }
}

function _bl_apt_down(event, item)
{
  if (bl_port_getEventTarget(event).getAttribute("bl_ignore_me") != null)
  {
    return;
  }
  
  if (bl_browserInfo.firefox && event.detail >= 2)
  {
    _bl_apt_dblclk(event, item);    
    bl_port_stop_event(event);
    return ;
  }

  bl_port_killEvent(event);
  
  item.mouseDown = true;
  var d   = item.cbData;
  var el  = d.controlEl;
  var sel = el.selectedEl;
  var ap  = el.firstChild;
  
  bl_apt_hide_tt(el, d);
  bl_apt_setKeyInput(ap);
  bl_apt_editContentDone(d.id ? true : false, false, false);
  
  if (sel != item)
  {
    if (sel != null)
    {
      bl_apt_deselectItem(sel, true);
    }
    
    bl_apt_selectItem(item, true);
  }
  
  var date = new Date();
  item.lastTime = date.getTime();
  
  var type  = bl_apt_computeMoveType(item, d, false, event);
  if (type >= 0)
  {
    bl_port_setCapture(item);
    
    var dObj       = ap.cbApt;
    item.moved     = false;
    item.cbx       = event.screenX;
    item.cby       = event.screenY;
    item.isDraging = true;
    item.moveType  = type;
    bl_apt_saveOrig(d, item);
    ap.dragItem    = item;
    
    item.origScIndex = item.lastIndex = dObj.findIndex(event.screenX - (bl_sys_find_x(ap, null, false) + cb_sys_getScreenLeft()));
    item.indexDiff   = item.lastIndex - d.dIndex;
    item.growHeight  = dObj.getDay(0).allDayEl.offsetHeight + 22;
    
    if (type == 0)
    {
      bl_apt_initMove(el, dObj, item, d, date, event);
    }
    else if (type == 1)
    {
      bl_apt_initDragLeft(el, dObj, item, d);
    }
    else if (type == 2)
    {
      bl_apt_initDragRight(el, dObj, item, d);
    }
    bl_apt_autoScrollFunc = bl_apt_itemAutoMove;
    bl_apt_autoScrollArg  = item;
  }
}

function bl_apt_itemAutoMove(item, x, y)
{
  bl_apt_move(item, x, y, false);
}

function bl_apt_initDragLeft(el, dObj, item, d)
{
  var lastI = dObj.length() - 1;
  var day   = dObj.getDay(lastI);
  var ld    = d.linkData;
  
  if (ld)
  {
    if (d.dIndex < ld.dIndex)
    {
      d.origCnt  = d.sMark;
      d.origDind = d.dIndex;
    }
    else
    {
      d.origCnt  = ld.sMark;
      d.origDind = ld.dIndex;
    }
  }
  else
  {
    d.origCnt  = d.sMark;
    d.origDind = d.dIndex;
  }
  
  if (bl_apt_great(d.eYear, day.year, d.eMonth, day.month, d.eDay, day.day))
  {
    d.anchorIndex = lastI;
    d.anchorMark  = el.bl_interval_tlt;
  }
  else if (ld)
  {
    bl_apt_replaceLinkData(d, ld, el.cbAptList, el.cbAptLen);
    d.anchorMark  = ld.eMark;
    d.anchorIndex = ld.dIndex;
  }
  else
  {
    if (d.isAllDay)
    {
      d.anchorMark  = d.eMark;
      d.anchorIndex = d.dIndex + d.dayCnt - 1;
      
      if (d.anchorMark == 0)
      {
        d.anchorMark = el.bl_interval_tlt;
      }
    }
    else
    {
      d.anchorMark  = (d.isZero()) ? d.sMark : d.eMark;
      d.anchorIndex = d.dIndex;
    }
  }
}

function bl_apt_initDragRight(el, dObj, item, d)
{
  var day = dObj.getDay(0);
  var ld  = d.linkData;
  
  if (ld)
  {
    if (d.dIndex < ld.dIndex)
    {
      d.origCnt  = ld.eMark;
      d.origDind = ld.dIndex;
    }
    else
    {
      d.origCnt  = d.eMark;
      d.origDind = d.dIndex;
    }
  }
  else
  {
    d.origCnt  = d.eMark;
    d.origDind = d.dIndex;
  }
  
  if (bl_apt_less(d.sYear, day.year, d.sMonth, day.month, d.sDay, day.day))
  {
    d.anchorIndex = 0;
    d.anchorMark  = 0;
  }
  else if (ld)
  {
    var ld        = d.linkData;
    bl_apt_replaceLinkData(d, ld, el.cbAptList, el.cbAptLen);
    d.anchorMark  = ld.sMark;
    d.anchorIndex = ld.dIndex;
  }
  else
  {
    d.anchorMark  = d.sMark;
    d.anchorIndex = d.dIndex;
  }
}

function bl_apt_initMove(el, dObj, item, d, date, event)
{
  var day = dObj.getDay(d.dIndex);
  date.setFullYear(d.eYear, d.eMonth, d.eDay - 1);
  
  var isLD = ((d.sYear == date.getFullYear() && d.sMonth == date.getMonth() && d.sDay == date.getDate()) &&
              (d.eYear == day.year && d.eMonth == day.month && d.eDay == day.day)                        &&
              (d.eHour < d.sHour || (d.eHour == d.sHour && d.eMinute < d.sMinute)));
  
  item.yhit = bl_port_offsetToItem(event, bl_port_getEventTarget(event)).y;
  d.origCnt = d.sMark;
  if (!d.isAllDay && isLD)
  {
    var pvc = (el.bl_interval_tlt - ((d.sHour * el.bl_interval_cnt) + Math.floor(d.sMinute/el.bl_interval_val)));
    
    d.origCnt -= pvc;
    item.yhit += (pvc * bl_apt_itemHeight);
  }
  d.lastCnt = d.origCnt;
  
  item.sbList = new Array();
  var sb = d.sideBar;
  
  while (sb != null)
  {
    item.sbList.push(sb);
    sb = sb.nextSB;
  }
  
  bl_apt_startFilter(d, false);
}

function bl_apt_saveOrig(d, el, type)
{
  d.origIndex     = d.dIndex;
  d.origAllDay    = d.isAllDay;
  d.origDuration  = d.duration;
  d.origSMark     = d.sMark;
  d.origEMark     = d.eMark;
  d.origWidth     = el.offsetWidth;
  d.origHeight    = el.offsetHeight;
  d.origLeft      = el.offsetLeft;
  d.origTop       = el.offsetTop;
  d.origADuration = d.aDuration;
  d.origSIndex    = d.sIndex
  d.origTDayCnt   = d.tDayCnt;
  d.origDayCnt    = d.dayCnt;
  
  if (d.linkData != null)
  {
    var ld  = d.linkData;
    var lv  = ld.view;
    
    d.origHasLink   = true;
    d.origLIndex    = ld.dIndex;
    d.origLAllDay   = ld.isAllDay;
    d.origLDuration = ld.duration;
    d.origLSMark    = ld.sMark;
    d.origLEMark    = ld.eMark;
    d.origLWidth    = lv.offsetWidth;
    d.origLHeight   = lv.offsetHeight;
    d.origLLeft     = lv.offsetLeft;
    d.origLTop      = lv.offsetTop;
    d.origLSIndex   = lv.sIndex
    d.origLTDayCnt  = lv.tDayCnt;
    d.origLDayCnt   = lv.dayCnt;
  }
  else
  {
    d.origHasLink = false;
  }
}

function bl_apt_dragDayPosDone(item, x, y, eventDriven)
{
  var d    = item.cbData;
  var ap   = d.controlEl.firstChild;
  var dObj = ap.cbApt;
  var date = new Date();
  
  if (eventDriven)
  {
    bl_apt_move(item, x, y, true);
  }
  else
  {
    bl_apt_dragDayPos(item, d, ap, d.origDind, d.origCnt, true);
  }
  
  var day = dObj.getDay(d.dIndex);
  
  bl_apt_setHeadH(ap, bl_apt_recomputeAllDays(ap), true);
  
  if (d.isAllDay)
  {
    bl_apt_allDayCnt(date, d, day);
  }
  
  if (eventDriven)
  {
    item.style.cursor = "wait";
    bl_apt_sendUpdate(d, false);
  }
}


function _bl_apt_up(event, item)
{
  var target = bl_port_getEventTarget(event);
  
  if (target.getAttribute("bl_ignore_me") != null)
  {
    return;
  }
  
  bl_apt_turnOffAutoScroll();
  item.mouseDown = false;
  if (item.isDraging)
  {
    bl_port_releaseCapture(item);
    item.mouseIn = false;
    
    var v = bl_port_getEventTarget(event);
    
    while (v != null)
    {
      if (v == item)
      {
        with (bl_port_offsetToItem(event, item))
        {
          item.mouseIn = (x >= 0 && y >= 0 && x <= item.offsetWidth && y <= item.offsetHeight);
        }
        break;
      }
      v = v.parentNode;
    }
    
    var x = event.screenX;
    var y = event.screenY;
    
    if (item.moved)
    {
      if (item.moveType == 0)
      {
        var list = item.sbList;
        var len  = list.length;
        
        for (var i = 0; i < len; i++)
        {
          list[i].style.visibility = "hidden";
        }
        
        bl_apt_moveDone(item, x, y);
        bl_apt_startFilter(item.cbData, true);
      }
      else
      {
        bl_apt_dragDayPosDone(item, x, y, true);
      }
    }
    else
    {
      if (item.moveType == 0)
      {
        bl_apt_filterDone(item);
        cb_sys_setOpFilter(item, "", true);
      }
    }
  }
  item.style.cursor = "default";
  item.moveType     = -1;
  item.isDraging    = false;
  
  var ap = item.cbData.controlEl.firstChild;
  ap.dragItem = null;
  
  if (target.name != "bl_apt_img")
  {
    bl_apt_setContentStr(item.cbData, false, false);
  }
  
  if (item.mouseIn)
  {
    bl_apt_activateItem(item);
  }
  else
  {
    bl_apt_deactivateItem(item);
  }
  
  if (!item.cbData.readonly)
  {
    if (bl_port_isLeftDown(event) && 
        !item.moved && 
        bl_port_offsetToItem(event, target).x > 6)
    {
      var date                  = new Date();
      bl_apt_content.cbData     = item.cbData;
      bl_apt_content.editCancel = false;
      if (date.getTime() - item.lastTime > 500)
      {
        _bl_apt_edit_content();
      }
      else
      {
        window.setTimeout('_bl_apt_edit_content()', 500);
      }
    }
  }
  bl_port_killEvent(event);
  item.moved = false;
}

function bl_apt_computeTimeStr(h, m, isMilt)
{
  var str = '';
  var md  = "";
  if (isMilt)
  {
    if (h < 10)
    {
      str += "0";
    }
  }
  else
  {
    md = "am";
    
    if (h >= 24)
    {
      h = 12;
    }
    else if (h >= 12)
    {
      md = "pm";
      h  = h - 12
    }
    if (!h)
    {
      h = 12;
    }
  }
  str += h;
  str += ":";
  if (m < 10)
  {
    str += "0";
  }
  str += m;
  str += md;
  return str;
}

function bl_apt_setContentStr(d, onlyThis, force)
{
  var version    = bl_version;
  var contentStr = d.contentDisplay;
  
  var str  = "";
  var usel = "<IMG name='bl_apt_img' unselectable='on' style='vertical-align:middle;' ";
  
  var meetingImg = d.meetingImage;
  if (d.remind)
  {
    str +=  usel + "src='/" + version + "/res/img/apt_remind.gif'/>";
  }
  if (meetingImg && meetingImg.length > 0)
  {
    str +=  usel + "src='/" + version + meetingImg + "'>";
  }
  else if (d.isMeeting)
  {
    str +=  usel + "src='/" + version + "/res/img/apt_meeting.gif'/>";
  }
  if (d.recurType != "n")
  {
    str += (d.recurType == "r") ?  (usel + "src='/" + version + "/res/img/apt_recur.gif'/>") : 
                                   (usel + "src='/" + version + "/res/img/apt_occur.gif'/>");
  }
  
  if (d.sOffset ||  d.eOffset || force)
  {
    var isMilt = (d.controlEl.getAttribute("bl_timeType") == "military");
    str +=bl_apt_computeTimeStr(d.sHour, d.sMinute, isMilt);
    str += "-";
    str +=bl_apt_computeTimeStr(d.eHour, d.eMinute, isMilt);
    str += " ";
  }
  
  str += contentStr;
  
  if (d.qual != "")
  {
    str += " (" + d.qualDisplay + ")";
  }
  
  var celement = bl_apt_contentPanel(d.view);
  
  celement.innerHTML   = str;
  d.cb_compute_tooltip = true;
  
  if (!onlyThis && d.linkData != null)
  {
    bl_apt_contentPanel(d.linkData.view).innerHTML = str;
    d.linkData.cb_compute_tooltip = true;
  }
  bl_apt_positionImage(d);
}

function bl_apt_setItemContent(d, content)
{
  var display = bl_apt_sanitizeText(content);
  d.content = content;
  d.contentDisplay = display;
  
  if (d.linkData != null)
  {
    d.linkData.content = content;
    d.linkData.contentDisplay = display;
  }
  bl_apt_setContentStr(d, false, false);
}

function bl_apt_setItemLocation(d, loc)
{
  var display = bl_apt_sanitizeText(loc);
  d.qual = loc;
  d.qualDisplay = display;
  
  if (d.linkData != null)
  {
    d.linkData.qual = loc;
    d.linkData.qualDisplay = display;
  }
  bl_apt_setContentStr(d, false, false);
}

function bl_apt_editContentDone(send, checkForce, reclaimFocus)
{
  if (bl_apt_content.isEditing)
  {
    var d         = bl_apt_content.currentData;
    var isNewItem = (d.id) ? false : true;
    var value     = bl_apt_content.value;
    
    bl_apt_content.onblur      = null;
    bl_apt_content.onkeypress  = null;
    bl_apt_content.isEditing   = false;
    
    with (bl_apt_content.style)
    {
      display = "none";
      left = "-100px";
      top  = "-100px";
      width = 0;
      height = 0;
    }
    
    if ((checkForce && isNewItem) || (value != d.content && send))
    {
      bl_apt_setItemContent(d, (isNewItem && !send) ? "" : value);
      bl_apt_sendUpdate(d, true);
    }
    else if (isNewItem)
    {
      bl_apt_setItemContent(d, value);
    }
    if (reclaimFocus)
    {
      bl_apt_setKeyInput(d.controlEl.firstChild);
    }
  }
}

function _bl_apt_edit_content()
{
  if (bl_apt_content.editCancel == false && bl_apt_content.cbData)
  {
    var d    = bl_apt_content.cbData;
    var item = d.view;
    
    if (item.parentNode)
    {
      var cp = bl_apt_contentPanel(item);
      
      item.appendChild(bl_apt_content);
      
      var coords = bl_sys_find_xy(cp,item,false);
      var tArea = bl_apt_content;
      
      with (bl_apt_content.style)
      {
        left         = coords.x+1+"px";
        top          = coords.y+1+"px";
        height       = (cp.offsetHeight-3)+"px";
        width        = (cp.offsetWidth-2)+"px";
        display = "block";
      }
      
      bl_apt_content.isEditing   = true
      bl_apt_content.currentData = d;
      tArea.value                = d.content;
      
      bl_port_focus(tArea);
      
      bl_apt_content.onblur      = bl_apt_editBlur;
      bl_apt_content.onkeypress  = bl_apt_editPress;
      
      // Mozilla and safari: explicitly insert the first character into the textarea
      if (!bl_browserInfo.ie && !tArea.value)
      {
        tArea.value            = bl_apt_content.newChar;
        tArea.selectionStart   = tArea.length;
        bl_apt_content.newChar = null;
      }
    }
  }
}

function _bl_apt_dblclk(event, item)
{
  if (bl_port_getEventTarget(event).getAttribute("bl_ignore_me") != null)
  {
    return;
  }

  if (item.isDraging)
  {
    item.isDraging = false;
    bl_port_releaseCapture(item);
  }

  bl_apt_content.editCancel = true;
  bl_apt_editContentDone(true, true, false);
  
  var d  = item.cbData;
  var el = d.controlEl;
  
  bl_apt_hide_tt(el, d);
  bl_mpr_send("<edit><id>" + d.id + "</id></edit>", el.id);
  bl_port_killEvent(event);
}

function _bl_apt_pdblclk(event, ap)
{
  if (bl_port_getEventTarget(event).getAttribute("bl_ignore_me") != null)
  {
    return;
  }

  var el = ap.parentNode;
  
  if (el.getAttribute("bl_readOnly") == null)
  {
    bl_apt_computeEditTimes(el, 1);
  }
}


function _bl_apt_autoScroll()
{
  if (bl_apt_auotScroll)
  {
    var stop = bl_apt_auotScroll.scrollTop;
    if (bl_apt_auotScroll.autoScrollUp)
    {
      stop -= bl_apt_itemHeight;
      if (stop < 0)
      {
        stop = 0;
      }
    }
    else
    {
      var ch = bl_apt_auotScroll.clientHeight;
      var sh = bl_apt_auotScroll.scrollHeight;
      stop  += bl_apt_itemHeight;
      if (stop + ch > sh)
      {
        stop = sh - ch;
      }
    }
    if (stop != bl_apt_auotScroll.scrollTop)
    {
      bl_apt_auotScroll.scrollTop = stop;
      
      if (bl_apt_autoScrollFunc)
      {
        bl_apt_autoScrollFunc(bl_apt_autoScrollArg, bl_apt_auotScroll.cb_x, bl_apt_auotScroll.cb_y);
      }
      window.setTimeout('_bl_apt_autoScroll()', 100);
    }
    else
    {
      bl_apt_turnOffAutoScroll();
    }
  }
}

function bl_apt_computePos(ap, yoffset, x, y, origIndex, moveType, oDind, oCnt)
{
  var screenTop  = cb_sys_getScreenTop();
  var screenLeft = cb_sys_getScreenLeft();
  var dObj       = ap.cbApt;
  var div        = dObj.divEl;
  var divy       = bl_sys_find_y(div, null, false) + screenTop;
  var inDiv      = (y >= divy && y <= divy + div.offsetHeight);
  var diff       = x - (bl_sys_find_x(ap, null, false) + screenLeft);
  var el         = ap.parentNode;
  var itvTlt     = el.bl_interval_tlt;
  
  ap.cb_dind = dObj.findIndex(diff);
  
  if (origIndex != undefined && origIndex >= 0 && inDiv && ap.cb_dind < 0 && diff <= 50 && diff >= 0)
  {
    ap.cb_dind = origIndex;
  }
  
  if (ap.cb_dind >= 0)
  {
    if (inDiv)
    {
      var ypos = y - divy;
      var diff = div.offsetHeight - ypos;
      
      if ((ypos > 0 && ypos < bl_apt_itemHeight) || (diff < bl_apt_itemHeight && diff > 0))
      {
        if (!div.autoScrollOn)
        {
          div.cb_x          = x;
          div.cb_y          = y;
          div.autoScrollOn  = true;
          div.autoScrollUp  = (ypos < bl_apt_itemHeight);
          bl_apt_auotScroll = div;
          _bl_apt_autoScroll();
        }
      }
      else
      {
        bl_apt_turnOffAutoScroll();
      }
      
      var pos = (ypos + div.scrollTop - yoffset)/bl_apt_itemHeight;
      
      if (moveType < 0)
      {
        moveType = (pos > oCnt && ap.cb_dind >= oDind) ? 2 : 0;
      }
      
      ap.cb_cnt = (moveType > 1) ? Math.ceil(pos) : Math.floor(pos);
      
      if (ap.cb_cnt > itvTlt)
      {
        ap.cb_cnt = itvTlt;
      }
      
      ap.cb_inAllDay = false;
      
      return true;
    }
    else
    {
      var hel = dObj.getDay(0).allDayEl;
      var hy  = bl_sys_find_y(hel, null, false) + screenTop;
      
      if (y >= hy                    &&
          y <= hy + hel.offsetHeight &&
          ap.cb_dind >= 0            &&
          el.getAttribute("bl_noAllday") == null)
      {
        ap.cb_inAllDay = true;
        ap.cb_cnt = 0;
        bl_apt_turnOffAutoScroll();
        return true;
      }
    }
  }
  bl_apt_turnOffAutoScroll();
  return false;
}

function bl_apt_findKeyInputElement(ap)
{
  if (bl_browserInfo.ie)
  {
    return ap.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.lastChild.lastChild;
  }
  else
  {
    return ap.firstChild.firstChild.firstChild.firstChild.firstChild.childNodes[1].lastChild.lastChild;
  }
}

function bl_apt_findTitleParentRow(ap)
{
  if (bl_browserInfo.ie)
  {
    return ap.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild;
  }
  else
  {
    return ap.firstChild.firstChild.firstChild.firstChild.firstChild.childNodes[1];
  }
}

function bl_apt_findBodyDiv(ap)
{
  return ap.firstChild.childNodes[1].firstChild.firstChild;
}

function bl_apt_findHeadDiv(ap)
{
  return ap.firstChild.firstChild.firstChild.firstChild;
}

function bl_apt_setKeyInput(ap)
{
  var handlerEl = bl_apt_findKeyInputElement(ap);
  handlerEl.style.display="block";
  bl_port_focus(handlerEl);
}

function _bl_apt_hideKeyInput(keyHandlerEl)
{
  keyHandlerEl.style.display="none";
  keyHandlerEl.value="";
}

function bl_apt_delayedKeyFocus()
{
  var ap = bl_apt_delayedKeyFocus.ap;
  
  if (ap)
  {
    bl_apt_delayedKeyFocus.ap = null;
    bl_apt_setKeyInput(ap);
  }
}

function _bl_apt_pdown(event, ap)
{
  if (bl_port_getEventTarget(event).getAttribute("bl_ignore_me") != null)
  {
    return;
  }
  
  bl_kb_focusOnElement(ap);
  bl_port_killEvent(event);
  bl_apt_delayedKeyFocus.ap = ap;
  bl_apt_delayedKeyFocus.timer = setTimeout(bl_apt_delayedKeyFocus,0);
  bl_apt_editContentDone(true, true, false);
  var el = ap.parentNode;
  
  if (bl_port_isLeftDown(event) && bl_apt_computePos(ap, 0, event.screenX, event.screenY, el.sDind, 0, 0, 0))
  {
    var cnt  = ap.cb_cnt;
    var dind = ap.cb_dind;
    
    el.aCnt  = cnt;
    el.sCnt  = cnt;
    el.aDind = dind;
    el.sDind = dind;
    if (ap.cb_inAllDay)
    {
      el.eCnt  = 0;
      el.eDind = dind + 1;
    }
    else
    {
      el.eCnt  = cnt + 1;
      el.eDind = dind;
    }
    bl_apt_clearSelect(el, false);
    bl_apt_setEditSelect(el);
    ap.cb_mouseDown       = true;
    bl_port_setCapture(ap);
    bl_apt_autoScrollFunc = bl_apt_pAutoMove;
    bl_apt_autoScrollArg  = ap;
  }
  bl_port_stop_event(event);
}

function bl_apt_pAutoMove(ap, x, y)
{
  var el = ap.parentNode;
  
  if (bl_apt_computePos(ap, 0, x, y, el.sDind, -1, el.aDind, el.aCnt))
  {
    var cnt  = ap.cb_cnt;
    var dind = ap.cb_dind;
    
    if (ap.cb_inAllDay)
    {
      if (dind <= el.aDind)
      {
        el.sDind = dind;
        el.sCnt  = 0;
        el.eDind = el.aDind + 1;
        el.eCnt  = 0;
      }
      else
      {
        el.sDind = el.aDind;
        el.sCnt  = 0;
        el.eDind = dind + 1;
        el.eCnt  = 0;
      }
    }
    else
    {
      if (dind < el.aDind || (dind == el.aDind && cnt < el.aCnt))
      {
        el.sDind = dind;
        el.sCnt  = cnt;
        el.eDind = el.aDind;
        el.eCnt  = (el.aCnt) ? el.aCnt : 1;
      }
      else
      {
        el.sDind = el.aDind;
        el.sCnt  = el.aCnt;
        el.eDind = dind;
        el.eCnt  = cnt;
      }
    }
    bl_apt_setEditSelect(el);
  }
}

function bl_apt_turnOffAutoScroll()
{
  if (bl_apt_auotScroll)
  {
    bl_apt_auotScroll.autoScrollOn = false;
    bl_apt_auotScroll = null;
  }
  bl_apt_autoScrollFunc = null;
  bl_apt_autoScrollArg  = null;
}

function _bl_apt_pmove(event, ap)
{
  if (bl_port_getEventTarget(event).getAttribute("bl_ignore_me") != null)
  {
    return;
  }
  
  if (ap.cb_mouseDown)
  {
    if (event.type == "mouseup")
    {
      bl_apt_turnOffAutoScroll();
      bl_port_releaseCapture(ap);
      ap.cb_mouseDown = false;
      bl_apt_computeEditTimes(ap.parentNode, 2);
    }
    else
    {
      bl_apt_pAutoMove(ap, event.screenX, event.screenY);
    }
  }
}

function bl_apt_computeEditTimes(el, type)
{
  var itvCnt = el.bl_interval_cnt;
  var itv    = el.bl_interval_val;
  var ap     = el.firstChild;
  var dObj   = ap.cbApt;
  var sind   = el.sDind;
  var eind   = el.eDind;
  var len    = dObj.length();
  var isoff  = false;
  
  if (eind > len - 1)
  {
    eind  = len - 1;
    isoff = true;
  }
  if (sind < 0)
  {
    sind = 0;
  }
  
  var sday = dObj.getDay(sind);
  var eday = dObj.getDay(eind);
  var sy   = sday.year;
  var sm   = sday.month;
  var sd   = sday.day;
  var sh   = Math.floor(el.sCnt/itvCnt);
  var smin = (el.sCnt%itvCnt) * itv;
  
  var ed   = new Date(eday.year, eday.month, eday.day + (isoff ? 1 : 0));
  var ey   = ed.getFullYear();
  var em   = ed.getMonth();
  var ed   = ed.getDate();
  var eh   = Math.floor(el.eCnt/itvCnt);
  var emin = (el.eCnt%itvCnt) * itv;
  
  if (type)
  {
    var isAllDay = ((sy != ey || sm != em || sd != ed) && sh == 0 && smin == 0 && emin == 0 && eh == 0);
    var xmlStr = null;
    var sendAsync = false;
    if (type == 1)
    {
      xmlStr = '<new><allDay>' + ((isAllDay) ? 'true' : 'false') + '</allDay><content></content><start>'
             + sy + ' ' + sm + ' ' + sd + ' ' + sh + ' ' + smin + '</start><end>'
             + ey + ' ' + em + ' ' + ed + ' ' + eh + ' ' + emin + '</end></new>';
    }
    else
    {
      el.cbDate.setFullYear(sy, sm, sd);
      xmlStr = '<editSelect><allDay>' + ((isAllDay) ? 'true' : 'false') + '</allDay><start>'
             + sy + ' ' + sm + ' ' + sd + ' ' + sh + ' ' + smin + '</start><end>'
             + ey + ' ' + em + ' ' + ed + ' ' + eh + ' ' + emin + '</end></editSelect>';
      sendAsync = true;
    }
    
    bl_mpr_send(xmlStr, el.id);
  }
  else
  {
    if (el.getAttribute("bl_readOnly") == null)
    {
      var sDate    = new Date(sy, sm, sd, sh, smin);
      var eDate    = new Date(ey, em, ed, eh, emin);
      var isAllDay = (sind != eind && el.eCnt >= el.sCnt);
      var d        = bl_apt_createTempData(sDate, eDate, isAllDay, el);
      window.bl_last_apt = d;

      bl_apt_content.cbData = d;
      bl_apt_placeData(dObj, d, new Date(), el.bl_interval_tlt);
      bl_apt_updateData(ap, d);
      bl_apt_clearSelect(el, false);
      bl_apt_selectItem(d.view, true);
      bl_apt_content.editCancel = false;
      _bl_apt_edit_content();
      bl_apt_setSelectRange(el, d, d.linkData);
    }
  }
}

function bl_apt_setEditSelect(el)
{
  var hide = (el.selectedEl != null || el.getAttribute("bl_readOnly") != null);
  var dObj = el.firstChild.cbApt;
  var len  = dObj.length();
  var justAllDay = (el.sDind != el.eDind && !el.sCnt && !el.eCnt && !hide);

  for (var i = 0; i < len; i++)
  {
    var day         = dObj.getDay(i);
    var adEl        = day.allDayEl;
    var origadColor = adEl.bl_OrigSelectBG;
    
    if (origadColor == undefined)
    {
      origadColor = adEl.bl_OrigSelectBG = adEl.style.backgroundColor;
    } 
    
    if (justAllDay && i >= el.sDind && i < el.eDind)
    {
      day.selEl.style.visibility = "hidden";
      adEl.style.backgroundColor = "#D7D7D7";
    }
    else if (i >= el.sDind && i <= el.eDind && !hide)
    {
      var selSt = day.selEl.style;
      var top   = (i == el.sDind) ? el.sCnt : 0;
      var hcnt  = (i == el.eDind) ? el.eCnt - top : el.bl_interval_tlt - top;
      
      if (hcnt > 0)
      {
        selSt.visibility = "visible";
        selSt.top        = (top * bl_apt_itemHeight + 1)+"px";
        selSt.height     = (hcnt * bl_apt_itemHeight)+"px";
        selSt.width      = (day.topEl.offsetWidth - 1)+"px";
        selSt.left       = (day.topEl.offsetLeft + 1)+"px";
      }
      else
      {
        day.selEl.style.visibility = "hidden";
        adEl.style.backgroundColor = ((i == el.eDind) || (i == el.sDind && el.sCnt)) ? origadColor : "#D7D7D7";
      }
    }
    else
    {
      day.selEl.style.visibility = "hidden";
      adEl.style.backgroundColor = origadColor;
    }
  }
}

function _bl_apt_pkeydown(event, el)
{
  var ap     = el.firstChild;
  var target = bl_port_getEventTarget(event);
  
  bl_apt_hide_tt(el, null);
  if (target != bl_apt_content)
  {
    if (ap.dragItem == null)
    {
      if (event.type == "keydown" || event.type == "vkd")
      {
        var kcode = bl_port_keyCode(event);
        
        if ((kcode == 46 || kcode == 8) && target != bl_apt_content)
        {
          if (el.selectedEl)
          {
            var d = el.selectedEl.cbData

            if (!d.readonly)
            {
              var msg = '<removeSelected ' 
                       + ((event.shiftKey) ? 'shiftDown="true"' : 'shiftDown="false"') 
                       + '></removeSelected>';
                       
              bl_apt_content.editCancel = true;
              bl_mpr_send(msg, el.id);
            }
          }
        }
      }
      else
      {
        if (el.selectedEl == null && bl_port_keyCode(event) != 27)
        {
          // Firefox and safari: save the character so we can explicitly add it to the textarea later.
          if (bl_port_isCharEvent(event))
          {
            bl_apt_content.newChar = String.fromCharCode(event.charCode);
            bl_apt_computeEditTimes(ap.parentNode, 0);
          }
        }
      }
    }
    else
    {
      var item = ap.dragItem;
      bl_apt_restoreItem(ap, item, true);
      bl_apt_setContentStr(item.cbData, false, false);
      bl_port_releaseCapture(item);
      item.mouseIn       = false;
      item.mouseDown     = false;
      item.style.cursor  = "default";
      item.moveType      = -1;
      item.isDraging     = false;
      item.moved         = false;
      ap.dragItem        = null;
      ap.dragData        = null;
      bl_port_killEvent(event);
    }
  }
}

function bl_apt_editPress(event)
{
  if (!event)
  {
    event = window.event;
  }

  var kcode = bl_port_keyCode(event);
  
  if (kcode == 27 && !bl_apt_content.currentData.id)
  {
    var d    = bl_apt_content.currentData;
    var el   = d.controlEl;
    var ap   = el.firstChild;
    var ld   = d.linkData;
    
    bl_apt_clearSelect(el, true);
    bl_apt_extractApt(d, true, el.cbAptList);
    bl_apt_setKeyInput(ap);
  }
  else if (kcode == 13 || kcode == 27)
  {
    bl_apt_editContentDone(true, true, true);
  }
}

function bl_apt_editBlur(event)
{
  if (!event)
  {
    event = window.event;
  }

  bl_apt_editContentDone(true, true, false);
}

function bl_apt_createSideBar()
{
  var ret = null;
  
  if (bl_apt_unusedSideBars.length > 0)
  {
    ret = bl_apt_unusedSideBars.pop();
  }
  else
  {
    ret = bl_apt_factory.create("<span bl_class='bl_apt_sideBar '></span>");
  }
  ret.nextSB = null;
  return ret;
}

function bl_apt_gleanSideBars(sb)
{
  if (sb)
  {
    var nsb   = sb.nextSB;
    sb.nextSB = null;
    while (nsb)
    {
      var temp = nsb;
      temp.style.visibility = "hidden";
      
      if (temp.parentNode != null)
      {
        temp.parentNode.removeChild(nsb);
      }
      bl_apt_unusedSideBars.push(temp);
      nsb = nsb.nextSB;
      temp.nextSB = null;
      
    }
  }
}

function bl_apt_attachControl(ap, type)
{
  if (type == "workweek")
  {
    return bl_apt_attachAP(ap, 5);
  }
  else if (type == "fullweek")
  {
    return bl_apt_attachAP(ap, 7);
  }
  else
  {
    // assume day
    return bl_apt_attachAP(ap, 1);
  }

  return null;
}

function _bl_apt_imageAction(image)
{
  var d   = image.parentNode.cbData;
  var ld  = d.linkData;
  var el  = d.controlEl;
  var sel = el.selectedEl;
  
  if (sel != d.view && sel != null)
  {
    bl_apt_deselectItem(sel, true);
  }
  
  bl_apt_selectItem(d.view, false);
  
  if (d.imagePopup)
  {
    var context = new cb_sys_popup_context(image, null, "popup-editor", true);
    var msg     = '<popup><id>' 
                + d.id 
                + '</id><popup_id>' 
                + context.id 
                + '</popup_id></popup>';
                
    bl_mpr_send(msg, el.id, 0);
    mpr.setPopupContext(context, true);
  }
  else
  {
    var msg = '<execute><id>' 
            + d.id 
            + '</id></execute>';
    bl_mpr_send(msg, el.id, 0);
  }
}

function bl_apt_createApt()
{
  if (bl_apt_aptText == null)
  {
/* DOM structure
<DIV>                           0         class bl_apt_initAptView
  <DIV top>                     0.0
  </DIV>
  <DIV>                         0.1
    <DIV side>                  0.1.0
      <DIV side>                0.1.0.0
        <IMG apt_zero.gif>      0.1.0.0.0
      </DIV>
    </DIV> 
    <SPAN content>              0.1.1
    </SPAN>
  </DIV>
  <IMG nourl>                   0.2
  <DIV bottom>                  0.3
  </DIV>
</DIV>
    
*/
    
    bl_apt_aptText = '<div id="appointment" class="bl_apt_initaptview" ';
    
    if (bl_browserInfo.ie)
    {
      bl_apt_aptText += ' onmouseenter="_bl_apt_enter(event,this)" onmouseleave="_bl_apt_leave(event, this)"';
    }
    else
    {
      bl_apt_aptText += ' onmouseover="_bl_apt_enter(event,this)" onmouseout="_bl_apt_leave(event, this)"';
    }
    
    bl_apt_aptText += ' onmouseup="_bl_apt_up(event,this)" onmousedown="_bl_apt_down(event,this)" onmousemove="_bl_apt_mouse_move(event, this)" ondblclick="_bl_apt_dblclk(event, this)"><div id="top"></div><div><div id="side"><div id="side"><img src="/' 
                    + bl_version
                    + '/res/img/apt_zero.gif" width="6px" height="6px" style="display:none"/></div></div><span id="content"></span></div><img class="bl_apt_image" bl_absorb_events ondblclick="bl_port_stop_event(event);" onmouseout="_bl_sys_img_leave(event, this);" onmouseover="_bl_sys_img_enter(event, this);" onmousedown="_bl_sys_img_down(event, this);" onmouseup="_bl_sys_img_up(event, this);" style="visibility:hidden;"/><div id="bottom" style="height:6px"></div></div>';
  }
  return this.create(bl_apt_aptText);
}

function bl_apt_createElement(html)
{
  var sp = this.span;
  sp.innerHTML = html;
  return sp.removeChild(sp.firstChild);
}

function bl_apt_factoryCreate()
{
  this.span          = document.createElement("SPAN");
  this.create        = bl_apt_createElement;
  this.createApt     = bl_apt_createApt;
  this.attachControl = bl_apt_attachControl;
  this.day           = null;
  this.workweek      = null;
  this.fullweek      = null;
  
  bl_port_insertAdjacentHTML(document.body, "beforeend", "<textarea bl_ignore_me style='font-family:tahoma,verdana,arial;font-size:11px;border:none;padding:0px 0px 0px 3px;display:none;position:absolute;background-color:#ffffff;z-index:2001;'></textarea>");
  bl_apt_content                      = document.body.lastChild;
  bl_apt_content.isEditing            = false;
  
  bl_apt_srtTester                  = document.createElement("SPAN");
  bl_apt_srtTester.style.visibility = "hidden";
  
  bl_apt_srtTester.style.fontSize   = "8pt";
  bl_apt_srtTester.style.fontFamily = "Tahoma";
  bl_apt_srtTester.style.position   = "absolute";
  bl_port_insertAdjacentElement(document.body, "afterBegin", bl_apt_srtTester);
  
  bl_apt_fadedFilt = bl_port_compute_opacity_style(65, false);
  
  bl_apt_bgMap          = new Array("bl_apt_Non", "bl_apt_Imp", "bl_apt_Bus", "bl_apt_Per", "bl_apt_Vac", "bl_apt_Att", "bl_apt_Trv", "bl_apt_Prp", "bl_apt_Bir", "bl_apt_Ann", "bl_apt_Phn");
  bl_apt_olMap          = new Array("bl_apt_Fre", "bl_apt_Ten", "bl_apt_Bsy", "bl_apt_Oof", "bl_apt_none", "bl_apt_group");
  bl_apt_unusedSideBars = new Array();
  bl_apt_crossList      = new Array();
}

function bl_apt_cleanup(el)
{
  bl_apt_removeAll(el, false);
  
  var list = el.cbAptList;
  var len  = el.length;
  for (var i = 0; i < len; i++)
  {
    list[i].cleanup();
  }
  list.splice(0, len);
  
  var list = el.pendingAptList;
  var len  = el.length;
  for (var i = 0; i < len; i++)
  {
    list[i].cleanup();
  }
  list.splice(0, len);
  
  var ap = el.firstChild;
  if (ap)
  {
    ap.cbApt.clear(true);
    ap.cbApt    = null;
    ap.dragItem = null;
    el.removeChild(ap);
  }
  
  var ttDiv = el.cb_ttDiv;
  
  if (ttDiv)
  {
    ttDiv.parentNode.removeChild(ttDiv);
    el.cb_ttDiv = null;
  }
}

function bl_apt_controlInit(el)
{
  if (!el.bl_contol_inited)
  {
    bl_sys_addCleanUpCall(el, bl_apt_cleanup);
    var dt = new Date().getTime();
    
    if (bl_apt_factory == null)
    {
      bl_apt_factory = new bl_apt_factoryCreate();
    }

    bl_apt_factory.attachControl(el.firstChild, el.getAttribute("bl_selectby"));
    
    bl_apt_setInterval(el, el.getAttribute("bl_interval"));
    el.sDind = 0;
    el.sCnt  = (8 * el.bl_interval_cnt);
    el.eDind = 0;
    el.eCnt  = el.sCnt + 1;

    el.cbDate           = new Date();
    el.cbAptList        = new Array();
    el.pendingAptList   = new Array();
    el.pendIdGen        = 0;
    el.selectedEl       = null;
    el.bl_contol_inited = true;
  }
}

function _bl_apt_init(id, date, apts)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    bl_apt_controlInit(el);
    
    if (date == null)
    {
      date = "0 0 0";
    }
    
    el.oldWidth  = el.offsetWidth;
    el.oldHeight = el.offsetHeight;
    bl_apt_clearSelect(el, false);
    bl_apt_procValue(el, date, apts);

    _bl_apt_resize(el, null);
    bl_apt_adjustPosition(el);
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_apt_last()
{
  var x = 0;
}


var bl_cal_popupButton   =  null;
var bl_cal_width         =  136;
var bl_cal_height        =  134;
var bl_cal_calTxtList    =  null;
var bl_cal_tester        =  null;
var bl_cal_t_todayIn     =  0;
var bl_cal_t_todayLess   =  1;
var bl_cal_t_todayMore   =  2;
var bl_cal_t_monthIn     =  3;
var bl_cal_t_monthLess   =  4;
var bl_cal_t_monthMore   =  5;
var bl_cal_t_blank       =  6;
var bl_cal_t_head        =  7;
var bl_cal_t_text_both   =  8;
var bl_cal_t_text_today  =  9;
var bl_cal_t_text_none   =  10;
var bl_cal_t_duration    = -2;
var bl_cal_t_time        = -1;
var bl_cal_t_multiple    =  0;
var bl_cal_t_pop_today   =  1;
var bl_cal_t_pop_none    =  2;
var bl_cal_t_in_today    =  3;
var bl_cal_t_in_none     =  4;
var bl_cal_t_pop_both    =  5;
var bl_cal_t_in_both     =  6;

function bl_cal_setDate(val, type)
{
  var dt = null;
  
  if (val)
  {
    if (type == bl_cal_t_time)
    {
      dt = bl_cal_parseTime(val);
    }
    else
    {
      var valList = val.split(" ");
      
      if (valList.length >= 3 && (valList[0] != '0' || valList[1] != '0' || valList[2] != '0'))
      {
        dt = new Date();
        bl_cal_setFullYear(dt, parseInt(valList[0]), parseInt(valList[1]), parseInt(valList[2]));
      }
    }
  }
  return dt;
}

function bl_cal_selectDate(el, text, formattedDate)
{
  bl_cal_clearSelection(el);

  var computeDays  = true;
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  var date         = bl_cal_set_date(el, bl_cal_setDate(text, calendarType));
  var tempDate = Date.parse(formattedDate);
  // check if the javascript is able to parse the formatted string as a date.
  if (isNaN(tempDate))
  {
    formattedDate = "";
  }
  if (calendarType == bl_cal_t_time)
  {
    computeDays = false;
    bl_cal_setPopupText(bl_cal_getText(el), date, calendarType, formattedDate);
  }
  else if (calendarType == bl_cal_t_pop_today ||
           calendarType == bl_cal_t_pop_none  ||
           calendarType == bl_cal_t_pop_both)
  {
    if (date != null)
    {
      var currentDate = bl_cal_currentDate(el);
      currentDate.setFullYear(date.getFullYear(), date.getMonth());
    }
    computeDays = false;
    bl_cal_setPopupText(bl_cal_getText(el), date, calendarType, formattedDate);
  }
  
  if (computeDays)
  {
    if (date)
    {
      bl_cal_locateToDate(el);
      bl_cal_computeSelection(el);
    }
  }
}

function _bl_cal_handler(item, el)
{
  var value = item.firstChild;
  var name  = value.nodeName;

  bl_cal_initElement(el);
    
  if (name == "dateEx")
  { //<dateEx><bl_date></bl_date><val></val></dateEx>
    var date = bl_port_get_text(value.firstChild);
    var formattedDate =  bl_port_get_text(value.childNodes[1]);
    bl_cal_selectDate(el, date, formattedDate);
  }
  else if (name == "date")
  { //<date></date>
    bl_cal_selectDate(el, bl_port_get_text(value));
  }
  else if (name == "hds")
  {
    bl_cal_loadXML(el, value, bl_cal_hiliteData(el));
    bl_cal_rebuildCalendar(el);
  }
  else if (name == "modify")
  {
    bl_cal_modify(el, value);
  }
  else if (name == "removeall")
  {
    bl_cal_hiliteData(el).clear();
    bl_cal_rebuildCalendar(el);
  }
  else if (name == "selectBy")
  {
    bl_cal_clearSelection(el);
    el.setAttribute("bl_selectby", bl_port_get_text(value));
    bl_cal_computeSelection(el);
  }
  else if (name == "startTime")
  {
    el.setAttribute("bl_cal_start_time", bl_port_get_text(value));

    el.bl_cal_timeList = null;    
    if (value.nextSibling.nodeName == "startDate")
    {
      var nChild = value.nextSibling;
      el.setAttribute("bl_cal_start_date", bl_port_get_text(nChild));
      nChild = nChild.nextSibling;
      el.setAttribute("bl_cal_end_date", bl_port_get_text(nChild));
    }
    
    bl_cal_setTime(el, bl_port_get_text(item.lastChild));
  }
  else if (name == "newTime")
  {
    bl_cal_setTime(el, bl_port_get_text(value));
  }
  else if (name == "showAlert")
  {
    window.alert(bl_port_get_text(value));
  }
  else if (name == "duration")
  {
    var valstr = cmd.attributes.getNamedItem("val");
    
    el.setAttribute("bl_cal_duration_val", (valstr)  ? parseInt(valstr.nodeValue) : 0);
    el.setAttribute("bl_cal_durationText", bl_port_get_text(value));
    bl_cal_setPopupText(bl_cal_getText(el), null, parseInt(el.getAttribute("bl_cal_type")));
  }
}

function bl_cal_setTime(el, valText)
{
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  
  var date   = bl_cal_set_date(el, bl_cal_setDate(valText, calendarType));
  el.oldHour = date.getHours();
  el.oldMin  = date.getMinutes();
  bl_cal_setPopupText(bl_cal_getText(el), date, calendarType);
  el.bl_cal_timeList = bl_cal_computeTimeList(el);
}

function bl_cal_removeHilight(el, text)
{
  var valList = text.split(" ");
  var dayEl   = bl_cal_findDayEl(el, parseInt(valList[0]), parseInt(valList[1]), parseInt(valList[2]));
  
  bl_cal_hiliteData(el).removeDate(text);
  if (dayEl != null)
  {
    dayEl.removeAttribute("bl_isHilited");
    dayEl.setAttribute("bl_fontWeight", "font-weight:normal;");
    dayEl.style.fontWeight = "normal";
  }
}

function bl_cal_addHilight(el, text)
{
  var valList = text.split(" ");
  var dayEl   = bl_cal_findDayEl(el, parseInt(valList[0]), parseInt(valList[1]), parseInt(valList[2]));
  
  bl_cal_hiliteData(el).addDate(text);
  if (dayEl != null)
  {
    dayEl.setAttribute("bl_isHilited", true);
    dayEl.setAttribute("bl_fontWeight", "font-weight:bold;");
    dayEl.style.fontWeight = "bold";
  }
}

function bl_cal_rebuildCalendar(el)
{
  bl_cal_clearSelection(el);
  if (parseInt(el.getAttribute("bl_cal_type")) == bl_cal_t_multiple)
  {
    bl_cal_recomputeMulti(el);
  }
  else
  {
    bl_cal_computeDays(el, el.bl_cal, bl_cal_currentDate(el), true, true, false, false);
  }
  bl_cal_computeSelection(el);
}

function bl_cal_findCal(el, year, month)
{
  var cnt = 1;
  var cal = null;
  var y;
  var m;
  var isMultiple = (parseInt(el.getAttribute("bl_cal_type")) == bl_cal_t_multiple);
  
  if (isMultiple)
  {
    if (el.firstChild == null)
    {
      return null;
    }
    
    y   = parseInt(el.firstChild.getAttribute("year"));
    m   = parseInt(el.firstChild.getAttribute("month"));
    cnt = el.childNodes.length;
  }
  else if (el.bl_cal)
  {
    y = parseInt(el.bl_cal.getAttribute("year"));
    m = parseInt(el.bl_cal.getAttribute("month"));
  }
  else
  {
    return null;
  }
  
  var selectby = bl_cal_selectby(el);
  var startIndex;
  var searchableCnt = cnt;
  if (selectby == "month")
  { // month select. We only want to return the current month that is selected
    // not overlapping days from other months
    startIndex = 0; // we only want to check for visible calendars
  }
  else
  { // week or day select
    m--;
    if (m < 0)
    {
      m = 11;
      y--;
    }
    startIndex = -1;
    searchableCnt += 1; /* search the next/previous visible months to see if the selected date 
                           is overlapping on multiple calendars */
  }  
  for (var i = startIndex; i < searchableCnt; i++)
  {
    if (year == y && month == m)
    {
      break;
    }
    m++;
    if (m > 11)
    {
      m = 0;
      y++;
    }
  }
  
  if (i < searchableCnt)
  { // we found the calendar within the range
    if (isMultiple)
    {
      if (i <= 0)
      {
        cal = el.firstChild;
      }
      else if (i >= (cnt-1))
      {
        cal = el.lastChild;
      }
      else
      {
        cal = el.childNodes[i];
      }
    }
    else if (i >= startIndex && i < searchableCnt)
    {
      cal = el.bl_cal;
    }
  }
  return cal;
}

function bl_cal_findDayEl(el, year, month, day)
{
  var cal = bl_cal_findCal(el, year, month);
  if (cal != null)
  {
    var dayEl = cal.childNodes[1].childNodes[7];
    while (dayEl)
    {
      if (dayEl.getAttribute("blid") == "day" && !dayEl.getAttribute("disabled"))
      {
        if (parseInt(dayEl.getAttribute("month")) == month && 
            parseInt(dayEl.getAttribute("day")) == day)
        {
          return dayEl;
        }
      }
      dayEl = dayEl.nextSibling;
    }
  }
  return null;
}

function bl_cal_shiftCal(el, yr1, yr2, m1, m2, arg, y, m)
{
  if (yr1 == yr2 && m1 == m2)
  {
    bl_cal_adjustCal(el, arg);
    bl_cal_computeRange(el);
    return true;
  }
  else if (yr1 < yr2 || (yr1 == yr2 && m1 < m2))
  {
    var currentDate = bl_cal_currentDate(el);
    currentDate.setFullYear(y, m);
    bl_cal_rebuildCalendar(el);
    bl_cal_computeRange(el);
    return true;
  }
  return false;
}

function bl_cal_locateToDate(el)
{
  var date        = bl_cal_date(el);
  var month       = date.getMonth();
  var year        = date.getFullYear();
  var currentDate = bl_cal_currentDate(el);
  
  var cdate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
  var sdate = new Date(year, month, date.getDate());
  var cnt   = (parseInt(el.getAttribute("bl_cal_type")) == bl_cal_t_multiple) ? el.childNodes.length : 1;
  
  
  cdate.setMonth(cdate.getMonth() + cnt);
  sdate.setMonth(month - cnt + 1);
  
  if (bl_cal_shiftCal(el, cdate.getFullYear(), year, cdate.getMonth(), month, "IncMonth", sdate.getFullYear(), sdate.getMonth()))
  {
    return null;
  }
  
  bl_cal_setFullYear(cdate, currentDate.getFullYear(), currentDate.getMonth() - 1, currentDate.getDate());
  
  if (bl_cal_shiftCal(el, year, cdate.getFullYear(), month, cdate.getMonth(), "DecMonth", year, month))
  {
    return null;
  }
}

function bl_cal_setFullYear(dt, year, month, day)
{
  dt.setFullYear(year, month, day);
  dt.setHours(0, 0, 0, 0);
}

function bl_cal_sendData(el)
{
  var xmlStr       = null;
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  
  if (calendarType == bl_cal_t_duration)
  {
    xmlStr = '<duration>' + val + '</duration>';
  }
  else
  {
    var curDate = bl_cal_date(el);
    
    if (curDate)
    {
      if (calendarType == bl_cal_t_time)
      {
        if (el.oldHour != curDate.getHours() || el.oldMin != curDate.getMinutes())
        {
          var durStr = (el.bl_time_duration) ? 'duration="' + el.bl_time_duration + '" ' : "";
          el.oldHour = curDate.getHours();
          el.oldMin  = curDate.getMinutes();
          xmlStr     = '<time ' + durStr + ' >' + curDate.getHours() + ' ' + curDate.getMinutes() + '</time>';
        }
      }
      else
      {
        xmlStr = "<date>" 
                + curDate.getFullYear() 
                + " " 
                + curDate.getMonth() 
                + " " 
                + curDate.getDate() 
                + " " 
                + curDate.getHours() 
                + " " 
                + curDate.getMinutes() 
                + " " 
                + curDate.getSeconds() 
                + "</date>";
      }
    }
    else
    {
      xmlStr = (calendarType == 'time') ?  "<time>none</time>" : "<date>none</date>";
    }
  }
  if (xmlStr)
  {
    var sendEl = el;
    
    if (sendEl.id == "")
    {
      sendEl = el.parentNode;
    }
    
    if (sendEl)
    {
      // this could be in a DataEdit or a MCL so let's 
      // call the DataEdit send function
      // it will not affect the normal path to do so    
      bl_de_sendMessage(sendEl, xmlStr);
    }
  }
}

function bl_cal_addButton(id, title, images, styles, hide, inEdit)
{
  var styleVal = "vertical-align:middle;width:12px;height:16px;"
  var attrs = '';
  
  if (styles || hide)
  {
    attrs += 'style="' + ((hide) ?'visibility:hidden;' : '') + styles + 'vertical-align:middle;"';
  }
  
  return bl_sys_button_html(id, null, title, true, "_bl_cal_action", attrs, inEdit, images);
}

function bl_cal_shiftMulti(el, right)
{
  var currentDate = bl_cal_currentDate(el);
  var curDate     = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
  
  if (right)
  {
    var cal   = el.lastChild;
    var child = el.removeChild(el.firstChild);
    var month = parseInt(cal.getAttribute("month"));
    var year  = parseInt(cal.getAttribute("year"));
    
    bl_cal_computeDays(el, el.firstChild, curDate, true, false, true, false);
    bl_cal_setFullYear(curDate, year, month, 1);
    bl_cal_computeDays(el, el.lastChild, curDate, false, false, false, true);
    curDate.setMonth(month + 1);
    bl_cal_computeDays(el, child, curDate, false, true, false, false);
    el.appendChild(child);
  }
  else
  {
    var child = el.removeChild(el.lastChild);
    var cal   = el.lastChild;
    var month = parseInt(cal.getAttribute("month"));
    var year  = parseInt(cal.getAttribute("year"));
    
    bl_cal_computeDays(el, child, curDate, true, false, false, false);
    curDate.setMonth(curDate.getMonth() + 1);
    bl_cal_computeDays(el, el.firstChild, curDate, false, false, true, false);
    bl_cal_setFullYear(curDate, year, month, 1);
    bl_cal_computeDays(el, el.lastChild, curDate, false, true, false, true);
    bl_port_insertAdjacentElement(el.firstChild, "BeforeBegin", child);
  }
  
  var idim   = Math.max(Math.floor((el.offsetWidth)/bl_cal_width), 1);
  var jdim   = Math.max(Math.floor((el.offsetHeight)/bl_cal_height), 1);
  bl_cal_positionCals(el, idim, jdim);
}

function bl_cal_recomputeMulti(el)
{
  var list        = el.childNodes;
  var last        = list.length - 1;
  var currentDate = bl_cal_currentDate(el);
  var curDate     = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
  
  for (var i = 0; i <= last; i++)
  {
    bl_cal_computeDays(el, list[i], curDate, (i == 0), (i == last), false, false);
    curDate.setMonth(curDate.getMonth() + 1);
  }
}

function bl_cal_adjustCal(el, id)
{
  bl_cal_clearSelection(el);
  var currentDate = bl_cal_currentDate(el);
  
  if (id == "DecYear")
  {
    currentDate.setFullYear(currentDate.getFullYear() - 1);
  }
  else if (id == "DecMonth")
  {
    currentDate.setMonth(currentDate.getMonth() - 1);
  }
  else if (id == "IncMonth")
  {
    currentDate.setMonth(currentDate.getMonth() + 1);
  }
  else if (id == "IncYear")
  {
    currentDate.setFullYear(currentDate.getFullYear() + 1);
  }
  
  if (parseInt(el.getAttribute("bl_cal_type")) == bl_cal_t_multiple)
  {
    if ((id == "IncMonth" || id == "DecMonth") && el.childNodes.length > 2)
    {
      bl_cal_shiftMulti(el, (id == "IncMonth"));
    }
    else
    {
      bl_cal_recomputeMulti(el);
    }
  }
  else
  {
    bl_cal_computeDays(el, el.bl_cal, currentDate, true, true, false, false);
  }
  bl_cal_computeSelection(el);
}

function bl_cal_getMonthEdit(cal)
{
  return cal.firstChild.childNodes[1];
}

function bl_cal_getPopup(el)
{
  return el.firstChild.firstChild.firstChild.lastChild.firstChild;
}

function bl_cal_getText(el)
{
  return el.firstChild.firstChild.firstChild.firstChild.firstChild;
}

function bl_cal_getTimeStr(hours, minutes)
{
  var retVal = new String();
  var pm     = (hours > 11 ? true : false);
  hours      = (pm ? hours - 12 : hours);
  if (!hours)
  {
    hours = 12;
  }
  retVal += hours.toString();
  retVal += ":";
  if (!minutes || minutes < 10)
  {
    retVal += "0";
  }
  retVal += minutes.toString();
  retVal += (pm ? " PM" : " AM");
  return retVal;
}

function bl_cal_setPopupText(item, date, calendarType, formattedDate)
{
  if (item)
  {
    if (date != null)
    {
      if (calendarType == bl_cal_t_time)
      {
        item.value =  bl_cal_getTimeStr(date.getHours(), date.getMinutes());
      }
      else
      {
        if (!formattedDate)
        {
          var w_list = bl_sys_days();
          item.value = w_list[date.getDay()] + " " + (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
        }
        else
        {
          item.value = formattedDate;  
        }
      }
    }
    else
    {
      if (calendarType == bl_cal_t_duration)
      {
        item.value = bl_cal_durationText(item);
      }
      else
      {
        item.value = "None";
      }
    }
    item.setAttribute("bl_old_value", item.value);
  }
}

function bl_cal_selectMonth(el, newMonth)
{
  if (el.currentMonth != newMonth)
  {
    var current = el.currentMonth;
    if (current)
    {
      current.removeAttribute("bl_selected");
      current.style.cssText = current.getAttribute("en");
    }
    
    if (newMonth != null)
    {
      newMonth.setAttribute("bl_selected", true);
      newMonth.style.cssText = newMonth.getAttribute("ov");
    }
    
    el.currentMonth = newMonth;
  }
}

function _bl_cal_monthmove(x, y)
{
  var body = document.body;
  
  if (body)
  {
    var ms = bl_cal_getPopupChild();
    
    if (ms)
    {
      var elY = bl_sys_find_y(ms, null, false);
      var elH = ms.offsetHeight;
      var elX = bl_sys_find_x(ms, null, false);
      var elW = ms.offsetWidth;
      
      ms.direction = 0;
      ms.speed     = 0;
      if (y >= elY && y <= (elY + elH) && x >= elX && x <= (elX + elW))
      {
        var index = Math.floor((y - elY)/((elH - 2)/8));
        
        if (index >= 8)
        {
          index = 7;
        }
        else if (index < 0)
        {
          index = 0;
        }
        
        bl_cal_selectMonth(ms, bl_cal_getMonthItem(ms, index));
        bl_cal_computeSelectMove(index);
      }
      else
      {
        bl_cal_selectMonth(ms, null);
        
        if (y < elY || y > (elY + elH))
        {
          var dif = 0;
          if (y < elY)
          {
            ms.direction = -1;
            dif = elY - y;
          }
          else if (y > elY + elH)
          {
            ms.direction = 1;
            dif = y - (elY + elH);
          }
          
          if (dif > 0)
          {
            if (dif < 20)
            {
              ms.speed = 400;
            }
            else if (dif > 20 && dif < 40)
            {
              ms.speed = 250;
            }
            else if (dif > 40 && dif < 80)
            {
              ms.speed = 100;
            }
            else
            {
              ms.speed = 50;
            }
          }
          if (ms.speed > 0 && ms.movingType != 2)
          {
            ms.movingType = 2;
            window.setTimeout('_bl_cal_timer_month(2)', ms.speed);
          }
        }
      }
    }
  }
}

function _bl_cal_timer_month(type)
{
  var ms = bl_cal_getPopupChild();
  
  if (ms)
  {
    if (ms.speed > 0 && ms.movingType == type)
    {
      if (ms.direction != 0)
      {
        var msObj = bl_cal_getMonthItem(ms, 0);
        var year  = msObj.year;
        var month = msObj.month;
        
        if (ms.direction < 0)
        {
          if (month == 0)
          {
            month = 11;
            year--;
          }
          else
          {
            month--;
          }
        }
        else
        {
          if (month == 11)
          {
            month = 0;
            year++;
          }
          else
          {
            month++;
          }
        }
        bl_cal_adjustMonths(month, year, false)
        if (ms.movingType == 1)
        {
          var index = (ms.direction < 0) ? 0 : 7;
          bl_cal_selectMonth(ms, bl_cal_getMonthItem(ms, index));
        }
      }
      window.setTimeout('_bl_cal_timer_month(' + type + ')', ms.speed);
    }
  }
}

function _bl_cal_multi_timer(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    var cur = el.style.cursor;
    
    el.style.cursor = 'wait';
    bl_cal_clearSelection(el);
    bl_cal_recomputeMulti(el);
    bl_cal_computeSelection(el);
    el.style.cursor = cur;
    bl_cal_computeRange(el);
  }
}

function _bl_cal_month_selected()
{
  var ms = bl_cal_getPopupChild();
  if (ms && ms.curEl)
  {
    var pwin = bl_sys_popupParent();
    if (ms.currentMonth)
    {
      var el          = ms.curEl;
      var isMulti     = (parseInt(el.getAttribute("bl_cal_type")) == bl_cal_t_multiple);
      var currentDate = bl_cal_currentDate(el);
      
      currentDate.setFullYear(ms.currentMonth.year, ms.currentMonth.month);
      if (isMulti)
      {
        var cal = ms.curMonthEdit;
        var cur = el.firstChild;
        var cnt = 0;
        
        while (cal.parentNode != el)
        {
          cal = cal.parentNode;
        }
        
        while (cur != cal)
        {
          cnt++;
          cur = cur.nextSibling;
        }
        currentDate.setMonth(ms.currentMonth.month - cnt);
        
        pwin.setTimeout('_bl_cal_multi_timer(' + el.id + ')', 1);
      }
      else
      {
        pwin.bl_cal_clearSelection(el);
        pwin.bl_cal_computeDays(el, el.bl_cal, currentDate, true, true, false, false);
        pwin.bl_cal_computeSelection(el);
        bl_cal_computeRange(el);
      }
    }
    pwin.cb_sys_popup_close(false);
  }
}

function bl_cal_MonthSelectorCreate(style)
{
  var html = null;
  
  if (style)
  {
    var html = '<div unselectable="on" id="blCalPopId" style="border:1px solid #000000;height:130px;"><table unselectable="on" style="font-family:tahoma,verdana,sans-serif;font-size:11px;width:100%;" cellspacing="0" cellpadding="0" >';
    for (var i = 0; i < 8; i++)
    {
      html += '<tr unselectable="on"><td align="center" unselectable="on"><div unselectable="on" id="ms_' 
           + i 
           + '" style="'
           + style.monthSelectEnableCSS
           + '" en="'
           + style.monthSelectEnableCSS
           + '" ov="'
           + style.monthSelectOverCSS
           +'"></div></td></tr>';
    }
    html += '</table></div>';
  }
  return  html;
}

function bl_cal_getMonthChildren(view)
{
  return view.firstChild.firstChild.childNodes;
}

function bl_cal_getMonthItem(view, index)
{
  return view.firstChild.firstChild.childNodes[index].firstChild.firstChild;
}

function bl_cal_adjustMonths(month, year, updateView)
{
  var ms = bl_cal_getPopupChild();
  
  if (ms)
  {
    var list = bl_cal_getMonthChildren(ms);
    var len  = list.length;
    
    for (var i = 0; i < len; i++, month++)
    {
      var fm_list     = bl_sys_fullMonths();
      var msObj       = list[i].firstChild.firstChild;
      msObj.innerHTML = fm_list[month] + " " + year;
      msObj.setAttribute("bl_it", bl_cal_t_monthIn);
      msObj.month     = month;
      msObj.year      = year;
      
      if (updateView)
      {
        var cssTextAttr = (msObj.getAttribute("cl_selected") != null) ? "ov":"en";
        msObj.style.cssText = msObj.getAttribute(cssTextAttr);
      }
      if (month == 11)
      {
        month = -1;
        year++;
      }
    }
  }
}

function bl_cal_mmove(event)
{
  if (!event)
  {
    event = window.event;
  }

  var popit = bl_sys_getPopupObj();
  
  if (popit)
  {
    popit = popit.popup_arg.customArg.cb_realMonthPopit;

    if (popit.popup_arg.isReady)
    {
      var win = window;
      var top = cb_sys_getTopWindow();
      
      while (!event && win != top)
      {
        win   = win.parent;
        event = win.event;
      }
      
      
      if (event)
      {
        if (bl_port_isLeftDown(event) || bl_port_isRightDown(event))
        {
          var pwin = bl_port_docWindow(bl_port_getOverLayDocument(popit));
          
          if (pwin._bl_cal_monthmove)
          {
            pwin._bl_cal_monthmove(event.screenX - pwin.cb_sys_getScreenLeft(true), event.screenY - pwin.cb_sys_getScreenTop(true));
          }
        }
        else
        {
          window.cb_sys_popup_close(false);
        }
      }
    }
  }
}

function bl_cal_findElFromItem(item)
{
  var el = null;
  
  if (window.bl_isCalPopup)
  {
    var popupArg = bl_sys_getMyPopupArg();
    
    if (popupArg)
    {
      el = popupArg.customArg;
    }
  }
  else
  {
    el = item.parentNode;
    
    while (el && el.getAttribute)
    {
      var cb_tag = el.getAttribute("cb_tag");
      if (cb_tag &&
          (cb_tag == "CAL"  ||
           cb_tag == "TCO" ||
           cb_tag == "DCO"))
      {
        break;
      }
      el = el.parentNode;
    }
  }
  
  return el;
}

function bl_cal_computeContext(el, type)
{
  if (el && type != undefined && type >= 0 && type <= bl_cal_t_text_none)
  {
    var contextList = bl_cal_contextList(el);
    return contextList[type];
  }
  return null;
}

function bl_cal_mup(event)
{
  if (!event)
  {
    event = window.event;
  }
  var popit = bl_sys_getPopupObj();
  
  if (popit)
  {
    var el   = popit.popup_arg.customArg;
    var item = el.bl_current_monthItem;
    var pwin = bl_port_docWindow(bl_port_getOverLayDocument(popit));
    var p    = item.parentNode;
   
    popit = el.cb_realMonthPopit;
    
    el.bl_inMonthSelect = false;

    bl_port_releaseCapture(p);
    p.onmousemove = null;
    p.onmouseup   = null;
    
    var win = window;
    var top = cb_sys_getTopWindow();
    
    while (!event && win != top)
    {
      win = win.parent;
      event  = win.event;
    }
    
    if (event && pwin._bl_cal_monthmove && popit.popup_arg.isReady)
    {
      var screenTop  = pwin.cb_sys_getScreenTop(true);
      var screenLeft = pwin.cb_sys_getScreenLeft(true);
      var sx         = event.screenX;
      var sy         = event.screenY;
      var mony       = bl_sys_find_y(item, null, false) + cb_sys_getScreenTop();
      var context    = bl_cal_computeContext(el, parseInt(item.getAttribute("bl_it")));
      
      if (sy >= mony && sy <= mony + item.offsetHeight)
      {
        bl_cal_setCSS(item, context.mainActiveCSS, context.h_mainActiveCSS);
      }
      else
      {
        bl_cal_setCSS(item, context.mainCSS, context.h_mainCSS);
      }
      pwin._bl_cal_monthmove(sx - screenLeft, sy - screenTop);
      pwin._bl_cal_month_selected();
      bl_port_stop_event(event);
    }
    window.cb_sys_popup_close(false);
  }
}

function bl_cal_popup_valid(win)
{
  return (win._bl_sys_last && win._bl_cal_last && win._bl_kb_last && win._bl_port_last);
}

function bl_cal_createPopupTail(initName)
{
  return "<div id='bl_inputBlocker_id' class='bl_inputBlocker' onmousepress='bl_port_killEvent(event)' onmousedown='bl_port_killEvent(event)' onmouseup='bl_port_killEvent(event)'></div><script language='javascript'>window." 
         + initName 
         + "();</script>";
}

function bl_cal_ms_cleanUp(popit)
{
  var el      = popit.popup_arg.customArg;
  var item    = el.bl_current_monthItem;
  var p       = item.parentNode;
  var context = bl_cal_computeContext(el, parseInt(item.getAttribute("bl_it")));
  
  bl_port_releaseCapture(p);
  bl_cal_setCSS(item, context.mainCSS, context.h_mainCSS);
}

function bl_cal_showMonthSelector(item, el)
{
  var ms = bl_cal_MonthSelectorCreate(window[el.getAttribute("bl_style_id")]);
  
  if (el && ms)
  {
    var html   = bl_cal_getHTMLHead();
    var p      = item.parentNode;
    
    el.bl_current_monthItem = item;
    html += ms;
    html += bl_cal_createPopupTail('_bl_cal_init_ms');
    
    var argData = { html:html,
                    customArg:el,
                    x:0,
                    y:-61,
                    w:item.offsetWidth,
                    h:130,
                    el:item,
                    cleanUp:bl_cal_ms_cleanUp,
                    canDestroy:true,
                    valid:bl_cal_popup_valid,
                    useVeil:true,
                    positionType:"control"
                  };

    el.cb_realMonthPopit = window.bl_sys_popupInvoke(argData);
    
    if (bl_browserInfo.safari)
    {
      el.bl_inMonthSelect = true;
    }
    bl_port_setCapture(p);
    p.onmousemove        = bl_cal_mmove;
    p.onmouseup          = bl_cal_mup;
  }
}

function bl_cal_computeSelectMove(index)
{
  var ms = bl_cal_getPopupChild();
  
  if (ms)
  {
    if (index == 7 || index == 0)
    {
      ms.speed     = 400;
      ms.direction = (index == 0) ? -1 : 1;
      
      if (ms.movingType != 1)
      {
        ms.movingType = 1;
        window.setTimeout('_bl_cal_timer_month(1)', 1000);
      }
    }
    else
    {
      ms.movingType = 0;
    }
  }
}

function bl_cal_clearSelection(el)
{
  var list  = bl_cal_selectList(el);
  var dayEl = list.pop();
  
  while (dayEl != undefined)
  {
    bl_cal_setSelect(el, dayEl, false);
    dayEl = list.pop();
  }
  
  if (el.blTodayEl)
  {
    var contextList = bl_cal_contextList(el);
    var todayDayEl  = el.blTodayEl;
    var type        = parseInt(todayDayEl.getAttribute("bl_it"));
    var newType     = bl_cal_t_todayIn;
    
    if (type == bl_cal_t_monthLess)
    {
      newType = bl_cal_t_todayLess;
    }
    else if (type == bl_cal_t_monthMore)
    {
      newType = bl_cal_t_todayMore
    }
    
    todayDayEl.setAttribute("bl_it", newType);
    
    var context = contextList[newType];
    bl_cal_setCSS(todayDayEl, context.mainCSS, context.h_mainCSS);
  }
}

function bl_cal_weekSelect(el, dayEl, list, fullweek)
{
  var row           = parseInt(dayEl.getAttribute("row"));
  var col           = parseInt(dayEl.getAttribute("col"));
  var cnt           = (fullweek) ? 7 : 5;
  var selectFailure = false;
  var month         = parseInt(dayEl.getAttribute("month")) + ((row) ? 1 : -1);
  var year          = parseInt(dayEl.getAttribute("year"));
  
  if (!fullweek)
  {
    if (col == 0)
    {
      dayEl = dayEl.nextSibling;
    }
    col--;
  }
  
  while (col > 0)
  {
    dayEl = dayEl.previousSibling;
    col--;
  }
  for (var i = 0; i < cnt; i++)
  {
    if (!bl_cal_selectEl(el, list, dayEl))
    {
      selectFailure = true;
    }
    dayEl = dayEl.nextSibling;
  }
  
  if (selectFailure)
  {
    if (month < 0)
    {
      month = 11;
      year--;
    }
    else if (month >= 12)
    {
      month = 0;
      year++;
    }
    var cal = bl_cal_findCal(el, year, month);
    
    if (cal)
    {
      var clist = cal.childNodes[1].childNodes;
      var index = (row) ? 7 : 48;
      
      if (row)
      {
        if (clist[index + 6].getAttribute("disabled"))
        {
          index = 14;
        }
      }
      else
      {
        if (clist[index].getAttribute("disabled"))
        {
          index = 42;
          
          if (clist[index].getAttribute("disabled"))
          {
            index = 35;
          }
        }
      }
      
      if (!fullweek)
      {
        index++;
      }
      
      dayEl = clist[index];
      for (var i = 0; i < cnt; i++)
      {
        bl_cal_selectEl(el, list, dayEl);
        dayEl = dayEl.nextSibling;
      }
    }
  }
}

function bl_cal_selectEl(el, list, item)
{
  if (!item.getAttribute("disabled"))
  {
    bl_cal_setSelect(el, item, true);
    list.push(item);
    return true;
  }
  return false;
}

function bl_cal_selectby(el)
{
  var selectby = el.getAttribute("bl_selectby");
  if (!selectby)
  {
    selectby = "day";
  }
  return selectby;
}

function bl_cal_clearOldSelect(el)
{
  var list = bl_cal_selectList(el);
  list.splice(0, list.length);
}

function bl_cal_computeSelection(el)
{
  var today = new Date();
  
  el.blTodayEl = bl_cal_findDayEl(el, today.getFullYear(), today.getMonth(), today.getDate());
  
  if (el.blTodayEl != null)
  {
    var contextList = bl_cal_contextList(el);
    var dayEl       = el.blTodayEl;
    var type        = parseInt(dayEl.getAttribute("bl_it"));
    
    if (type && type > bl_cal_t_todayMore)
    {
      var newType = bl_cal_t_todayIn;
      
      if (type == bl_cal_t_monthLess)
      {
        newType = bl_cal_t_todayLess;
      }
      else if (type == bl_cal_t_monthMore)
      {
        newType = bl_cal_t_todayMore
      }
      
      dayEl.setAttribute("bl_it", newType);

      var context = contextList[newType];
      bl_cal_setCSS(dayEl, context.mainCSS, context.h_mainCSS);
    }
  }
  
  var date = bl_cal_date(el);
  
  if (date != null)
  {
    var day      = date.getDate();
    var month    = date.getMonth();
    var year     = date.getFullYear();
    var list     = bl_cal_selectList(el);
    var selectby = bl_cal_selectby(el);
    
    if (selectby == "month")
    {
      var cal = bl_cal_findCal(el, year, month);
      if (cal != null)
      {
        var dayEl = cal.childNodes[1].childNodes[7];
        while (dayEl)
        {
          if (dayEl.getAttribute("blid") == "day")
          {
            bl_cal_selectEl(el, list, dayEl);
          }
          dayEl = dayEl.nextSibling;
        }
      }
    }
    else
    {
      var dayEl = bl_cal_findDayEl(el, year, month, day);
      if (dayEl != null)
      {
        if (selectby == "day")
        {
          bl_cal_selectEl(el, list, dayEl);
        }
        else
        {
          bl_cal_weekSelect(el, dayEl, list, (selectby == "fullweek"));
        }
      }
    }
  }
}

// this function is to ensure that data and script are created in the same window
// as the calendar element
function bl_cal_initElement(el)
{
  if (!el.bl_cal_inited)
  {
    el.bl_cal_inited = true;
    bl_sys_addCleanUpCall(el, bl_cal_cleanup);
    var calendarType = parseInt(el.getAttribute("bl_cal_type"));
    
    if (calendarType == bl_cal_t_in_today ||
        calendarType == bl_cal_t_in_none  ||
        calendarType == bl_cal_t_in_both)
    {
      el.bl_cal = el.firstChild;
    }
    bl_cal_date(el);

    if (calendarType == bl_cal_t_in_today ||
        calendarType == bl_cal_t_in_none  ||
        calendarType == bl_cal_t_in_both  ||
        calendarType == bl_cal_t_multiple)
    {
      var cal  = el.firstChild;
      var idim = Math.floor((el.offsetWidth)/bl_cal_width)

      while (cal)
      {
        bl_cal_initCalendar(el, cal);
        
        if (cal.blDMonth.style.visibility != "hidden")
        {
          el.blDMonth = cal.blDMonth;
        }
        if (cal.blIMonth.style.visibility != "hidden")
        {
          el.blIMonth = cal.blIMonth;
        }
        if (cal.blDYear.style.visibility != "hidden")
        {
          el.blDYear = cal.blDYear;
        }
        if (cal.blIYear.style.visibility != "hidden")
        {
          el.blIYear = cal.blIYear;
        }
        
        cal = cal.nextSibling;
      }
      
      bl_cal_computeSelection(el);
    }

    bl_cal_hiliteData(el);
    bl_cal_contextList(el);
    bl_cal_selectList(el);
    bl_cal_currentDate(el);
  }
}

function bl_cal_monthAction(el, item)
{
  var win          = window;
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  
  // must init before doing anything
  bl_cal_initElement(el);
  
  var popit = bl_sys_getPopupObj();

  if (calendarType > 0 && popit)
  {
    win = bl_port_docWindow(bl_port_getOverLayDocument(popit));
  }
  
  win.bl_cal_showMonthSelector(item, el);
  item.bl_mouseIsDown = false;
  return false;
}

function bl_cal_hideSelect(el, item)
{
  var list = bl_cal_selectList(el);
  var cnt  = list.length;
  
  for (var i = 0; i < cnt; i++)
  {
    bl_cal_setSelect(el, list[i], false);
  }
  return true;
}

function bl_cal_activeCheck(el, item)
{
  bl_cal_setActive(el, item);
}

function bl_cal_restoreSelect(el, item)
{
  var list = bl_cal_selectList(el);
  var cnt  = list.length;
  
  for (var i = 0; i < cnt; i++)
  {
    bl_cal_setSelect(el, list[i], true);
  }
  bl_cal_activeCheck(el, item);
}

function bl_cal_findFirst(cal)
{
  if (cal)
  {
    var dayEl = cal.childNodes[1].childNodes[7];
    while (dayEl)
    {
      if (dayEl.getAttribute("blid") == "day" && !dayEl.getAttribute("disabled"))
      {
        return dayEl;
      }
      dayEl = dayEl.nextSibling;
    }
  }
  return null;
}

function bl_cal_findLast(cal)
{
  if (cal)
  {
    var dayEl = cal.childNodes[1].lastChild;
    while (dayEl)
    {
      if (dayEl.getAttribute("blid") == "day" && !dayEl.getAttribute("disabled"))
      {
        return dayEl;
      }
      dayEl = dayEl.previousSibling;
    }
  }
  return null;
}

function bl_cal_computeRange(el)
{
  if (el.getAttribute("bl_sendRange") != null)
  {
    var fchild = bl_cal_findFirst(el.firstChild);
    var lchild = bl_cal_findLast(el.lastChild);
    if (fchild && lchild)
    {
      var curStart = el.cb_startRange;
      var curEnd   = el.cb_endRange;
      
      var sr = new Date(parseInt(fchild.getAttribute("year")), 
                        parseInt(fchild.getAttribute("month")), 
                        parseInt(fchild.getAttribute("day")));
      var er = new Date(parseInt(lchild.getAttribute("year")), 
                        parseInt(lchild.getAttribute("month")), 
                        parseInt(lchild.getAttribute("day")));
                        
      if (!curStart                                  ||
          !curEnd                                    ||
          curStart.getFullYear() != sr.getFullYear() ||
          curStart.getMonth()    != sr.getMonth()    ||
          curStart.getDate()     != sr.getDate()     ||
          curEnd.getFullYear()   != er.getFullYear() ||
          curEnd.getMonth()      != er.getMonth()    ||
          curEnd.getDate()       != er.getDate())
      {
        el.cb_startRange = sr;
        el.cb_endRange   = er;
        var xmlStr       = '<range><start>' 
                          + sr.getFullYear() 
                          + ' '
                          + sr.getMonth() 
                          + ' ' 
                          + sr.getDate() 
                          + '</start><end>' 
                          + er.getFullYear() 
                          + ' ' 
                          + er.getMonth() 
                          + ' ' 
                          + er.getDate() 
                          + '</end></range>';
        
        bl_mpr_send(xmlStr, el.id, 0, BL_MPR_ASAP, true);
      }
    }
    else
    {
      var currentDate = bl_cal_currentDate(el);
      var year        = currentDate.getFullYear();
      var month       = currentDate.getMonth();
      sr              = new Date(year, month, -14);
      er              = new Date(year, month + 1, 14);
    }
    var curStart = el.cb_startRange;
    var curEnd   = el.cb_endRange;
    if (sr && er && (!curStart                     ||
        !curEnd                                    ||
        curStart.getFullYear() != sr.getFullYear() ||
        curStart.getMonth()    != sr.getMonth()    ||
        curStart.getDate()     != sr.getDate()     ||
        curEnd.getFullYear()   != er.getFullYear() ||
        curEnd.getMonth()      != er.getMonth()    ||
        curEnd.getDate()       != er.getDate()))
    {
      el.cb_startRange = sr;
      el.cb_endRange   = er;
      var xmlStr       = '<range><start>' 
                        + sr.getFullYear() 
                        + ' ' 
                        + sr.getMonth() 
                        + ' ' 
                        + sr.getDate() 
                        + '</start><end>' 
                        + er.getFullYear() 
                        + ' ' 
                        + er.getMonth() 
                        + ' '  
                        + er.getDate() 
                        + '</end></range>';
      
      bl_mpr_send(xmlStr, el.id, 0);
    }
  }
}

function bl_cal_updateCalendar(el)
{
  var win          = window;
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  
  if (calendarType == bl_cal_t_pop_today ||
      calendarType == bl_cal_t_pop_none  ||
      calendarType == bl_cal_t_pop_both)
  {
    bl_cal_setPopupText(bl_cal_getText(el), bl_cal_date(el), calendarType);
    cb_sys_popup_close(false);
  }
  
  bl_cal_computeRange(el);
  win.bl_cal_sendData(el);
}

function bl_cal_dayAction(el, item)
{
  var date = new Date();
  bl_cal_setFullYear(date, 
                     parseInt(item.getAttribute("year")), 
                     parseInt(item.getAttribute("month")), 
                     parseInt(item.getAttribute("day")));
                   
  bl_cal_set_date(el, date);
  
  var type = parseInt(item.getAttribute("bl_it"));
  
  if (type == bl_cal_t_todayLess || type == bl_cal_t_monthLess)
  {
    bl_cal_adjustCal(el, "DecMonth");
  }
  else if (type == bl_cal_t_todayMore || type == bl_cal_t_monthMore)
  {
    bl_cal_adjustCal(el, "IncMonth");
  }
  else
  {
    bl_cal_clearSelection(el);
    bl_cal_computeSelection(el);
  }
  
  return bl_cal_updateCalendar(el);
}

function bl_cal_createDate()
{
  return new Date();
}

function bl_cal_textAction(el, item)
{
  var id          = item.id;
  var currentDate = bl_cal_currentDate(el);
  
  if (id == "today")
  {
    var date = bl_cal_set_date(el, new Date());
    bl_cal_setFullYear(currentDate, date.getFullYear(), date.getMonth(), 1);
    bl_cal_clearSelection(el);
    bl_cal_computeDays(el, el.bl_cal, currentDate, true, true, false, false);
    bl_cal_computeSelection(el);
  }
  else if (id == "none")
  {
    bl_cal_set_date(el, null);
    bl_cal_clearSelection(el);
    bl_cal_computeDays(el, el.bl_cal, currentDate, true, true, false, false);
  }
  bl_cal_updateCalendar(el);
}

function _bl_cal_action(event, item)
{
  var el = bl_cal_findElFromItem(item);
  
  // must init before doing anything
  bl_cal_initElement(el);
  bl_cal_adjustCal(el, item.id);
  bl_cal_computeRange(el);
  return null;
}

function bl_cal_cleanupContext()
{
  this.downCSS         = null;
  this.mainCSS         = null;
  this.downdownCSS     = null;
  this.downActiveCSS   = null;
  this.mainActiveCSS   = null;
  this.h_downCSS       = null;
  this.h_mainCSS       = null;
  this.h_downdownCSS   = null;
  this.h_downActiveCSS = null;
  this.h_mainActiveCSS = null;
  this.downAction      = null;
  this.restoreAction   = null;
  this.action          = null;
}

function bl_cal_createContext(daFunc, rFunc, aFunc)
{
  this.downAction      = daFunc;
  this.restoreAction   = rFunc;
  this.action          = aFunc;
  this.cleanup         = bl_cal_cleanupContext;
}

function bl_cal_create(cName, type, style)
{
  if (!style.bl_cal_calTxtList)
  {
    style.bl_cal_calTxtList = new Array(7);
  }
  
  var html = style.bl_cal_calTxtList[type];
  
  if (html == undefined)
  {
    var inEdit      = bl_contain_isFormEditor();
    var contextList = bl_cal_styleContextList(style);
    
    html      = "";
    var hDays = "SMTWTFS";
    var dayB;
    var usel;
    var hideButtons = (type == bl_cal_t_multiple);

    if (inEdit)
    {
      dayB  = "";
      usel  = " hidefocus='true' ";
    }
    else
    {
      dayB  = "onmouseout='_bl_cal_text_leave(event, this)' onmouseover='_bl_cal_text_enter(event, this)' onmousedown='_bl_cal_text_down(event, this)' onmouseup='_bl_cal_text_up(event, this)'";
      usel  = " unselectable='on' hidefocus='true' ";
    }
    
    html += "<div " 
         + usel 
         + " style='" 
         + cName 
         + "'><div " 
         + usel 
         + " title='Select for scroll to month' style='border-top:1px solid "
         + style.titleHilite
         + ";border-left:1px solid "
         + style.titleHilite
         + ";border-right:1px solid "
         + style.titleBorder
         + ";border-bottom:1px solid "
         + style.titleBorder
         + ";background-color:"
         + style.monthEnabled.background
         + ";display:block;position:absolute;height:18px;width:136px;left:0px;'>";
    
    html += bl_cal_addButton("DecMonth", "Decrement Month", style.decMonth, "position:absolute;", hideButtons, inEdit);
    html += "<div " 
         + usel 
         + dayB 
         + " style='" 
         + contextList[bl_cal_t_head].mainCSS 
         + "' bl_it=7 ></div>";
         
    html += bl_cal_addButton("IncMonth", "Increment Month", style.incMonth, "position:absolute;left:122px;", hideButtons, inEdit);
    html += "</div><div" 
         + usel 
         + "style='position:absolute;display:block;top:18px;left:11px;width:114px;height:117px;";
    if (type)
    {
      html += "border-bottom:1px solid " + style.divider;
    }
    
    html += ";'>";

    var currentTop  = 0;
    var currentLeft = 0;
    var columnStyle = "overflow:hidden;text-align:right;padding:2px;position:absolute;display:block;width:16px;height:18px;border-bottom:1px solid ";
    
    columnStyle += style.divider;
    columnStyle += ";color:";
    columnStyle += style.columnTitle;

    for (var i = 0; i < 7; i++)
    {
      html += "<div style='left:" 
           + currentLeft 
           + "px;top:"
           + currentTop 
           + "px;"
           + columnStyle 
           + "' "
           + usel 
           + ">" 
           + hDays.charAt(i) 
           + "</div>";
           
      currentLeft += 16;
    }
    
    currentTop += 3;
    for (var i = 0; i < 6; i++)
    {
      currentLeft = 0;
      currentTop += 16;
      for (var j = 0; j < 7; j++)
      {
        var pos = "left:" 
                +  currentLeft
                + "px;top:"
                + currentTop
                + "px;";
        html += "<div style='position:absolute;display:block;width:16px;height:16px;text-align:right;overflow:hidden;" 
             + pos 
             + "' title='Select date' blid='day'" 
             + usel 
             + dayB 
             + " row="
             + i 
             + " col=" 
             + j 
             + " bl_pos='"
             + pos
             + "' unselectable='on' hidefocus='true'  bl_fontWeight='font-weight:normal;'></div>";
        currentLeft += 16;
      }
    }
    
    html += "</div>";
    
    if (type == bl_cal_t_multiple)
    {
      html += bl_cal_addButton("DecYear", "Decrement Year", style.decYear, "position:absolute; left:2px;top:118px;", true, inEdit);
      html += bl_cal_addButton("IncYear", "Increment Year", style.incYear, "position:absolute; left:122px;top:118px;", true, inEdit);
    }
    else if (type < bl_cal_t_pop_both)
    {
      var txt = (type == bl_cal_t_pop_today || type == bl_cal_t_in_today) ? "Today" : "None";
      var tip = (type == bl_cal_t_pop_today || type == bl_cal_t_in_today) ? "Select today's date" : "Set date to none";
      html += bl_cal_addButton("DecYear", "Decrement Year", style.decYear, "position:absolute; left:2px;top:138px;", false, inEdit);
      
      html += "<div" 
           + usel 
           + "title='" 
           + tip 
           + "' id='" 
           + txt.toLowerCase() 
           + "' " 
           + dayB 
           + " bl_it=8 style='" 
           + contextList[bl_cal_t_text_both].mainCSS
           + "'>" 
           + txt 
           + "</div>";
      
      html += bl_cal_addButton("IncYear", "Increment Year", style.incYear, "position:absolute; left:122px;top:138px;", false, inEdit);
    }
    else
    {
      html += bl_cal_addButton("DecYear", "Decrement Year", style.decYear, "position:absolute;left:2px;top:138px;", false, inEdit);
      html += "<div"
           + usel 
           + "id='today' " 
           + dayB 
           + " bl_it=9 title='Select today\'s date' style='"
           + contextList[bl_cal_t_text_today].mainCSS
           + "' >Today</div><div" 
           + usel 
           + "id='none' " 
           + dayB 
           + " bl_it=10 title='Set date to none' style='"
           + contextList[bl_cal_t_text_none].mainCSS
           + "' >None</div>";
      html += bl_cal_addButton("IncYear", "Increment Year", style.incYear, "position:absolute;left:122px;top:138px;", false, inEdit);
    }
    
    html += "</div>";
    style.bl_cal_calTxtList[type] = html;
  }
  
  return html;
}

function _bl_cal_timer(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    var item = el.cb_curTimerItem;
    
    if (item && item.bl_mouseIsIn && item.bl_mouseIsDown)
    {
      bl_cal_adjustCal(el, item.id);
      window.setTimeout('_bl_cal_timer("' + id + '")', 100);
    }
  }
}

function _bl_cal_startTimer(ev)
{
  if (ev != null)
  {
    var item = bl_port_getEventTarget(ev);
    
    if (item.bl_mouseIsIn && item.bl_mouseIsDown)
    {
      var el             = bl_cal_findElFromItem(item);
      el.cb_curTimerItem = item;
      window.setTimeout("_bl_cal_timer('" + el.id + "')", (ev.type == "mousedown") ? 500 : 100);
    }
  }
}

function bl_cal_getMonthDays(year, month)
{
  if (!window.bl_cal_MonthDays)
  {
    window.bl_cal_MonthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  }
  
  if (((0 == (year%4)) && ((0 != (year%100)) || (0 == (year%400)))) && month == 1)
  {
    return 29;
  }
  return window.bl_cal_MonthDays[month];
}

function bl_cal_initCalendar(el, cal)
{
  cal.blInited = true;
  cal.blDMonth = cal.firstChild.firstChild;
  cal.blIMonth = cal.firstChild.lastChild;
  cal.blDYear  = cal.childNodes[2];
  cal.blIYear  = cal.lastChild;
  
  if (parseInt(el.getAttribute("bl_cal_type")) > bl_cal_t_multiple)
  {
    bl_addEventListener(cal.blDMonth, "mousedown", _bl_cal_startTimer, false);
    bl_addEventListener(cal.blDMonth, "mouseover", _bl_cal_startTimer, false);
    bl_addEventListener(cal.blIMonth, "mousedown", _bl_cal_startTimer, false);
    bl_addEventListener(cal.blIMonth, "mouseover", _bl_cal_startTimer, false);
    bl_addEventListener(cal.blDYear,  "mousedown", _bl_cal_startTimer, false);
    bl_addEventListener(cal.blDYear,  "mouseover", _bl_cal_startTimer, false);
    bl_addEventListener(cal.blIYear,  "mousedown", _bl_cal_startTimer, false);
    bl_addEventListener(cal.blIYear,  "mouseover", _bl_cal_startTimer, false);
  }
}

function bl_cal_cleanup(el)
{
  el.bl_cal          = null;
  el.blTodayEl      = null;
  el.bl_contextList = null;
  
  if (el.cbSelectList)
  {
    var slen        = el.cbSelectList.length;
    el.cbSelectList.splice(0, slen);
    el.cbSelectList = null;
  }
}

function bl_cal_initContext(style)
{
  var common      = "position:absolute;display:block;width:16px;height:16px;text-align:right;overflow:hidden;";
  var blankStyle  = common + "background-color:#ffffff;color:#ffffff;border:none;padding-top:2px;padding-right:1px;padding-left:1px;padding-bottom:1px;";
  var offE        = style.offEnabled.color;
  var todayOn     = new bl_cal_createContext(bl_cal_hideSelect, bl_cal_restoreSelect, bl_cal_dayAction);
  var todayOff    = new bl_cal_createContext(bl_cal_hideSelect, bl_cal_restoreSelect, bl_cal_dayAction);
  var dayOn       = new bl_cal_createContext(bl_cal_hideSelect, bl_cal_restoreSelect, bl_cal_dayAction);
  var dayOff      = new bl_cal_createContext(bl_cal_hideSelect, bl_cal_restoreSelect, bl_cal_dayAction);
  var blank       = new bl_cal_createContext(null, null, null);
  var month       = new bl_cal_createContext(bl_cal_monthAction, bl_cal_activeCheck, null);
  var both        = new bl_cal_createContext(null, bl_cal_activeCheck, bl_cal_textAction);
  var actionToday = new bl_cal_createContext(null, bl_cal_activeCheck, bl_cal_textAction);
  var actionNone  = new bl_cal_createContext(null, bl_cal_activeCheck, bl_cal_textAction);
  var list        = new Array(todayOn, todayOff, todayOff, dayOn, dayOff, dayOff, blank, month, both, actionToday, actionNone);
                   
  style.contextList = list;                     
  
  todayOn.downCSS           = bl_cal_computeCSS(common, style.todaySelected,   null, 1, 2, 1, 1, 0, 0, 0, 0, 0);
  todayOn.mainCSS           = bl_cal_computeCSS(common, style.todayEnabled,    null, 1, 2, 1, 1, 0, 0, 0, 0, 0);
  todayOn.downdownCSS       = bl_cal_computeCSS(common, style.todaySelectOver, null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  todayOn.downActiveCSS     = bl_cal_computeCSS(common, style.todaySelectOver, null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  todayOn.mainActiveCSS     = bl_cal_computeCSS(common, style.todayOver,       null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  todayOn.h_downCSS         = bl_cal_computeCSS(common, style.todaySelected,   null, 1, 2, 1, 1, 0, 0, 0, 0, 1);
  todayOn.h_mainCSS         = bl_cal_computeCSS(common, style.todayEnabled,    null, 1, 2, 1, 1, 0, 0, 0, 0, 1);
  todayOn.h_downdownCSS     = bl_cal_computeCSS(common, style.todaySelectOver, null, 1, 1, 1, 1, 0, 1, 0, 0, 1);
  todayOn.h_downActiveCSS   = bl_cal_computeCSS(common, style.todaySelectOver, null, 1, 1, 1, 1, 0, 1, 0, 0, 1);
  todayOn.h_mainActiveCSS   = bl_cal_computeCSS(common, style.todayOver,       null, 1, 1, 1, 1, 0, 1, 0, 0, 1);
  
  todayOff.downCSS          = bl_cal_computeCSS(common, style.todaySelected,   offE, 1, 2, 1, 1, 0, 0, 0, 0, 0);
  todayOff.mainCSS          = bl_cal_computeCSS(common, style.todayEnabled,    offE, 1, 2, 1, 1, 0, 0, 0, 0, 0);
  todayOff.downdownCSS      = bl_cal_computeCSS(common, style.todaySelectOver, null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  todayOff.downActiveCSS    = bl_cal_computeCSS(common, style.todaySelectOver, null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  todayOff.mainActiveCSS    = bl_cal_computeCSS(common, style.todayOver,       null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  todayOff.h_downCSS        = bl_cal_computeCSS(common, style.todaySelected,   null, 1, 2, 1, 1, 0, 0, 0, 0, 1);
  todayOff.h_mainCSS        = bl_cal_computeCSS(common, style.todayEnabled,    null, 1, 2, 1, 1, 0, 0, 0, 0, 1);
  todayOff.h_downdownCSS    = bl_cal_computeCSS(common, style.todaySelectOver, null, 1, 1, 1, 1, 0, 1, 0, 0, 1);
  todayOff.h_downActiveCSS  = bl_cal_computeCSS(common, style.todaySelectOver, null, 1, 1, 1, 1, 0, 1, 0, 0, 1);
  todayOff.h_mainActiveCSS  = bl_cal_computeCSS(common, style.todayOver,       null, 1, 1, 1, 1, 0, 1, 0, 0, 1);

  dayOn.downCSS             = bl_cal_computeCSS(common, style.onSelected,      null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOn.mainCSS             = bl_cal_computeCSS(common, style.onEnabled,       null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOn.downdownCSS         = bl_cal_computeCSS(common, style.onSelectOver,    null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOn.downActiveCSS       = bl_cal_computeCSS(common, style.onSelectOver,    null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOn.mainActiveCSS       = bl_cal_computeCSS(common, style.onOver,          null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOn.h_downCSS           = bl_cal_computeCSS(common, style.onSelected,      null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  dayOn.h_mainCSS           = bl_cal_computeCSS(common, style.onEnabled,       null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  dayOn.h_downdownCSS       = bl_cal_computeCSS(common, style.onSelectOver,    null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  dayOn.h_downActiveCSS     = bl_cal_computeCSS(common, style.onSelectOver,    null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  dayOn.h_mainActiveCSS     = bl_cal_computeCSS(common, style.onOver,          null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  
  dayOff.downCSS            = bl_cal_computeCSS(common, style.offSelected,     null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOff.mainCSS            = bl_cal_computeCSS(common, style.offEnabled,      null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOff.downdownCSS        = bl_cal_computeCSS(common, style.offSelectOver,   null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOff.downActiveCSS      = bl_cal_computeCSS(common, style.offSelectOver,   null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOff.mainActiveCSS      = bl_cal_computeCSS(common, style.offOver,         null, 1, 1, 1, 1, 1, 0, 0, 0, 0);
  dayOff.h_downCSS          = bl_cal_computeCSS(common, style.offSelected,     null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  dayOff.h_mainCSS          = bl_cal_computeCSS(common, style.offEnabled,      null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  dayOff.h_downdownCSS      = bl_cal_computeCSS(common, style.offSelectOver,   null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  dayOff.h_downActiveCSS    = bl_cal_computeCSS(common, style.offSelectOver,   null, 1, 1, 1, 1, 1, 0, 0, 0, 1);
  dayOff.h_mainActiveCSS    = bl_cal_computeCSS(common, style.offOver,         null, 1, 1, 1, 1, 1, 0, 0, 0, 1);

  blank.downCSS             = blankStyle;
  blank.mainCSS             = blankStyle;
  blank.downdownCSS         = blankStyle;
  blank.downActiveCSS       = blankStyle;
  blank.mainActiveCSS       = blankStyle;

  common = "display:block;text-align:center;width:110px;position:absolute;left:12px;margin:0px;";

  month.downCSS             = bl_cal_computeCSS(common, style.monthDown,       null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  month.mainCSS             = bl_cal_computeCSS(common, style.monthEnabled,    null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  month.downdownCSS         = bl_cal_computeCSS(common, style.monthDown,       null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  month.downActiveCSS       = bl_cal_computeCSS(common, style.monthDown,       null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  month.mainActiveCSS       = bl_cal_computeCSS(common, style.monthOver,       null, 1, 1, 1, 1, 0, 1, 0, 0, 0);

  common = "text-align:center;display:block;position:absolute;top:138px;left:24px;width:87px;";

  both.downCSS               = bl_cal_computeCSS(common, style.actionDown,     null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  both.mainCSS               = bl_cal_computeCSS(common, style.actionEnabled,  null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  both.downdownCSS           = bl_cal_computeCSS(common, style.actionDown,     null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  both.downActiveCSS         = bl_cal_computeCSS(common, style.actionDown,     null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  both.mainActiveCSS         = bl_cal_computeCSS(common, style.actionOver,     null, 1, 1, 1, 1, 0, 1, 0, 0, 0);

  common = "text-align:center;display:block;position:absolute;top:138px;left:22px;width:40px;";

  actionToday.downCSS        = bl_cal_computeCSS(common, style.actionDown,     null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  actionToday.mainCSS        = bl_cal_computeCSS(common, style.actionEnabled,  null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  actionToday.downdownCSS    = bl_cal_computeCSS(common, style.actionDown,     null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  actionToday.downActiveCSS  = bl_cal_computeCSS(common, style.actionDown,     null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  actionToday.mainActiveCSS  = bl_cal_computeCSS(common, style.actionOver,     null, 1, 1, 1, 1, 0, 1, 0, 0, 0);

  common = "text-align:center;display:block;position:absolute;top:138px;left:72px;width:40px;";

  actionNone.downCSS        = bl_cal_computeCSS(common, style.actionDown,      null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  actionNone.mainCSS        = bl_cal_computeCSS(common, style.actionEnabled,   null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  actionNone.downdownCSS    = bl_cal_computeCSS(common, style.actionDown,      null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  actionNone.downActiveCSS  = bl_cal_computeCSS(common, style.actionDown,      null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  actionNone.mainActiveCSS  = bl_cal_computeCSS(common, style.actionOver,      null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  
  common = "width:100%;height:100%;";

  style.monthSelectEnableCSS = bl_cal_computeCSS(common, style.monthSelectorEnable,    null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  style.monthSelectOverCSS   = bl_cal_computeCSS(common, style.monthSelectorOver,      null, 1, 1, 1, 1, 0, 1, 0, 0, 0);
  return list;
}

function bl_cal_styleContextList(style)
{
  var list = style.contextList;
  
  if (!list)
  {
    list = bl_cal_initContext(style);      
  }
  
  return list;
}

function bl_cal_contextList(el)
{
  var list = el.bl_contextList;
  
  if (!list)
  {
    list = bl_cal_styleContextList(window[el.getAttribute("bl_style_id")]);
    el.bl_contextList = list;
    bl_cal_initElement(el);
  }    
  
  return list;
}

function bl_cal_computeCSS(common, stateObj, fontColor,
                           bTop, bBottom, bLeft, bRight,
                           pTop, pBottom, pLeft, pRight, doHilite)
{
  var ret = common + "color:";
  
  if (fontColor)
  {
    ret += fontColor;
  }
  else
  {
    ret += ((doHilite == 1)? stateObj.hilite:stateObj.color);
  }
  
  ret += ";background-color:";
  ret += stateObj.background;
  ret += ";";

  if (bTop == bBottom == bLeft == bRight)
  {
    ret += "border:";
    ret += bTop;
    ret += "px solid "
    ret += stateObj.border;
    ret += ";"
  }
  else
  {
    ret += "border-top:";
    ret += bTop;
    ret += "px solid "
    ret += stateObj.border;
    ret += ";border-bottom:";
    ret += bBottom;
    ret += "px solid "
    ret += stateObj.border;
    ret += ";border-left:";
    ret += bLeft;
    ret += "px solid "
    ret += stateObj.border;
    ret += ";border-right:";
    ret += bRight;
    ret += "px solid "
    ret += stateObj.border;
    ret += ";"
  }
  
  if (pTop == pBottom == pLeft == pRight)
  {
    ret += "padding:";
    ret += pTop;
    ret += "px;"
  }
  else
  {
    ret += "padding-top:";
    ret += pTop;
    ret += "px;padding-bottom:";
    ret += pBottom;
    ret += "px;padding-left:";
    ret += pLeft;
    ret += "px;padding-right:";
    ret += pRight;
    ret += "px;"
  }
  
  return ret;
}                           

function bl_cal_setCSS(item, text, h_text)
{
  var fontWeight = item.getAttribute("bl_fontWeight");
  var position   = item.getAttribute("bl_pos");
  var extra      = "";
  
  if (position)
  {
    extra += position;
  }
  if (fontWeight)
  {
    extra += fontWeight;
  }
  
  if (item.getAttribute("bl_isHilited") != null &&  h_text)
  {
    item.style.cssText = h_text + extra;
  }
  else
  {
    item.style.cssText = text + extra;
  }
}

function bl_cal_computeDays(el, cal, curDate, showPrev, showNext, justPrev, justNext)
{
  if (cal)
  {
    var contextList = bl_cal_contextList(el);
    if (!cal.blInited)
    {
      bl_cal_initCalendar(el, cal);
    }
    
    var hdata     = bl_cal_hiliteData(el);
    var month     = curDate.getMonth();
    var year      = curDate.getFullYear();
    var day       = curDate.getDay();
    var fm_list   = bl_sys_fullMonths();
    
    var curMonth  = (month == 0) ? 11 : month - 1;
    var curYear   = (month == 0) ? year - 1 : year;
    var curType   = bl_cal_t_monthLess;
    var curC      = contextList[curType];
    var blkC      = contextList[bl_cal_t_blank];
    var curHi     = hdata.getYear(curYear, false);
    var end       = bl_cal_getMonthDays(curYear, curMonth);
    var count     = end - day + 1;
    var show      = showPrev;
    
    var monthEl = bl_cal_getMonthEdit(cal);
    var dayEl   = cal.childNodes[1].childNodes[7];
    
    if (day == 0)
    {
      count -= 7;
    }
    
    monthEl.innerHTML = fm_list[month] + " " + year;
    monthEl.setAttribute("month", month);
    monthEl.setAttribute("year", year);
    cal.setAttribute("month", month);
    cal.setAttribute("year", year);
    
    while (dayEl)
    {
      if (dayEl.getAttribute("blid") == "day")
      {
        if (!justNext || curType > 0)
        {
          dayEl.removeAttribute("bl_selected");
          
          if (show)
          {
            var wasHilited = dayEl.getAttribute("bl_isHilited") != null;
            var hilited = (curHi && curHi.isSet(curMonth, count));
            dayEl.setAttribute("day", count);
            dayEl.setAttribute("month", curMonth);
            dayEl.setAttribute("year", curYear);
            dayEl.setAttribute("bl_fontWeight", (hilited ? "font-weight:bold;" : "font-weight:normal;"));
            dayEl.innerHTML        = count;
            dayEl.removeAttribute("disabled");
            
            if (hilited)
            {
              dayEl.setAttribute("bl_isHilited", true);
            }
            else
            {
              dayEl.removeAttribute("bl_isHilited");
            }
            
            if (parseInt(dayEl.getAttribute("bl_it")) != curType || wasHilited != hilited)
            {
              dayEl.setAttribute("bl_it", curType);
              bl_cal_setCSS(dayEl, curC.mainCSS, curC.h_mainCSS);
            }
          }
          else
          {
            dayEl.innerHTML = ' ';
            dayEl.setAttribute("disabled", "true");
            
            if (parseInt(dayEl.getAttribute("bl_it")) != bl_cal_t_blank)
            {
              dayEl.setAttribute("bl_it", bl_cal_t_blank);
              dayEl.removeAttribute("bl_isHilited");
              dayEl.setAttribute("bl_fontWeight", "font-weight:normal;");
              bl_cal_setCSS(dayEl, "position:absolute;display:block;width:16px;height:16px;overflow:hidden;text-align:right;background-color:#ffffff;color:#ffffff;border:none;padding-top:2px;padding-right:1px;padding-left:1px;padding-bottom:1px;")
            }
          }
        }
        if (count >= end)
        {
          if (curType == bl_cal_t_monthLess)
          {
            if (justPrev)
            {
              return ;
            }
            end      = bl_cal_getMonthDays(year, month);
            curMonth = month;
            curType  = bl_cal_t_monthIn;
            curC     = contextList[curType];
            curYear  = year;
            show     = true;
          }
          else
          {
            curMonth = (month == 11) ? 0 : month + 1;
            curYear  = (month == 11) ? year + 1 : year;
            end      = bl_cal_getMonthDays(curYear, curMonth);
            curType  = bl_cal_t_monthMore;
            curC     = contextList[curType];
            show     = showNext;
          }
          count = 1;
          if (curHi == null || curHi.year != curYear)
          {
            curHi = hdata.getYear(curYear, false);
          }
        }
        else
        {
          count++;
        }
      }
      dayEl = dayEl.nextSibling;
    }
  }
}

function bl_cal_popupCreate(type, style)
{
  var html = '<div id="blCalPopId" style="background-color:'
           + style.background
           + ';padding:1px;border:1px solid '
           + style.borderColor
           + ';width:139px;height:162px;" unselectable="on">';
  var topCSS = 'overflow:hidden;font-family:tahoma,verdana,sans-serif;font-size:11px;background-color:'
             + style.background
             + ';font-family:tahoma;width:136px;height:159px;position:absolute;'
  
  html += bl_cal_create(topCSS, type, style);
  html += '</div>'
  return html;
}

function bl_cal_popupCleanup()
{
  var item = bl_cal_popupButton;
  
  if (item)
  {
    var el = bl_cal_findElFromItem(item);

    bl_cal_clearOldSelect(el);
    
    el.bl_cal           = null;
    el.blTodayEl        = null;
    bl_cal_popupButton  = null;
    item.bl_mouseIsDown = false;
    item.removeAttribute("bl_selected");
    bl_sys_img_set(item, false, item.bl_mouseIsIn);
    bl_sys_img_thaw(item);
  }
}

function bl_cal_getTime(minutes, start, el, durVal)
{
  var hours = Math.floor(minutes/60);
  var min   = minutes % 60;
  var date  = new Date();
  var dur   = (durVal && durVal >= 0)? (durVal + minutes):(minutes - start);
  var ret   = ' no_cb_hour_val=' + hours + ' no_cb_minutes_val=' + min + ' no_cb_duration_val=' + dur + '>';
  var txt   = '';
  
  date.setHours(hours, min);
  txt += bl_cal_getTimeStr(date.getHours(), date.getMinutes());
  if (start)
  {
    var durHours = Math.floor(dur/60);
    var frac     = dur % 60;
    if (!durHours)
    {
      txt += " (" + frac + " minutes)";
    }
    else
    {
      txt += " (" + durHours;
      if (frac)
      {
        var str = new String((frac/60).toString());
        txt     += str.substring(1);
      }
      txt += ((!frac && durHours == 1) ? " hour)" : " hours)");
    }
  }
  
  bl_cal_tester.innerHTML = txt;
  el.cb_popupWidth        = Math.max(bl_cal_tester.offsetWidth + 22, el.cb_popupWidth);
  
  return ret + txt;
}

function _bl_cal_key(event, el)
{
  var src    = bl_port_getEventTarget(event);
  var parent = src.parentNode;
  var kcode  = bl_port_keyCode(event);
  
  if ((kcode == 38 || kcode == 37) && src.previousSibling)
  {
    bl_cal_timeDivChangeSel(parent, src, src.previousSibling, true);
    bl_port_stop_event(event);
  }
  if ((kcode == 40 || kcode == 39) && src.nextSibling)
  {
    bl_cal_timeDivChangeSel(parent, src, src.nextSibling, true);
    bl_port_stop_event(event);
  }
}

function bl_cal_timeDivChangeSel(parent, oldSel, newSel, setFocus)
{
  if (oldSel)
  {
    bl_port_setBGColor(oldSel.style, 'white');
    oldSel.style.color = 'black';
  }
  
  bl_port_setBGColor(newSel.style, '#316AC5');
  newSel.style.color  = 'white';
  parent.selectedItem = newSel;
  
  if (setFocus)
  {
    bl_port_focus(newSel);
    newSel.hideFocus = false;
  }
}

function _bl_cal_mouse_move(event)
{
  var src     = bl_port_getEventTarget(event);
  var parent  = src.parentNode;
  var current = parent.selectedItem;
  bl_cal_timeDivChangeSel(parent, current, src, true);
}

function bl_cal_getTimeOption(i, start, el, dur)
{
  var ft   = el.cb_popupFont;
  var html = '<div style="white-space:nowrap;width:100%;padding-left:2px;background-color:white;color:black;font:';
  html     += ft;
  html     += '" onkeydown="_bl_cal_key(event, this)" onkeypress="_bl_cal_time_key(event, this)" onclick="_bl_cal_click(event)" onmouseover="_bl_cal_mouse_move(event, this)"';
  html     += bl_cal_getTime(i, start, el, dur);
  html     += '</div>';
  return html;
}

function bl_cal_getDurationOption(val, str, el)
{
  var ft   = el.cb_popupFont;
  var html = '<div style="white-space:nowrap;width:100%;padding-left:2px;background-color:white;color:black;font:';
  html     += ft;
  html     += '" onkeydown="_bl_cal_key(event, this)" onkeypress="_bl_cal_time_key(event, this)" onclick="_bl_cal_click(event)" onmouseover="_bl_cal_mouse_move(event, this)" no_cb_duration_val=';
  html     += val;
  html     += ">";
  html     += str;
  html     += '</div>';
  return html;
}

function bl_cal_less(y1, y2, m1, m2, d1, d2)
{
  return ((y1 < y2) || (y1 == y2 && m1 < m2) || (y1 == y2 && m1 == m2 && d1 < d2));
}

function bl_cal_init_popupData(el)
{
  if (!el.cb_popupFont)
  {
    var cs             = bl_port_getComputedStyle(bl_cal_getText(el));
    el.cb_popupFont    = cs.fontSize + " " + cs.fontFamily;
    
    el.cb_popupWidth   = el.offsetWidth;
    if (!bl_cal_tester)
    {
      bl_cal_tester    = document.createElement("SPAN");
      var style        = bl_cal_tester.style;
      style.visibility = "hidden";
      style.font       = el.cb_popupFont;
      style.position   = "absolute";
      style.top        = "-300px";
      bl_port_insertAdjacentElement(document.body, "afterBegin", bl_cal_tester);
    }
  }
}

function bl_cal_computeTimeList(el)
{
  bl_cal_init_popupData(el);
  var html = '<div id="blCalPopId" style="white-space:nowrap;overflow-y:scroll;width:100%;height:100%;border:black 1px solid;"><span>';
  
  var interval          = parseInt(el.getAttribute("bl_interval"));
  var innerStr          = new String();
  var doFullList        = true;
  var dur               = 0;
  var bl_cal_start_time = el.getAttribute("bl_cal_start_time");
  var bl_cal_start_date = el.getAttribute("bl_cal_start_date");
  var bl_cal_end_date   = el.getAttribute("bl_cal_end_date");
  
  if (bl_cal_start_time)
  {
    var sDate = bl_cal_parseTime(bl_cal_start_time);
    
    if (bl_cal_start_date && bl_cal_end_date)
    {
      var std = bl_cal_setDate(bl_cal_start_date, "");
      var etd = bl_cal_setDate(bl_cal_end_date, "");
      
      if (std && etd)
      {
        if (std.getFullYear() == etd.getFullYear() &&
            std.getMonth()    == etd.getMonth()    &&
            std.getDate()     == etd.getDate())
        {
          doFullList = false;
        }
        else
        {
          var date = bl_cal_date(el);
          std.setDate(std.getDate() + 1);
          var dval = date.getHours() * 60 + date.getMinutes();
          var sval = sDate.getHours() * 60 + sDate.getMinutes();
          dur      = 1440 - sval;
          if (std.getFullYear() == etd.getFullYear() &&
              std.getMonth()    == etd.getMonth()    &&
              std.getDate()     == etd.getDate())
          {
            if (sval > dval)
            {
              doFullList = false;
            }
          }
          else
          {
            while (bl_cal_less(std.getFullYear(), 
                               etd.getFullYear(), 
                               std.getMonth(), 
                               etd.getMonth(), 
                               std.getDate(), 
                               etd.getDate()))
            {
              dur += 1440;
              std.setDate(std.getDate() + 1);
            }
          }
        }
      }
    }
    else
    {
      doFullList = false;
    }
    
    if (doFullList == false)
    {
      var start  = ((sDate.getHours() * 60) + sDate.getMinutes());
      var lim    = 1440 + start;
      for (var i = start; i < lim; i += interval)
      {
        html += bl_cal_getTimeOption(i, start, el, -1);
      }
    }
  }
  if (doFullList)
  {
    for (var i = 0; i < 1440; i += interval)
    {
      html += bl_cal_getTimeOption(i, 0, el, dur);
    }
  }
  html += '</span></div>';
  return html;
}

function bl_cal_selectTime(list, el)
{
  var date     = bl_cal_date(el);
  var hour     = date.getHours();
  var min      = date.getMinutes();
  var sList    = list.firstChild;
  var children = sList.childNodes;
  var len      = children.length;
  for (var i = 0; i < len; i++)
  {
    var item       = children.item(i);
    var currentSel = sList.selectedItem;
    if (item.no_cb_hour_val == hour)
    {
      if (item.no_cb_minutes_val <= min)
      {
        bl_cal_timeDivChangeSel(sList, currentSel, item, false);
      }
    }
    else
    {
      bl_port_setBGColor(item.style, 'white');
      item.style.color = 'black';
    }
  }
  if (!sList.selectedItem && len)
  {
    sList.selectedItem = children.item(0);
  }
}


function bl_cal_selectDuration(list, el)
{
  var dur      = el.bl_cal_duration_val;
  var sList    = list.firstChild;
  var children = sList.childNodes;
  var len      = children.length;
  var last     = null;
  var selected = false;
  
  for (var i = 0; i < len; i++)
  {
    var item       = children.item(i);
    var currentSel = sList.selectedItem;
    var ival       = parseInt(item.no_cb_duration_val);
    if (ival == dur)
    {
      bl_cal_timeDivChangeSel(sList, currentSel, item, false);
      selected = true;
    }
    else
    {
      if (ival > dur && last && !selected)
      {
        bl_cal_timeDivChangeSel(sList, currentSel, last, false);
        selected = true;
      }
      
      bl_port_setBGColor(item.style, 'white');
      item.style.color = 'black';
    }
  }
  if (!sList.selectedItem && len)
  {
    sList.selectedItem = children.item(0);
  }
}


function _bl_cal_click(event, el)
{
  var src = bl_port_getEventTarget(event);
  bl_cal_timeSelectChanged(src, src.parentNode.parentNode.bl_cal_curEl);
  bl_port_killEvent(event);
  return true;
}

function _bl_cal_time_key(event, el)
{
  if (bl_port_keyCode(event) == 13)
  {
    var src     = bl_port_getEventTarget(event);
    var selItem = null;
    
    if (src.selectedItem)
    {
      selItem = src.selectedItem;
    }
    else if (src.parentNode.selectedItem)
    {
      selItem = src.parentNode.selectedItem;
    }
    bl_cal_timeSelectChanged(selItem, selItem.parentNode.parentNode.bl_cal_curEl);
    bl_port_stop_event(event);
  }
}

function bl_cal_timeSelectChanged(selected, el)
{
  var strVal       = bl_port_getInnerText(selected);
  var txt          = bl_cal_getText(el);
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  
  if (calendarType == bl_cal_t_time)
  {
    var tm              = bl_cal_parseTime(strVal);
    var date            = bl_cal_set_date(el, new Date(tm));
    el.bl_time_duration = selected.no_cb_duration_val;
    bl_cal_setPopupText(txt, date, calendarType);
  }
  else
  {
    el.setAttribute("bl_cal_durationText", strVal);
    bl_cal_setPopupText(txt, null, calendarType);
  }
  bl_sys_closeThisPopup();
  bl_port_focus(txt);
  bl_sys_popupParent().bl_cal_sendData(el);
}

function bl_cal_getDurationList(el)
{
  if (!el.bl_cal_durationList)
  {
    bl_cal_init_popupData(el);
    var html = '<div style="white-space:nowrap;overflow-y:scroll;width:100%;height:100%;border:black 1px solid;"><div>';
    
    html += bl_cal_getDurationOption(0, "0 minutes", el);
    html += bl_cal_getDurationOption(5, "5 minutes", el);
    html += bl_cal_getDurationOption(10, "10 minutes", el);
    html += bl_cal_getDurationOption(15, "15 minutes", el);
    html += bl_cal_getDurationOption(20, "20 minutes", el);
    html += bl_cal_getDurationOption(30, "30 minutes", el);
    html += bl_cal_getDurationOption(45, "45 minutes", el);
    html += bl_cal_getDurationOption(60, "1 hour", el);
    html += bl_cal_getDurationOption(120, "2 hours", el);
    html += bl_cal_getDurationOption(180, "3 hours", el);
    html += bl_cal_getDurationOption(240, "4 hours", el);
    html += bl_cal_getDurationOption(300, "5 hours", el);
    html += bl_cal_getDurationOption(360, "6 hours", el);
    html += bl_cal_getDurationOption(420, "7 hours", el);
    html += bl_cal_getDurationOption(480, "8 hours", el);
    html += bl_cal_getDurationOption(540, "9 hours", el);
    html += bl_cal_getDurationOption(600, "10 hours", el);
    html += bl_cal_getDurationOption(660, "11 hours", el);
    html += bl_cal_getDurationOption(720, ".5 days", el);
    html += bl_cal_getDurationOption(1080, "18 hours", el);
    html += bl_cal_getDurationOption(1440, "1 day", el);
    html += bl_cal_getDurationOption(2880, "2 days", el);
    html += bl_cal_getDurationOption(4320, "3 days", el);
    html += bl_cal_getDurationOption(5760, "4 days", el);
    html += bl_cal_getDurationOption(7200, "5 days", el);
    html += bl_cal_getDurationOption(8640, "6 days", el);
    html += bl_cal_getDurationOption(10080, "1 week", el);
    html += bl_cal_getDurationOption(20160, "2 weeks", el);
    html += bl_cal_getDurationOption(30240, "3 weeks", el);
    html += bl_cal_getDurationOption(40320, "4 weeks", el);
    html += '</div></div>';
    el.bl_cal_durationList = html;
  }
  return el.bl_cal_durationList;
}

function bl_cal_getTimeList(el)
{
  if (!el.bl_cal_timeList)
  {
    el.bl_cal_timeList = bl_cal_computeTimeList(el);
  }
  return el.bl_cal_timeList;
}

function bl_cal_computePopup(type, styleId)
{
  var style = window[styleId];
  
  if (type == 1)
  {
    if (!style.popupToday)
    {
      style.popupToday = bl_cal_popupCreate(type, style);
    }
    return style.popupToday;
  }
  else if (type == 2)
  {
    if (!style.popupNone)
    {
      style.popupNone = bl_cal_popupCreate(type, style);
    }
    return style.popupNone;
  }
  else
  {
    if (!style.popupBoth)
    {
      style.popupBoth = bl_cal_popupCreate(type, style);
    }
    
    return style.popupBoth;
  }
  
  return null
}

function _bl_cal_popup_action(event, item)
{
  var el = bl_cal_findElFromItem(item);
  
  if (bl_cal_popupButton == item)
  {
    bl_cal_popupCleanup();
    return null;
  }
  
  // must init before doing anything
  bl_cal_initElement(el);
  
  var html         = bl_cal_getHTMLHead();
  var width        = 139;
  var height       = 162;
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  var rightAlign   = true;
  
  if (calendarType == bl_cal_t_time)
  {
    html += bl_cal_getTimeList(el);
    html += bl_cal_createPopupTail('_bl_cal_init_time');
    width =  el.offsetWidth - 5;
    
    if (el.cb_popupWidth > width)
    {
      width = el.cb_popupWidth;
    }
    height       = 100;
    rightAlign   = false;
  }
  else if (calendarType == bl_cal_t_duration)
  {
    html += bl_cal_getDurationList();
    html += bl_cal_createPopupTail('_bl_cal_init_duration');
    width =  el.offsetWidth - 5;
    
    if (el.cb_popupWidth > width)
    {
      width = el.cb_popupWidth;
    }
    height       = 100;
    rightAlign   = false;
  }
  else
  {
    html += bl_cal_computePopup(calendarType, el.getAttribute("bl_style_id"));
    html += bl_cal_createPopupTail('_bl_cal_init_popup');
  }
  
  var alignStr = (rightAlign)? "Right":"Left";
  var argData  = { html:html,
                   customArg:el,
                   x:0,
                   y:0,
                   w:width,
                   h:height,
                   el:el,
                   cleanUp:bl_cal_popupCleanup,
                   controlHAlign:alignStr,
                   canDestroy:true,
                   valid:bl_cal_popup_valid,
                   useVeil:true,
                   positionType:"control"
                 }
  
  
  window.bl_sys_popupInvoke(argData);
  bl_cal_popupButton = item;
  item.setAttribute("bl_selected", true);
  bl_port_killEvent(event);
  bl_sys_img_freeze(item);
}

function bl_cal_parseTime(val)
{
  var dTime = "November 1, 1997 ";
  
  dTime += val;
  return  new Date(Date.parse(dTime));
}

function bl_cal_textChanged(item)
{
  var el           = bl_cal_findElFromItem(item);
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  var oldValue     = item.getAttribute("bl_old_value");
  
  if (oldValue != item.value)
  {
    var val  = item.value.toLowerCase();
    var date = null;
    
    if (calendarType != bl_cal_t_duration)
    {
      if (val == 'today' || val == 'now')
      {
        date = new Date();
      }
      else if (val == 'none')
      {
        date = null;
      }
      else
      {
        var str = item.value;
        var tm  = (calendarType == bl_cal_t_time)? bl_cal_parseTime(str):Date.parse(str);
        
        if (isNaN(tm))
        {
          item.value = oldValue;
          if (calendarType == 'time')
          {
            window.alert("Invalid or incomplete time entered!");
          }
          else
          {
            window.alert("Invalid or incomplete date entered!");
          }
          
          return ;
        }
        else
        {
          date = new Date(tm);
        }
      }
      bl_cal_set_date(el, date);
      el.bl_time_duration = null;
      bl_cal_setPopupText(item, date, calendarType);
    }
    else
    {
      el.setAttribute(bl_cal_durationText, val);
    }
    bl_cal_sendData(el);
  }
}

function _bl_cal_focus_out(event, item)
{
  bl_cal_textChanged(item);
}

function _bl_cal_keyup(event, item)
{
  if (bl_port_keyCode(event) == 40 && bl_cal_popupButton == null)
  {
    var el = bl_cal_findElFromItem(item);
    
    if (parseInt(el.getAttribute("bl_cal_type")) < bl_cal_t_multiple)
    {
      var popupButton = bl_cal_getPopup(el);
      _bl_cal_popup_action(event, popupButton);
    }
  }
}

function _bl_cal_keypressed(event, item)
{
  if (bl_port_keyCode(event) == 13)
  {
    bl_cal_textChanged(item);
  }
}

function _bl_cal_keydown(event, item)
{
  if (cb_sys_disabled(item) && event)
  {
    bl_port_stop_event(event);
  }
}

function bl_cal_disable(el)
{
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));
  
  if (calendarType == bl_cal_t_duration    ||
      calendarType == bl_cal_t_time        ||
      calendarType == bl_cal_t_pop_today   ||
      calendarType == bl_cal_t_pop_none    ||
      calendarType == bl_cal_t_pop_both)
  {
    bl_cal_getPopup(el).setAttribute("disabled", "true");
    bl_cal_getText(el).setAttribute("disabled", "true");
  }
}

function bl_cal_enable(el)
{
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));

  
  if (calendarType == bl_cal_t_duration    ||
      calendarType == bl_cal_t_time        ||
      calendarType == bl_cal_t_pop_today   ||
      calendarType == bl_cal_t_pop_none    ||
      calendarType == bl_cal_t_pop_both)
  {
    bl_cal_getPopup(el).removeAttribute("disabled");
    bl_cal_getText(el).removeAttribute("disabled");
  }
}

function bl_cal_show(el, retainSpace)
{
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));

  if (retainSpace)
  {
    el.style.visibility = "visible";
    if (calendarType == bl_cal_t_duration    ||
        calendarType == bl_cal_t_time        ||
        calendarType == bl_cal_t_pop_today   ||
        calendarType == bl_cal_t_pop_none    ||
        calendarType == bl_cal_t_pop_both)
    {
      bl_cal_getPopup(el).style.visibility = "visible";
      bl_cal_getText(el).style.visibility  = "visible";
    }
  }
  else
  {
    var display = el.getAttribute("bl_display");
    el.style.display = (display)? display:"";
  }

}

function _bl_cal_showHide(el, retainSpace, isHide)
{
  if (isHide)
  {
    bl_cal_hide(el);
  }
  else
  {
    bl_cal_show(el);
  }
}

function bl_cal_hide(el, retainSpace)
{
  var calendarType = parseInt(el.getAttribute("bl_cal_type"));

  if (retainSpace)
  {
    el.style.visibility = "hidden";

    if (calendarType == bl_cal_t_duration    ||
        calendarType == bl_cal_t_time        ||
        calendarType == bl_cal_t_pop_today   ||
        calendarType == bl_cal_t_pop_none    ||
        calendarType == bl_cal_t_pop_both)
    {
      bl_cal_getPopup(el).style.visibility = "hidden";
      bl_cal_getText(el).style.visibility  = "hidden";
    }
  }
  else
  {
    el.style.display = "none";
  }

}

function _bl_cal_resize(el, resizeQueue)
{
  var idim   = Math.max(Math.floor((el.offsetWidth)/bl_cal_width), 1);
  var jdim   = Math.max(Math.floor((el.offsetHeight)/bl_cal_height), 1);
  var cnt    = idim * jdim;
  var id     = el.id;
  var curCnt = el.childNodes.length;
  
  if (curCnt != cnt)
  {
    var currentDate = bl_cal_currentDate(el);
    var curDate     = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1, 0, 0);
    var diff        = cnt - el.childNodes.length;
    var html        = '';
    
    if (curCnt < cnt)
    {
      var curLast = el.lastChild;
      var topCSS  = "overflow:hidden;font-family:tahoma,verdana,sans-serif;font-size:11px;width:136px;height:134px;position:absolute;background-color:";
      var style   = window[el.getAttribute("bl_style_id")];
      
      for (var i = cnt - diff; i < cnt; i++)
      {
        html += bl_cal_create(topCSS, bl_cal_t_multiple, style);
      }
      
      var first = diff == cnt;
      bl_port_insertAdjacentHTML(el, "beforeend", html);
      
      var list = el.childNodes;
      
      if (!first && curLast != null)
      {
        curDate.setFullYear(parseInt(curLast.getAttribute("year")), parseInt(curLast.getAttribute("month")));
        bl_cal_computeDays(el, curLast, curDate, false, false, false, true);
        curDate.setMonth(curDate.getMonth() + 1);
      }
      for (var i = cnt - diff; i < cnt; i++)
      {
        var ch = list[i];
        bl_cal_computeDays(el, ch, curDate, first, (i == cnt - 1), false, false);
        curDate.setMonth(curDate.getMonth() + 1);
        first = false;
      }
    }
    else
    {
      while (diff < 0)
      {
        el.removeChild(el.lastChild);
        diff++;
      }
      if (el.lastChild != null)
      {
        var cal = el.lastChild;
        curDate.setFullYear(parseInt(cal.getAttribute("year")), parseInt(cal.getAttribute("month")));
        bl_cal_computeDays(el, el.lastChild, curDate, false, true, false, false);
      }
    }
    bl_cal_positionCals(el, idim, jdim);
    bl_cal_computeRange(el);
  }
  else
  {
    if (el.firstChild != null &&
        (bl_sys_real_x(el, null, true) != el.firstChild.offsetLeft || bl_sys_real_y(el, null, true) != el.firstChild.offsetTop))
    {
      bl_cal_positionCals(el, idim, jdim);
    }
  }
  el.oldWidth  = el.offsetWidth;
  el.oldHeight = el.offsetHeight;
}

function bl_cal_proc(mon, rep)
{
  if (mon != rep)
  {
    if (mon)
    {
      mon.bl_mouseIsDown  = false;
      mon.bl_mouseIsIn    = false;
      cb_sys_img_buildSrc(mon, "en");
      mon.style.visibility = "hidden";
    }
    rep.style.visibility = "visible";
  }
  return rep;
}

function bl_cal_positionCals(el, idim, jdim)
{
  var iwidth  = idim * bl_cal_width;
  var jheight = jdim * bl_cal_height;
  var idif    = el.offsetWidth - iwidth;
  var jdif    = el.offsetHeight - jheight;
  var x0      = Math.floor(idif/2);
  var x       = x0;
  var y       = Math.floor(jdif/2);
  var right   = x0 + iwidth;
  
  if (el.firstChild != null && el.lastChild != null)
  {
    el.blDMonth = bl_cal_proc(el.blDMonth, el.firstChild.blDMonth);
    el.blIMonth = bl_cal_proc(el.blIMonth, el.childNodes[idim - 1].blIMonth);
    el.blDYear  = bl_cal_proc(el.blDYear, el.childNodes[el.childNodes.length - idim].blDYear);
    el.blIYear  = bl_cal_proc(el.blIYear, el.lastChild.blIYear);
  }
  
  for (var ch = el.firstChild; ch != null; ch = ch.nextSibling)
  {
    ch.style.left = x+"px";
    ch.style.top  = y+"px";
    x += bl_cal_width;
    if ((x + bl_cal_width) > right)
    {
      x = x0;
      y += bl_cal_height;
    }
  }
}

function _bl_cal_pop_resize(el, event)
{
  var width = el.cbLastWidth;
  
  if (width == undefined || width != el.offsetWidth)
  {
    el.firstChild.style.width = (width - el.lastChild.offsetWidth)+"px";
    el.cbLastWidth = width;
  }
}

function bl_cal_modify(el, data)
{
  if (el && data)
  {
    var node = data.firstChild;
    
    while (node != null)
    {
      var valList = bl_port_get_text(node).split(" ");
      
      if (node.nodeName == "RD")
      {
        bl_cal_removeHilight(el, bl_port_get_text(node));
      }
      else
      {
        bl_cal_addHilight(el, bl_port_get_text(node));
      }
      node = node.nextSibling;
    }
  }
}

function bl_cal_isDaySelected(month, day)
{
  return (this.months[month][day] == true);
}

function bl_cal_setValue(month, day, val)
{
  this.months[month][day] = val;
}


function bl_cal_clearData(list)
{
  for (var i = 0; i < 31; i++)
  {
    list[i] = false;
  }
  return list;
}

function bl_cal_clearYearData()
{
  var mns    = this.months;
  
  this.year  = 0;
  for (var i = 0; i < 12; i++)
  {
    bl_cal_clearData(mns[i]);
  }
}

function bl_cal_createDataLookup()
{
  this.months = new Array(bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)), 
                          bl_cal_clearData(new Array(31)));
  this.isSet    = bl_cal_isDaySelected;
  this.setValue = bl_cal_setValue;
  this.clear    = bl_cal_clearYearData;
  this.year     = 0;
}

function bl_cal_getYear(year, create)
{
  var item  = null;
  var list  = this.list;
  var len   = this.newItemIndex;
  for (var i = 0; i < len; i++)
  {
    if (list[i].year == year)
    {
      item = list[i];
      break;
    }
  }
  if (item == null && create)
  {
    if (len >= list.length)
    {
      item = new bl_cal_createDataLookup();
      list.push(item);
    }
    else
    {
      item = list[len];
    }
    this.newItemIndex++;
    item.year = year;
  }
  return item;
}

function bl_cal_clearHiliteData()
{
  var lst           = this.list;
  var len           = lst.length;
  this.newItemIndex = 0;
  for (var i = 0; i < len; i++)
  {
    lst[i].clear();
  }
}

function bl_cal_addDateData(val)
{
  var valList = val.split(" ");
  var item    = this.getYear(parseInt(valList[0]), true);
  item.setValue(parseInt(valList[1]), parseInt(valList[2]), true);
}

function bl_cal_removeDateData(val)
{
  var valList = val.split(" ");
  var item    = this.getYear(parseInt(valList[0]), false);
  
  if (item)
  {
    item.setValue(parseInt(valList[1]), parseInt(valList[2]), false);
  }
}

function bl_cal_createHiliteData()
{
  this.list = new Array(new bl_cal_createDataLookup(), 
                        new bl_cal_createDataLookup(), 
                        new bl_cal_createDataLookup());
  this.newItemIndex = 0;
  this.getYear      = bl_cal_getYear;
  this.clear        = bl_cal_clearHiliteData;
  this.addDate      = bl_cal_addDateData;
  this.removeDate   = bl_cal_removeDateData;
}

function bl_cal_hiliteData(el)
{
  var ret = el.cbHilites;
  
  if (!ret)
  {
    el.cbHilites = ret = new bl_cal_createHiliteData();
  }
  
  return ret;
}

function bl_cal_loadXML(el, xmlData, hilightData)
{
  if (el && hilightData && xmlData)
  {
    hilightData.clear();
    
    var node = xmlData.firstChild;
    
    while (node != null)
    {
      hilightData.addDate(bl_port_get_text(node));
      node = node.nextSibling;
    }
  }
}

function bl_cal_setSelect(el, item, val)
{
  var context = bl_cal_computeContext(el, parseInt(item.getAttribute("bl_it")));
  var wasSelected = (item.getAttribute("bl_selected") != null);
  
  if (val != wasSelected)
  {
    if (val)
    {
      item.setAttribute("bl_selected","true");
      bl_cal_setCSS(item, context.downCSS, context.h_downCSS);
    }
    else
    {
      item.removeAttribute("bl_selected");
      bl_cal_setCSS(item, context.mainCSS, context.h_mainCSS);
    }
  }
}

function bl_cal_setActive(el, item)
{
  var context = bl_cal_computeContext(el, parseInt(item.getAttribute("bl_it")));
  if (item && context && !item.getAttribute("disabled"))
  {
    item.bl_mouseIsIn = true;
    if (item.bl_mouseIsDown)
    {
      if (bl_port_hasAttribute(item,"bl_selected"))
      {
        bl_cal_setCSS(item, context.downdownCSS, context.h_downdownCSS);
      }
      else
      {
        bl_cal_setCSS(item, context.downActiveCSS, context.h_downActiveCSS);
      }
    }
    else
    {
      if (bl_port_hasAttribute(item,"bl_selected"))
      {
        bl_cal_setCSS(item, context.downActiveCSS, context.h_downActiveCSS);
      }
      else
      {
        bl_cal_setCSS(item, context.mainActiveCSS, context.h_mainActiveCSS);
      }
    }
  }
}

function _bl_cal_text_enter(event, item)
{
  var target = bl_port_getEventTarget(event);
  
  if (target == item)
  {
    with (bl_port_offsetToItem(event, target))
    {
      if (x >= -1 && y >= -1 && x <= item.offsetWidth && y <= item.offsetHeight)
      {
        var el = bl_cal_findElFromItem(item);
        
        if (!el.bl_inMonthSelect)
        {
          bl_cal_setActive(el, item);
        }
      }
    }
  }
}

function _bl_cal_text_leave(event, item)
{
  item = bl_port_computeEventElEXE(item);

  var context = bl_cal_computeContext(bl_cal_findElFromItem(item), parseInt(item.getAttribute("bl_it")));
  
  if (context)
  {
    item.bl_mouseIsIn = false;
    if (item.bl_mouseIsDown)
    {
      if (item.getAttribute("bl_selected") != null)
      {
        bl_cal_setCSS(item, context.downActiveCSS, context.h_downActiveCSS);
      }
      else
      {
        bl_cal_setCSS(item, context.mainActiveCSS, context.h_mainActiveCSS);
      }
    }
    else
    {
      if (item.getAttribute("bl_selected") != null)
      {
        bl_cal_setCSS(item, context.downCSS, context.h_downCSS);
      }
      else
      {
        bl_cal_setCSS(item, context.mainCSS, context.h_mainCSS);
      }
    }
  }
}

function _bl_cal_text_up(event, item)
{
  item = bl_port_computeEventElEXE(item);
  item.bl_mouseIsDown = false;
  
  var el      = bl_cal_findElFromItem(item);
  var type    = parseInt(item.getAttribute("bl_it"));
  var context = bl_cal_computeContext(el, type);
  
  if (context)
  {
    if (item.bl_mouseIsIn)
    {
      var resetClass = true;
      if (context.action)
      {
        var calType = parseInt(el.getAttribute("bl_cal_type"));
        
        context.action(el, item);
        resetClass = (!type || calType == bl_cal_t_todayIn || calType == bl_cal_t_monthIn)
      }
      
      if (resetClass)
      {
        if (item.getAttribute("bl_selected") != null)
        {
          bl_cal_setCSS(item, context.downActiveCSS, context.h_downActiveCSS);
        }
        else if (type == bl_cal_t_monthLess || type == bl_cal_t_monthMore)
        {
          bl_cal_setCSS(item, context.mainCSS, context.h_mainCSS);
        }
        else
        {
          bl_cal_setCSS(item, context.mainActiveCSS, context.h_mainActiveCSS);
        }
      }
    }
    else
    {
      if (context.restoreAction)
      {
        context.restoreAction(el, item);
      }

      if (item.getAttribute("bl_selected") != null)
      {
        bl_cal_setCSS(item, context.downCSS, context.h_downCSS);
      }
      else
      {
        bl_cal_setCSS(item, context.mainCSS, context.h_mainCSS);
      }
    }
  }
  bl_port_releaseCapture(item);
  bl_port_killEvent(event);
}

function _bl_cal_text_down(event, item)
{
  var el         = bl_cal_findElFromItem(item);
  var context    = bl_cal_computeContext(el, parseInt(item.getAttribute("bl_it")));
  
  if (context)
  {
    var isSelected = (item.getAttribute("bl_selected") != null);
    
    item.bl_mouseIsDown = true;

    if (isSelected)
    {
      bl_cal_setCSS(item, context.downdownCSS, context.h_downdownCSS);
    }
    else
    {
      bl_cal_setCSS(item, context.downActiveCSS, context.h_downActiveCSS);
    }
    
    if (isSelected || !context.downAction || context.downAction(el, item))
    {
      bl_port_setCapture(item);
    }
    else
    {
      bl_port_killEvent(event);
    }
  }
}

function bl_cal_getHTMLHead()
{
  if (this.popupHead == undefined)
  {
    this.popupHead = '<script language="javascript">window.bl_version="'
                    + bl_version 
                    + '"; window.bl_isCalPopup = true; document.body.bgColor="#ffffff"; window.onclick=\"_bl_sys_popupClose();\";</script>';
  }
  
  return this.popupHead;
}

function bl_cal_durationText(el)
{
  var text = el.getAttribute("bl_cal_durationText");
  if (!text)
  {
    text = "0";
  }
  return text;
}

function bl_cal_selectList(el)
{
  if (!el.cbSelectList)
  {
    el.cbSelectList = new Array();
  }
  return el.cbSelectList;
}

function bl_cal_currentDate(el)
{
  if (!el.blCurrentDate)
  {
    var type = parseInt(el.getAttribute("bl_cal_type"));
    el.blCurrentDate = new Date();
    
    if (type >= bl_cal_t_multiple)
    {
      var date   = bl_cal_date(el);
      var fchild = null;
      
      if (type == bl_cal_t_in_today ||
          type == bl_cal_t_in_none  ||
          type == bl_cal_t_in_both  ||
          type == bl_cal_t_multiple)
      {
        fchild = el.firstChild;
      }
      
      
      if (fchild)
      {
        bl_cal_setFullYear(el.blCurrentDate, parseInt(fchild.getAttribute("year")), parseInt(fchild.getAttribute("month")), 1);
      }
      else if (date != null)
      {
        bl_cal_setFullYear(el.blCurrentDate, date.getFullYear(), date.getMonth(), 1);
      }
      else
      {
        bl_cal_setFullYear(el.blCurrentDate, el.blCurrentDate.getFullYear(), el.blCurrentDate.getMonth(), 1);
      }
    }
    else
    {
      bl_cal_setFullYear(el.blCurrentDate, el.blCurrentDate.getFullYear(), el.blCurrentDate.getMonth(), 1);
    }
  }
  return el.blCurrentDate;
}

function bl_cal_set_date(el, date)
{
  el.bl_date_val    = date;
  el.bl_date_inited = true;
  return date;
}

function bl_cal_date(el)
{
  if (!el.bl_date_inited)
  {
    var calendarType = parseInt(el.getAttribute("bl_cal_type"));
    
    el.bl_date_val   = bl_cal_setDate(el.getAttribute("bl_date"), calendarType);
    
    if (el.bl_date_val && calendarType == bl_cal_t_time)
    {
      el.oldHour = el.bl_date_val.getHours();
      el.oldMin  = el.bl_date_val.getMinutes();
    }
    el.bl_date_inited = true;
  }
  
  return el.bl_date_val;
}

function bl_cal_getPopupChild()
{
  return document.getElementById("blCalPopId");
}


// this is to be called from generated script.
function _bl_cal_init_popup()
{
  var top = cb_sys_getTopWindow();

  var el = bl_sys_getMyPopupArg().customArg;

  // must init before doing anything
  bl_cal_initElement(el);
  
  var styleId = el.getAttribute("bl_style_id");
  
  window[styleId] = bl_sys_popupParent()[styleId];
  
  el.bl_cal          = bl_cal_getPopupChild().firstChild;
  el.bl_cal.blInited = false;
  bl_cal_computeDays(el, el.bl_cal, bl_cal_currentDate(el), true, true, false, false);
  bl_cal_clearOldSelect(el);
  bl_cal_computeSelection(el);
  _bl_sys_clearInputBlocker();
}

function _bl_cal_init_duration()
{
  var el         = bl_sys_getMyPopupArg().customArg;
  var v          = bl_cal_getPopupChild();
  v.bl_cal_curEl = el;
  bl_cal_selectDuration(v, el);
  selectedItem.scrollIntoView(true);
  bl_port_focus(selectedItem);
  selectedItem.hideFocus = false;
  _bl_sys_clearInputBlocker();
}

function _bl_cal_init_time()
{
  var el                 = bl_sys_getMyPopupArg().customArg;
  var v                  = bl_cal_getPopupChild();
  v.bl_cal_curEl         = el;
  bl_cal_selectTime(v, el);
  var selectedItem       = v.firstChild.selectedItem;
  selectedItem.scrollIntoView(true);
  bl_port_focus(selectedItem);
  selectedItem.hideFocus = false;
  _bl_sys_clearInputBlocker();
}

function _bl_cal_init_ms()
{
  var arg   = bl_sys_getMyPopupArg();
  var el    = arg.customArg;
  var ms    = bl_cal_getPopupChild();
  var item  = el.bl_current_monthItem;
  var month = parseInt(item.getAttribute("month")) - 3;
  var year  = parseInt(item.getAttribute("year"));
  
  ms.curMonthEdit = item;
  ms.curEl        = el;
  ms.speed        = -1;

  if (month < 0)
  {
    month = 12 + month;
    year--;
  }
  bl_cal_adjustMonths(month, year, true);
  _bl_sys_clearInputBlocker();
  arg.isReady = true;
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_cal_last()
{
  var x = 0;
}

function _bl_ce_handler(item, el)
{
  var val = item.firstChild;
  if (val.nodeName == "value")
  {
    var text = bl_port_get_text(val);
    bl_ce_setText(el,text);
  }
  else if (!el.isDisabled && val.nodeName == "triggerSelect")
  {
  }
  else if (val.nodeName == "default_text")
  {
  }
}

function bl_ce_setText(el,text)
{
  if (bl_port_hasAttribute(el,"bl_editorReady"))
  {
    el.contentWindow._bl_ce_pushToFlash(text);
  }
  else
  {
    el.setAttribute("bl_text",text);
  }
}

function _bl_ce_editorReady(el)
{
  el.setAttribute("bl_editorReady","true");
  if (bl_port_hasAttribute(el,"bl_text"))
  {
    var text = el.getAttribute("bl_text");
    el.removeAttribute("bl_text");
    bl_ce_setText(el,text);
  }
}

function _bl_ce_sendToServer(el,text)
{
  var send = true;

  if (send)
  {
    // set the old value here to ensure that the next time
    // we enter this function they will equal if there was
    // no user interation.  otherwise we will send twice.
    
    var xmlStr = "";
    if (text.indexOf("]]") == -1)
    {
      // Much more efficient, but we can only do this if there's not closing
      // CDATA symbol (because CDATA sections cannot be nested). It makes sense
      // to do this for potentially large strings, but most small strings can
      // just be encoded quickly.
      xmlStr = "<changed><value><![CDATA[" + text + "]]></value></changed>";
    }
    else
    {
      // Less efficient but guantees the data will not break the XML document.
      xmlStr = "<changed><value>"+bl_port_encodeXml(text)+"</value></changed>";
    }
    
    // send the data to the server
    bl_mpr_send(xmlStr, el.id, 0, bl_sys_readSendType(el));
  }

}

function _bl_ce_sendLinkNavigate(el,lineIndex,lineText)
{
  var xmlStr = "<linknavigate index='"+lineIndex+"'>"+parent.bl_port_encodeXml(lineText)+"</linknavigate>";
  bl_mpr_send(xmlStr, el.id, 0, bl_sys_readSendType(el));
}

function _bl_color_move(event, el)
{
  var srcEl = bl_port_getEventTarget(event);
  if (srcEl.tagName == "TD")
  {
    if (el.bl_oldElement)
    {
      with (el.bl_oldElement.parentNode)
      {
        bl_port_setBGColor(style, "#FFFFFF");
        lastChild.style.color = "#000000";
      }
    }
    
    var bgColor = srcEl.getAttribute("bgColor");

    if (!bgColor)
    {
      if (srcEl.lastChild.firstChild)
      {
        bgColor = srcEl.lastChild.firstChild.firstChild.getAttribute("bgColor");
      }
      
      if (!bgColor && srcEl.previousSibling)
      {
        bgColor = srcEl.previousSibling.getAttribute("bgColor");
      }
    }
    
    var color = (bgColor == "#00ff00" || bgColor == "#ffff00" || bgColor == "#00ffff")? "#000000":"#FFFFFF";

    with (el.bl_oldElement.parentNode)
    {
      bl_port_setBGColor(style, bgColor);
      lastChild.style.color = color;
    }
        
    el.bl_oldElement = srcEl;
  }
}

function _bl_color_clicked(event, el)
{
  // Setup the string to send to the server
  var srcEl = bl_port_getEventTarget(event);
  var color = srcEl.getAttribute("bgColor");
  
  if (!color)
  {
    color = srcEl.previousSibling.getAttribute("bgColor");
  }
  
  if (color != "" && color != null)
  {
    var xmlStr = "<colorChanged>" + color + "</colorChanged>";
    
    if (elength.getAttribute("BigPicker") != null)
    {
      bl_setColorProperties(el, color);
    }
    
    bl_mpr_send(xmlStr, el.id, -1, bl_sys_readSendType(el));
  }
}

function bl_setColorProperties(el, color)
{
  bl_port_setBGColor(bl_get_colorWell(el).style, color);
  bl_colorInput(el).value = color;
}

function bl_get_colorWell(el)
{
  return el.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild;
}

function bl_colorInput(el)
{
  return el.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.firstChild.childNodes[1].firstChild;
}

function no_cb_color_handler(item, element)
{
  var el = item.firstChild;
  if (el.nodeName == "colorChanged")
  {
    var parentID = el.firstChild;
    var element  = document.getElementById(bl_port_get_text(parentID));
    var color    = bl_port_get_text(el.childNodes.item(1));
    
    bl_set_color_picker_properties(element, color);
  }
}


//***********************************************************************
//***********************************************************************
//********                    bl_controls.js                    *********
//***********************************************************************
//***********************************************************************

function cb_control_getBuddy(el)
{
  while (el && !el.buddyEl)
  {
    el = el.parentNode;
  }
  return (el ? el.buddyEl : null);
}

function cb_control_findChildBuddy(curEl, buddy)
{
  if (curEl.id == buddy)
  {
    return curEl;
  }
  
  var fChild = curEl.firstChild;
  
  while (fChild)
  {
    var bel = cb_control_findChildBuddy(fChild, buddy);
    
    if (bel)
    {
      return bel;
    }
    fChild = fChild.nextSibling;
  }
  
  return null;
}

function cb_control_findBuddyInParent(curEl, parentEl, buddy)
{
  if (buddy == undefined)
  {
    return null;
  }
  
  var bel = null;
  
  if (parentEl)
  {
    if (parentEl.id == buddy)
    {
      return parentEl;
    }
    
    var fChild = parentEl.firstChild
    while (fChild)
    {
      if (fChild != curEl)
      {
        bel = cb_control_findChildBuddy(fChild, buddy);
        if (bel)
        {
          return bel;
        }
      }
      fChild = fChild.nextSibling;
    }
    
    bel = cb_control_findBuddyInParent(parentEl, parentEl.parentNode, buddy)
  }
  
  return bel;
}

function _bl_sys_funcBuddyInit(id, buddy)
{
  var el  = document.getElementById(id);
  var col = document.all;
  
  if (el && buddy)
  {
    var len      = document.all.length;
    var buddyCol = null;
    for (var i = 0; i < len; i++)
    {
      var item = document.all[i];
      var cb_buddy_id = item.getAttribute("cb_buddy_id");
      
      if (item && cb_buddy_id && item.getAttribute("cb_buddy_func") != null)
      {
        var buddyList = cb_buddy_id.split(' ');
        for (var j = 0; j < buddyList.length; j++)
        {
          if (buddyList[j] == buddy)
          {
            if (!buddyCol)
            {
              buddyCol = new Array();
            }
            buddyCol.push(item);
          }
        }
      }
    }
    if (buddyCol)
    {
      el.buddyExecutionList = buddyCol;
      bl_sys_addCleanUpCall(el, no_cb_control_cleanup_buddy);
    }
  }
}

function no_cb_control_cleanup_buddy(el)
{
  var bel = el.buddyEl;
  if (bel)
  {
    bel.buddyEl  = null;
    el.buddyEl   = null;
  }
  if (el.buddyExecutionList)
  {
    el.buddyExecutionList = null;
  }
}

function _bl_sound_handler(item, el)
{
  var cmd = item.firstChild;
  
  if (cmd.nodeName == "pingSound")
  {
    if (bl_port_hasAttribute(el, "bl_toFront"))
    {
      bl_port_focus(window);
    }
    
    el.src = bl_port_get_text(cmd);
  }
}

// Form Editing ....

function _bl_layout_handler(item, el)
{
  var cmd       = item.firstChild;
  var ctype     = el.getAttribute("cb_tag");
  
  if (ctype == "FER")
  {
    if (el.getAttribute("bl_isPage"))
    {
      el.contentWindow.bl_page_handleMessage(item, cmd.nodeName, cmd);
    }
    else
    { 
      el.contentWindow.bl_contain_handleMessage(item, cmd.nodeName, cmd, null);
    }
  }
  else
  {
    window.bl_contain_handleMessage(item, cmd.nodeName, cmd, el);
  }
}

function bl_de_sendMessage(el, msg)
{
  var id       = el.id;
  var realMsg  = msg
  var rowId    = el.getAttribute("bl_rowId");
  
  if (rowId)
  {
    var idList = id.split(".");
    realMsg = "<cellChange><row>" 
            + rowId 
            + "</row><col>"  
            + idList[1] 
            + "</col>" 
            + msg 
            + "</cellChange>";
    id = idList[0];
  }
  
  bl_mpr_send(realMsg, id, -1, bl_sys_readSendType(el));
}

function _bl_de_select(event, item)
{
  var msg = "<select><index>" + item.selectedIndex + "</index></select>";
  bl_de_sendMessage(item.parentNode, msg);
}

function _bl_de_changed(event, item)
{
  var val = item.value;
  
  if (val != item.getAttribute("bl_old_val"))
  {
    item.setAttribute("bl_old_val", val);
    
    var msg = "<changed><value><![CDATA[" + val + "]]></value></changed>";
    
    bl_de_sendMessage(item.parentNode, msg);
  }
}

function _bl_de_pressed(event, item)
{
  if (bl_port_keyCode(event) == 13)
  {
    _bl_de_changed(event, item);
  }
}

function _bl_de_handler(item, el)
{
  var val = item.firstChild;
  
  if (val.nodeName == "value")
  {
    el.innerHTML = bl_port_get_text(val);
    bl_sys_procInitTags(val);
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_controls_last()
{
  var x = 0;
}

// JScript source code

//***********************************************************************
//***********************************************************************
//********                  bl_dfl.js                           *********
//***********************************************************************
//***********************************************************************
function bl_dfl_cleanup(el)
{
  try
  {
    if (el.selectMgr)
    {
      var selMgr          = el.selectMgr;
      selMgr.sigSelect    = null;
      
      delete selMgr.list;
      selMgr.list         = null;
      
      delete selMgr;
      el.selectMgr        = null;
    }
  }
  catch (exception)
  {
  }
}

function bl_dfl_inlineChanged(el)
{
  var mgr = this.selectMgr;
  if (mgr)
  {
    var row   = mgr.findRow(this, el);
    if (cb_sel_isSelected(row))
    {
      bl_sel_selectRow(this, row);
    }
  }
}

function bl_dfl_selectChild(child, saveOff, textColor)
{
  var cb_tag = child.getAttribute("cb_tag");
  if (child.tagName != "INPUT" && cb_tag != "List")
  {
    var list  = child.childNodes;
    var len   = list.length;
    
    if (saveOff)
    {
      var color = child.style.color; 
     
      if (color == "" || color != textColor)
      {
        if (child.bl_oldColor == undefined)
        {
          child.bl_oldColor  = color;
        }
        child.style.color  = textColor;
      }
    }
    else
    {
      if (child.bl_oldColor != undefined)
      {
        child.style.color = child.bl_oldColor;
      }
    }

    for (var i = 0; i < len; i++)
    {
      if (list[i].nodeType != 3 || (bl_browserInfo.firefox && list[i].nodeType != Node.TEXT_NODE))
      {
        // Firefox branch to use the constant "Node.TEXT_NODE" rather than the magic number 3.
        // WARNING: If "Node.TEXT_NODE" is ever NOT 3, in firefox, this branch will be executed for ALL nodes,
        // For example, if Node.TEXT_NODE == 4, the test will effectively be:
        //  if( nodeType != 3 || nodeType != 4)
        bl_dfl_selectChild(list[i], saveOff, textColor);
      }
    }
  }
}

function bl_dfl_getSelect(el)
{
  var child = el;
  if (child && !bl_port_isTextNode(child) && child.getAttribute("bl_useInSelect") != null)
  {
    return child;
  }
  else if (!cb_sys_isInput(child))
  {
    var children = child.childNodes;
    var len      = children.length;
    for (var i = 0; i < len; i++)
    {
      var ch = bl_dfl_getSelect(children[i]);
      if (ch)
      {
        return ch;
      }
    }
  }
  return null;
}

function bl_dfl_selectInChildren(row, text)
{
  var metaChild = bl_dfl_getSelect(row);
  var child     = (metaChild ? metaChild : row);
  if (child)
  {
    bl_dfl_doSelectAction(child, text);
    
    // we want to save off if the text is null
    bl_dfl_selectChild(child, (text != null), child.style.color);
  }
}

function bl_dfl_doSelectAction(row, text)
{
  if (row.bl_orig_css == undefined)
  {
    row.bl_orig_css = row.style.cssText;
  }
  
  var style  = row.style;
  var left   = style.left;
  var top    = style.top;
  var width  = style.width;
  var height = style.height;
  
  if (text != null)
  {
    var stickStyles = row.getAttribute("bl_selectText");
    
    if (stickStyles == null)
    {
      stickStyles = "";
    }
    
    style.cssText = text + stickStyles;
  }
  else
  {
    style.cssText = row.bl_orig_css;
  }

  if (left != "")
  {
    style.left   = left;
  }
  if (top != "")
  {
    style.top   = top;
  }
  if (width != "")
  {
    style.width   = width;
  }
  if (height != "")
  {
    style.height   = height;
  }
}

function bl_dfl_itemSelected(el, row, selected, active, flyover, concretSelect)
{
  if (concretSelect)
  {
    cb_sys_popup_close(false);
  }
  
  var text = null;

  if (flyover)
  {
    text = (selected)? el.getAttribute('bl_sel_st'):el.getAttribute('bl_sel_f_st');
  }
  else if (selected)
  {
    text = (active)? el.getAttribute('bl_sel_st'):el.getAttribute('bl_sel_d_st');
  }
  
  if (el.getAttribute("bl_selectInChilren") != null)
  {
    bl_dfl_selectInChildren(row, text);
  }
  else
  {
    bl_dfl_doSelectAction(row, text)
  }
}

function _bl_dfl_init(id, sig, sel, ism, rem, clo)
{
  var el = document.getElementById(id);
  if (el)
  {
    el.bl_inlineChanged = bl_dfl_inlineChanged;
    
    var layoutType  = bl_contain_getLayout(el).type;

    if (layoutType == bl_contain_type_2dHorizontal || 
        layoutType == bl_contain_type_2dVertical)
    {
      el.bl_visibleCount = bl_dfl_visibleCount;
      el.bl_stepStart    = bl_dfl_stepStart;
    }
    
    var mgr = new bl_sel_createMgr(el, 
                                   sig, 
                                   sel, 
                                   ism, 
                                   rem, 
                                   clo, 
                                   bl_dfl_rowIndex,
                                   bl_dfl_row,
                                   bl_dfl_findRow,
                                   null,
                                   bl_dfl_mouseDown,
                                   bl_dfl_itemSelected,
                                   bl_dfl_getLength,
                                   (el.getAttribute("bl_out_margin") != null ? bl_dfl_getMargin : null));

    bl_sys_addCleanUpCall(el, bl_dfl_cleanup);
  
    setTimeout("_bl_dfl_initialResize('"+id+"')",1);
  }
}

function _bl_dfl_initialResize(id)
{
  var el = document.getElementById(id);
  if (el)
  {
    // Attempt to resize this on the client. Only resize this directly if all 
    // parent DFL's have already been initialized. This is a quick patch for
    // bug #3815.
    el.bl_initted   = true;

    var needsResize = true;
    var node        = el;
    
    while ((node = node.parentNode) && (node.nodeType == 1))
    {
      if (node.getAttribute("cb_tag") == "DFL")
      {
        if (!el.bl_initted)
        {
          needsResize = false;
        }
        break;
      }
    }
    if (needsResize)
    {
      try
      {
        bl_contain_layoutContainer(el, false);
      }
      catch(E)
      {
        // Ignore this error. Sometimes an element may not be completely initialized which throws an exception.
      }
    }
  }
}

function bl_dfl_getMargin(el, outside)
{
  if (outside)
  {
    return parseInt(el.getAttribute("bl_out_margin"));
  }
  return parseInt(el.getAttribute("bl_in_margin"));
}

function bl_dfl_findRow(el, src)
{
  var layout = bl_contain_getLayout(el);
  return layout.findChild(el, src);
}

function bl_dfl_rowIndex(el, row)
{
  var layout = bl_contain_getLayout(el);
  return layout.getChildIndex(el, row);
}

function bl_dfl_row(el, index)
{
  var layout = bl_contain_getLayout(el);
  return layout.getChild(el, index);
}

function bl_dfl_dblclk(event, el)
{
  if (!bl_dfl_findRow(el, bl_port_getEventTarget(event)))
  {
    el.selectMgr.selectAll(el.selectMgr, true);
    bl_port_stop_event(event);
  }
  else
  {
    _bl_sel_dbl_clk(event, el);
  }
}

function bl_dfl_mouseDown(event, el)
{
  if (!el.isDisabled)
  {
    var target = bl_port_getEventTarget(event);
    
    if (!bl_dfl_findRow(el, target))
    {
      // focus added because a click on the 'white space' didn't
      // cause the Notes textarea onblur to fire.Nothing was receiving focus.
      bl_port_focus(el);
      
      if (!bl_port_point_on_scrollbar(target, event.clientX, event.clientY))
      {
        if (el.getAttribute("bl_noEmptySelect") == null)
        {
          window.setTimeout("_bl_sel_sendDeselectAll('" + el.id + "')", 50);
        }
      }
    }
  }
}

function bl_dfl_getLength(el)
{
  var layout = bl_contain_getLayout(el);
  return layout.numChildren(el);
}

function bl_dfl_stepStart(stepDown, dispStart)
{
  var step = parseInt(this.getAttribute("bl_stepDownStart"));
  return (stepDown ? dispStart + step : dispStart - step);
}

function bl_dfl_visibleCount(el)
{
  return parseInt(el.getAttribute("bl_visibleCount"));
}

function bl_dfl_removeIndex(el, index, last)
{
  var layout = bl_contain_getLayout(el);
  layout.removeChild(el, index);
}

function bl_dfl_setItem(el, cmd)
{
  var index = parseInt(bl_port_get_text(cmd.childNodes.item(0)));
  bl_dfl_removeIndex(el, index, true);
  bl_dfl_insertItem(el, cmd);
  return index;
}

function bl_dfl_findContext(cmd)
{
  var list = cmd.childNodes;
  var i    = list.length - 1;
  
  for (var i = list.length - 1; i >=0; i--)
  {
    var obj = list.item(i);
    
    if (obj.nodeName == "context")
    {
      return bl_port_get_text(obj);
    }
  }
  
  return null;
}

function bl_dfl_insertItem(el, cmd)
{
  // account for the artifact bag that is always generated to the container
  var index   = parseInt(bl_port_get_text(cmd.childNodes.item(0)));
  var payload = cmd.childNodes.item(1);
  var context = bl_dfl_findContext(cmd);
  var layout  = bl_contain_getLayout(el);
  var newEl   = layout.addChild(el, index, bl_port_get_text(payload), context);
  
  bl_sys_procInitTags(payload);
  
  return index;
}

function bl_dfl_move(el, oldIndex, newIndex)
{
  var layout = bl_contain_getLayout(el);
  return layout.moveChild(el, oldIndex, newIndex);
}

function _bl_dfl_handler(itemNode, el)
{
  var cmd  = itemNode.childNodes.item(0);
  var name = cmd.nodeName;
  
  if (name == "setSizes")
  {
    _bl_layout_handler(itemNode, el);
  }
  else if (name == "removeAll")
  {
    var layout = bl_contain_getLayout(el);
    return layout.removeAll(el);
  }
  else if (name == "invalidate")
  {
    bl_sel_invalidate(el, cmd);
  }

  // bl_sel_handler return true ifthe geometry needs to be pinged  
  if (bl_sel_handler(el, name, cmd, bl_dfl_removeIndex, bl_dfl_insertItem, bl_dfl_setItem, bl_dfl_move))
  {
    bl_dfl_pingLayout(el);
  }
}

function bl_dfl_pingLayout(el)
{
  el.currentPositionWidth   = 0;
  el.currentPositionHeight  = 0;
  bl_contain_layoutContainer(el, true)
}

// This function looks up the hierarchy of elements and notifies
// any dynamic forms controls that a child element has been selected.
function bl_dfl_notifyInnerSelect(childEl)
{
  var parentEl = bl_port_findTrueParent(childEl);
  while (parentEl)
  {
    if (parentEl.getAttribute("cb_tag") == "DFL")
    {
      // TODO: Before doing a select, make sure the selection is valid?
      var mgr   = parentEl.selectMgr;
      var index = mgr.computeRowIndex(parentEl, childEl);
      if (!cb_sel_isSelected(childEl))
      {
        bl_sel_selectRows(mgr, ""+index, true, true, true);
      }  
    }
    childEl  = parentEl;
    parentEl = bl_port_findTrueParent(parentEl);
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_dfl_last()
{
}

function _bl_edit_keyupTimer(id, timer)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    if (el.cb_keyup_timer == timer)
    {
      _bl_edit_changed(null, el, false);
    }
  }
}

function _bl_sys_doSelect(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    if (bl_browserInfo.firefox)
    {
      if (el.selectionStart == el.selectionEnd)
      {
        // For firefox, the element should only be selected if it is
        // not already selected. Otherwise a toggle effect can ensue.
        // TODO: Make this a port function?
        el.select();
      }
    }
    else
    {
      el.select();
    }
  }
}

function _bl_sys_focusin(event, el)
{
  // This timeout is here because most browsers do some automatic selection
  // during the mouseup event, but the focusin happens on the mousedown event.
  // If this timeout happens *after* the mouseup occurs, the function will work
  // correctly. However, if it happens *before* the mouseup, there is a fair
  // chance the text will not be properly selected.
  window.setTimeout("_bl_sys_doSelect(" + el.id + ")", 100);
  bl_port_killEvent(event);
}

function _bl_edit_keydown(event, el)
{
  var vk = event.virtualKey;
  if (vk == "left" || vk == "right" || vk == "home" || vk == "end" || vk == "del" || vk == "bksp")
  {
    event.allowShortcuts = false;
    bl_port_stopPropagation(event);
  }
  else if (vk == "enter")
  {
    if (bl_port_hasAttribute(el,"bl_cancelEnter") && el.value != el.getAttribute("bl_old_val"))
    {
      event.allowShortcuts = false;
      bl_port_stopPropagation(event);
    }
    
    _bl_edit_changed(event, el, false);
  }
}

function _bl_edit_keyup(event, el)
{
  var keyDelay = el.getAttribute("bl_keyDelay");
  
  if (keyDelay != null)
  {
    if (el.cb_keyup_timer == undefined)
    {
      el.cb_keyup_timer = 0;
    }
    else
    {
      el.cb_keyup_timer++;
    }
    if (bl_port_keyCode(event) == 13)
    {
      _bl_edit_changed(event, el, false);
      bl_port_stop_event(event);
    }
    else
    {
      window.setTimeout("_bl_edit_keyupTimer(" + el.id + "," + el.cb_keyup_timer + ")", parseInt(keyDelay));
    }
  }
}

function _bl_textarea_keydown(event, el)
{
  var vk = event.virtualKey;
  if (vk == "up" || vk == "down" || vk == "left" || vk == "right" || vk == "home" || vk == "end" || vk == "pgup" || vk == "pgdn" || vk == "del" || vk == "bksp" || vk == "enter")
  {
    event.allowShortcuts = false;
    bl_port_stopPropagation(event);
  }
}

function _bl_textarea_onblur(event, el)
{
  var xmlStr = "<changed><value><![CDATA[" + el.value + "]]></value></changed>";
  
  // if changed, send.
  if (xmlStr != el.bl_last)
  {
    el.bl_last = xmlStr;
    
    bl_mpr_send(xmlStr, el.id, 0, bl_sys_readSendType(el));
  }
}

function _bl_textarea_changed(event, el)
{
  _bl_textarea_onblur(event, el);
}

function _bl_edit_changed(event, el, compareOld)
{
  var send = true;
  if (compareOld)
  {
    if (el.value == el.getAttribute("bl_old_val"))
    {
      send = false;
    }
  }
  
  var defaultText = el.getAttribute("bl_default_text");
  if (defaultText && el.value  == "")
  {
    el.value = defaultText;
  }
  
  if (send)
  {
    // set the old value here to ensure that the next time
    // we enter this function they will equal if there was
    // no user interation.  otherwise we will send twice.
    el.setAttribute("bl_old_val", el.value);
    var xmlStr = "<changed><value><![CDATA[" + el.value + "]]></value></changed>";
    
    // send the data to the server
    bl_mpr_send(xmlStr, el.id, 0, bl_sys_readSendType(el));
  }
}

function _bl_edit_handler(item, el)
{
  var cmd  = item.firstChild;
  var name = cmd.nodeName;
  var val  = bl_port_get_text(item.firstChild);
  
  if (name == "value")
  {
    if (el.tagName == "TEXTAREA")
    {
      if (el.getAttribute("bl_allow_html") != null)
      {
        el.innerHTML = val;
      }
      else
      {
        bl_port_setInnerText(el, val);
      }
      
      //need to reset this when setting value.
      el.bl_last = "";
    }
    else
    {
      el.value = val;
      el.setAttribute("bl_old_val", val);
    }
  }
  else if (!el.isDisabled && name == "triggerSelect")
  {
    bl_port_focus(el);
    el.select();
  }
  else if (name == "default_text")
  {
    el.setAttribute("bl_default_text", val);
  }
}


function cb_sys_setOpFilter(el, opacity, cancelFilter)
{
  el.cancelFilter = cancelFilter;
  bl_port_set_opacity(el, opacity);
  
  if (el.filterLinkView)
  {
    bl_port_set_opacity(el.filterLinkView, opacity);
  }
}

function cb_sys_startFilter(el, goDown, startP, endP, inc, linkView, finalOpacity, doneFunc)
{
  el.goDown         = goDown;
  el.curOpacity     = startP;
  el.cancelFilter   = false;
  el.filterEndPoint = endP;
  el.filterInc      = inc;
  el.filterLinkView = linkView;
  el.finalOpacity   = finalOpacity;
  el.doneFunc       = doneFunc;
  
  var list = window.bl_filterEls;
  
  if (!list)
  {
    window.bl_filterEls = list = [];
  }
  
  list.push(el);
  cb_sys_setOpFilter(el, startP,  false);
  if (list.length == 1)
  {
    // Only start the timer if it isn't already running.
    window.setTimeout('_bl_sys_filter()', 10);
  }
}

function _bl_sys_filter()
{
  var list = window.bl_filterEls;
  
  if (list)
  {
    var len = list.length;
    
    if (len > 0)
    {
      var cont = false;
      
      for (var i = len - 1; i >= 0; i--)
      {
        var el  = list[i];
        var rem = el.cancelFilter;
        
        if (!rem)
        {
          if (el.goDown)
          {
            el.curOpacity = Math.ceil(el.curOpacity - el.filterInc);
            if (el.curOpacity <= el.filterEndPoint)
            {
              el.curOpacity = el.filterEndPoint;
              rem = true;
            }
          }
          else
          {
            el.curOpacity = Math.floor(el.curOpacity += el.filterInc);
            if (el.curOpacity >= el.filterEndPoint)
            {
              rem = true;
              el.curOpacity = el.filterEndPoint;
            }
          }
          if (rem && !el.goDown)
          {
            bl_port_set_opacity(el, el.finalOpacity);
            if (el.filterLinkView)
            {
              bl_port_set_opacity(el.filterLinkView, el.finalOpacity);
            }
          }
          else
          {
            cb_sys_setOpFilter(el, el.curOpacity, false);
          }
        }
        
        if (rem)
        {
          if (el.doneFunc)
          {
            el.doneFunc(el);
          }
          list.splice(i, 1);
        }
      }
    }
    
    if (list.length > 0)
    {
      window.setTimeout('_bl_sys_filter()', 10);
    }
  }
}

/*
	Interpolation and time based tweening functions
*/


// Linear interpolation
function bl_sys_lerp(a, b, p)
{
  return ((b-a)*p) + a;
}

// Smooth interpolation
function bl_sys_serp(a, b, p)
{
  return bl_sys_lerp(a, b, (1-Math.cos(p*Math.PI))/2);
}

// Smooth interpolation (2x smoothing)
function bl_sys_serp2(a, b, p)
{
  return bl_sys_serp(a, b, bl_sys_serp(0,1,p));
}


//	Time based tweening
//	call_back will get called each step, like so:  call_back(pos, arg, is_done, interp)
//	pos will be the correct value taking into account time.
function bl_sys_tween(s, e, t, arg, call_back, interp)
{
  var tlw = cb_sys_getTopWindow();

  if (typeof tlw.tweening == "undefined")
  {
    tlw.tween_list = [];
  }

  if (arguments.length >= 5)
  {
    if (arguments.length == 5)
    {
      interp = bl_sys_lerp;
    }

    tlw.tween_list.push({"s":s,"e":e,"t":t,"arg":arg,"call_back":call_back,"begin_time":(new Date()).getTime()/1000,"interp":interp,"remove":false});
    call_back(s, arg, false, interp);

    if (tlw.tween_list.length == 1)
    {
      // 35ms =~ 28fps
      tlw.tweening = tlw.setTimeout(bl_sys_tween, 35); 
    }

    return;
  }

  var now = (new Date()).getTime()/1000;

  // Update positions
  for (var i = tlw.tween_list.length - 1; i >= 0; i--)
  {
    var item   = tlw.tween_list[i];
    var p      = (now-item.begin_time)/item.t; 
    var isDone = (p >= 1);

    if (!item.remove)
    {
      item.call_back(isDone? item.e : item.interp(item.s,item.e,p), item.arg, isDone, item.interp);
    }
    
    if (isDone || item.remove)
    {
      tlw.tween_list.splice(i,1);
    }
  }

  if (tlw.tween_list.length == 0)
  {
    tlw.clearTimeout(tlw.tweening);
  } 
  else
  {
    // 35ms =~ 28fps
    tlw.tweening = tlw.setTimeout(bl_sys_tween, 35); 
  }
}


// Will flag for removal tween events with matching arg
function bl_sys_remove_tween(arg)
{
  var tList = cb_sys_getTopWindow().tween_list;
  
  if (tList)
  {
    var len = tList.length;
    
    for (var i = 0; i < len; i++)
    {
      var item = tList[i];
      
      if (item.arg == arg)
      {
        item.remove = true;
      }
    }
  }
}

/* Tweening helper functions */
function bl_sys_tweener_alpha(pos, arg, is_done, interp)
{
  arg.style.opacity = pos;
  arg.style.filter = "alpha(opacity=" + (pos*100) + ")";
}

/*
  Called from the FileUpload Control (bl_file.h). 
*/
function _bl_control_file_onComplete(id)
{
  var xmlStr = "<onComplete/>";
  bl_mpr_send(xmlStr, id, 0);
}

function _bl_control_file_open(event, el)
{
  var href = el.getAttribute("bl_href");
  
  if (href)
  {
    var feature = "resizable:yes;status:no;unadorned:no;help:no;scroll:no";
    var inputCount = 1;
    var height;
    var startIndex = href.lastIndexOf("blf_count=") + 10;
    if (startIndex > 0)
    {
      inputCount = parseInt(href.substring(startIndex));
    }
    height = (bl_browserInfo.ie6 ? 120 : 95) + (25* inputCount);
    // ie6 doesn't subtract the size of the window frame from the size of the window.
    el.bl_fileWin = _bl_sys_open("",  href, bl_port_computeFeature(event, feature, 400, height), 1, 0, -1, false);
  }
  
  bl_port_stop_event(event);
}

/*
  Called on the parent window from the file upload dialog
*/
function _bl_control_file_close(id, fileInput)
{
  if (fileInput != null)
  {
    var msg = "<FileName>" + fileInput.value + "</FileName>"
    bl_mpr_send(msg, id);
  }
}

function _bl_control_file_initFileUpload(id)
{
  var msg = "<Init/>";
  bl_mpr_send(msg, id);
}

// Because this control subclasses from FunctionButton it will receive a done message
function _bl_control_file_handler(item, element)
{
  var el   = item.firstChild;
  var name = el.nodeName;
  switch(name)
  {
    case ("done"):
      window.setTimeout("_bl_img_clearButton(" + element.id + ")", 1000);
      break;
    case ("trigger"):
      element.click();
      break;
    case ("UploadCommand"):
      /*set the upload command on the upload dialog.*/
      bl_control_file_UploadCommand(element, bl_port_get_text(el.childNodes.item(0)));
      break;
    case ("CustomInputs"):
      /*set the Custom inputs on the upload dialog.*/
      bl_control_file_CustomInputs(element, bl_port_get_text(el.childNodes.item(0)));
      /*modify the redirect URL if we are using bungee_redirect*/
      if (item.childNodes.length == 2)
      {
        var redirect = item.childNodes[1];
        if (redirect.nodeName == "redirectURL")
        {
          bl_control_file_RedirectURL(element, redirect.getAttribute("id"), bl_port_get_text(redirect.childNodes.item(0)));
        }
      }
      break;
    case ("closeDialog"):
      /*Close the dialog*/
      if (element &&  element.bl_fileWin)
      {
        element.bl_fileWin.close();
      }
      break;
    default:
      break;
  }
}

function bl_control_file_UploadCommand(el, htmlContents)
{
  // save the Upload Command on the fileUpload Window
  if (el &&  el.bl_fileWin)
  {
    el.bl_fileWin.bl_file_uploadCommands(htmlContents);
  }
}

function bl_control_file_CustomInputs(el, htmlContents)
{
  if (el && el.bl_fileWin && el.bl_fileWin.bl_file_AddCustomInputs)
  {
    el.bl_fileWin.bl_file_AddCustomInputs(htmlContents);
  }
}

function bl_control_file_RedirectURL(el, name, value)
{
  value = document.location.protocol + value;
  if (el && el.bl_fileWin && el.bl_fileWin.bl_file_RedirectURL)
  {
    el.bl_fileWin.bl_file_RedirectURL(name, value);
  }
}

function cb_sys_slideDataCreate(vertical,
                                size,
                                slideSpeed,
                                replacementElText,
                                scriptNode,
                                expanding,
                                origOverFlow,
                                origVis,
                                useParentSize,
                                both,
                                altSize)
{
  this.fIsVerticalSide     = vertical;
  this.fSize               = size;
  this.fSlideSpeed         = slideSpeed;
  this.fSlideStep          = 1;
  this.fReplacementElText  = replacementElText;
  this.fExpanding          = expanding;
  this.fScriptNode         = scriptNode;
  this.fOrigOverFlow       = origOverFlow;
  this.fOrigVisibility     = origVis;
  this.fUseParentSize      = useParentSize;
  this.fBoth               = both;
  this.fAltSize            = altSize;
  this.state               = 0;
}

function bl_sys_resumeSize(el)
{
  var sData = el.slideData;
  
  if (sData)
  {
    sData.state++;
    if (sData.state > 1)
    {
      if (sData.fBoth)
      {
        if (sData.fIsVerticalSide)
        {
          el.style.width = sData.fAltSize+"px";
        }
        else
        {
          el.style.height = sData.fAltSize+"px";
        }
      }
      else
      {
        el.style.width  = "";
        el.style.height = "";
      }
      el.slideData = null;
    }
  }
}

function _bl_sys_slideInline(callTimer)
{
  var elArray = document.cbSlideArray;
 
  if (elArray)
  {
    var len = elArray.length;
    
    for (var i_slide = len - 1; i_slide >= 0; i_slide--)
    {
      var el = elArray[i_slide];
      
      try
      {
        if (el && el.slideData)
        {
          var sData   = el.slideData;
          var step    = Math.floor(sData.fSlideStep);
          var curSize = 0;
          
          sData.fSlideStep *= sData.fSlideSpeed;
          
          if (sData.fExpanding)
          {
            var height  = parseInt(el.style.height);
            var width   = parseInt(el.style.width);

            if (sData.fIsVerticalSide)
            {
              curSize = (height + step > sData.fSize) ? sData.fSize : height + step;
              el.style.height = curSize+"px";
              
              if (sData.fBoth)
              {
                el.style.width = ((width + step > sData.fAltSize) ? sData.fAltSize : width + step)+"px";
              }
            }
            else
            {
              curSize = (width + step > sData.fSize) ? sData.fSize : width + step;
              el.style.width  = curSize+"px";
              
              if (sData.fBoth)
              {
                el.style.height = ((height + step > sData.fAltSize) ? sData.fAltSize : height + step)+"px";
              }
            }
            
            if (curSize >= sData.fSize)
            {
              el.style.overflow   = sData.fOrigOverFlow;
              el.style.visibility = sData.fOrigVisibility;

              // this must be called after the above
              bl_sys_resumeSize(el);
              elArray.splice(i_slide, 1);
              bl_sys_inlineChanged(el);
            }
          }
          else
          {
            var height = parseInt(el.style.height);
            var width  = parseInt(el.style.width);
            
            if (sData.fIsVerticalSide)
            {
              curSize = (height - step < sData.fSize) ? sData.fSize : height - step;
              el.style.height = curSize+"px";
              
              if (sData.fBoth)
              {
                el.style.width = ((width - step < sData.fAltSize) ? sData.fAltSize : width - step)+"px";
              }
            }
            else
            {
              curSize = (width - step < sData.fSize) ? sData.fSize : width - step;
              el.style.width = curSize+"px";
              if (sData.fBoth)
              {
                el.style.height = ((height - step < sData.fAltSize) ? sData.fAltSize : height - step)+"px";
              }
            }
            
            
            if (curSize <= sData.fSize)
            {
              if (sData.fReplacementElText)
              {
                bl_port_insertAdjacentHTML(el, "beforebegin", sData.fReplacementElText);
                
                var nel = el.previousSibling;
                
                nel.style.visibility = sData.fOrigVisibility;
                if (sData.fScriptNode)
                {
                  bl_sys_procInitTags(sData.fScriptNode);
                }
                if (nel)
                {
                  bl_sys_inlineChanged(nel);
                }
              }
              
              // this must be called after the above
              bl_sys_resumeSize(el);
              elArray.splice(i_slide, 1);
              bl_port_removeComplexEl(el, el.parentNode);
            }
          }
        }
        else 
        {
          el.sideData = null;
          elArray.splice(i_slide, 1);
        }
      }
      catch (exception)
      {
        el.sideData = null;
        elArray.splice(i_slide, 1);
      }
    }
    if (elArray.length > 0 && callTimer)
    {
      window.setTimeout("_bl_sys_slideInline(true)", 25);
    }
  }
}

function bl_sys_fadeData(el, text, scriptNode, step, mix)
{
  if (step > 100.0)
  {
    step = 100.0
  }
  if (step < 0.0)
  {
    step = 1.0;
  }
  
  this.el         = el;
  this.text       = text;
  this.scriptNode = scriptNode;
  this.step       = step;
  this.mix        = mix;
}

function cb_sys_inline_filterDone(el)
{
  var fdata = el.fadeData;
  
  if (fdata)
  {
    var step = fdata.step;
    
    el.fadeData = null;

    var pel = bl_sys_createSlideChild(fdata.text, el);

    cb_sys_startFilter(pel, false, 0, 100, step, null, "", null);
    bl_sys_injectInline(el, pel, fdata.scriptNode, true);
  }
}

function cb_sys_setUpInlineFade(nelText, el, scriptNode)
{
  if (el.fadeData)
  {
    el.fadeData.text = nelText;
    el.fadeData.scriptNode = scriptNode;
  }
  else
  {
    var mix     = el.getAttribute("bl_fade_mix") != null;
    var step    = parseFloat(el.getAttribute("bl_fade_step"));
    el.fadeData = new bl_sys_fadeData(el, nelText, scriptNode, step, mix);
    cb_sys_startFilter(el, true, 100, 0, step, null, "", cb_sys_inline_filterDone);
  }
}

function bl_sys_createSlideChild(text, el)
{
  var ret;

  // for ie aaaa
  if (bl_browserInfo.ie)
  {
    bl_port_insertAdjacentHTML(el, "beforebegin", text);
    ret = el.previousSibling;
  }
  else
  {
    bl_port_insertAdjacentHTML(el, "beforebegin", "<div style='left:-1000;top:-1000;position:absolute'>" + text + "</div>");
    var injectedEl = el.previousSibling;
    ret = injectedEl.firstChild;
  }
  return ret;
}

function bl_sys_setUpInlineSlide(nelText, rel, scriptNode)
{
  var el            = bl_sys_createSlideChild(nelText, rel);
  var useParentSize = el.getAttribute("bl_parent") != null;
  var both          = el.getAttribute("bl_both") != null;
  var nOrigVis      = "visible";
  var nOrigOv       = el.style.overflow;
  var addEl         = null;
  var speed         = parseFloat(el.getAttribute("bl_slide_speed"));
  var isVertical    = el.getAttribute("bl_slide_hor") == null;
  var fade          = el.getAttribute("bl_fade") != null;
  var nsize         = 0;
  var rsize         = 0;
  var n_altsize     = 0;
  var r_altsize     = 0;
  var vis           = el.getAttribute("bl_orig_vis");
  
  if (isVertical)
  {
    nsize       = el.offsetHeight;
    rsize       = rel.offsetHeight;
    n_altsize   = el.offsetWidth;
    r_altsize   = rel.offsetWidth;
  }
  else
  {
    nsize       = el.offsetWidth;
    rsize       = rel.offsetWidth;
    n_altsize   = el.offsetHeigh;
    r_altsize   = rel.offsetHeight;
  }

  if (useParentSize && nsize > rsize)
  {
    var parent  = el.parentNode;
    var pstyle  = parent.style;
    var ptop    = parseInt(pstyle.paddingTop);
    var pleft   = parseInt(pstyle.paddingLeft);
    var pright  = parseInt(pstyle.paddingRight);
    var pbottom = parseInt(pstyle.paddingBottom);
    
    if (isVertical)
    {
      nsize = parent.offsetHeight;
      
      if (ptop)
      {
        nsize -= ptop;
      }
      if (pbottom)
      {
        nsize -= pbottom;
      }
      
      if (both)
      {
        n_altsize = parent.offsetWidth;
        if (pleft)
        {
          n_altsize -= pleft;
        }
        if (pright)
        {
          n_altsize -= pright;
        }
      }
    }
    else
    {
      nsize = parent.offsetWidth;
      
      if (pleft)
      {
        nsize -= pleft;
      }
      if (pright)
      {
        nsize -= pright;
      }
      
      if (both)
      {
        n_altsize = parent.offsetHeight;
        
        if (ptop)
        {
          n_altsize -= ptop;
        }
        if (pbottom)
        {
          n_altsize -= pbottom;
        }
      }
    }
  }
  
  if (vis)
  {
    nOrigVis = vis;
  }
  
  if (nsize > rsize)
  {
    var style   = el.style;
    
    
    el.slideData = new cb_sys_slideDataCreate(isVertical,
                                              nsize,
                                              speed,
                                              null,
                                              null,
                                              true,
                                              nOrigOv,
                                              nOrigVis,
                                              useParentSize,
                                              both,
                                              n_altsize);
                                              
                                              

    bl_contain_layoutContainer(el.firstChild, true);
    
    style.overflow = "hidden";
    
    if (isVertical)
    {
      style.height = rsize+"px";
      
      if (both)
      {
        style.width = r_altsize+"px";
      }
    }
    else
    {
      style.width = rsize+"px";
      if (both)
      {
        style.height = r_altsize+"px";
      }
    }
    
    // for ie aaaa
    if (!bl_browserInfo.ie)
    {
      var injectedEl = el.parentNode;
      bl_port_insertAdjacentElement(rel, "beforebegin", el);
      injectedEl.parentNode.removeChild(injectedEl);
    }
    
    addEl = rel.previousSibling;
    bl_port_removeComplexEl(rel, rel.parentNode)

    if (scriptNode)
    {
      bl_sys_procInitTags(scriptNode);
    }

    style.visibility = "visible";
    
    var origOp = bl_port_orig_opacity_style(el);
    
    if (fade)
    {
      bl_port_set_opacity(el, 0);
    }    

    if (fade)
    {
      cb_sys_startFilter(addEl, false, 0, 100, 5, null, origOp, bl_sys_resumeSize);
    }
  }
  else
  {
    var origOpacity = bl_port_orig_opacity_style(el);
    rel.slideData = new cb_sys_slideDataCreate(isVertical,
                                               nsize,
                                               speed,
                                               nelText,
                                               scriptNode,
                                               false,
                                               nOrigOv,
                                               nOrigVis,
                                               useParentSize,
                                               both,
                                               n_altsize);
    rel.style.overflow = "hidden";
    if (!bl_browserInfo.ie)
    {
      // point to the container div created in bl_sys_createSlideChild
      el = el.parentNode;
    }
    if (el.parentNode)
    {
      el.parentNode.removeChild(el);
      el = null;
    }
    
    if (isVertical)
    {
      rel.style.height = rsize+"px";
      
      if (both)
      {
        rel.style.width = r_altsize+"px";
      }
    }
    else
    {
      rel.style.width = rsize+"px";
      if (both)
      {
        rel.style.height = r_altsize+"px";
      }
    }
    
    if (fade)
    {
      cb_sys_startFilter(rel, true, 100, 0, 5, null, origOpacity, bl_sys_resumeSize);
    }
    
    addEl = rel;
  }
  if (!document.cbSlideArray)
  {
    document.cbSlideArray = new Array();
  }
  document.cbSlideArray.push(addEl);
  
  _bl_sys_slideInline(document.cbSlideArray.length <= 1);
}

function bl_sys_injectInline(el, textOrEl, val, isEl)
{
  var parent           = el.parentNode;
  var prev             = null;
  el.style.visibility  = "hidden";
  el.innerHTML         = "";
  
  if (isEl)
  {
    bl_port_insertAdjacentElement(el, "beforebegin", textOrEl);
  }
  else
  {
    bl_port_insertAdjacentHTML(el, "beforebegin", textOrEl);
  }
  
  var prev = el.previousSibling;
  
  if (el.getAttribute("cb_check_top") != null)
  {
    var child = prev.firstChild;
    
    if (child)
    {
      if (child.getAttribute("cb_bring_top") != null)
      {
        parent.scrollTop = prev.offsetTop;
      }
      else if (child.getAttribute("cb_restore_top") != null)
      {
        parent.scrollTop = 0;
      }
    }
  }
  
  prev.cb_orig_name  = prev.className;
  prev.className     = el.className;
  prev.bl_isSelected = el.bl_isSelected;
  
  bl_port_removeComplexEl(el, parent);
  
  bl_dlg_cleanUpForEl(el);
  
  if (prev.getAttribute("cb_reset_focus") != null)
  {
    // reset focus to first field or whichever field marked with name="cb_focus"
    var tlw = cb_sys_getTopLevelWindow();
    tlw.bl_kb_doFirstFocus(false);
  }
  
  bl_sys_procInitTags(val);
  
  if (prev)
  {
    bl_contain_grid_child_posCheck(parent, prev);
    bl_sys_inlineChanged(prev);
  }
  
  return prev;
}

function bl_sys_shutDownIframes(list)
{
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    var frameEl = list[i];

    if (frameEl)
    {
      try
      {    
        var win = frameEl.contentWindow;

        if (win.bl_sys_shutDownIframes && 
            win._bl_sys_shutdown_window)
        {
          
          win.bl_sys_shutDownIframes(win.document.getElementsByTagName("IFRAME"));

          // seting the iframes to not send shutdown
          win.bl_close_type = 2;
          _bl_sys_shutdown_window(win);
        }

        var doc = win.document;
        doc.open("text/html", "replace");
        doc.close();
      }
      catch (ex)
      {
        // the iframe's internals may be inaccesable so just move on
      }
    }
  }
}

function _bl_sys_inline_handler(item, el)
{
  var val = item.firstChild;
  
  bl_sys_shutDownIframes(el.getElementsByTagName("IFRAME"));
  
  if (val.nodeName == "value")
  {
    var cName = el.className;
    
    if (el.getAttribute("bl_do_slide") != null)
    {
      bl_sys_setUpInlineSlide(bl_port_get_text(val), el, val);
    }
    else if (el.getAttribute("bl_do_fade") != null)
    {
      cb_sys_setUpInlineFade(bl_port_get_text(val), el, val);
    }
    else
    {
      bl_sys_injectInline(el, bl_port_get_text(val), val, false);
    }
  }
  else if (val.nodeName == "srcChanged")
  {
    bl_setFrameSrc(el)
  }
}

function _bl_setFrameSrcDelay(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    bl_setFrameSrc(el);
  }
}

function bl_inline_checkPending(frm)
{
  if (frm && frm.getAttribute("cb_tag") == "IF_EMB")
  {
    var prevState = frm.getAttribute("bl_state");

    frm.setAttribute("bl_state", "ready");
    if (prevState == "pending")
    {
      bl_setFrameSrc(frm);
      return true;
    }
  }
  
  return false;
}

function bl_setFrameSrc(frm)
{
  if (frm)
  {
    var win = frm.contentWindow;
    
    if (win)
    {
      if (frm.getAttribute("bl_state") == "ready")
      {
        var src = bl_mpr_buildControlUrl(frm);

        try
        {
          // setting to not send shutdown
          frm.contentWindow.bl_close_type = 2;
          _bl_sys_shutdown_window(frm.contentWindow);
        }
        catch (exception)
        {
        }
        
        frm.setAttribute("bl_state", "loading");
        bl_port_openWindow(frm.contentWindow, src, null, "", "_self", "", true, null);
      }
      else
      {
        frm.setAttribute("bl_state", "pending");
      }
    }
  }
}

function _bl_inline_disable_init(id)
{
  cb_sys_setDisableInputChildren(document.getElementById(id), true);
}

function bl_sys_deferLayout(el)
{
  if (el)
  {
    var list = window.bl_deferList;
    
    if (!window.bl_deferList)
    {
      list = new Array();
      window.bl_deferList = list;
    }
    
    var len = list.length;
    
    for (var i = 0; i < len; i++)
    {
      if (list[i] == el)
      {
        return ;
      }
    }
    
    list.push(el);
    
    if (len == 0)
    {
      window.setTimeout('_bl_sys_doDeferLayout()', 1);
    }
  }
}

function _bl_sys_doDeferLayout()
{
  var list = window.bl_deferList;
  
  if (list)
  {
    var len = list.length;
    
    for (var i = 0; i < len; i++)
    {
      var el = list.pop();

      if (el)
      {
        bl_contain_layoutContainer(el, true);
      }
    }
  }
}

function bl_sys_inlineChanged(el)
{
  var parent = el.parentNode;
  
  while (parent && parent.style)
  {
    var layout = bl_contain_getLayout(parent);
    
    if (layout && (layout.type == 1 || layout.type == 3))
    {
      var style    = parent.style;
      var overflow = style.overflow;
      
      if (overflow == "")
      {
        overflow = style.overflowY; 

        if (overflow != "auto" && overflow != "scroll")
        {
          overflow = style.overflowX; 
        } 
      } 
      
      if (overflow == "auto" || overflow == "scroll")
      {
        bl_sys_deferLayout(parent);
      }
    }
        
    if (parent.bl_inlineChanged)
    {
      parent.bl_inlineChanged(el);
      break;
    }
    parent = parent.parentNode;
  }
}


function _bl_emb_ddOver(event, el)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    try
    {
      var item = ddObj.srcContext.item;

      if (el != item && !bl_port_contains(item, el, false))
      {
        var zoneList = el.getAttribute("bl_zone_list");
        
        if (zoneList && bl_dd_checkList(ddObj, event, zoneList))
        { 
          // show hint
          bl_port_killEvent(event);
          return ;
        }
      }
    }
    catch(exp)
    {
    }
    ddObj.clearEffect();
  }
}

function _bl_emb_ddOut(event, el)
{
  //need to figure out what we want as a drop hint
}

function _bl_emb_drop(event, el)
{
  var ddObj = bl_dd_getDragDropObj();
  var item  = bl_port_getEventTarget(event);

  if (bl_port_contains(el, item, true) && bl_dd_checkList(ddObj, event, el.getAttribute("bl_zone_list")))
  {
    var target = { id:el.id, index:-1 }
    bl_dd_procDrop(target);
    bl_port_killEvent(event);
  }
}

// JScript source code

//***********************************************************************
//***********************************************************************
//********                    bl_html.js                        *********
//***********************************************************************
//***********************************************************************

function _bl_htm_init(escapedStr, id, mailToHandler)
{
  var frm = document.getElementById(id);
  
  frm.onreadystatechange  = bl_htm_frameState;
  frm.mailToHandler       = mailToHandler;

  var doc = frm.contentWindow.document;
  
  doc.open("text/html", "replace");
  doc.write(unescape(escapedStr));
  doc.close();
}

function _bl_hv_handler(item, el)
{
  var value   = item.firstChild;
  var cmdName = value.nodeName;
  
  if (cmdName == "setsrc")
  {
    var url = bl_port_get_text(value);
    
    try
    {
      el.src = url;
    }
    catch(exception)
    {
      var doc = el.ownerDocument;
      doc.open("text/html", "replace");
      doc.write("<html><head><title>Send</title><body><a href='" + url + "'>Click Here</a></body></html>");
      doc.close();
    }
  }
  else if (cmdName == "srcChanged")
  {
    el.contentWindow.open(bl_mpr_buildControlUrl(el), "_self", "", true);
  }
  else if (cmdName == "value")
  {
    eval(bl_port_get_text(value));
  }
}

function bl_htm_handleMailTo(event)
{
  if (!event)
  {
    event = window.event;
  }

  try
  {
    var hrefStr = this.href;
    var ev      = bl_port_docWindow(this.ownerDocument).event;
    var xmlStr  = "<mailto><href><![CDATA[" 
                  + hrefStr 
                  + "]]></href></mailto>";
    
    bl_mpr_send(xmlStr, this.parentFrame);
    bl_port_stop_event(ev);
  }
  catch(exception)
  {
  }
}

function bl_htm_frameState(event)
{
  if (!event)
  {
    event = window.event;
  }

  var src = bl_port_getEventTarget(event);
  
  if (src.readyState == "complete")
  {
    var elDoc  = src.contentWindow.document;
    
    if (elDoc)
    {
      var links = elDoc.links;
      var len   = links.length;
      
      for (var i = 0; i < len; i++)
      {
        var linkItem = links[i];
        
        if (linkItem.href && (linkItem.href.indexOf("bungee?") == -1 || linkItem.hash == "" || linkItem.hash == "#"))
        {
          linkItem.target = "_blank";
        }
       
        if (src.mailToHandler)
        {
          var hrefStr = linkItem.href;
          
          if (hrefStr.indexOf("mailto:") >= 0)
          {
            linkItem.parentFrame = src.id;
            linkItem.onclick     = bl_htm_handleMailTo;
          }
        }
      }
      
      src.onreadystatechange = null;
      elDoc.oncontextmenu    = bl_sys_context_menu;
    }
  }
}

function bl_hv_sendSelect(el, str)
{
  var xmlStr = "<select>" + str + "</select>";
  bl_mpr_send(xmlStr, el.id, -1, bl_sys_readSendType(el));
}

// this functionis here to allow the porting code to call into it

function _bl_string_handler(item, el)
{
  var value = item.firstChild;
  var cmd   = value.nodeName;
  
  if (cmd == "value")
  {
    blu_setElContent(el, value);
  }
}


function _bl_link_handler(item, el)
{
  for (var i = 0; i < item.childNodes.length; i++)
  {
    var item = item.childNodes.item(i);
    if (item.nodeName == "href")
    {
      el.href = bl_port_get_text(item);
    }
    else if (item.nodeName == "text")
    {
      bl_port_setInnerText(el, bl_port_get_text(item));
    }
  }
}

function _bl_link_pressed(event,el)
{
  bl_port_clickLink(el);
}


function cb_list_computeOptionIndex(list)
{
  var len = list.length;
  
  for (var i = 0; i < len; i++)
  {
    if (list.item(i).selected)
    {
      return i;
    }
  }
  return -1;
}

function _bl_list_keydown(event, el)
{
  var vk = event.virtualKey;
  if (vk == "up" || vk == "down")
  {
    event.allowShortcuts = false;
    bl_port_stopPropagation(event);
  }
  else if ((vk == "del" || vk == "bksp") && bl_port_hasAttribute(el,"bl_supportsRemove"))
  {
    var sStr   = (event.shiftKey)? 'shiftDown="true"':'shiftDown="false"';
    var xmlStr = '<removeSelected ' + sStr + '></removeSelected>';
    
    bl_mpr_send(xmlStr, el.id, 2);
    bl_port_stop_event(event);
  }
}

function _bl_list_dblclk(event, el)
{
  var xmlStr = "<dblclick><index>" + el.selectedIndex + "</index></dblclick>";
  
  bl_mpr_send(xmlStr, el.id, -1, bl_sys_readSendType(el));
  
  if (el.getAttribute("bl_close_dblclk") != null)
  {
    window._bl_sys_closeWindow('Ok');
  }
}

function _bl_list_select(event, el)
{
  var xmlStr = "<selectChanged>";
  
  if (el.multiple)
  {
    var len = el.childNodes.length;
    for (var i = 0; i < len; i++)
    {
      if (el.childNodes.item(i).selected)
      {
        xmlStr += "<index>";
        xmlStr += i;
        xmlStr += "</index>";
      }
    }
  }
  else
  {
    xmlStr += "<index>";
    xmlStr += el.selectedIndex;
    xmlStr += "</index>";
  }
  xmlStr += "</selectChanged>";
  
  bl_mpr_send(xmlStr, el.id, -1, bl_sys_readSendType(el));
}

function cb_list_addSelectElement(selectElement, labelNode, index, justAdd)
{
  var optionElement = document.createElement("OPTION");
  
  bl_port_setInnerText(optionElement, bl_port_get_text(labelNode));
  
  if (index < selectElement.childNodes.length && !justAdd)
  {
    var beforeNode = selectElement.childNodes.item(index);
    bl_port_insertAdjacentElement(beforeNode, "beforeBegin", optionElement);
  }
  else
  {
    selectElement.appendChild(optionElement);
  }
  if (labelNode.getAttribute("SELECTED"))
  {
    optionElement.selected = true;
  }
}

function cb_list_ClearSelection(selectElement, newSel)
{
  var cNodes = selectElement.childNodes;
  var len    = cNodes.length;

  for (var i = 0; i < len; i++)
  {
    var item = cNodes.item(i);
    item.selected = (bl_port_getInnerText(item) == newSel);
  }
}

function cb_list_removeAll(element, list)
{
  var len = list.length;
  
  for (var i = len - 1; i >= 0; i--)
  {
    var child = list[i];
    
    if (!bl_port_hasAttribute(child,"bl_isBlank"))
    {
      element.removeChild(child);
    }
  }
}

function _bl_list_mousedown(event, el)
{
  bl_kb_focusOnElement(bl_port_getEventTarget(event));
  bl_sys_checkDialogSelect(el);    
}

function _bl_list_clearSelect(el)
{
  if (el)
  {
    cb_list_ClearSelection(el, "")
    bl_mpr_send("<deselectAll/>", el.id, -1, bl_sys_readSendType(el));
  }
}

function _bl_performSelect(id, indexStr, selectRemoves, val)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    if (selectRemoves)
    {
      cb_list_ClearSelection(el, "");
    }

    var indexes = indexStr.split(" ");
    var len     = indexes.length;
    for (var i = 0; i < len; i++)
    {
      var n = parseInt(indexes[i]);
      el.childNodes.item(n).selected = val;
    }
  }
}

function _bl_list_handler(item, el)
{
  var cmd          = item.firstChild;
  var cmdName      = cmd.nodeName;
  var cNodes       = cmd.childNodes;
  var elementNodes = el.childNodes;
  if (cmdName == "listChanged")
  {
    if (elementNodes.length > 0)
    {
      cb_list_removeAll(el, elementNodes);
    }
    var len = cNodes.length;
    for (var i = 0; i < len; i++)
    {
      cb_list_addSelectElement(el, cNodes.item(i), i, true);
    }
  }
  else if (cmdName == "elementChanged")
  {
    cb_list_ClearSelection(el, bl_port_get_text(cmd));
  }
  else if (cmdName == "move")
  {
    var oldIndex = parseInt(bl_port_get_text(cmd.childNodes.item(0)));
    var newIndex = parseInt(bl_port_get_text(cmd.childNodes.item(1)));
    var child    = elementNodes.item(oldIndex);
    el.removeChild(child);
    
    if (newIndex < el.childNodes.length)
    {
      var beforeNode = elementNodes.item(newIndex);
      bl_port_insertAdjacentElement(beforeNode, "beforeBegin", child);
    }
    else
    {
      el.appendChild(child);
    }
  }
  else if (cmdName == "insert")
  {
    var labelNode = cNodes.item(0);
    var n         = new Number(bl_port_get_text(cNodes.item(1)));
    cb_list_addSelectElement(el, labelNode, n, false);
  }
  else if (cmdName == "set")
  {
    var labelNode  = cNodes.item(0);
    var n          = parseInt(bl_port_get_text(cNodes.item(1)));
    var item       = elementNodes.item(n);
    
    bl_port_setInnerText(item, bl_port_get_text(labelNode));
  }
  else if (cmdName == "remove")
  {
    var n = parseInt(bl_port_get_text(cmd));
    el.removeChild(elementNodes.item(n));
  }
  else if (cmdName == "removeselect")
  {
    var list  = bl_port_get_text(cmd).split(" ");
    var len   = list.length;
    var elLen = elementNodes.length;
    
    for (var i = 0; i < len; i++)
    {
      var index = parseInt(list[i]);
      
      if (index >= 0 && index < elLen)
      {
        var item = elementNodes.item(index);
        el.removeChild(item);
      }
    }
  }
  else if (cmdName == "removeall")
  {
    if (elementNodes.length > 0)
    {
      cb_list_removeAll(el, elementNodes);
    }
  }
  else if (cmdName == "deselect")
  {
    var n = parseInt(bl_port_get_text(cmd));
    elementNodes.item(n).selected = false;
  }
  else if (cmdName == "select")
  {
    var selr          = cmd.attributes.getNamedItem("selectRemoves");
    var selectRemoves = (selr) ? (selr.nodeValue == "true") : false;
    window.setTimeout('_bl_performSelect("' + el.id + '","' + bl_port_get_text(cmd) + '",' + selectRemoves + ', true);', 1);
  }
  else if (cmdName == "multipleselect")
  {
    var selr          = cmd.attributes.getNamedItem("selectRemoves");
    var selectRemoves = (selr) ? (selr.nodeValue == "true") : false;

    window.setTimeout('_bl_performSelect("' + el.id + '","' + bl_port_get_text(cmd) + '",' + selectRemoves + ', true);', 1);
  }
  else if (cmdName == "multipledeselect")
  {
    var indexes = bl_port_get_text(cmd).split(" ");

    window.setTimeout('_bl_performSelect("' + el.id + '","' + bl_port_get_text(cmd) + '",false, false);', 1);
  }
}

//***********************************************************************
//***********************************************************************
//********                      bl_map.js                       *********
//***********************************************************************
//***********************************************************************

var fileRoot = "http://www.google.com/mapfiles/";
var gApplication = null;
var bl_map = 
{
  "lookups" : new Array()
};

function _bl_map_marker(el, point, label, iconArgs)
{
  var marker         = new el.wincx.GMarker(point, {icon:bl_map_markerIcon(el, iconArgs)});
  marker.bl_label    = (label && label.length ? label : undefined);
  marker.bl_parentEl = el;
  marker.iconArgs = iconArgs;
  marker.bl_listeners = new Array();
  if (el.getAttribute("bl_clickEvent"))
  {
    marker.bl_listeners["click"] = el.wincx.GEvent.addListener(marker, "click", _bl_map_marker_click);
  }
  if (el.getAttribute("bl_hoverEvent"))
  {
    marker.bl_listeners["mouseover"] = el.wincx.GEvent.addListener(marker, "mouseover", _bl_map_marker_mOver);
    marker.bl_listeners["mouseout"] = el.wincx.GEvent.addListener(marker, "mouseout", _bl_map_marker_mOut);
  }
  return marker;
}

function _bl_map_marker_cleanup(wincx, marker)
{
  if (wincx && wincx.GEvent)
  {
    // Sometimes the window is cleaned up before we get the cleanup
    // code finished, so this protects us
    for (var event in marker.bl_listeners)
    {
      wincx.GEvent.removeListener(marker.bl_listeners[event]);
      marker.bl_listeners[event] = null;
    }
  }
  _bl_map_closeMarkerInfoWindow.call(marker);
  marker.bl_listeners  = null;
}

function bl_map_markerIcon(el, args)
{
  var icon = el.wincx.G_DEFAULT_ICON;
  if (args)
  {
    icon = new el.wincx.GIcon(el.wincx.G_DEFAULT_ICON);
    for (var mem in args)
    {
      /*Notice that while the two parameters of a GPoint/GSize are accessible as properties, 
        it is better to never modify them, but to create a new object with different paramaters instead.*/
      switch(mem)
      {
        case "iconWidth":            // ignore these attributes - they are handled elsewhere
        case "shadowWidth":          // ***
        case "iconAnchorLeft":       // ***
        case "infoWindowAnchorLeft": // ***
          break;
        case "iconHeight":
          if (!args["iconWidth"]) 
            continue;
          icon["iconSize"] = new el.wincx.GSize(parseInt(args["iconWidth"]), parseInt(args["iconHeight"]));
          break;
        case "shadowHeight":
          if (!args["shadowWidth"]) 
            continue;
          icon["shadowSize"] = new el.wincx.GSize(parseInt(args["shadowWidth"]), parseInt(args["shadowHeight"]));
          break;
        case "iconAnchorTop":
          if (!args["iconAnchorLeft"]) 
            continue;
          icon["iconAnchorTop"] = new el.wincx.GPoint(parseInt(args["iconAnchorLeft"]), parseInt(args["iconAnchorTop"]));
          break;
        case "infoWindowAnchorTop":
          if (!args["infoWindowAnchorLeft"]) 
            continue;
          icon["infoWindowAnchorTop"] = new el.wincx.GPoint(parseInt(args["infoWindowAnchorLeft"]), parseInt(args["infoWindowAnchorTop"]));
          break;
        default:
          icon[mem] = args[mem];
      }
    }
  }
  return icon;
}

var gCenterTimer = null;
var gZoomTimer = null;
/*Notify the bungee server that the center point has changed.
  We don't need to do this if the bungee server told us to move
  to this point as it will cause bouncing.*/
function _bl_map_center_changed()
{
  if (gCenterTimer != null)
  {
    clearTimeout(gCenterTimer);
    gCenterTimer = null;
  }
  var el = document.getElementById(this.cb_id);
  if (el)
  {
    var center  = el.cb_map.getCenter();
    if (center.equals(el.lastCenter))
    {
      return;
    }
    el.lastCenter = center;
    gCenterTimer = setTimeout("_bl_map_delayCenterChanged('" + this.cb_id + "')", 200);
  }
}

function _bl_map_delayCenterChanged(id)
{
  gCenterTimer = null;
  var el = document.getElementById(id);
  
  if (el)
  {
    var latLng = el.cb_map.getBounds();
    var center = latLng.getCenter();
    var xmlStr = "<centerChanged>"
               + bl_map_dumpLatLng(center) 
               + "</centerChanged>"
               + bl_map_dumpBounds(latLng);
    bl_mpr_send(xmlStr, el.id, 0);
  }
}

/*Notify the bungee server that the zoom level has changed.
  We don't need to do this if the bungee server told us to zoom
  to this point as it will cause bouncing.*/
function _bl_map_zoom_changed(oldZoom, newZoom)
{
  if (gZoomTimer != null)
  {
    clearTimeout(gZoomTimer);
    gZoomTimer = null;
  }
  gZoomTimer = setTimeout("_bl_map_delayZoomChanged(" + this.cb_id + "," + newZoom + ")", 
                          200);
}

function bl_map_dumpBounds(latLng)
{
  var sw = latLng.getSouthWest();
  var ne = latLng.getNorthEast();
  return ("<bounds><sw>" 
          + bl_map_dumpLatLng(sw) 
          + "</sw><ne>"
          + bl_map_dumpLatLng(ne) 
          + "</ne></bounds>");
}

function bl_map_dumpLatLng(latLng)
{
  return ("<lng>" + latLng.x + "</lng><lat>" + latLng.y + "</lat>");
}

function _bl_map_delayZoomChanged(id, newZoom)
{
  gZoomTimer = null;
  var el = document.getElementById(id);
  if (el && newZoom != el.cb_zoom_factor)
  {
    el.cb_zoom_factor = newZoom;
    var xmlStr = "<zoomLevelChanged>" + newZoom + "</zoomLevelChanged>";
    // include the bounding rect which changes with 
    var latLng = el.cb_map.getBounds();
    xmlStr += bl_map_dumpBounds(latLng);

    bl_mpr_send(xmlStr, el.id, 1);
  }
}

// The map is loaded and positioned notify the server of the current bounds.
function _bl_map_loaded(oldZoom, newZoom)
{
  var latLng = this.getBounds();
  var xmlStr = bl_map_dumpBounds(latLng);
  bl_mpr_send(xmlStr, this.cb_id, 0);
}

function bl_map_update_markers(el)
{
  var list = el.cb_marker_list;
  if (list.length > 1)
  {
    var map     = el.cb_map;
    for (var i in list.length)
    {
      var current = list[i];
      _bl_map_marker_cleanup(el.wincx, current);
      map.removeOverlay(current);
      if (!el.cb_trip_mode)
      {
        var newOver = _bl_map_marker(el, current.getPoint(), current.bl_label, current.iconArgs);
        list[i]     = newOver;
        map.addOverlay(newOver);
      }
    }
  }
}

function _bl_map_marker_click(point)
{
  var index = blu_array_findIndex(this.bl_parentEl.cb_marker_list, this);
  bl_map_selectIndex(this.bl_parentEl, index);
  if (index >= 0)
  {
    if (this.bl_label)
    {
      var html = "<div><b>" + this.bl_label + "</b></div>";
      this.openInfoWindowHtml(html);
    }
    var xmlStr = "<pinClicked>" + index + "</pinClicked>";
    bl_mpr_send(xmlStr, this.bl_parentEl.id, 0);
  }
}

function delayHover(elId)
{
  var el = document.getElementById(elId);
  if (el)
  {
    var xmlStr = "<pinHovered>" + el.hoverIndex + "</pinHovered>";
    bl_mpr_send(xmlStr, elId, 0);
  }
}

function _bl_map_marker_mOver(point)
{
  if (this.bl_parentEl.hoverTimer)
  {
    this.bl_parentEl.hoverTimer = clearTimeout(this.bl_parentEl.hoverTimer);
  }
  if (this.bl_label)
  {
    var html = "<div><b>" + this.bl_label + "</b></div>";
    this.openInfoWindowHtml(html);
  }
  var index = blu_array_findIndex(this.bl_parentEl.cb_marker_list, this);
  // If there is already a popup visible we need to take it down.
  bl_map_selectIndex(this.bl_parentEl, index);
  if (index >= 0)
  {
    this.bl_parentEl.hoverIndex = index;
    this.bl_parentEl.hoverTimer = setTimeout("delayHover(" + this.bl_parentEl.id + ")",250);
  }
}

function _bl_map_marker_mOut(point)
{
  if (this.bl_parentEl.hoverTimer)
  {
    this.bl_parentEl.hoverTimer = clearTimeout(this.bl_parentEl.hoverTimer);
  }
  bl_map_selectIndex(this.bl_parentEl, -1);
}

function _bl_map_closeMarkerInfoWindow()
{
  if (this.bl_label)
  {
    this.closeInfoWindow();
  }
  // find the popup window if one exists
  if (this.bl_parentEl.infoWindow && this.bl_parentEl.infoWindow.isOpen)
  {
    _bl_port_HidePopup(null, this.bl_parentEl.infoWindow.container);
  }
}

function bl_map_registerPopup(popup)
{
  // save off the infoWindow
  if (!this.infoWindow)
  {
    this.infoWindow = popup;
    this.infoWindow.popup_arg.canDestroy = false;
  }
    
  /*Find the marker location in browser window coordinates*/
  if (this.currPopupIndex >= 0 && this.selectedIndex == this.currPopupIndex)
  {
    var marker = this.cb_marker_list[this.currPopupIndex];
    if (marker)
    {
      return true;
    }
  }
  
  // we failed to register the Popup. The hover/selected pin has changed.
  _bl_port_HidePopup(null, popup.container);
  return false;
}

function bl_map_contentPosition(itemIndex, bounds)
{  
  /*Find the marker location in browser window coordinates*/
  if (itemIndex >= 0)
  {
    if (this.currPopupIndex != itemIndex && this.currPopupIndex >= 0)
    { // close down previous popup windows
      var oldMarker = this.cb_marker_list[itemIndex];
      if (oldMarker)
      {
        _bl_map_closeMarkerInfoWindow.call(oldMarker);
      }
    }
    this.currPopupIndex = itemIndex;
    var marker = this.cb_marker_list[itemIndex];
    if (marker)
    {
      var mapBounds = this.cb_map.getBounds();
      var latLng = marker.getLatLng();
      if (mapBounds.contains(latLng))
      {
        var point = this.cb_map.fromLatLngToContainerPixel(latLng);
        var icon = marker.getIcon();
        bounds.x += (point.x - icon.iconAnchor.x);
        bounds.y += (point.y - icon.iconAnchor.y);
        bounds.bottom = bounds.y + icon.iconSize.height;  
        bounds.right  = bounds.x + icon.iconSize.width;
        bounds.width  = icon.iconSize.width;  
        bounds.height = icon.iconSize.height;
        return true;
      }
    }
  }
  return false;
}
/*
  Verify that the map already has a popup window. Re-position it
  anchored to the marker[itemIndex]
*/
function bl_map_showInfoWnd(el, itemIndex)
{
  if (el.infoWindow)
  {
    el.infoWindow.popup_arg.itemIndex = itemIndex;
    el.infoWindow.show();
  }
}

function _bl_map_get_size(wincx, item)
{
  return new wincx.GSize(bl_port_get_text(parseInt(item.childNodes[0])), parseInt(item.childNodes[1]));
}

function _bl_map_get_point(wincx, item)
{
  return new wincx.GPoint(parseInt(bl_port_get_text(item.childNodes[0])), parseInt(item.childNodes[1]));
}

/*
Request the GeoCoded point from either the address text or LatLng points.
This function is delayed as it may require a call to Google server. 
*/
function bl_map_getLatLngFromAddress(el, index, item, retryCount)
{
  if (!el)
  {
    return; 
  }
  if ((item.lat == 0 || item.lat == NaN) && (item.lng == NaN || item.lng == 0) && item.addr && item.addr != "")
  { // using GGeoClientCode get the lat and long from a textual address.
    if (!el.clientGeoCoder)
    {
      el.clientGeoCoder = new el.wincx.GClientGeocoder(new el.wincx.bl_map_GeocodeCache());
    }
    if (el.clientGeoCoder)
    {
      // create a closure function
      var geoCodePlacemarkCallback = function (arg)
      {
        if (arg.Status.code == el.wincx.G_GEO_SUCCESS)
        { // we successfully looked-up the address
          item.addrLookup = true;
          item.lng = arg.Placemark[0].Point.coordinates[0];
          item.lat = arg.Placemark[0].Point.coordinates[1];
          bl_map_AddOrUpdatePoint(el, index, item);
        }
        else
        {
          if (arg.Status.code == el.wincx.G_GEO_TOO_MANY_QUERIES && retryCount < 10)
          { 
            retryCount++;
            // send the message again
            bl_map_getLatLngFromAddress(el, index, item, retryCount);
          }
          else
          { // send the error code back to the server
            var xmlStr = "<error code='" + arg.Status.code + "' index='" + index + "'/>";
            // send the error message now 
            bl_mpr_send(xmlStr, el.id, -1, BL_MPR_ASAP);
          }
        }
      } // end geoCodePlacemarkCallback

      // We want to delay this request for addresses because
      bl_map.lookups.push({"addr" : item.addr, "callback" : geoCodePlacemarkCallback, "el" : el})
      if (!bl_map.intervalId)
      {
        bl_map.intervalId = setInterval(bl_map_lookupAddresses, 500); 
      }
    }
  }
  else
  {
    // we need to have the map centered before we can add the points to the map.
    bl_map_AddOrUpdatePoint(el, index, item);
  }
}

/*Called from SetInterval*/
function bl_map_lookupAddresses()
{
  var addrLookup;
  var count = Math.min(bl_map.lookups.length, 4);
  for (var i = 0; i < count; i++)
  {
    addrLookup = bl_map.lookups.pop()
    addrLookup.el.clientGeoCoder.getLocations(addrLookup.addr, addrLookup.callback);
    if (bl_map.lookups.length == 0)
    { // we don't have any more items to lookup. Clear the interval timer
      bl_map.intervalId = clearInterval(bl_map.intervalId);
      return;
    }
  }
}

function bl_map_AddOrUpdatePoint(el, index, item)
{
  // add the point to the marker list  
  var map       = el.cb_map;
  /* send the point back to the server but we don't want to do it right away
     because we assume the address is the correct point */
  var latLng = new el.wincx.GLatLng(item.lat, item.lng);
  if (item.addrLookup)
  { // if we looked up the address send the lat lng back to the server
    var xmlStr = "<pointChanged><index>" + index + "</index>"
                 + bl_map_dumpLatLng(latLng) 
                 + "</pointChanged>";
    // determine if we want to send this now or defer it based on if we have more addresses to lookup
    var msgType = bl_map.lookups.length == 0 ? BL_MPR_ASAP : BL_MPR_DEFER;
    bl_mpr_send(xmlStr, el.id, -1, msgType);
  }

  var marker = el.cb_marker_list[index];
  if (!marker)
  { // create the marker
    marker = _bl_map_marker(el, latLng, item.label, item.iconArgs);
    el.cb_marker_list[index] = marker;
    // Add the marker to the map if we are displaying markers.
    if (!el.cb_trip_mode)
    { 
      map.addOverlay(marker);
    }
  }
  else
  { // update the marker location
    marker.setLatLng(latLng);
  }
  if (el.selectedIndex && el.selectedIndex == index)
  {
    _bl_map_pan_to(el, latLng);
  }
}

function _bl_map_remove(el, item)
{
  var index        = parseInt(bl_port_get_text(item.firstChild));
  var removedList  = el.cb_marker_list.splice(index, 1);
  var marker       = removedList[0];
  el.cb_map.removeOverlay(marker);
  _bl_map_marker_cleanup(el.wincx, marker);
}

function bl_map_select(el, item, zoom)
{
  var index = parseInt(bl_port_get_text(item.firstChild));

  bl_map_selectIndex(el, index);
  if (zoom)
  {
    var marker  = el.cb_marker_list[index];
    if (marker)
    {
      _bl_map_pan_to(el, marker.getLatLng());
    }
  }
}

function bl_map_selectIndex(el, index)
{
  var marker;
  var oldSelection = el.selectedIndex;
  if (oldSelection == index)
  {
    return;
  }
  
  el.selectedIndex = index;
  if (oldSelection >= 0)
  {
    marker  = el.cb_marker_list[oldSelection];
    if (marker)
    {
      with (marker)
      {
        if (iconArgs && iconArgs.hoverImage)
        {
          setImage(iconArgs.image);
        }
      }
      _bl_map_closeMarkerInfoWindow.call(marker);
    }
  }
  if (index >= 0)
  {
    marker = el.cb_marker_list[index];
    if (marker)
    {
      with (marker)
      {
        if (iconArgs && iconArgs.hoverImage)
        {
          setImage(iconArgs.hoverImage);
        }
      }
    }
  }
}


function _bl_map_removeAll(el, item)
{
  var markerList = el.cb_marker_list;
  el.cb_map.clearOverlays();
  for (var i in markerList)
  {
    _bl_map_marker_cleanup(el.wincx, markerList[i]);
  }
  el.cb_marker_list = new Array();
}

function bl_map_removePendingLookups()
{
  // remove the pending lookups
  if (bl_map.lookups.length)
  {
    bl_map.lookups = new Array();
  }
  if (bl_map.intervalId)
  {
    bl_map.intervalId = clearInterval(bl_map.intervalId);
  }
}

function _bl_map_invalidate(el, item)
{
  bl_map_removePendingLookups();
  _bl_map_removeAll(el, item);
  _bl_map_add_collection(el, item);
}

function _bl_map_add_collection(el, item)
{
  var nodes  = item.childNodes;
  var len    = nodes.length;
  for (var i = 0; i < len; i++)
  {
    _bl_map_process_xml(el, nodes.item(i), true);
  }
}

function _bl_map_remove_collection(el, item)
{
  var nodes  = item.childNodes;
  var len    = nodes.length;
  for (var i = 0; i < len; i++)
  {
    _bl_map_process_xml(el, nodes.item(i), false);
  }
}

function _bl_map_move(el, item)
{
  var list        = el.cb_marker_list;
  var oldIndex    = parseInt(bl_port_get_text(item.firstChild));
  var newIndex    = parseInt(bl_port_get_text(item.lastChild));
  var removedList = el.cb_marker_list.splice(oldIndex, 1);
  var marker = removedList[0];
  list.splice(newIndex, 0, marker);
}

function bl_map_add(el, addNode)
{
  if (addNode && addNode.firstChild)
  {
    var itemEv = {label:0, lng:1, lat:2, addr:3, iconArgs:4};
    var itemNode = addNode.firstChild;
    var index = parseInt(bl_port_get_text(addNode.lastChild));
    var args = { 
    "lng" : parseFloat(bl_port_get_text(itemNode.childNodes[itemEv.lng])),
    "lat" : parseFloat(bl_port_get_text(itemNode.childNodes[itemEv.lat])),
    "addr" : bl_port_get_text(itemNode.childNodes[itemEv.addr]),
    "label" : bl_port_get_text(itemNode.childNodes[itemEv.label]),
    "iconArgs":eval(bl_port_get_text(itemNode.childNodes[itemEv.iconArgs]))};
    bl_map_getLatLngFromAddress(el, index, args, 0);
  }
}


function bl_map_updateMarkerPosition(el, posNode)
{
  if (posNode)
  {
    var updateEv = {addr:0, lng:1, lat:2, index:3};
    var index = parseInt(bl_port_get_text(posNode.childNodes[updateEv.index]));
    var args = {     
    "lng"  : parseFloat(bl_port_get_text(posNode.childNodes[updateEv.lng])),
    "lat"  : parseFloat(bl_port_get_text(posNode.childNodes[updateEv.lat])),
    "addr" : bl_port_get_text(posNode.childNodes[updateEv.addr])};
    bl_map_getLatLngFromAddress(el, index, args, 0) 
  }
}


function _bl_map_process_xml(el, data, add)
{
  if (data)
  {
    var node = data.firstChild;
    if (node && node.nodeName == "points")
    {
      node = node.firstChild;
    }
    while (node != null)
    {
      if (add)
      {
        bl_map_add(el, node);
      }
      else
      {
        _bl_map_remove(el, node);
      }
      node = node.nextSibling;
    }
  }
}

function _bl_map_pan_to(el, latLng)
{
  if (latLng.lng() == -95.677068 && latLng.lat() == 37.062500)
  {
    bl_map_centerAndZoom(el, latLng, 15)
  }
  else
  {
    el.cb_map.setZoom(el.cb_zoom_factor);
    el.cb_map.panTo(latLng);
  }
}

function bl_map_centerAndZoom(el, latLng, zoomFac)
{
  var map    = el.cb_map;
  // Changes the center point of the map to the given point
  var centerPt = map.getCenter();
  if (!centerPt || !centerPt.equals(latLng))
  {
    el.lastCenter = latLng;
    el.cb_map.setCenter(latLng, zoomFac);
  }
}

function _bl_resize_map(el, resizeQueue)
{
  if (el.cb_map)
  {
    el.cb_map.checkResize();
  }
}

/*NULL out the element's properties. GUnload should have already taken care of unloading the map's elements*/
function _bl_map_cleanup(el)
{
  if (el.directions)
  {
    el.directions.wayPoints = null;
    el.directions         = null;
  }

  var markerList  = el.cb_marker_list;
  for (var i in markerList)
  {
    _bl_map_marker_cleanup(el.wincx, markerList[i]);
  }
  el.cb_map       = null;
  el.cb_polyline_list   = null;
  el.cb_marker_list     = null;
  el.onresize           = null;
  if (el.infoWindow)
  {
    el.infoWindow.popup_arg.canDestroy = true;
    _bl_port_doClosePopup(null, el.infoWindow.container);
    el.infoWindow         = null;
  }
  for (var event in el.bl_listeners)
  {
    el.bl_listeners[event] = null;
  }
  el.bl_listeners  = null;
  el.cb_large_control   = null;
  el.cb_type_control    = null;
  el.cb_overview_contrl = null;
  el.dirPanel           = null;
  el.mapObj             = null;
}

function bl_gmap_window_context(id)
{
  var elem = document.getElementById(id);
  return elem.getElementsByTagName("iframe")[0].contentWindow;
}

function _bl_gmap_load(id, centerLong, centerLat, zoomLevel, tripMode)
{
  var XMLData = document.getElementById(id + "_Data");
  var el      = document.getElementById(id);

  var wincx = bl_gmap_window_context(id);

  if (wincx && wincx.GBrowserIsCompatible && wincx.GBrowserIsCompatible() && el)
  {
    bl_sys_addCleanUpCall(el, _bl_map_cleanup);
    el.mapObj = wincx.document.getElementById("map");
    var map = el.cb_map = new wincx.GMap2(el.mapObj);

    el.wincx = wincx;
    el.selectedIndex = -1;
    el.cb_marker_list     = new Array();
    el.cb_polyline_list   = new Array();
    el.cb_large_control   = new wincx.GLargeMapControl();
    el.cb_type_control    = new wincx.GMapTypeControl();
    el.cb_overview_contrl = new wincx.GOverviewMapControl();
    el.cb_trip_mode       = parseInt(tripMode);
    el.bl_listeners = new Array();
    el.bl_listeners["zoomed"] = wincx.GEvent.addListener(el.cb_map, "zoomend", _bl_map_zoom_changed);
    el.bl_listeners["moved"]  = wincx.GEvent.addListener(el.cb_map, "moveend", _bl_map_center_changed);
    el.bl_listeners["loaded"] = wincx.GEvent.addListener(el.cb_map, "load", _bl_map_loaded);
    el.contentPosition = bl_map_contentPosition;
    el.registerPopup   = bl_map_registerPopup;
    map.cb_id             = id;
    el.cb_zoom_factor     = parseInt(zoomLevel);
    map.enableScrollWheelZoom(true);
    map.addControl(el.cb_large_control);
    map.addControl(el.cb_type_control);
    map.addControl(el.cb_overview_contrl);
    var point  = new wincx.GPoint(centerLong, centerLat);
    var data;

    if (XMLData)
    {
      data = bl_port_selectSingleNode(bl_port_get_XMLDocument(XMLData), "mapdata");
      
      if (data.childNodes.length == 2 && data.lastChild.nodeName == "directions")
      { /*Create the map coordinates.*/
        bl_map_directions(el, data.lastChild);
      }
      if (XMLData.parentNode)
      {
        XMLData.parentNode.removeChild(XMLData);
      }
      // TODO: test in ff for parentNode
      else if (XMLData.parentElement)
      {
        XMLData.parentElement.removeChild(XMLData);
      }
      if (!el.printLink)
      {
        var bShowPrint = XMLData.getAttribute("printLink");
        if (bShowPrint == 1)
        { 
          bl_map_createPrintLink(el);
        }
      }
      el.selectedIndex = parseInt(data.getAttribute("selected"));
    }
    if (!el.cb_trip_mode || !el.directions)
    { // Mapping directions will automatically center and zoom the map.
      bl_map_centerAndZoom(el, new wincx.GLatLng(point.y, point.x), parseInt(zoomLevel));
    }
    // process
    if (data)
    {
      _bl_map_process_xml(el, data, true);
    }
    
  }
}

/*Create the print link and add it to the google map element.*/
function bl_map_createPrintLink(el)
{
  // skip out if we don't have a map element or if we already created the print Link.
  if (!el.mapObj || el.printLink)
  {
    return;
  }
  el.printLink = el.wincx.document.createElement("div");
  el.printLink.className = "gmnoprint";
  el.printLink.style.position = "absolute";
  el.printLink.style.left = "70px";
  el.printLink.style.bottom = "10px";
  el.printLink.innerHTML = "<a href='javascript:void(0);' onclick='window.parent._bl_map_onPrint(event," + el.id + 
                           "); return false;' style='font:10pt arial;'>" +
                           "<img style='vertical-align:bottom; border:none;background:transparent;' " +
                           "src='/" + bl_version + "/res/img/bungee/controls/print.png'/>" +
                           "<span>Print</span></a>";
  el.mapObj.appendChild(el.printLink);
}

/*Hide/Show functionality for the GoogleMaps*/
function bl_map_showPrintLink(el, val)
{
  if (val == 1)
  { 
    if (!el.printLink)
    {
      bl_map_createPrintLink(el);
    }
    else if (el.printLink.style.display == "none")
    {
      el.printLink.style.display = "";
    }
  }
  else if(el.printLink && el.printLink.style.display != "none")
  {
    el.printLink.style.display = "none";
  }
}

// Print the google maps iframe.
function _bl_map_onPrint(event, id)
{
  var el = document.getElementById(id);
  if (el)
  {
    _bl_map_print(el)
  }
  bl_port_killEvent(event);
  return false;
}

function _bl_map_label_changed(el, item)
{
  var label = item.firstChild;
  var index = parseInt(bl_port_get_text(item.lastChild));
  var marker = el.cb_marker_list[index];
  if (marker)
  {
    marker.bl_label = bl_port_get_text(label);
  }
}

/*Create the print URL and open a new window. 
Printing directions opens a google maps window.
Printing a regular map with markers just prints the iframe.
http://maps.google.com/maps?f=d&hl=en&geocode=&saddr=625+E+1600+N,+Orem,+UT+84097
&daddr=528+Rocky+Knoll+Ln,+Draper,+UT+84020+
to:14712+Evening+Side+Dr,+Riverton,+UT+84065&mra=ps&mrcr=0,1&jsv=107
&sll=40.417105,-111.853&sspn=0.342939,0.600815&ie=UTF8&z=11&pw=2
*/
function _bl_map_print(el)
{
  if (el.cb_trip_mode && el.directions && el.directions.wayPoints.length > 1)
  {
    var start = el.directions.wayPoints[0]
    var end = getEndAddress(el.directions.wayPoints);
    var center = el.cb_map.getCenter();
    var url = "http://maps.google.com/maps?f=d&hl=en&geocode=&saddr=" + start.replace(/ /g, "+") + 
              "&daddr=" + end.replace(/ /g, "+") + "&sll=" + center.toUrlValue(6) +
              "&sspn=" + el.cb_map.getBounds().toSpan().toUrlValue(6)+
              "&ie=UTF8&z=" + el.cb_map.getZoom() + "&pw=2";
    window.open(url, "printWindow");
  }
  else
  { // print the map as it is visible so that we can keep the customized markers.
    el.wincx.print()
  }
}

/*create the end addres from the waypoints. this allows us to have multiple points
 along the route*/
function getEndAddress(waypoints)
{
  var end = "";
  for (var i = 1; i < waypoints.length; i++)
  {
    if (i > 1)
    {
      end += "+to:";
    }
    end += waypoints[i];
  }
  return end;
}

//Handler to center the map at this position
function _bl_map_zoom_position(el, item)
{
  var map         = el.cb_map;
  var lng         = parseFloat(bl_port_get_text(item.childNodes[0]));
  var lat         = parseFloat(bl_port_get_text(item.childNodes[1]));
  var latLng      = new el.wincx.GLatLng(lat, lng);
  // Changes the center point of the map to the given point
  var center = map.getCenter();
  if (!center.equals(latLng))
  {
    el.lastCenter = latLng;
    map.panTo(latLng)
  }
}

function bl_map_clear_directions(dir)
{
  if (dir)
  {
    dir.clear();
    // Clear out the old wayPoints and force garbage collection.
    if (dir.wayPoints)
    {
      delete dir.wayPoints;
      dir.wayPoints = null;
    }
  }
}
/*
  Create a list of GDirections in order to create the directions
*/
function bl_map_directions(el, val)
{
  if (val)
  {
    var list = val.childNodes;
    if (list.length < 2)
    { // we need at least two points in order to have directions
      bl_map_clear_directions(el.directions);
      return;
    }
    var wayPoints = new Array();
    for (var i = 0; i < list.length; i++)
    {
      /* PolyList indexes
        Lat = 0
        Long = 1
        address = 2
      */
      var xmlPolyList   = list[i].childNodes;
      var line          = new String;
      if (xmlPolyList.length != 3)
      { // there is something wrong with xml. We were expecting a different number of children.
        return;
      }
      line.address      = bl_port_get_text(xmlPolyList[2]);
      // A textual input address gets precedence to lat/lon points
      if (line.address != "")
      { 
        wayPoints.push(line.address);
      }
      else if (parseFloat(bl_port_get_text(xmlPolyList[0]) && parseFloat(bl_port_get_text(xmlPolyList[1]))))
      {
        wayPoints.push(bl_port_get_text(xmlPolyList[1]) + "," + bl_port_get_text(xmlPolyList[0]))
      }
    }
    // Create a directions object and register a map and DIV to hold the 
    // resulting computed directions
    if (wayPoints.length > 1)
    {
      var bLeft = (val.getAttribute("align") != "rt");
      var dirPanelLeft = el.wincx.document.getElementById("dirPanelLt");
      var dirPanelRight = el.wincx.document.getElementById("dirPanelRt");
      if (dirPanelLeft && dirPanelRight)
      {
        if (bLeft)
        { 
          if (el.dirPanel != dirPanelLeft)
          {
            // clear out the old direction control because the panel is tied to something else now
            el.directions = null;
            el.dirPanel = dirPanelLeft;
          }
          // hide the dirPanelRight
          dirPanelRight.parentNode.parentNode.style.display = "none";
        }
        else
        { // hide the dirPanelLeft
          if (el.dirPanel != dirPanelRight)
          {
            // clear out the old direction control because the panel is tied to something else now
            el.directions = null;
            el.dirPanel = dirPanelRight;
          }
          dirPanelLeft.parentNode.parentNode.style.display = "none";
        }      
      }
      if (el.dirPanel)
      { 
        el.dirPanelProportion = val.getAttribute("proportion");
        el.dirPanelProportion = el.dirPanelProportion ? +el.dirPanelProportion : 0;
        // if the dirPanel Proportion won't show the dirPanel keep it hidden;
        if (el.dirPanelProportion > 0 && el.dirPanelProportion < 100)
        {
          el.mapObj.parentNode.style.width = (100 - el.dirPanelProportion) + "%";
          el.dirPanel.parentNode.parentNode.style.width = el.dirPanelProportion + "%";;
          el.dirPanel.parentNode.parentNode.style.display = "";
        }
        else
        {
          el.dirPanel.parentNode.parentNode.style.display = "none";
          el.dirPanel = null;
        }
        _bl_resize_map(el)
      }
      if (!el.directions)
      {
        el.directions = new el.wincx.GDirections(el.cb_map, el.dirPanel);
        el.wincx.GEvent.addListener(el.directions, "load", bl_map_gDir_onLoad);
        el.wincx.GEvent.addListener(el.directions, "error", bl_map_gDir_handleErrors);
      }
      el.directions.bl_xmlDirections = val;
      el.directions.parentObject = el;
      el.directions.wayPoints = wayPoints;

      /* we want the map to load the directions on a delayed basis so that
         the dirPanel and map area can size properly first*/
      var loadDirections = function ()
      {
        if (el.directions)
        {
          el.directions.loadFromWaypoints(el.directions.wayPoints);
        }
      }
      setTimeout(loadDirections,1);
    }
  }
  else
  {
    bl_map_clear_directions(el.directions);
  }
}

/*This event is triggered when the results of a directions query issued 
  via GDirections.load() are available. Note that the load() method initiates 
  a new query, which in turn triggers a "load" event once the query has 
  finished loading. The "load" event is triggered before any overlay elements 
  are added to the map/panel.*/
function  bl_map_gDir_onLoad()
{ /*Event fired when the directions have loaded. We can modify the PolyLines at this time */
  var xml = this.bl_xmlDirections;
  var polyLine = this.getPolyline();
  // we decorate the polyline with the attributes from the directions node
  if (!polyLine || !xml)
  { return;
  }
  var color = xml.getAttribute("color");
  if (color && color != "")
  {
    polyLine.color = color;
  }
  var weight = xml.getAttribute("weight");
  if (weight > 0)
  {
    polyLine.weight = parseInt(weight);
  }
  var opacity = xml.getAttribute("opacity");;
  if (opacity > 0)
  {
    polyLine.opacity = parseFloat(opacity);
  }
}

function  bl_map_gDir_handleErrors()
{ /*These strings need to be translated*/
  var gWindow = this.parentObject.wincx;
  bl_map_handleErrors(gWindow, this.getStatus().code)
}

function  bl_map_handleErrors(wincx, code, name)
{ /*These strings need to be translated*/
  if (code == wincx.G_GEO_UNKNOWN_ADDRESS)
    wincx.GLog.write("No corresponding geographic location could be found for one of the specified addresses.\nThis may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " 
          + code 
          + "\nAddress: " + name);
  else if (code == wincx.G_GEO_SERVER_ERROR)
    wincx.GLog.write("A geocoding or directions request could not be successfully processed, yet the exact \nreason for the failure is not known.\n Error code: "
          + code 
          + "\nAddress: " + name);
  else if (code == wincx.G_GEO_MISSING_QUERY)
    wincx.GLog.write("The HTTP q parameter was either missing or had no value. For geocoder requests, this \nmeans that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " 
          + code 
          + "\nAddress: " + name);
  else if (code == wincx.G_GEO_UNAVAILABLE_ADDRESS)
    wincx.GLog.write("The geocode for the given address or the route for the given directions query cannot \nbe returned due to legal or contractual reasons.\n Error code: " 
          + code 
          + "\nAddress: " + name);
  else if (code == wincx.G_GEO_BAD_KEY)
    wincx.GLog.write("The given key is either invalid or does not match the domain for which it was given. \n Error code: " 
          + code 
          + "\nAddress: " + name);
  else if (code == wincx.G_GEO_BAD_REQUEST)
    wincx.GLog.write("A directions request could not be successfully parsed.\n Error code: "
          + code 
          + "\nAddress: " + name);
  else wincx.GLog.write("An unknown error occurred. \nGoogle Maps error code: " 
          + code 
          + "\nAddress: " + name);
}

function bl_map_toggle_trip_mode(el)
{
  el.cb_trip_mode = !el.cb_trip_mode;
  if (el.directions)
  {
    //clear out the previous directions.
    el.directions.clear();
  }
  if (!el.cb_trip_mode)
  {
    // hide the dirPanel
    if (el.dirPanel)
    {
      el.dirPanel.parentNode.parentNode.style.display = "none";
    }
    // show any markers
    bl_map_update_markers(el);
    _bl_resize_map(el);
  }
  else
  {
    //clear out any points
    el.cb_map.clearOverlays();
  }
  // the directions are updated when processing its xml
}


// change the color/opacity or weight of the directions polyline
// the arg paramet is a JSON object with one color opacity or weight parameter defined.
function bl_map_polyline_changed(el, arg)
{
  if (!el.directions || !arg)
  {
    return false;
  }
  var polyLine = el.directions.getPolyline();
  // we decorate the polyline with the attributes from the directions node
  if (!polyLine)
  {
    return false;
  }
  var polyLineNew = polyLine;
  var val
  if (arg.color)
  {
    val = bl_port_get_text(arg.color.firstChild);
    if (val && val != "")
    {
      polyLineNew.color = val;
    }
  }
  else if (arg.opacity)
  {
    val = parseFloat(bl_port_get_text(arg.opacity.firstChild));
    if (val)
    {
      polyLineNew.opacity = val;
    }
  }
  else if (arg.weight)
  {
    val = parseInt(bl_port_get_text(arg.weight.firstChild));
    if (val)
    {
      polyLineNew.weight = val;
    }
  }
  //Hide/Show the polyline to cause it to redraw.
  el.cb_map.removeOverlay(polyLine);
  el.cb_map.addOverlay(polyLineNew);
}

function bl_map_zoom_factor_changed(el, val)
{
  el.cb_zoom_factor = parseInt(bl_port_get_text(val));
  el.cb_map.setZoom(el.cb_zoom_factor);
}

function _bl_map_directions_defer(id)
{
  var el = document.getElementById(id);
  if (el && el.cb_trip_mode)
  {
    bl_map_directions(el, el.cb_directions_data);
    el.cb_directions_data = null;
  }
}

function _bl_map_handler(item, el)
{
  var val   = item.firstChild;
  var name  = val.nodeName;

  if (el.cb_map)
  {
    if (name == "add")
    {
      bl_map_add(el, item.firstChild);
    }
    else if (name == "remove")
    {
      _bl_map_remove(el, item);
    }
    else if (name == "removeAll")
    {
      _bl_map_removeAll(el, item);
    }
    else if (name == "invalidate")
    {
      _bl_map_invalidate(el, item);
    }
    else if (name == "move")
    {
      _bl_map_move(el, item.firstChild);
    }
    else if (name == "addCollection")
    {
      _bl_map_add_collection(el, item);
    }
    else if (name == "removeCollection")
    {
      _bl_map_remove_collection(el, item);
    }
    else if (name == "select")
    {
      bl_map_select(el, item, (val.getAttribute("zoom") == "true"));
    }
    else if (name == "labelChanged")
    {
      _bl_map_label_changed(el, val);
    }
    else if (name == "positionChanged")
    {
      bl_map_updateMarkerPosition(el, val);
    }
    else if (name == "showPrint")
    {
      var bShowPrint = bl_port_get_text(val);
      bl_map_showPrintLink(el, parseInt(bShowPrint));
    }
    else if (name == "zoomPosition")
    {
      _bl_map_zoom_position(el, val);
    }
    else if (name == "directions")
    {
      el.cb_directions_data = val;
      window.setTimeout("_bl_map_directions_defer(" + el.id + ");", 1);
    }
    else if (name == "toggleTripMode")
    {
      bl_map_toggle_trip_mode(el);
    }
    else if (name == "polyColor")
    {
      bl_map_polyline_changed(el, {color:val});
    }
    else if (name == "polyOpacity")
    {
      bl_map_polyline_changed(el, {opacity:val});
    }
    else if (name == "polyWeight")
    {
      bl_map_polyline_changed(el, {weight:val});
    }
    else if (name == "zoomLevel")
    {
      bl_map_zoom_factor_changed(el, val);
    }
    else if (name == "showInfoWnd" && !el.cb_trip_mode)
    {
      bl_map_showInfoWnd(el, bl_port_get_text(val));
    }
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_map_last()
{
  var x = 0;
}

//***********************************************************************
//***********************************************************************
//********                     bl_mcl.js                        *********
//***********************************************************************
//***********************************************************************
var bl_mcl_drag_el             = null;
var bl_mcl_header_drag_el      = null;

function _bl_mcl_init(id, sig, sel, ism, rem, clo)
{
  var el = document.getElementById(id);
 
  if (el)
  {
    var mgr = new bl_sel_createMgr(el, 
                                   sig, 
                                   sel, 
                                   ism, 
                                   rem, 
                                   clo, 
                                   bl_mcl_rowIndex,
                                   bl_mcl_row,
                                   bl_mcl_findRow,
                                   null,
                                   null,
                                   bl_mcl_itemSelected,
                                   bl_mcl_getLength,
                                   null);

    bl_mcl_adjustForHeight(el);
  }
}


function bl_mcl_adjustForHeight(el)
{
  if (el && bl_browserInfo.firefox)
  {
    var divEl = bl_mcl_get_table(el).parentNode;

    if (divEl.getAttribute("bl_natural") == null)
    {
      // This allows the height of the entire table to be computed correctly.
      divEl.style.height = 0;
      var clientHeight   = el.clientHeight;
      var offsetHeight   = el.offsetHeight;
      divEl.style.height = (clientHeight - el.rows[0].offsetHeight - (offsetHeight - clientHeight)) + "px";
    }

    if (bl_browserInfo.firefox3)
    {
      // The browser does not calculate the correct initial size based on the
      // value of the COLGROUP tag. This appears to be related to mozilla bug
      // #359636.  https://bugzilla.mozilla.org/show_bug.cgi?id=359636
      var parentEl     = el.parentNode;
      var parentLayout = parseInt(parentEl.getAttribute("bl_layout"));

      if (parentLayout > bl_contain_type_vertical)
      {
        var headerTable  = blu_getChild(el,"TABLE", "items");
        headerTable.style.width = (el.clientWidth - window.bl_sb_dim.width - 2)+"px";

        if (el.ff3_widthTimer)
        {
          clearTimeout(el.ff3_widthTimer);
        }
        el.ff3_widthTimer = setTimeout("_bl_mcl_ff3_fixHeaderWidth('"+el.id+"')",10);
      }      
    }

  }
}

function _bl_mcl_ff3_fixHeaderWidth(id)
{
  var el          = document.getElementById(id);
  var headerTable = blu_getChild(el,"TABLE", "items");

  headerTable.style.width = "100%";
  delete el.ff3_widthTimer;
}

function _bl_mcl_initHeight(id)
{
  bl_mcl_adjustForHeight(document.getElementById(id));
}

function bl_mcl_itemSelected(el, row, selected, active, flyover, concretSelect)
{
  var isAlt = (row.getAttribute('bl_bk_alt') != null);
  
  if (flyover)
  {
    bl_mcl_copy_background_tr(row, bl_mcl_get_sel_f_css(row, isAlt));
  }
  else
  {
    if (selected)
    {
      var sourceCss = (active ? bl_mcl_get_sel_css(row, isAlt) : bl_mcl_get_sel_d_css(row, isAlt));
      bl_mcl_copy_background_tr(row, sourceCss);
    }
    else
    {
      var sourceCss = bl_mcl_get_cell_css(row, isAlt);
      bl_mcl_copy_background_tr(row, sourceCss);
    }
  }
}

function _bl_mcl_resize(el, resizeQueue)
{
  var tableEl = bl_mcl_get_table(el);
  var row     = tableEl.lastChild.firstChild;
  
  while (row)
  {
    var cell = row.firstChild;
    
    while (cell)
    {
      var item = cell.firstChild;
      
      if (item && item.getAttribute("cb_tag") == "CTR")
      {
        item.style.width = "100%";
        resizeQueue.push(item);
      }
      cell = cell.nextSibling;
    }
    row = row.nextSibling;
  }

  bl_mcl_adjustForHeight(el);
  
  
  if (!el.bl_timerid)
  {
    el.bl_timerid = window.setTimeout("_bl_mcl_callSave(" + el.id + ");", 500);
  }
}

function _bl_mcl_callSave(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    el.bl_timerid = undefined;
    
    if (!bl_mcl_save_state(el, true))
    {
      el.bl_timerid = window.setTimeout("_bl_mcl_callSave(" + el.id + ");", 500);
    }    
  }
}

function bl_mcl_get_tbody(el)
{
  return el.rows[1].firstChild.firstChild.firstChild.firstChild;
}

function bl_mcl_get_rows(el)
{
  return el.rows[1].firstChild.firstChild.firstChild.rows;
}

function bl_mcl_get_table(el)
{
  return el.rows[1].firstChild.firstChild.firstChild;
}

function bl_mcl_findRow(par, src)
{
  var row = src;
  while (row)
  {
    row = row.parentNode;
    if (row && row.tagName == "TR")
    {
      var el = row.parentNode;
      if (el && el.tagName == "TBODY" && el.parentNode.id == "LIST_TABLE")
      {
        return row;
      }
    }
  }
  return null;
}

function bl_mcl_rowIndex(par, row)
{
  return bl_port_get_rowIndex(row);
}

function bl_mcl_getLength(par)
{
  var len = 0;
  try
  {
    var rows  = bl_mcl_get_rows(par);
    if (rows)
    {
      len = rows.length;
    }
  }
  catch (exception)
  {
    len = 0;
  }
  return len;
}

function bl_mcl_row(par, index)
{
  var row = null;
  try
  {
    var rows = bl_mcl_get_rows(par);
    if (rows.length > index && index >= 0)
    {
      row = rows[index];
    }
  }
  catch (exception)
  {
  }
  return row;
}

function bl_mcl_inListParent(el, src)
{
  var parent = src;
  
  while (parent && parent.id != el.id)
  {
    if (parent.id == "LIST_PARENT")
    {
      return parent;
    }
    
    parent = parent.parentNode;
  }
  return null;
}

function _bl_mcl_ddHintDrop(event, hintImage)
{
  _bl_mcl_drop(event, this.el);
}

function _bl_mcl_ddOver(event, el)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {
    var zoneList     = el.getAttribute("bl_zone_list");
    var src          = bl_port_getEventTarget(event);
    var child        = bl_mcl_findRow(el, src);
    var divParent    = bl_mcl_inListParent(el, src);
    var isValidDrop  = false;
    
    if (zoneList)
    {
      if (child)
      {
        if (!cb_sys_isInput(src))
        {
          isValidDrop = bl_dd_checkList(ddObj, event, zoneList);
        }
      }
      else if (divParent)
      {
        child = divParent;
        isValidDrop = bl_dd_checkList(ddObj, event, zoneList)
      }
    }
        
    if (isValidDrop)
    {
      var maxwidth    = (divParent && divParent.clientWidth < 100)? divParent.clientWidth:100;
      var hintContext = { el:el,
                          child:child,
                          hintDrop:_bl_mcl_ddHintDrop,
                          dimension:3,
                          size:maxwidth,
                          x:event.clientX,
                          y:event.clientY,
                          isVertical:true
                        };
                    
      ddObj.setHint(hintContext);
      bl_port_killEvent(event);
      return ;
    }

    ddObj.clearEffect();
  }
}

function _bl_mcl_ddOut(event, el)
{
  var ddObj  = bl_dd_getDragDropObj();
  
  if (ddObj)
  {
    var clientx = event.clientX;
    var clienty = event.clientY;
    var pos     = bl_sys_find_xy(el, null, false);
    
    if (pos.x <= clientx && 
        clientx <= pos.x + el.offsetWidth && 
        pos.y <= clienty && 
        clienty <= pos.y + el.offsetHeight)
    {
      _bl_mcl_ddOver(event, el);
    }
    else
    {
      ddObj.setHint(null);
      ddObj.clearEffect();
    }
  }
}

function _bl_mcl_drop(event, el)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {
    var index = -1;
    
    if (ddObj.hintContext)
    {
      var child     = ddObj.hintContext.child;
      var divParent = bl_mcl_get_table(el).parentNode;
      
      if (child != divParent)
      {
        index = bl_mcl_rowIndex(el, child);
        
        if (!ddObj.isTopLeft)
        {
          index++;
        }
      }
      else
      {
        index = bl_mcl_getLength(el);
      }
    }  
    
    if (index >= 0)
    {
      var target = { id:el.id, index:index, aboutToDrop:bl_sel_aboutToDrop, selectMgr:el.selectMgr };

      ddObj.setHint(null);
      bl_dd_procDrop(target);
      bl_port_killEvent(event);
    }
  }
}

function bl_mcl_removeIndex(el, index, last)
{
  var table = bl_mcl_get_table(el);
  var row   = table.rows.item(index);
  var next  = row.nextSibling;

  table.lastChild.removeChild(row);
  
  if (last && next)
  {
    bl_mcl_compute_alt_style(el, next);  
  }
}

function bl_mcl_setItem(el, cmd)
{
  var index = parseInt(bl_port_get_text(cmd.childNodes.item(0)));
  bl_mcl_removeIndex(el, index, true);
  bl_mcl_insertItem(el, cmd);
  return index;
}

function bl_mcl_compute_alt_style(el, startRow)
{
  if (startRow && el.getAttribute('bl_alt_back') != null)
  {
    var cellCss = bl_mcl_get_cell_css(el, false);
    var altCss  = bl_mcl_get_cell_css(el, true);
    
    if (cellCss.length && altCss.length)
    {
      var index     = bl_port_get_rowIndex(startRow);
      var nodes     = startRow.parentNode.childNodes;
      var len       = nodes.length; 
      var styleList = null;
      
      for (var i = index;i < len;i++)
      {
        var row = nodes.item(i);
        if ((i && (i % 2 > 0)))
        {
          styleCss = altCss;
          row.setAttribute('bl_bk_alt', true);
        }
        else
        {
          styleCss = cellCss;
          row.removeAttribute('bl_bk_alt');
        }
        if (!row.bl_isSelected)
        {
          bl_mcl_copy_background_tr(row, styleCss);
        }
      }
    }
  }
}

function bl_mcl_insert(el, index, payloadText, payload, last)
{
  // TODO: This algorythm needs to be worked over to 
  //       be more optimal
  var tableStr  = "<table>" + payloadText + "</table>";
  var tableBody = document.createElement("BODY");
  var row       = null;
  var tBodyList = bl_mcl_get_table(el).tBodies;

  tableBody.innerHTML = tableStr;
  
  if (tBodyList && tBodyList.length)
  {
    var tbody = tBodyList.item(0);
    var rows  = tbody.rows;
    
    index = (rows.length > index) ? index : rows.length;
    row   = tbody.insertRow(index);
  }
  
  // now reach down and get the cells to put into the display cell
  var parentRow = tableBody.firstChild.firstChild.firstChild;
  var cells     = parentRow.cells;
  
  bl_port_mergeAttributes(row, parentRow);
  
  if (bl_browserInfo.firefox)
  {
    // Performs custom sizing for firefox.
    row.parentNode.parentNode.style.width = "100%";
  }
  
  for (var i = 0; i < cells.length; i++)
  {
    bl_mcl_copy_cell(cells[i], row, i);
  }
  
  if (payload)
  {
    bl_sys_procInitTags(payload);
  }
  
  if (row)
  {
    if (bl_browserInfo.ie)
    {
      //ping class name ie problem with border-collapse style.
      var temptd = document.createElement("TD");
      row.appendChild(temptd);
      row.removeChild(temptd);
    }
    
    if (last)
    {
      bl_mcl_compute_alt_style(el, row.nextSibling);  
    }
  }
  return index;
}

function bl_mcl_copy_cell(cell, row, index, el)
{
  // assign the inner HTML into the display cell
  var c  = row.insertCell(index);
  
  bl_port_mergeAttributes(c, cell);
  c.id = cell.id;
  
  // insert children of local cell into real cell
  var els     = cell.childNodes;
  var elsLen  = els.length;
  
  for (var j = 0; j < elsLen; j++)
  {
    // always get first since it pulls it off after
    retVal = c.appendChild(els[0]);
  }
  
  if (row.bl_isSelected && el)
  {
    var selectMgr = (el ? el.selectMgr : null);
    var isAlt     = (row.getAttribute('bl_bk_alt') != null);
    
    c.style.cssText = (selectMgr.isActive ? bl_mcl_get_sel_css(row, isAlt) : bl_mcl_get_sel_d_css(row, isAlt));
  }
  else
  {
    c.style.cssText = cell.style.cssText;
  }
  
  return c;
}

function bl_mcl_insertItem(el, cmd, last)
{
  var retVal;
  var index     = parseInt(bl_port_get_text(cmd.childNodes.item(0)));
  var payload   = cmd.childNodes.item(1);
  return bl_mcl_insert(el, index, bl_port_get_text(payload), payload, last);
}

function bl_mcl_move(el, oldIndex, newIndex)
{
  var childTable = bl_mcl_get_table(el);
  var lineIndex  = (oldIndex > newIndex ? newIndex : oldIndex);

  if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    // IE has a "move" row method, but the DOM standard only has "delete"
    // and "insert" The code could be refactored for simplicity if both
    // browsers used the "delete+insert" method.
    var html = bl_port_getOuterHTML(childTable.rows[oldIndex]);
    
    childTable.deleteRow(oldIndex);
    bl_mcl_insert(el, newIndex, html, false);
  }
  else
  {
    childTable.moveRow(oldIndex, newIndex);
  }
  
  var row = childTable.rows.item(lineIndex);
  
  if (row)
  {
    bl_mcl_compute_alt_style(el, row);  
  }
}

function bl_mcl_remove_all(el)
{
  var childTable = bl_mcl_get_table(el);
  if (childTable.rows.length > 0)
  {
    var numDel = childTable.rows.length;
    for (var i = 0; i < numDel; i++)
    {
      childTable.deleteRow(0);
    }
  }
}

function bl_mcl_changeCell(item)
{
  var cel = document.getElementById(bl_port_get_text(item.childNodes.item(0)));
  
  if (cel)
  {
    var refocus = bl_kb_isFocusInside(cel);
    cel.innerHTML = bl_port_get_text(item.childNodes.item(1));
    if (refocus)
    {
      bl_kb_activateFromTab(cel,true);
    }
  }
}

function bl_mcl_setCells(item)
{
  var list = item.childNodes;
  var len  = list.length;
  
  for (var i = 0; i < len; i++)
  {
    bl_mcl_changeCell(list.item(i));
  }
  
  bl_sys_procInitTags(item);
}

function _bl_mcl_handler(item, el)
{
  var cmd  = item.childNodes.item(0);
  var name = cmd.nodeName;
  
  if (name == "ColumnSelect")
  {
    var isA = cmd.attributes.getNamedItem("isAscend");
    bl_mcl_set_column(el, bl_port_get_text(cmd), (isA || isA == "true"));
  }
  else if (name == "cellTitle")
  {
    var el = document.getElementById(bl_port_get_text(cmd.childNodes.item(0)));
    if (el)
    {
      el.title = bl_port_get_text(cmd.childNodes.item(1));
    }
  }
  else if (name == "setCells")
  {
    bl_mcl_setCells(cmd);
  }
  else if (name == "cellChanged")
  {
    bl_mcl_changeCell(cmd);
    bl_sys_procInitTags(cmd);
  }
  else if (name == "cellMsg")
  {
    bl_mcl_handleCellMsg(cmd);
  }
  else if (name == "header")
  {
    bl_mcl_headerMsg(cmd);
  }
  else if (name == "addToList")
  {
    bl_mcl_add_to_header_list(el, cmd);
  }
  else if (name == "insertColumn")
  {
    bl_mcl_move_insert_column(el, cmd);
  }
  else if (name == "moveColumn")
  {
    bl_mcl_move_column(el, cmd);
  }
  else if (name == "removeAll")
  {
    bl_mcl_remove_all(el);
  }
  else if (name == "setHideHeaders")
  {
    bl_mcl_setHideHeaders(el, cmd);
  }
  else if (name == "invalidate")
  {
    bl_sel_invalidate(el, cmd);
  }
  
  bl_sel_handler(el, name, cmd, bl_mcl_removeIndex, bl_mcl_insertItem, bl_mcl_setItem, bl_mcl_move);
}


//Global variables
function bl_mcl_get_list_table(src)
{
  var topEl         = cb_util_getParent(src, "MCL");
  return blu_getChild(topEl, "TABLE", "LIST_TABLE");
}

function bl_mcl_style_obj(name, value)
{
  this.name   = name;
  this.value  = value;
}

function bl_mcl_build_style_list(styleAttributes)
{
  var list      = null;
  var styleList = styleAttributes.split(";");
  var len       = styleList.length;
  if (len > 0)
  {
    list = new Array();
    for (var i = 0;i < styleList.length;i++)
    {
      var current     = styleList[i];
      var currentList = current.split(":");
      var name        = currentList[0];
      var value       = currentList[1];
      if (name.length)
      {
        list.push(new bl_mcl_style_obj(name, value));
      }
    }
  }
  return list;
}
 
function bl_mcl_get_table_cg(cg)
{
  var topEl     = cb_util_getParent(cg, "MCL");
  var index     = bl_mcl_computeCGIndex(topEl, cg);
  var listTable = blu_getChild(topEl, "TABLE", "LIST_TABLE");
  var colGroup  = listTable.childNodes.item(0);
  return colGroup.childNodes.item(index);
}

function bl_mcl_get_header_cg(cg)
{
  var topEl    = cb_util_getParent(cg, "MCL");
  var index    = bl_mcl_computeCGIndex(topEl, cg);
  var colGroup = blu_getChild(topEl, "COLGROUP", "HEADERGROUP");
  return colGroup.childNodes.item(index);
}

function bl_mcl_get_header(src, index)
{
  var list = bl_mcl_get_group_list(src);
  return list.item(index);
}

function bl_mcl_get_group_list(src)
{
  var topEl     = cb_util_getParent(src, "MCL");
  var groupRow  = blu_getChild(topEl, "TR", "HEADERROW");
  return groupRow.childNodes;
}

function bl_mcl_get_str_test(src)
{
  var topEl = cb_util_getParent(src, "MCL");
  return blu_getChild(topEl, "DIV", "HEADER_STR_TEST");
}

function bl_mcl_get_cell_css(src, isAlt)
{
  var topEl   = cb_util_getParent(src, "MCL");
  var testDiv = blu_getChild(topEl, "DIV", "HEADER_STR_TEST");
  return (isAlt)? testDiv.getAttribute('bl_alt_st') : testDiv.getAttribute('bl_cell_st');
}

function bl_mcl_get_sel_css(src, isAlt)
{
  var topEl   = cb_util_getParent(src, "MCL");
  var testDiv = blu_getChild(topEl, "DIV", "HEADER_STR_TEST");
  var base    = (isAlt)? testDiv.getAttribute('bl_alt_base'):testDiv.getAttribute('bl_cell_base')
  return base + testDiv.getAttribute('bl_sel_st');
}

function bl_mcl_get_sel_d_css(src, isAlt)
{
  var topEl   = cb_util_getParent(src, "MCL");
  var testDiv = blu_getChild(topEl, "DIV", "HEADER_STR_TEST");
  var base    = (isAlt)? testDiv.getAttribute('bl_alt_base'):testDiv.getAttribute('bl_cell_base')
  return base + testDiv.getAttribute('bl_sel_d_st');
}

function bl_mcl_get_sel_f_css(src, isAlt)
{
  var topEl   = cb_util_getParent(src, "MCL");
  var testDiv = blu_getChild(topEl, "DIV", "HEADER_STR_TEST");
  var base    = (isAlt)? testDiv.getAttribute('bl_alt_base'):testDiv.getAttribute('bl_cell_base')
  return base + testDiv.getAttribute('bl_sel_f_st');
}

function bl_mcl_get_header_css(src)
{
  var topEl   = cb_util_getParent(src, "MCL");
  var testDiv = blu_getChild(topEl, "DIV", "HEADER_STR_TEST");
  return testDiv.getAttribute('bl_header_base') + testDiv.getAttribute('bl_header_st');
}

function bl_mcl_get_header_active_css(src)
{
  var topEl   = cb_util_getParent(src, "MCL");
  var testDiv = blu_getChild(topEl, "DIV", "HEADER_STR_TEST");
  return testDiv.getAttribute('bl_header_base') + testDiv.getAttribute('bl_header_active_st');
}

function bl_mcl_get_header_down_css(src)
{
  var topEl   = cb_util_getParent(src, "MCL");
  var testDiv = blu_getChild(topEl, "DIV", "HEADER_STR_TEST");
  return testDiv.getAttribute('bl_header_base') + testDiv.getAttribute('bl_header_down_st');
}

function bl_mcl_apply_style_list(el, list)
{
  var len = list.length;
  for (var i = 0;i < len;i++)
  {
    var styleObj = list[i];
    el.style.setAttribute(styleObj.name, styleObj.value);
  }
}

function bl_mcl_copy_background_tr(dest, css)
{
  var nodes = dest.childNodes;
  var len   = nodes.length;
  
  for (var i = 0; i < len; i++)
  {
    var child = nodes.item(i);
    var alignment = child.getAttribute("bl_alignment");
    
    if (alignment)
    {
      child.style.cssText = alignment + css;
    }
    else
    {
      child.style.cssText = css;
    }
  }
}

function bl_mcl_move_child(parent, oldIndex, newIndex)
{
  var nodes     = parent.childNodes;
  var child     = nodes.item(oldIndex);
  var childIn   = null;
  if (newIndex >= nodes.length)
  {
    parent.removeChild(child);
    parent.appendChild(child);
  }
  else
  {
    childIn = nodes.item(newIndex);
    parent.removeChild(child);
    parent.insertBefore(child, childIn);
  }
}

function bl_mcl_insert_child_col(group, index, colHtml)
{
  var newCol = document.createElement("COL");
  var nodes  = group.childNodes;

  if (nodes.length && index < nodes.length)
  {
    var currentChild = group.childNodes.item(index);
    group.insertBefore(newCol, currentChild);
  }
  else
  {
    group.appendChild(newCol);
  }
}

function bl_mcl_insert_child_td(row, index, childHtml, el)
{
  var tableStr        = "<table><tr>" + childHtml + "</tr></table>";
  var tableBody       = document.createElement("BODY");
  tableBody.innerHTML = tableStr;
  
  // now reach down and get the cells to put into the display cell
  var parentRow = tableBody.firstChild.firstChild.firstChild;
  var cells     = parentRow.cells;
  bl_mcl_copy_cell(cells[0], row, index, el);
}

function bl_mcl_add_to_header_list(el, cmd)
{
  var divHtml = bl_port_get_text(cmd.firstChild);
  if (el.bl_header_win && !el.bl_header_win.closed)
  {
    try
    {
      var document = el.bl_header_win.document;
      bl_port_insertAdjacentHTML(document.body.lastChild, "beforeend", divHtml);
    }
    catch (exception)
    {
    }
  }
}

function bl_mcl_move_insert_column(el, cmd)
{
  var nodes           = cmd.childNodes;
  var colGroup        = bl_port_get_text(nodes.item(0));
  var header          = bl_port_get_text(nodes.item(1));
  var bodyCol         = bl_port_get_text(nodes.item(2));
  var cells           = nodes.item(3);
  var headerRow       = blu_getChild(el, "TR", "HEADERROW");
  var headerColGroup  = blu_getChild(el, "COLGROUP", "HEADERGROUP");
  var tableColGroup   = bl_mcl_get_list_table(el).childNodes.item(0);
  var index           = parseInt(bl_port_get_text(nodes.item(4)));
  
  var tBodyList = bl_mcl_get_table(el).tBodies;

  if (tBodyList && tBodyList.length)
  {
    var rows      = tBodyList.item(0).rows;
    var len       = rows.length;
    var cellNodes = cells.childNodes;
    
    for (var i = 0; i < len; i++)
    {
      var row = rows[i];
      bl_mcl_insert_child_td(row, index, bl_port_get_text(cellNodes.item(i)), el);
    }
  }
  
  bl_mcl_insert_child_td(headerRow, index, header, el);
  bl_mcl_insert_child_col(headerColGroup, index, colGroup);
  bl_mcl_insert_child_col(tableColGroup, index, bodyCol);
  bl_mcl_computeWidths(el, null);
  bl_sys_procInitTags(cmd);
}

function bl_mcl_move_column(el, cmd)
{
  var nodes         = cmd.childNodes;
  var oldIndex      = parseInt(bl_port_get_text(nodes.item(0)));
  var newIndex      = parseInt(bl_port_get_text(nodes.item(1)));
  var headerRow     = blu_getChild(el, "TR", "HEADERROW");
  var colGroup      = blu_getChild(el, "COLGROUP", "HEADERGROUP");
  var tableColGroup = bl_mcl_get_list_table(el).childNodes.item(0);
  
  bl_mcl_move_child(colGroup, oldIndex, newIndex);
  bl_mcl_move_child(tableColGroup, oldIndex, newIndex);
  bl_mcl_move_child(headerRow, oldIndex, newIndex);
  
  var tBodyList = bl_mcl_get_table(el).tBodies;

  if (tBodyList && tBodyList.length)
  {
    var tbody = tBodyList.item(0);
    var rows  = tbody.rows;
    var len   = rows.length;
    
    for (var i = 0; i < len; i++)
    {
      var row     = rows[i];
      var cell    = row.cells[oldIndex];
    
      bl_mcl_copy_cell(cell, row, newIndex);
      if (oldIndex > newIndex)
      {
        row.deleteCell(oldIndex + 1);
      }
      else
      {
        row.deleteCell(oldIndex);
      }
    }
  }
  
  bl_mcl_save_state(el, false);
}

function bl_mcl_setHideHeaders(el, item)
{
  var hide = bl_port_get_text(item.firstChild)=="true";
  
  var row = blu_getChild(el, "TR", "OUTERHEADERROW");
  if (row)
  {
    row.style.display = (hide?"none":"");
  }
}

function no_bl_mcl_get_sort_image(src, imageName)
{
  var image = "";
  var testH = bl_mcl_get_str_test(src);
  if (testH)
  {
    image = testH.getAttribute(imageName);
  }
  return image;
}

function bl_mcl_cleanUp(el)
{
  el.bl_mcl_currentDown     = null;
  el.bl_mcl_currentSelected = null;
  el.bl_mcl_currentDragEl   = null;
  el.bl_mcl_leftResizer     = null;
  el.bl_mcl_rightResizer    = null;
  if (el.bl_header_win && !el.bl_header_win.closed)
  {
    el.bl_header_win.close();
  }
}

function bl_mcl_set_column(el, indexStr, isAscend)
{
  var list  = bl_mcl_get_group_list(el);
  var sel   = null;
  var index = parseInt(indexStr);
  
  if (index >= 0 && index < list.length)
  {
    var tmpEl = list[index];
    
    if (isAscend.nodeValue == "true")
    {
      tmpEl.setAttribute("bl_is_up", true);
    }
    else
    {
      tmpEl.removeAttribute("bl_is_up");
    }
    
    tmpEl.isSelected  = true;
    
    var currentSelected = el.bl_mcl_currentSelected;
    
    if (currentSelected)
    {
      currentSelected.isSelected = false;
      bl_mcl_computeImage(currentSelected, false, false, false);
    }
    
    bl_mcl_computeImage(tmpEl, true, false, false);
    el.bl_mcl_currentSelected = tmpEl;
  }
}

function bl_mcl_computeLocalWidths(topEl)
{
  if (topEl && !topEl.bl_local_computed)
  {
    topEl.bl_local_computed = true;
    var clList              = bl_mcl_get_group_list(topEl);
    var len                 = clList.length;
    for (var i = 0; i < len; i++)
    {
      var cg = clList[i];
      cg.setAttribute("bl_width", cg.offsetWidth);
    }
  }
}

function bl_mcl_computeWidths(el, cgPt)
{
  var listTable = blu_getChild(el, "TABLE", "LIST_TABLE" );
  var headerTd  = blu_getChild(el, "COLGROUP", "HEADERGROUP").parentNode.parentNode;
  var pWidth    = headerTd.offsetWidth;
  var left      = pWidth;
  var leftPrev  = 0;
  var clList    = bl_mcl_get_group_list(el);
  var len       = clList.length;
  if (!len)
  {
    return;
  }
  var begin     = 0;
  var cg        = null;
  var flexpart  = pWidth - parseInt(el.getAttribute("bl_solid_width"));
  if (cgPt)
  {
    for (var i = begin; i < len; i++)
    {
      cg          = clList[i];
      var cgWidth = parseInt(cg.getAttribute("bl_width"));
      left       -= cgWidth;
      if (cg == cgPt)
      {
        begin = i + 1;
        break;
      }
    }
    if (begin >= len)
    {
      begin = 0;
      left  = pWidth - parseInt(cgPt.getAttribute("bl_width"));
    }
    else
    {
      cgPt = null;
    }
  }
  
  for (var i = begin; i < len; i++)
  {
    cg = clList[i];
    if (cg != cgPt)
    {
      leftPrev += parseInt(cg.getAttribute("bl_width"));
    }
  }
  
  for (var j = begin; j < len; j++)
  {
    cg = clList[j];
    if (cg != cgPt)
    {
      cg.cbPerVal = (Math.floor((parseInt(cg.getAttribute("bl_width")) / leftPrev) * left));
    }
  }
  
  for (var i = begin; i < len; i++)
  {
    cg = clList[i];
    
    if (cg != cgPt)
    {
      var w   = cg.cbPerVal;
      var max = parseInt(cg.getAttribute("bl_max_width"));
      var min = parseInt(cg.getAttribute("bl_min_width"));
      if (w > max)
      {
        cg.setAttribute("bl_width", max);
        left -= max;
        for (var j = begin; j < len; j++)
        {
          cg = clList[j];
          if (cg != cgPt)
          {
            var width   = cg.getAttribute("bl_width");
            cg.cbPerVal = (Math.floor((width / leftPrev) * left));
          }
        }
      }
      else if (w < min)
      {
        cg.setAttribute("bl_width", min);
        left -= min;
        for (var j = begin; j < len; j++)
        {
          cg = clList[j];
          if (cg != cgPt)
          {
            cg.cbPerVal = (Math.floor((min / leftPrev) * left));
          }
        }
      }
      else
      {
        cg.setAttribute("bl_width", w);
        left -= w;
      }
    }
  }
  var edit      = true;
  if (left < 0)
  {
    var forceRoom = false;
    while (left < 0 && edit)
    {
      var room = false;
      for (var i = begin; i < len; i++)
      {
        cg = clList[i];
        
        var elMin   = parseInt(cg.getAttribute("bl_min_width"));
        var elWidth = parseInt(cg.getAttribute("bl_width"));
        if ((cg != cgPt && elWidth > elMin) || (cgPt && forceRoom))
        {
          elWidth--;
          cg.setAttribute("bl_width", elWidth);
          left++;
          room = ((elWidth > elMin) || room);
        }
        else if (len == 1)
        {
          edit = false;
        }
      }
      if (!room)
      {
        if (cgPt)
        {
          forceRoom = true;
        }
        else
        {
          break;
        }
      }
    }
  }
  else if (left > 0)
  {
    var forceRoom = false;
    while (left > 0 && edit)
    {
      var room = false;
      for (var i = begin; i < len; i++)
      {
        cg          = clList[i];
        var elMax   = parseInt(cg.getAttribute("bl_max_width"));
        var elWidth = parseInt(cg.getAttribute("bl_width"));
        
        if ((cg != cgPt && elWidth < elMax) || (cgPt && forceRoom))
        {
          elWidth++;
          cg.setAttribute("bl_width", elWidth);
          left--;
          room = ((elWidth < elMax) || room);
        }
        else if (len == 1)
        {
          edit = false;
        }
      }
      if (!room)
      {
        if (cgPt)
        {
          forceRoom = true;
        }
        else
        {
          break;
        }
      }
    }
  }
  
  var listCG    = listTable.childNodes.item(0);
  var headCG    = blu_getChild(el, "COLGROUP", "HEADERGROUP");
  var newListCG = listCG.cloneNode(true);
  var newHeadCG = headCG.cloneNode(true);

  var headNode = newHeadCG.firstChild;
  var listNode = newListCG.firstChild;
 
  var flexCols = 0;
  for (var i=0; i<len; i++)
  {
    if (bl_port_hasAttribute(clList[i],"bl_can_resize"))
    {
      flexCols++;
    }
  }
  
  var stateStr = "<state>" + pWidth;
  var rounder = new blu_Rounder(100,flexCols);
  
  for (var i = 0; i < len; i++)
  {
    cg = clList[i];
    
    var elWidth = parseInt(cg.getAttribute("bl_width"));
    var newWidthStr = elWidth;
    if (bl_port_hasAttribute(cg,"bl_can_resize"))
    {
      if (flexpart > 0)
      {
        var percent = rounder.round((elWidth * 100) / flexpart);
        newWidthStr = percent + "%";
      }
      else
      {
        newWidthStr = "0";
      }
    }

    stateStr += "," + elWidth + "," + percent;
    headNode.setAttribute("width",newWidthStr);
    listNode.setAttribute("width",newWidthStr);
    headNode = headNode.nextSibling;
    listNode = listNode.nextSibling;
  }
  
  listCG.parentNode.insertBefore(newListCG,listCG);
  listCG.parentNode.removeChild(listCG);
  
  headCG.parentNode.insertBefore(newHeadCG,headCG);
  headCG.parentNode.removeChild(headCG);
  
  stateStr += "</state>";
  bl_contain_procChildResize(el);
}

function bl_mcl_createHeaders(el, table, row, data)
{
  if (data)
  {
    var xList = data.childNodes;
    
    if (xList != null)
    {
      var len  = xList.length;
      
      while (row.firstChild)
      {
        row.removeChild(row.firstChild);
      }
      
      for (var i = 0; i <len; i++)
      {
        bl_mcl_addHeader(el, xList[i].childNodes, table, row, -1);
      }
    }
  }
}

function bl_mcl_scrupCGItem(item)
{
  if (item.parentNode)
  {
    item.parentNode.removeChild(item)
  }
  delete item;
}

function bl_mcl_findHeader(src)
{
  while (src && src.getAttribute("bl_is_header") == null)
  {
    src = src.parentNode;
  }
  return src;
}

function bl_mcl_computeImage(el, isSelected, isDown, isIn)
{
  if (el.getAttribute("bl_show_image") != null)
  {
    var img   = null;
    var blank = null;
    
    if (el.getAttribute("bl_imgLeft") != null)
    {
      blank = el.firstChild.lastChild.previousSibling;
      img   = blank.previousSibling;
    }
    else
    {
      img   = el.firstChild.lastChild;
      blank = img.previousSibling;
    }
    
    if (isSelected)
    {
      img.style.visibility  = "visible";
      blank.style.width     = "7px";
      var imgName           = "";
      var isUp              = el.getAttribute("bl_is_up") != null;
      
      if (isDown)
      {
        if (isIn)
        {
          imgName = (isUp ? "uSDI" : "dSDI");
        }
        else
        {
          imgName = (isUp ? "uSAI" : "dSAI");
        }
      }
      else
      {
        if (isIn)
        {
          imgName = (isUp ? "uSAI" : "dSAI");
        }
        else
        {
          imgName = (isUp ? "uSI" : "dSI");
        }
      }
      img.src = no_bl_mcl_get_sort_image(el, imgName);
    }
    else
    {
      img.style.visibility = "hidden";
      blank.style.width ="7px";
    }
  }
}

function bl_mcl_computeLeave(el)
{
  el.bl_mouseIsIn    = false;
  var mouseIsDown = el.getAttribute("bl_mouseIsDown") != null;
  bl_mcl_computeImage(el, el.isSelected, mouseIsDown, false);
  if (mouseIsDown)
  {
    el.style.cssText = bl_mcl_get_header_down_css(el);
  }
}

function bl_mcl_computeEnter(el)
{
  el.bl_mouseIsIn    = true;
  var mouseIsDown = el.getAttribute("bl_mouseIsDown") != null;
  bl_mcl_computeImage(el, el.isSelected, mouseIsDown, true);
  if (mouseIsDown)
  {
    el.style.cssText = bl_mcl_get_header_down_css(el);
  }
}

function _bl_mcl_mouse_move(event, el)
{
  if (bl_mcl_drag_el)
  {
    if (bl_mcl_drag_el.bl_mcl_currentDragEl)
    {
      el         = bl_mcl_drag_el.bl_mcl_currentDragEl;
      el.blMoved = true;
      bl_mcl_setCursor(el.parentNode.parentNode.parentNode, true);
      var elMin  = parseInt(el.getAttribute("bl_min_width"));
      var diff   = bl_mcl_adjustDiff(event.screenX - el.bl_screenLeft, elMin, el.blMaxAllowed);
      bl_mcl_drag_el.bl_mcl_rightResizer.style.left = diff + bl_sys_real_x(el, null, false);
      bl_port_stop_event(event);
    }
  }
  else
  {
    var src   = bl_port_getEventTarget(event);
    var topEl = cb_util_getParent(src, "MCL");
    
    if (topEl == undefined)
    {
      _bl_mcl_mouseUp(event, el);
      return;
    }
    
    if (topEl.bl_mcl_currentDown)
    {
      var curDownEl = topEl.bl_mcl_currentDown;
      bl_mcl_computeHeaderState(el, event, (el == curDownEl));
    }
    else
    {
      bl_mcl_setCursor(el.parentNode.parentNode.parentNode, (bl_mcl_isInResize(event, el) != null));
    }
  }
}

function bl_mcl_canAlterHeader(topEl)
{
  return (topEl.bl_mcl_currentDragEl == null && topEl.bl_mcl_currentDown == null);
}

function _bl_mcl_mouse_enter(event, el)
{
  var topEl = cb_util_getParent(el, "MCL");
  
  if (bl_mcl_drag_el)
  {
    topEl = bl_mcl_drag_el;
  }
  
  if (topEl && bl_mcl_canAlterHeader(topEl))
  {
    if (el.getAttribute("bl_is_header") != null && el.getAttribute("bl_sort_type") != "None")
    {
      if (bl_mcl_in_bounds(event, el))
      {
        bl_mcl_computeEnter(el)
      }
    }
  }
}

function bl_mcl_in_bounds(event, el)
{
  var srcEl     = bl_port_getEventTarget(event);
  var offPos    = bl_port_offsetToItem(event, srcEl);
  var top       = bl_sys_real_y(srcEl, null, false) + offPos.y;
  var left      = bl_sys_real_x(srcEl, null, false) + offPos.x;
  var itemTop   = bl_sys_real_y(el, null, false);
  var itemLeft  = bl_sys_real_x(el, null, false);
  var width     = el.offsetWidth;
  var height    = el.offsetHeight;
  if (!bl_browserInfo.firefox)
  {
    // Removes the element borders from the calculation.
    width  -= (bl_port_clientLeft(el) * 2);
    height -= (bl_port_clientTop(el) * 2);
  }
  if (left < itemLeft + width &&
      left > itemLeft &&
      top < itemTop + height &&
      top > itemTop)
  {
    return true;
  }
  return false;
}

function _bl_mcl_mouse_leave(event, el)
{
  var topEl = cb_util_getParent(el, "MCL");
  
  if (bl_mcl_drag_el)
  {
    topEl = bl_mcl_drag_el;
  }
  
  if (topEl && bl_mcl_canAlterHeader(topEl) && (el.getAttribute("bl_is_header") != null  && el.getAttribute("bl_sort_type") != "None"))
  {
    if (!bl_mcl_in_bounds(event, el))
    {
      bl_mcl_computeLeave(el);
    }
  }
}

function bl_mcl_dragDetect(topEl, el)
{
  var ctop  = bl_sys_real_y(el, null, false);
  var cleft = bl_sys_real_x(el, null, false);
  var h     = bl_sys_real_y(topEl, null, false) + topEl.offsetHeight - ctop;
  
  if (!topEl.bl_mcl_leftResizer)
  {
    topEl.bl_mcl_leftResizer = document.getElementById("bl_mcl_resize_left");
    
    if (!topEl.bl_mcl_leftResizer)
    {
      var imageHTML = "<img src='/" 
                    + bl_version
                    + "/res/img/th_seporator.gif' style='z-index:3000;position:absolute;left:0px;top:0px;visibility:hidden;filter:alpha(Opacity=60);-moz-opacity:0.6;opacity:0.6;' id='bl_mcl_resize_right' /><img src='/"
                    + bl_version
                    + "/res/img/th_seporator.gif' style='z-index:3000;position:absolute;left:0px;top:0px;visibility:hidden;filter:alpha(Opacity=60);-moz-opacity:0.6;opacity:0.6;' id='bl_mcl_resize_left' />"
      
      bl_port_insertAdjacentHTML(document.body, "beforeend", imageHTML);
      topEl.bl_mcl_leftResizer  = document.getElementById("bl_mcl_resize_left");
    }
  
    topEl.bl_mcl_rightResizer = document.getElementById("bl_mcl_resize_right");
  }

  with (topEl.bl_mcl_leftResizer.style)
  {
    width      = 3;
    height     = h;
    left       = cleft - 1;
    top        = ctop;
    visibility = "visible";
  } 
   
  with (topEl.bl_mcl_rightResizer.style)
  {
    width      = 3;
    height     = h;
    left       = cleft + el.offsetWidth - 1;
    top        = ctop;
    visibility = "visible";
  }
  
  bl_mcl_drag_el             = topEl;
  el.bl_screenLeft           = bl_port_getScreenLeft(window) + cleft;
  el.blMoved                 = false;
  topEl.bl_mcl_currentDragEl = el;
  el.blMaxAllowed            = bl_mcl_computeAbsoluteMax(el);
}

function bl_mcl_computeAbsoluteMax(el)
{
  var temp  = el.nextSibling;
  var max   = el.offsetWidth;
  
  while (temp)
  {
    var elMin = parseInt(temp.getAttribute("bl_min_width"));
    if (temp.id != "lastHeader")
    {
      max += (temp.offsetWidth - elMin);
    }
    temp = temp.nextSibling;
  }
  var elMax = parseInt(el.getAttribute("bl_max_width"));
  return Math.min(elMax, max);
}

function bl_mcl_isInResize(event, el)
{
  var h   = el.offsetHeight;
  var ely = bl_sys_find_y(el, null, false) + h + cb_sys_getScreenTop() - event.screenY;
  
  if (el.getAttribute("bl_can_resize") != null && ely >= -3 && ely < h)
  {
    var x      = event.screenX;
    var elLeft = bl_sys_find_x(el, null, false) + cb_sys_getScreenLeft();
    
    if (Math.abs(elLeft - x) < 5)
    {
      var prev = el.previousSibling;
      return (prev && prev.getAttribute("bl_can_resize") != null ? prev : null);
    }
    else if (Math.abs(elLeft + el.offsetWidth - x) < 5)
    {
      var next = el.nextSibling;
      return (next && next.getAttribute("bl_can_resize") != null ? el : null);
    }
  }
  return null;
}

function bl_mcl_computeCGIndex(el, cg)
{
  var list = bl_mcl_get_group_list(el);
  var len  = list.length;
  
  for (var i = 0; i < len; i++)
  {
    if (cg == list[i])
    {
      return i;
    }
  }
  return -1;
}

function _bl_mcl_dbl_click(event, el)
{
  var src = bl_port_getEventTarget(event);
  
  el = bl_mcl_isInResize(event, el);
  
  if (el)
  {
    var topEl = cb_util_getParent(src, "MCL");
    var cg    = el;
    var index = bl_mcl_computeCGIndex(topEl, el);
    
    if (index >= 0)
    {
      max = 0;
      var maxAllowed  = bl_mcl_computeAbsoluteMax(el);
      var rList       = bl_mcl_get_list_table(topEl).rows;
      var len         = rList.length;
      
      for (var i = 0; i < len; i++)
      {
        var row   = rList[i];
        var cList = row.childNodes;
        if (index < cList.length)
        {
          var item        = cList[index];
          var neededWidth = Math.max(item.firstChild.scrollWidth, item.firstChild.offsetWidth) + 10;
          max = Math.max(max, neededWidth);
        }
      }
      
      if (max)
      {
        bl_mcl_computeLocalWidths(topEl);
        cg.setAttribute("bl_width", Math.min(max, maxAllowed));
        bl_mcl_computeWidths(topEl, el);
      }
    }
    bl_mcl_setCursor(el.parentNode.parentNode.parentNode, false);
  }
  bl_port_stop_event(event);
}

function bl_mcl_setCursor(parent, resizing)
{
  if (!parent.bl_resize_cur)
  {
    // IE5 supports a limited subset of cursor names. The "E-resize"
    // cursor is the closest available to "col-resize".
    parent.bl_resize_cur = (bl_browserInfo.ie6up ? "col-resize" : "E-resize");
  }
  
  var cur                        = (resizing) ? parent.bl_resize_cur : "default";
  parent.style.cursor            = cur;
  parent.firstChild.style.cursor = cur;
  
  var list = parent.firstChild.childNodes;
  var len  = list.length;
  
  for (var i = 0; i < len; i ++)
  {
    var el          = list[i];
    el.style.cursor = cur;
    var first       = el.firstChild;
    if (first)
    {
      first.style.cursor            = cur;
      first.firstChild.style.cursor = cur;
    }
  }
}

function bl_mcl_menu_dragInner(event)
{
  return this.item.innerHTML
}

function _bl_header_menu_down(event, el)
{
  var src  = bl_port_getEventTarget(event);
  var item = (el ? el : this);
  
  bl_kb_focusOnElement(src);

  if (item && bl_port_isLeftDown(event))
  {
    item.className  = 'bl_mcl_header_menu_select';
    
    var parent = item.parentNode;
    
    if (parent.bl_prev)
    {
      parent.bl_prev.className = 'bl_mcl_header_menu';
    }
    
    parent.bl_prev = item;
    
    var diaArgs    = bl_port_getDialogArguments(window); 
    var srcContext = { source:diaArgs.parent.bl_mcl_top, 
                       item:item, 
                       did:window.bl_did,
                       indexes:[-1], 
                       dragContext:("<col id='" + item.id + "'>" + bl_port_getInnerText(item) + "</col>"),
                       computeShadow:bl_mcl_menu_dragInner,
                       zoneName:parent.getAttribute("bl_zone")
                     };
    
    bl_dd_detect(event, srcContext);
  }
  bl_port_stop_event(event);
}

function bl_mcl_header_dragInner(event)
{
  var item    = this.item;
  var width   = item.offsetWidth;
  var height  = item.offsetHeight;
  var dim     = "width:" + width + "px;height=" + height + "px'";
  var style   = "style='" + item.style.cssText + dim;
  
  return "<table style='" + dim + "><tr><td " + style + ">" + item.innerHTML + "</td></tr></table>";
}

function _bl_mcl_mouse_down(event, el)
{
  var stopEvent = false;
  var src       = bl_port_getEventTarget(event);
  var item      = (el ? el : this);
  bl_kb_focusOnElement(src);
  
  if (item)
  {
    var topEl = cb_util_getParent(src, "MCL");
    
    if (topEl.bl_mcl_cleanUpValid == undefined)
    {
      topEl.bl_mcl_cleanUpValid = true;
      bl_sys_addCleanUpCall(topEl, bl_mcl_cleanUp);
    }
    
    if (bl_port_isLeftDown(event))
    {
      var headerCanEdit = topEl.getAttribute("bl_allow_header_ed") != null;
      var groupRow      = blu_getChild(topEl, "TR", "HEADERROW");
      var rel = bl_mcl_isInResize(event, item);
      
      if (rel)
      {
        bl_port_stop_event(event);
        bl_mcl_setCursor(rel.parentNode.parentNode.parentNode, true);
        bl_mcl_dragDetect(topEl, rel);
        bl_port_setCapture(rel);
        stopEvent = true;
      }
      else if (headerCanEdit && groupRow.getAttribute("bl_zone") != null)
      {
        var childxy = bl_sys_find_xy(item, null, false);
        
        item.setAttribute("bl_mouseIsDown", true);
        item.style.cssText = bl_mcl_get_header_down_css(item);
        bl_port_stop_event(event);
        
        var srcContext = { source:topEl, 
                           item:item, 
                           did:window.bl_did,
                           indexes:[bl_port_get_cellIndex(item)], 
                           computeShadow:bl_mcl_header_dragInner,
                           shadowOpacity:90,
                           dragEnd:bl_header_dragEnd, 
                           zoneName:groupRow.getAttribute("bl_zone")
                         };
        
        bl_dd_detect(event, srcContext);
      }
      else if (el.getAttribute("bl_sort_type") != "None")
      {
        bl_port_stop_event(event);
        item.setAttribute("bl_mouseIsDown", true);
        item.style.cssText       = bl_mcl_get_header_down_css(item);
        topEl.bl_mcl_currentDown = item;
        bl_mcl_computeImage(item, item.isSelected, true, true);
        bl_port_setCapture(item);
        bl_mcl_header_drag_el    = topEl;
      }
    }
  }
}

function bl_mcl_computeSelected(topEl, el)
{
  var wsel = (el == topEl.bl_mcl_currentSelected);
  
  if (topEl.bl_mcl_currentSelected && el != topEl.bl_mcl_currentSelected)
  {
    var item              = topEl.bl_mcl_currentSelected;
    var tableCG           = bl_mcl_get_table_cg(item);
    item.isSelected       = false;
    bl_mcl_computeImage(item, false, false, false);
  }
  var fireEvent = false;
  var sortType  = el.getAttribute("bl_sort_type");
  var isUp      = el.getAttribute("bl_is_up") != null;
  if (sortType == "Ascend")
  {
    if (!isUp)
    {
      fireEvent = true;
    }
    isUp = true;
  }
  else if (sortType == "Descend")
  {
    if (isUp)
    {
      fireEvent = true;
    }
    isUp = false;
  }
  else if (sortType == "Both")
  {
    fireEvent = true;
    if (wsel)
    {
      isUp = (isUp ? false : true);
    }
    else
    {
      isUp = el.getAttribute("bl_defAscend") != null;
    }
  }
  
  if (isUp)
  {
    el.setAttribute("bl_is_up", true);
  }
  else
  {
    el.removeAttribute("bl_is_up");
  }
  
  if (fireEvent)
  {
    bl_mcl_selected(topEl, bl_port_get_cellIndex(el), isUp);
  }
  
  topEl.bl_mcl_currentSelected  = el;
  el.isSelected                 = true;
}

function bl_mcl_adjustDiff(diff, min, max)
{
  if (diff < min)
  {
    diff = min;
  }
  if (diff > max)
  {
    return max;
  }
  return diff;
}

function _bl_mcl_mouseUp(event, el)
{
  if (bl_port_isLeftDown(event))
  {
    if (bl_mcl_drag_el)
    {
      if (bl_mcl_drag_el.bl_mcl_currentDragEl)
      {
        var tmpEl = bl_mcl_drag_el.bl_mcl_currentDragEl;
        bl_mcl_drag_el.bl_mcl_currentDragEl = null;
        bl_port_releaseCapture(tmpEl);
        bl_mcl_setCursor(tmpEl.parentNode.parentNode.parentNode, false);
        
        var elMin = parseInt(tmpEl.getAttribute("bl_min_width"));
        var diff  = bl_mcl_adjustDiff(event.screenX - tmpEl.bl_screenLeft, elMin, tmpEl.blMaxAllowed);
        
        if (tmpEl.blMoved)
        {
          bl_mcl_computeLocalWidths(cb_util_getParent(el, "MCL"));
          tmpEl.setAttribute("bl_width", diff);
          bl_mcl_computeWidths(bl_mcl_drag_el, tmpEl);
        }
        
        bl_mcl_drag_el.bl_mcl_leftResizer.style.visibility  = "hidden";
        bl_mcl_drag_el.bl_mcl_rightResizer.style.visibility = "hidden";
        bl_mcl_computeHeaderState(tmpEl, event, false);
      }
      bl_mcl_drag_el = null;
    }
    else
    {
      var src   = bl_port_getEventTarget(event);
      var el    = bl_mcl_findHeader(src);
      var topEl = cb_util_getParent(src, "MCL");
      
      if (topEl == undefined && bl_mcl_header_drag_el != undefined)
      {
        topEl = bl_mcl_header_drag_el;
      }
      
      var tmpEl = topEl.bl_mcl_currentDown;
      if (topEl && tmpEl)
      {
        var mouseWasDown = tmpEl.getAttribute("bl_mouseIsDown") != null;
        topEl.bl_mcl_currentDown = null;
        bl_port_releaseCapture(tmpEl);
        tmpEl.removeAttribute("bl_mouseIsDown");
        
        if (tmpEl.bl_mouseIsIn)
        {
          bl_mcl_computeSelected(topEl, tmpEl);
        }
        
        bl_mcl_computeImage(tmpEl, tmpEl.isSelected, false, tmpEl.bl_mouseIsIn);
        if (mouseWasDown)
        {
          tmpEl.style.cssText = bl_mcl_get_header_down_css(tmpEl);
        }
      }
    }
  }
}

function bl_mcl_computeHeaderState(el, event, canBeEnter)
{
  if (bl_mcl_in_bounds(event, el) && canBeEnter)
  {
    bl_mcl_computeEnter(el);
  }
  else
  {
    bl_mcl_computeLeave(el);
  }
}

function bl_mcl_selected(el, columnIndex, isAscend)
{
  var xmlStr = new String();

  xmlStr += "<SelCol><idx>";
  xmlStr += columnIndex;
  xmlStr += "</idx><Asc>";
  xmlStr += (isAscend) ? "true" : "false";
  xmlStr += "</Asc></SelCol>";
  
  bl_mpr_send(xmlStr, el.id, -1, bl_sys_readSendType(el));
}

function _bl_hdr_ddHintDrop(event, hintImage)
{
  _bl_hdr_drop(event, this.child);
}

function _bl_hdr_drop(event, headerItem)
{
  var ddObj     = bl_dd_getDragDropObj();
  var dragIndex = -1;

  if (ddObj)
  {
    if (ddObj.zoneName == "bl_header_zone")
    {
      var hd = ddObj.srcContext.item;
      hd.parentNode.removeChild(hd);
    }
    else
    {
      dragIndex = ddObj.srcContext.indexes[0];
    }
  
    if (ddObj.hintContext)
    {
      var item  = ddObj.hintContext.child;
      var topEl = cb_util_getParent(item, "MCL");
      
      if (item && topEl)
      {
        var index = bl_port_get_cellIndex(item);

        if (!ddObj.isTopLeft)
        {
          index++;
        }
        
        if (index != dragIndex)
        {
          var target = { id:topEl.id, index:index };
          bl_dd_procDrop(target);
        }
        ddObj.setHint(null);
      }
    }
  }

  bl_port_killEvent(event);
}

function bl_header_dragEnd(source, item, dragStarted)
{
  item.style.cssText  = bl_mcl_get_header_css(item);
  item.removeAttribute("bl_mouseIsDown");
  
  if (!dragStarted)
  {
    bl_mcl_computeSelected(source, item);
    bl_mcl_computeImage(item, item.isSelected, true, true);
  }
}

function _bl_hdr_ddOver(event, headerItem)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {    
    var item  = bl_get_header_parent(bl_port_getEventTarget(event));
    var topEl = cb_util_getParent(item, "MCL");

    if (item && topEl && !topEl.getAttribute("disabled") && !bl_port_contains(ddObj.srcContext.item, item, false))
    {
      var groupRow = blu_getChild(topEl, "TR", "HEADERROW");
      
      if (bl_dd_checkList(ddObj, event, groupRow.getAttribute("bl_zone_list")))
      {
        var hintContext = { child:item,
                            dimension:2,
                            hintDrop:_bl_hdr_ddHintDrop,
                            size:(item.offsetHeight),
                            x:event.clientX,
                            y:event.clientY
                          };
                          
        ddObj.setHint(hintContext);
        bl_port_killEvent(event);
        return ;
      }
    }
    ddObj.clearEffect();
  }
}

function _bl_hdr_ddOut(event, headerItem)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {    
    if (item && bl_mcl_in_bounds(event, headerItem))
    {
      _bl_hdr_ddOver(event, item);
    }
    else
    {
      ddObj.setHint(null);
      ddObj.clearEffect();
    }
  }
}

function _bl_remove_column(event, el)
{
  var arg = bl_sys_getMyPopupArg();
  
  if (arg)
  {
    arg.customArg.bl_remove_header();
  }
}

function _bl_show_fields_popup(event, el)
{
  var arg = bl_sys_getMyPopupArg();
  
  if (arg)
  {
    arg.customArg.bl_edit_headers(event);
    _bl_sys_popupClose();
  }
}

function bl_mcl_remove_column(el, index)
{
  var headerRow       = blu_getChild(el, "TR", "HEADERROW");
  var headerColGroup  = blu_getChild(el, "COLGROUP", "HEADERGROUP");
  var tableColGroup   = bl_mcl_get_list_table(el).childNodes.item(0);
  
  var child = headerRow.childNodes.item(index);
  
  headerRow.deleteCell(index);
  
  if (el.bl_mcl_currentSelected == child)
  {
    el.bl_mcl_currentSelected = null;
  }
  
  headerColGroup.removeChild(headerColGroup.childNodes.item(index));
  tableColGroup.removeChild(tableColGroup.childNodes.item(index));
  
  var tBodyList = bl_mcl_get_table(el).tBodies;
  
  if (tBodyList && tBodyList.length)
  {
    var rows = tBodyList.item(0).rows;
    var len  = rows.length;
    
    for (var i = 0; i < len; i++)
    {
      rows[i].deleteCell(index);
    }
  }
  
  bl_mcl_computeWidths(el, null);
}

function bl_mcl_remove_header()
{
  if (this.bl_right_click_cell != undefined)
  {
    var index   = this.bl_right_click_cell;
    var xmlStr  = "<RemoveColumn>"
                  + index
                  + "</RemoveColumn>";
    
    bl_mpr_send(xmlStr, this.id, -1, bl_sys_readSendType(this));
    bl_mcl_remove_column(this, index);
    this.bl_right_click_cell = undefined;
  }
}

function bl_mcl_edit_headers(event)
{
  if (this.bl_header_win && !this.bl_header_win.closed)
  {
    bl_port_focus(this.bl_header_win);
  }
  else
  {
    var src = this.getAttribute("bl_edit_src");

    if (src)
    {
      var featureObj = bl_port_computeFeature(event, "resizable:yes;status:no;unadorned:no;help:no;scroll:no", 150, 250);                    
      window.bl_mcl_top  = this;
      this.bl_header_win = _bl_sys_open("", src, featureObj, 1, 0, -1, false);
    }
  }
}

function bl_get_header_parent(el)
{
  var parent = el;
  while (el && el.tagName != "TD")
  {
    el = el.parentNode;
  }
  return el;
}

function _bl_show_right_click(event, el)
{
  var src           = bl_port_getEventTarget(event);
  var topEl         = cb_util_getParent(el, "MCL");
  var parentHeader  = bl_get_header_parent(src);
  var list          = bl_mcl_get_group_list(src);
  var imageHTML     = "";
  var allowDel      = true;
  if (parentHeader)
  {
    topEl.bl_right_click_cell = bl_port_get_cellIndex(parentHeader);
    allowDel = (parentHeader.getAttribute("bl_required") == null && list.length > 0);
  }
  else if (list.length == 0)
  {
    allowDel = false;
  }
  
  var height        = (allowDel == 0 ? 20 : 38);
  var attributes    = " topElId='" + topEl.id + "' width=192 height=18 "
  if (allowDel)
  {
    imageHTML = bl_sys_button_html("RC", "img/rc_remove_this_column_", "", false, "_bl_remove_column", attributes, false, null);
  }
  imageHTML += bl_sys_button_html("EC", 'img/rc_field_chooser_', "", false, "_bl_show_fields_popup", attributes, false, null);
  
  
  var html   = "<script language='javascript'>var bl_version='" 
             + bl_version
             + "';</script><div style='overflow:hidden;padding:0px;margin:0px;border:1px solid #9F9F9F;'>" 
             + imageHTML 
             + "</div>";

  topEl.bl_edit_headers   = bl_mcl_edit_headers;
  topEl.bl_remove_header  = bl_mcl_remove_header;

  var argData = { html:html,
                  customArg:topEl,
                  x:event.clientX,
                  y:event.clientY,
                  w:194,
                  h:height,
                  canDestroy:true,
                  useVeil:true,
                  positionType:"left-top"
                };
  
  window.bl_sys_popupInvoke(argData);
  bl_port_killEvent(event);
}

function bl_mcl_compute_state(el)
{
  var width     = el.offsetWidth;
  var colGroup  = blu_getChild(el, "COLGROUP", "BODYGROUP");
  var list      = colGroup.childNodes;
  var len       = list.length;
  var stateStr  = "<state>" + width;
  for (var i = 0;i < len;i++)
  {
    var col = list.item(i);
    stateStr += "," + col.offsetWidth + "," + col.getAttribute("width");
  }
  stateStr += "</state>";
  return stateStr;
}

function bl_mcl_save_state(el, defer)
{
  var colGroup  = blu_getChild(el, "COLGROUP", "BODYGROUP");

  if (colGroup.offsetWidth > 0)
  {
    var width     = el.offsetWidth;
    var list      = colGroup.childNodes;
    var len       = list.length;
    var stateStr  = "<state>" + width;

    for (var i = 0; i < len; i++)
    {
      var col = list.item(i);
      stateStr += "," + col.offsetWidth + "," + col.getAttribute("width");
    }
    stateStr += "</state>";

    var sendType = (defer)? BL_MPR_DEFER:bl_sys_readSendType(el);
    
    bl_mpr_send(stateStr, el.id, -1, sendType);
    
    return true;
  }
  
  return false;
}

function _bl_mcl_functionInvoke(event, el)
{
  if (!el.bl_pending)
  {
    var tag = el.getAttribute("cb_tag");
    if (tag && (tag == "IB" || tag == "SIB"))
    {
      bl_sys_img_freeze(el);
    }
    el.bl_pending = true;
    window.alert("call function");
    
    bl_de_sendMessage(el.parentNode, "<call/>");
  }
}

function bl_mcl_headerMsg(cmd)
{
  var header = document.getElementById(bl_port_get_text(cmd.childNodes.item(0)));
  
  if (header)
  {
    var msg     = cmd.childNodes.item(1);
    var msgName = msg.nodeName;
    
    if (msgName == "title")
    {
      bl_port_setInnerText(header, bl_port_get_text(msg));
    }
  }
}

function bl_mcl_handleCellMsg(cmd)
{
  var cell = document.getElementById(bl_port_get_text(cmd.childNodes.item(0)));
  
  if (cell)
  {
    var msg     = cmd.childNodes.item(1).childNodes.item(0);
    var msgName = msg.nodeName;
    
    if (msgName == "done")
    {
      var el  = cell.firstChild;
      var tag = el.getAttribute("cb_tag");
      
      if (tag && (tag == "IB" || tag == "SIB"))
      {
        cb_img_clear_state(el);
      }
      
      el.bl_pending = false;
      window.alert("done");
    }
    else if ("label")
    {
    }
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_mcl_last()
{
  var x = 0;
}

//***********************************************************************
//***********************************************************************
//********                    bl_menu.js                        *********
//***********************************************************************
//***********************************************************************

cb_menu_currentItem     = null;
cb_menu_currentCapture  = null;
cb_menu_currentRoot     = null;
cb_menu_currentKeyItem  = null;
cb_menu_currentHilite   = null;
cb_menu_mouseDown       = null;

function cb_menu_span_parent(span)
{
  var parent = span.parentNode;
  if (parent && parent.getAttribute("bl_menu_node") != null)
  {
    return parent;
  }
  else
  {
    var parent = span.bl_parent;
    return (parent ? parent : span.firstChild.nextSibling.bl_parent);
  }
}

function cb_menu_parentItem(item)
{
  var parentItem  = item.parentNode;
  if (item.getAttribute("bl_is_root") == null && parentItem)
  {
    parentItem = cb_menu_span_parent(parentItem.parentNode);
  }
  return parentItem;
}

function cb_menu_rootItem(item)
{
  while (item && item.getAttribute("bl_is_root") == null)
  {
    item = cb_menu_parentItem(item);
  }
  return item;
}

function cb_menu_isPrim(item)
{
  return cb_menu_rootItem(item).parentNode.getAttribute("bl_is_prim") != null;
}

function cb_menu_asIcon(item)
{
  return cb_menu_rootItem(item).parentNode.getAttribute("bl_as_icon") != null;
}

function cb_menu_cleanup(el)
{
  cb_menu_currentItem     = null;
  cb_menu_currentCapture  = null;
  cb_menu_currentRoot     = null;
  cb_menu_currentKeyItem  = null;
}

function cb_menu_get_item(element, checkRoot)
{
  while (element && element.getAttribute("bl_menu_node") == null)
  {
    var bl_parent = element.bl_parent;
    if (bl_parent)
    {
      element = bl_parent;
    }
    else
    {
      element = element.parentNode;
    }
  }
  if (checkRoot && element && element.getAttribute("bl_is_root") != null && cb_menu_currentRoot && cb_menu_currentRoot != element)
  {
    element = null;
  }
  return element;
}

function cb_menu_image_child(item)
{
  return item.childNodes[0];
}

function cb_menu_ex_image_child(item)
{
  return item.childNodes[2];
}

function cb_menu_span_child(item)
{
  var children = item.childNodes;
  if (children.length > 3)
  {
    var span = children[3];
    if (span.firstChild)
    {
      return span.firstChild.nextSibling;
    }
    else
    {
      return span;
    }
  }
  else
  {
    return item.cb_span;
  }
}

function cb_menu_text_child(item)
{
  return item.childNodes[1];
}

// BL Port: functionality specific to the menu control
function bl_moz_mouse_wheel(event)
{
  var item    = null;
  var target  = event.target;
  if (target.nodeType == 3)
  {
    item = cb_menu_get_item(target.parentNode);
  }
  else
  {
    item = cb_menu_get_item(target);
  }
  if (item)
  {
    try
    {
      var span      = item.parentNode.parentNode;
      var scroller  =  (event.detail > 0 ? span.lastChild : span.firstChild);
      var element   = (scroller.nextSibling ? cb_menu_span_parent(scroller.nextSibling) : cb_menu_span_parent(scroller.previousSibling));
      cb_menu_clearAllChildren(element, false, false);
      cb_menu_scroll(scroller);
    }
    catch (exception)
    {
    }
    event.preventDefault();
  }
}

function _bl_menu_focus_out(event, el)
{
  if (el)
  {
    if (cb_menu_mouseDown && cb_menu_mouseDown != el.firstChild)
    {
      cb_menu_clicked(cb_menu_mouseDown, null);
    }
    
    // Port: functionality specific to the menu control
    if (bl_browserInfo.firefox)
    {
      window.removeEventListener('DOMMouseScroll', bl_moz_mouse_wheel, true);
    }
    
    var root = el.firstChild;
    root.removeAttribute("bl_menu_focus");
    cb_menu_clearAll(root, true, true);
  }
  
  bl_port_stop_event(event);
}

function _bl_menu_focus_in(event, el)
{
  cb_menu_mouseDown = null;
  
  var root = el.firstChild;
  if (root)
  {

    // Port: functionality specific to the menu control
    if (bl_browserInfo.firefox)
    {
      window.addEventListener('DOMMouseScroll', bl_moz_mouse_wheel, true);
    }

    root.setAttribute("bl_menu_focus", true);
    if (root.getAttribute("bl_is_root") != null)
    {
      cb_menu_highLightChild(root);
    }
  }
  bl_port_stop_event(event);
}

function cb_menu_setRootShow(item)
{
  cb_menu_currentRoot     = item;
  cb_menu_currentKeyItem  = item;
  if (item.getAttribute("bl_show") != null)
  {
    var span = cb_menu_span_child(item)
    if (span)
    {
      var nodes = span.childNodes;
      if (nodes && nodes.length)
      {
        cb_menu_setKeyActive(nodes.item(0));
      }
    }
  }
  else
  {
    cb_menu_showMenu(item);
  }
  bl_port_stop_event(event);
}

function cb_menu_setKeyActive(item)
{
  cb_menu_currentKeyItem  = item;
  if (cb_menu_currentHilite && cb_menu_currentHilite != item)
  {
    cb_menu_clearChild(cb_menu_currentHilite);
  }
  if (!item.cb_expand_requested)
  {
    cb_menu_handleMouseOver(item);
  }
  else
  {
    cb_menu_highLightChild(item);
  }
  bl_port_stop_event(event);
}

function cb_menu_computeAdjacentChild(item)
{
  var top     = bl_sys_find_y(item, null, false);
  var span    = cb_menu_span_child(item, false);
  var height  = item.offsetHeight;
  var nodes   = span.childNodes;
  for (var i = 0; i < nodes.length; i++)
  {
    var child = nodes.item(i);
    var cTop  = bl_sys_find_y(child, null, false);
    if (Math.abs(top - cTop) < height)
    {
      return child;
    }
  }
  return nodes.item(0);
}

function cb_menu_moveToKey(down, rootItem)
{
  if (cb_menu_currentItem && cb_menu_currentItem.getAttribute("bl_is_root") == null)
  {
    var nodeToSel = (down ? cb_menu_currentItem.nextSibling : cb_menu_currentItem.previousSibling);
    if (!down && !nodeToSel)
    {
      var parEl = cb_menu_parentItem(cb_menu_currentItem);
      if (parEl && parEl.getAttribute("bl_is_root") != null)
      {
        nodeToSel = parEl;
      }
    }
    if (nodeToSel)
    {
      cb_menu_setKeyActive(nodeToSel);
    }
  }
  else
  {
    if (down)
    {
      if (rootItem.getAttribute("bl_show") != null)
      {
        var span  = cb_menu_span_child(rootItem);
        if (span)
        {
          var nodes = span.childNodes;
          if (nodes.length)
          {
            cb_menu_setKeyActive(nodes.item(0));
          }
        }
      }
      else
      {
        cb_menu_setRootShow(rootItem);
      }
    }
    else
    {
      cb_menu_clearAll(rootItem, true, false);
      cb_menu_currentRoot   = null;
      bl_port_stop_event(event);
    }
  }
}

function _bl_menu_key_down(event, el)
{
  if (!event)
  { 
    event = window.event;
  }
  
  var rootItem = (el.firstChild.getAttribute("bl_is_root") != null ? el.firstChild : cb_menu_rootItem(el));
  
  if (rootItem)
  {
    var kcode = bl_port_keyCode(event);
    if (kcode == 13)
    {
      cb_menu_currentKeyItem  = cb_menu_currentItem;
      bl_port_stop_event(event);
      cb_menu_clicked(cb_menu_currentItem, null);
    }
    else if (kcode == 27)
    {
      cb_menu_clearAll(rootItem, true, true);
      bl_port_stop_event(event);
    }
    else if (kcode == 38)
    {
      cb_menu_moveToKey(false, rootItem);
    }
    else if (kcode == 40)
    {
      cb_menu_moveToKey(true, rootItem);
    }
    else if (kcode == 37)
    {
      if (cb_menu_currentItem && cb_menu_currentItem.getAttribute("bl_is_root") == null)
      {
        var parent = cb_menu_parentItem(cb_menu_currentItem);
        if (parent)
        {
          cb_menu_setKeyActive(parent);
        }
      }
      else
      {
        cb_menu_clearAll(rootItem, true, false);
        cb_menu_currentRoot = null;
        bl_port_stop_event(event);
      }
    }
    else if (kcode == 39)
    {
      if (cb_menu_currentItem && cb_menu_currentItem.getAttribute("bl_is_root") == null)
      {
        var span  = cb_menu_span_child(cb_menu_currentItem);
        if (span && span.childNodes.length && cb_menu_currentItem.getAttribute("bl_show") != null)
        {
          cb_menu_setKeyActive(cb_menu_computeAdjacentChild(cb_menu_currentItem));
        }
      }
      else
      {
        cb_menu_setRootShow(rootItem);
      }
    }
  }
}

function cb_menu_moveElement(item, oldIndex, newIndex)
{
  var span = cb_menu_span_child(item);
  if (span)
  {
    var nodeItem = span.childNodes.item(oldIndex);
    cb_menu_nodeRemoveObj(nodeItem);
    cb_menu_nodeInsert(item, nodeItem, "", newIndex);
  }
}

function cb_menu_getObjectID(elementID, singleInstance)
{
  var val = new String(elementID);
  var index = val.indexOf(".");
  if (index != -1)
  {
    val = val.substring(index + 1, val.length);
  }
  if (singleInstance)
  {
    index = val.indexOf("_");
    if (index != -1)
    {
      val = val.substring(0, index);
    }
  }
  return val;
}

function _bl_menu_dbl_click(event, el)
{
  if (!event)
  {
    event = window.event;
  }
  
  bl_port_stop_event(event);
}

function cb_menu_handleMouseOver(item)
{
  if (item && (item.getAttribute("bl_mouse_in") != null || cb_menu_currentKeyItem == item))
  {
    cb_menu_highLightChild(item);
    if (item.getAttribute("bl_show") == null && item.getAttribute("bl_is_root") == null)
    {
      cb_menu_showMenu(item);
    }
  }
}

function cb_menu_mouse_over_timeout(id)
{
  var element = document.getElementById(id);
  if (element)
  {
    if (element.getAttribute("bl_mouse_in") != null && cb_menu_currentCapture == element && !element.cb_expand_requested)
    {
      cb_menu_itemMouseOver(element);
    }
  }
}

function cb_menu_itemMouseOver(item)
{
  if (item                                    &&
      !cb_sys_disabled(item.parentNode)       &&
      item.getAttribute("bl_is_root") == null && 
      cb_menu_currentRoot                     && 
      cb_menu_currentRoot != item)
  {
    var exImageItem = cb_menu_ex_image_child(item);
    if (item.getAttribute("bl_is_root") != null && exImageItem)
    {
      exImageItem.src = "/" + bl_version + "/res/img/button/down_arrow_ov.gif";
    }
    cb_menu_handleMouseOver(item);
  }
}

function _bl_menu_mouse_over(event, el)
{
  if (!event)
  {
    event = window.event;
  }
    
  var src = bl_port_getEventTarget(event);
  
  if (src.getAttribute("cb_scroller") != null)
  {
    _bl_scroller_over(event, src);
  }
  else
  {
    if (src == cb_menu_span_child(el))
    {
      bl_port_stop_event(event);
    }
    else
    {
      var text = cb_menu_text_child(el);
      
      if (text && text.title.length == 0 && text.scrollWidth > text.offsetWidth)
      {
        text.title = bl_port_getInnerText(text);
      }
      
      if (cb_menu_currentHilite && cb_menu_currentHilite != el)
      {
        cb_menu_clearChild(cb_menu_currentHilite);
      }
      if (el.getAttribute("bl_is_root") == null || !cb_sys_disabled(el.parentNode))
      {
        cb_menu_highLightChild(el);
        
        if (el != cb_menu_currentKeyItem)
        {
          el.setAttribute("bl_mouse_in", true);
        }
        
        if (el != cb_menu_currentCapture)
        {
          cb_menu_setCapture(el, false, false);
        }
        
        if (el.getAttribute("bl_show") == null && !el.cb_expand_requested)
        {
          // Optimize rollovers by avoiding unnecessary calls to "cb_menu_mouse_over_timeout".
          clearTimeout(window.menuItemOverTimeout);
          window.menuItemOverTimeout = window.setTimeout("cb_menu_mouse_over_timeout('" + el.id + "')", 350);
        }
        else
        {
          cb_menu_set_current(el);
        }
        
        bl_port_stop_event(event);
      }
    }
  }
}

function cb_menu_setCapture(captureItem, clearMenuItems, clearChildren)
{
  if (cb_menu_currentCapture != captureItem)
  {
    var c = cb_menu_currentCapture;
    cb_menu_currentCapture = null;
    if (c && clearChildren)
    {
      cb_menu_clearAll(c, true, true);
    }
    if (clearMenuItems)
    {
      cb_menu_currentRoot     = null;
      cb_menu_currentItem     = null;
    }
    cb_menu_currentCapture  = captureItem;
  }
}

function _bl_menu_mouse_out(event, el)
{
  if (!event)
  {
    event = window.event;
  }
  
  var src       = bl_port_getEventTarget(event);
  var toEl      = event.toElement;
  var clear     = false;

  if (src == el)
  {
    clear = true;
  }
  else
  {
    if (el)
    {
      var toMenuItem = cb_menu_get_item(toEl, true);
      
      if (toMenuItem != el)
      {
        clear = true;
      }
    }
    else if (bl_browserInfo.firefox)
    {
      var el = bl_port_getEventTarget(event);
      
      if (el.getAttribute("cb_tag") != "Menu" && !el.className.match(/menu/i))
      {
        cb_menu_setCapture(null, false, true);
      }
    }
  }
  if (clear)
  {
    if (el.getAttribute("bl_is_root") != null &&
        el.getAttribute("bl_show") == null  && 
        (!cb_menu_currentRoot || cb_menu_currentRoot == el))
    {
      cb_menu_setCapture(null, false, true);
    }
    cb_menu_clearChild(el);
    element.removeAttribute("bl_mouse_in");
  }
  
  bl_port_stop_event(event);
}

function cb_menu_clearAllChildren(item, includeThis, clearThis)
{
  var span  = cb_menu_span_child(item);
  if (span)
  {
    var nodes = span.childNodes;
    var len   = nodes.length;
    for (var i = 0; i < len; i++)
    {
      var cNode = nodes[i];
      if (cNode.getAttribute("bl_show") != null)
      {
        cb_menu_clearAllChildren(cNode, true, true);
        break;
      }
    }
    if (includeThis)
    {
      cb_menu_hideMenu(item);
    }
    if (clearThis)
    {
      cb_menu_clearChild(item);
    }
  }
}

function cb_menu_clearChild(item)
{
  if (item)
  {
    var childStyle = item.style;
    if (item == cb_menu_currentHilite)
    {
      cb_menu_currentHilite = null;
    }
    
    var isRoot = item.getAttribute("bl_is_root") != null;
    
    bl_port_setBGColor(childStyle, (isRoot ? '#FFFFFF' : 'transparent'));
    childStyle.color = '#000000';
    
    var tChild = cb_menu_text_child(item);
    if (tChild)
    {
      tChild.style.color = '#000000';
    }
    var exImageItem = cb_menu_ex_image_child(item);
    if (exImageItem)
    {
      exImageItem.src = "/" + bl_version + (isRoot ? "/res/img/button/down_arrow_en.gif" : "/res/img/child_arrow.gif");
    }
  }
}

function cb_menu_highLightChild(item)
{
  cb_menu_currentHilite   = item;
  var chStyle             = item.style;
  
  bl_port_setBGColor(chStyle, '#A0B5C5');
  chStyle.color = '#FFFFFF';
  
  var tChild = cb_menu_text_child(item);
  
  if (tChild)
  {
    tChild.style.color = '#FFFFFF';
  }
  var exImageItem = cb_menu_ex_image_child(item);
  if (exImageItem)
  {
    exImageItem.src =  "/" + bl_version + (item.getAttribute("bl_is_root") != null ? "/res/img/button/down_arrow_ov.gif" : "/res/img/child_arrow_over.gif");
  }
}

function cb_menu_clearAll(item, includeThis, clearThis)
{
  if (cb_menu_currentItem && (item != cb_menu_currentItem || clearThis))
  {
    if (item != cb_menu_currentItem)
    {
      cb_menu_clearAll(cb_menu_currentItem, true, true);
    }
    else
    {
      cb_menu_clearChild(cb_menu_currentItem);
    }
    cb_menu_currentItem = null;
  }
  if (cb_menu_currentRoot && (item != cb_menu_currentRoot || clearThis))
  {
    cb_menu_clearChild(cb_menu_currentRoot);
    cb_menu_currentRoot = null;
  }
  if (cb_menu_currentKeyItem && (item != cb_menu_currentKeyItem || clearThis))
  {
    cb_menu_clearChild(cb_menu_currentKeyItem);
    cb_menu_currentKeyItem = null;
  }
  if (item && item.getAttribute("bl_is_root") != null)
  {
    cb_menu_clearAllChildren(item, includeThis, clearThis);
  }
  else
  {
    var childItem = (includeThis ? item : cb_menu_parentItem(item));
    if (childItem && includeThis)
    {
      cb_menu_clearAllChildren(item, true, true);
    }
    while (childItem && childItem.getAttribute("bl_menu_node") != null)
    {
      childItem.removeAttribute("bl_mouse_in");
      if (childItem != item || clearThis)
      {
        cb_menu_clearChild(childItem);
      }
      cb_menu_hideMenu(childItem);
      childItem = cb_menu_parentItem(childItem);
    }
  }
}

function _bl_mouse_down(event, el)
{
  cb_menu_mouseDown = el;
}

function cb_menu_clicked(item, eventObj)
{
  cb_menu_mouseDown = null;
  if (item)
  {
    var isRoot    = item.getAttribute("bl_is_root") != null;
    var parentEl  = item.parentNode;
    var disabled  = cb_sys_disabled(parentEl);
    
    if (isRoot)
    {
      if (item.getAttribute("bl_is_root") != null || disabled)
      {
        cb_menu_clearAll(item, true, false);
        cb_menu_currentRoot = null;
      }
      else
      {
        cb_menu_currentRoot = item;
        cb_menu_showMenu(item);
      }
    }
    else
    {
      cb_menu_clearAll(item, true, true);
      cb_menu_sendSelectToServer(item);
    }
    if (eventObj)
    {
      bl_port_stop_event(eventObj);
    }
  }
  if (cb_menu_currentCapture && (!item || !isRoot))
  {
    cb_menu_setCapture(null, false, true)
  }
}

function _bl_menu_clicked(event, el)
{
  if (!event)
  {
    event = window.event;
  }
  
  var srcEl = bl_port_getEventTarget(event);
  
  if (el)
  {
    var span = cb_menu_span_child(el);
    
    if (srcEl == span)
    {
      item = cb_menu_currentCapture;
    }
  }
  
  cb_menu_clicked(el, event);
}

function cb_menu_nodeRemove(item, index)
{
  var span = cb_menu_span_child(item);
  if (span)
  {
    var itemToRemove = span.childNodes.item(index);
    cb_menu_nodeRemoveObj(nodeToRemove);
  }
}

function cb_menu_nodeRemoveObj(itemToRemove)
{
  var parentSpan        = itemToRemove.parentNode;
  var parentItem        = cb_menu_span_parent(parentSpan);
  var parentExImageItem = cb_menu_ex_image_child(parentItem);
  parentSpan.removeChild(itemToRemove);
  if (parentItem.childNodes.length == 0 && parentExImageItem)
  {
    parentExImageItem.style.visibility = "hidden";
  }
  cb_menu_nodeComputeExImage(parentItem);
}

function cb_menu_nodeInsert(parentItem, item, html, index)
{
  var span  = cb_menu_span_child(parentItem);
  if (span)
  {
    var nodes     = span.childNodes;
    var len       = nodes.length;
    var nextItem  = null;
    var newItem   = item;
    if (index >= 0 && len > index)
    {
      nextItem = nodes.item(index);
    }
    if (newItem)
    {
      if (index >= 0 && nextItem)
      {
        span.insertBefore(newItem, nextItem);
      }
      else
      {
        span.appendChild(newItem);
      }
    }
    else
    {
      if (index >= 0 && nextItem)
      {
        bl_port_insertAdjacentHTML(nexItem, "beforebegin", html);
      }
      else
      {
        bl_port_insertAdjacentHTML(span, "beforeend", html);
      }
    }
  }
}

function cb_menu_nodeRemoveAll(item)
{
  cb_menu_hideMenu(item);
  
  var span = cb_menu_span_child(item);
  if (span)
  {
    var exImageItem   = cb_menu_ex_image_child(item);
    span.innerHTML    = "";
    
    item.removeAttribute("bl_loaded");
    
    if (item.parentNode && exImageItem && item.getAttribute("bl_is_root") == null)
    {
      exImageItem.style.display = "none";
    }
  }
}

function cb_menu_scroll_timeout(id, top)
{
  var el = document.getElementById(id);
  if (el)
  {
    var span     = cb_menu_span_child(el);
    var scroller = (top ? span.previousSibling : span.nextSibling);
    if (scroller.cb_timer_on > 0)
    {
      cb_menu_scroll(scroller);
      scroller.cb_timer_on -= 10;
      if (scroller.cb_timer_on < 20)
      {
        scroller.cb_timer_on = 20;
      }
      window.setTimeout("cb_menu_scroll_timeout('" + id + "'," + top + ")", scroller.cb_timer_on);
    }
  }
}

function cb_menu_scroll(scroller)
{
  var next = scroller.nextSibling;
  var span = (next ? next : scroller.previousSibling);
  if (next)
  {
    span.scrollTop -= 21;
  }
  else
  {
    span.scrollTop += 21;
  }
}

function _bl_scroller_over(event, scroller)
{
  if (bl_port_getEventTarget(event) == scroller)
  {
    scroller.cb_current_capture     = cb_menu_currentCapture;
    bl_port_setBGColor(scroller.style, 'lightsteelblue');
  }
  if (scroller.cb_timer_on == 0)
  {
    var isTop   = (scroller.nextSibling ? 1 : 0);
    var element = (scroller.nextSibling ? cb_menu_span_parent(scroller.nextSibling) : cb_menu_span_parent(scroller.previousSibling));
    
    cb_menu_clearAllChildren(element, false, false);
    cb_menu_scroll(scroller);
    scroller.cb_timer_on = 150;
    window.setTimeout("cb_menu_scroll_timeout('" + element.id + "'," + isTop + ")", scroller.cb_timer_on);
  }
  bl_port_stop_event(event);
}

function _bl_scroller_leave(event, scroller)
{
  scroller.cb_timer_on = 0;
  bl_port_setBGColor(scroller.style, 'lightgrey');
  bl_port_stop_event(event);
}

function _bl_menu_wheel_mouse(event, el)
{
  if (el.cb_scrollers)
  {
    try
    {
      if (!event)
      {
        event = window.event;
      }
      
      var scroller = (event.wheelDelta > 0 ? el.firstChild : el.lastChild);
      var item     = (scroller.nextSibling ? cb_menu_span_parent(scroller.nextSibling) : cb_menu_span_parent(scroller.previousSibling));

      cb_menu_clearAllChildren(item, false, false);
      cb_menu_scroll(scroller);
    }
    catch (exception)
    {
    }
    bl_port_stop_event(event);
  }
}

function cb_menu_show_scrollers(src, show)
{
  var top = src.firstChild;
  var bot = src.lastChild;
  if (show)
  {
    top.style.display = 'block';
    bot.style.display = 'block';
    top.cb_timer_on   = 0;
    bot.cb_timer_on   = 0;
    src.cb_scrollers  = true;
  }
  else
  {
    src.cb_scrollers  = false;
    top.style.display = 'none';
    bot.style.display = 'none';
  }
}

function cb_menu_checkVisible(src, parent, rTop, rLeft, parIsRoot)
{
  var srcStyle    = src.style;
  var docEl       = document.body;
  var scrollDim   = (docEl.scroll == "no" ? 0 : 25) + 10;
  var docScrollL  = docEl.scrollLeft;
  var docScrollT  = docEl.scrollTop;
  var docHeight   = docEl.offsetHeight - scrollDim;
  var docWidth    = docEl.offsetWidth - scrollDim;
  var bodyHDim    = docHeight + docScrollT;
  var bodyRDim    = docWidth + docScrollL;
  var bot         = src.offsetHeight + rTop;
  var right       = src.offsetWidth + rLeft;
  var shiftRoot   = false;
  
  if (bot > bodyHDim)
  {
    var top     = rTop - ((bot - bodyHDim) + scrollDim);
    var buffer  = (parent.offsetHeight / 2);
    if (top < docScrollT)
    {
      srcStyle.top     = buffer + docScrollT;
      srcStyle.height  = docHeight - (scrollDim + buffer);
      
      var span      = src.firstChild.nextSibling;
      var height    = parseInt(srcStyle.height);
      if (span.offsetHeight > height)
      {
        cb_menu_show_scrollers(src, true);
        span.style.height = height;
      }
      else
      {
        cb_menu_show_scrollers(src, false);
      }
    }
    else
    {
      cb_menu_show_scrollers(src, false);
      srcStyle.top = top;
    }
    if (parIsRoot)
    {
      rLeft         = bl_sys_find_x(parent, null, true) + parent.offsetWidth - 5;
      srcStyle.left = rLeft;
      srcStyle.top  = parseInt(srcStyle.top);
      shiftRoot     = true;
    }
  }
  else
  {
    cb_menu_show_scrollers(src, false);
  }
  var srcWidth    = src.offsetWidth;
  var parentWidth = parent.offsetWidth;
  right           = srcWidth + rLeft;
  if (right > bodyRDim)
  {
    src.cb_flow     = 1;
    var parentLeft  = bl_sys_find_x(parent, null, true);
    var shiftDim    = 0;
    if (!shiftRoot && parIsRoot)
    {
      shiftDim = (srcWidth + rLeft) - bodyRDim;
    }
    else
    {
      shiftDim = (srcWidth + parentWidth) - 6;
    }
    srcStyle.left     = parseInt(srcStyle.left) - shiftDim;
    srcStyle.width    = srcWidth;
    if (parseInt(srcStyle.left) < 0)
    {
      srcStyle.left  = 0;
      src.cb_flow    = 0;
    }
  }
  else if (rLeft < 0)
  {
    var parentLeft  = bl_sys_find_x(parent, null, true);
    srcStyle.left   = parentLeft + parentWidth;
    src.cb_flow     = 0;
  }
  if (!parIsRoot || shiftRoot)
  {
    rTop        = bl_sys_find_y(src, null, true);
    var parTop  = bl_sys_find_y(parent, null, true);
    bot         = src.offsetHeight + rTop;
    var parBot  = parent.offsetHeight + parTop;
    if (rTop > parTop)
    {
      srcStyle.top = parseInt(srcStyle.top) - (rTop - parTop);
    }
    if (bot < parBot)
    {
      srcStyle.top = parseInt(srcStyle.top) + (parBot - bot);
    }
  }
}

function cb_menu_is_parent(parent, newItemParent)
{
  while (newItemParent && newItemParent.getAttribute("bl_is_root") == null)
  {
    if (newItemParent == parent)
    {
      return true;
    }
    newItemParent = cb_menu_parentItem(newItemParent);
  }
  return newItemParent == parent;
}

function cb_menu_set_current(newItem)
{
  if (cb_menu_currentItem && cb_menu_currentItem != newItem)
  {
    var sItem   = cb_menu_currentItem;
    var parent  = (newItem.getAttribute("bl_is_root") != null ? newItem : cb_menu_parentItem(newItem));
    if (!cb_menu_is_parent(sItem, parent))
    {
      cb_menu_clearAllChildren(sItem, true, true);
      sItem   = cb_menu_parentItem(sItem);
      while (sItem && sItem != parent && sItem != newItem && sItem.getAttribute("bl_is_root") == null)
      {
        cb_menu_hideMenu(sItem);
        sItem   = cb_menu_parentItem(sItem);
      }
    }
  }
  cb_menu_currentItem = newItem;
}

function cb_menu_showMenu(item)
{
  if (item)
  {
    var root = cb_menu_rootItem(item);
    if (!root || root.getAttribute("bl_menu_focus") == null)
    {
      if (root)
      {
        cb_menu_clearAllChildren(root, true, true);
      }
      return;
    }
    if (item.getAttribute("bl_loaded") == null)
    {
      item.cb_expand_requested = true;
      cb_menu_SendToServer(item, "expand", false);
    }
    else if ((cb_menu_currentHilite == item && item.getAttribute("bl_mouse_in") != null) || cb_menu_currentKeyItem == item)
    {
      cb_menu_set_current(item);
      
      var span        = cb_menu_span_child(item);
      var exImageItem = cb_menu_ex_image_child(item);
      var isRoot      = item.getAttribute("bl_is_root") != null;
      
      if (span && span.childNodes.length)
      {
        var parSpan       = span.parentNode;
        var body          = document.body;
        var sStyle        = parSpan.style;
        var flow          = item.parentNode.parentNode.cb_flow;
        var docScrollLeft = body.scrollLeft;
        var docScrollTop  = body.scrollTop;
        var top           = 0;
        var left          = bl_sys_find_x(item, null, true);
        
        span.bl_parent    = item;
        item.cb_span      = span;
        span.style.height = 'auto';
        item.setAttribute("bl_show", true);
        item.removeChild(parSpan);
        body.appendChild(span.parentNode);
        sStyle.display    = "inline";
        
        
        if (isRoot)
        {
          parSpan.cb_flow  = 0;
          top  = bl_sys_find_y(item, null, true) + item.offsetHeight - 1;
        }
        else
        {
          top               = bl_sys_find_y(item, null, true);
          parSpan.cb_flow   = flow;
          if (flow == 0)
          {
            left += (item.offsetWidth - 3);
          }
          else
          {
            left -= (span.offsetWidth + 3);
          }
        }
        top   += docScrollTop;
        left  += docScrollLeft;
        sStyle.top  = top;
        sStyle.left = left;
        
        cb_menu_checkVisible(span.parentNode, item, top, left, isRoot);
        bl_port_hideInputs(span, new Array("INPUT", "SELECT"));
      }
      else if (exImageItem)
      {
        exImageItem.style.display = "none";
      }
    }
  }
}

function cb_menu_hideMenu(item)
{
  if (item && item.getAttribute("bl_show") != null )
  {
    var span = cb_menu_span_child(item);
    if (span)
    {
      item.removeAttribute("bl_show");
      span.bl_parent = null;
      item.cb_span   = null;
      bl_port_showInputs(span)
      span.parentNode.style.display = "none";
      document.body.removeChild(span.parentNode);
      item.appendChild(span.parentNode);
    }
  }
}

function cb_menu_getSelectPath(item)
{
  var selPath = new String(cb_menu_getObjectID(item.id, true));
  if (item.getAttribute("bl_is_root") == null)
  {
    item = cb_menu_parentItem(item);
    while (item.getAttribute("bl_is_root") == null)
    {
      selPath = cb_menu_getObjectID(item.id, true) + "." + selPath;
      item    = cb_menu_parentItem(item);
    }
    selPath = cb_menu_getObjectID(item.id, true) + "." + selPath;
  }
  return selPath;
}

function cb_menu_sendSelectToServer(item)
{
  var xmlStr = new String();
  xmlStr += "<select>";
  xmlStr += "<path>";
  xmlStr += cb_menu_getSelectPath(item);
  xmlStr += "</path>";
  xmlStr += "<id>";
  xmlStr += cb_menu_getObjectID(item.id, true);
  xmlStr += "</id>";
  var parentItem = cb_menu_parentItem(item);
  if (parentItem)
  {
    xmlStr += "<parentId>";
    xmlStr += cb_menu_getObjectID(parentItem.id, true);
    xmlStr += "</parentId>";
  }
  xmlStr += "</select>";
  
  var rootItem = cb_menu_rootItem(item);
  if (rootItem)
  {
    if (rootItem.parentNode.getAttribute("bl_is_prim") != null)
    {
      var imageItem     = cb_menu_image_child(item);
      var rootImageItem = cb_menu_image_child(rootItem);
      
      if (rootItem.parentNode.getAttribute("bl_as_icon") == null)
      {
        var rootTextItem = cb_menu_text_child(rootItem);
        var textItem     = cb_menu_text_child(item);
        
        bl_port_setInnerText(rootTextItem, bl_port_getInnerText(textItem));
      }
      if (imageItem && rootImageItem)
      {
        rootImageItem.src = imageItem.src;
      }
    }
    bl_mpr_send(xmlStr, rootItem.parentNode.id, 0);
  }
}

function cb_menu_SendToServer(item, message, singleInstance)
{
  var xmlStr = "<" 
             + message 
             + ">"
             + cb_menu_getObjectID(item.id, singleInstance)
             + "</" 
             + message 
             + ">";
                
  var rootItem  = cb_menu_rootItem(item);
  if (rootItem)
  {
    bl_mpr_send(xmlStr, rootItem.parentNode.id);
  }
}

function cb_menu_nodeComputeExImage(item)
{
  var span        = cb_menu_span_child(item);
  var exImageItem = cb_menu_ex_image_child(item);
  var imageName   = "/" + bl_version + "/res/img/spacer.gif";
  var isRoot      = item.getAttribute("bl_is_root") != null;
  var show        = false;
  
  if (isRoot)
  {
    imageName = "/" + bl_version + "/res/img/button/down_arrow_en.gif";
    show = true;
  }
  else if ((span && span.childNodes.length) || item.getAttribute("bl_loaded") == null)
  {
    imageName = "/" + bl_version + "/res/img/child_arrow.gif";
    show = true;
  }
  if (exImageItem)
  {
    exImageItem.src = imageName;
    if (show)
    {
      exImageItem.style.display = "inline";
    }
  }
  return exImageItem;
}

function cb_menu_handleInsert(el)
{
  var nodes         = el.childNodes;
  var parentId      = bl_port_get_text(nodes.item(0));
  var item          = bl_port_get_text(nodes.item(1));
  var index         = parseInt(bl_port_get_text(nodes.item(2)));
  
  var menuItem      = document.getElementById(parentId);
  if (menuItem)
  {
    cb_menu_nodeInsert(menuItem, null, item, index);
  }
}

function cb_menu_compute_child_set(childElement, html)
{
  var exImageSrc  = cb_menu_ex_image_child(childElement).src;
  bl_port_setOuterHTML(childElement, html.replace(/cb_replace_set/g, exImageSrc));
}

function cb_menu_set(nodes)
{
  var parentId  = bl_port_get_text(nodes.item(0));
  var item      = bl_port_get_text(nodes.item(1));
  var index     = parseInt(bl_port_get_text(nodes.item(2)));
  
  if (parentId.length > 0 && index >= 0)
  {
    var menuItem = document.getElementById(parentId);
    if (menuItem)
    {
      var span        = cb_menu_span_child(treeElement);
      var nodes       = (span ? span.childNodes : null);
      if (nodes && nodes.length > index)
      {
        cb_menu_compute_child_set(nodes[index], item)
      }
    }
  }
}

function cb_menu_setId(nodes)
{
  var id       = bl_port_get_text(nodes.item(0));
  var menuItem = document.getElementById(id);
  
  if (menuItem)
  {
    var item = bl_port_get_text(nodes.item(1));
    var type = bl_port_get_text(nodes.item(2));
    
    if (type == "text")
    {
      var text = cb_menu_text_child(menuItem);
      bl_port_setOuterHTML(text, item);
    }
    else if (type == "icon")
    {
      var icon = cb_menu_image_child(menuItem);
      bl_port_setOuterHTML(icon, item);
    }
    else
    {
      cb_menu_compute_child_set(menuItem, item);
    }
  }
}

function cb_menu_expand(parentId, payload, nodeName)
{
  var isExpand = nodeName == "expand";
  var menuItem = document.getElementById(parentId);
  if (menuItem)
  {
    var listChanged   = (nodeName == "listChanged" ? true : false);
    if (listChanged)
    {
      span = cb_menu_span_child(menuItem);
      if (span)
      {
        menuItem.removeChild(span.parentNode);
      }
    }
    bl_port_insertAdjacentHTML(menuItem, "beforeend", payload);
    menuItem.setAttribute("bl_loaded", true);
    if (!listChanged)
    {
      menuItem.cb_expand_requested = false;
      cb_menu_showMenu(menuItem);
    }
    else
    {
      cb_menu_nodeComputeExImage(menuItem);
    }
  }
}

function cb_menu_remove(id, removeAll)
{
  var menuItem = document.getElementById(id, false);
  if (menuItem)
  {
    if (removeAll)
    {
      cb_menu_nodeRemoveAll(menuItem);
    }
    else
    {
      cb_menu_nodeRemoveObj(menuItem);
    }
  }
}

function cb_menu_move(nodes)
{
  var menuItem = document.getElementById(bl_port_get_text(nodes.item(0)), false);
  if (menuItem)
  {
    cb_menu_moveElement(menuItem, parseInt(bl_port_get_text(nodes.item(1))), parseInt(bl_port_get_text(nodes.item(2))));
  }
}

function no_cb_menu_handler(item, element)
{
  var el    = item.firstChild;
  var nodes = el.childNodes;
  if (el.nodeName == "expand" || el.nodeName == "listChanged")
  {
    var idChild = el.firstChild;
    cb_menu_expand(bl_port_get_text(idChild), bl_port_get_text(idChild.nextSibling), el.nodeName);
  }
  else if (el.nodeName == "select")
  {
    var element = document.getElementById(bl_port_get_text(el));
    if (element)
    {
      cb_menu_sendSelectToServer(element);
    }
  }
  else if (el.nodeName == "insert")
  {
    cb_menu_handleInsert(el);
  }
  else if (el.nodeName == "addColl")
  {
    for (var i = 0; i < el.childNodes.length; i++)
    {
      cb_menu_handleInsert(nodes.item(i));
    }
  }
  else if (el.nodeName == "move")
  {
    cb_menu_move(nodes);
  }
  else if (el.nodeName == "set")
  {
    cb_menu_set(el.childNodes);
  }
  else if (el.nodeName == "setId")
  {
    cb_menu_setId(el.childNodes);
  }
  else if (el.nodeName == "remove")
  {
    cb_menu_remove(bl_port_get_text(nodes.item(0)), false);
  }
  else if (el.nodeName == "removeAll")
  {
    cb_menu_remove(bl_port_get_text(el.firstChild), true);
  }
  else if (el.nodeName == "titleChanged")
  {
    element.title = bl_port_get_text(el);
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_menu_last()
{
  var x = 0;
}

//***********************************************************************
//***********************************************************************
//********                 bl_overlay.js                        *********
//***********************************************************************
//***********************************************************************

// Contains the number of open popup windows at the current time. The popup
// veil is hidden when there are no more popups. The count is maintained by
// bl_port_popupHide and bl_port_popupShow.
var bl_port_openPopupCount = 0;

function bl_port_showVeil()
{
  bl_port_openPopupCount++;
  if (bl_port_openPopupCount > 0)
  {
    var veil = document.getElementById("popup_veil");
  
    if (!veil)
    {
      veil = document.createElement("div");
      veil.id = "popup_veil";
      document.body.insertBefore(veil, document.body.firstChild);
      veil.onmousedown = bl_sys_popupVeilDown;
      veil.onmousemove = bl_sys_popupVeilMove;
    }

    with (veil.style)
    {
      left     = "0px";
      top      = "0px";
      fontSize = "1px";
      width    = "100%";
      height   = "100%";
      position = "absolute";
      zIndex   = "10000";
      display  = "block";
    }
    
    bl_port_adjustVeil(veil);
  }
}

function bl_port_adjustVeil(veil)
{
  // Set the popup vail to the popup with the greatest zIndex
  var pl = cb_sys_getTopWindow().bl_tempPopups;
  
  if (pl)
  {
    var len  = pl.length
    var newZ = 0;
  	
    for (var i = 0; i < len; i++)
    {
      var popit = pl[i];
      
      if (popit.isOpen)
      {
        newZ = Math.max(parseInt(popit.container.style.zIndex), newZ);
      }
    }
  	
    veil.style.zIndex = newZ - 1;
  }
}

/* HTMLIFrameElement Methods */
function bl_port_popupShow()
{
  var popupArg  = this.popup_arg;
  var container = this.container;
  var topWin    = cb_sys_getTopWindow();
  var iframe    = container.iframe;
  var pos = blu_computeDialogPos(popupArg, topWin);

  if (popupArg.positionType == "control" && popupArg.el && popupArg.el.registerPopup)
  { 
    // register this popup with the map
    if (!popupArg.el.registerPopup(this))
    { // If we failed to register the popup don't display it.
      return;
    }
  }

  this.isOpen = true;

  if (popupArg.useVeil)
  {
    topWin.bl_port_showVeil();
  }
  
  
  with (container.style)
  {
    top        = pos.y + "px";
    left       = pos.x + "px";
    visibility = 'visible';
    display    = 'block';
  }
  
  with (iframe.style)
  {
    width  = popupArg.computedWidth + "px";
    height = popupArg.computedHeight + "px";
  }

  try
  {
    iframe.contentWindow.document.body.style.backgroundColor = "transparent";
  } catch (_E) {}

  if (popupArg.fade)
  {
    var tweenFunc = function (pos, elmt, is_done, interp)
                    {
                      elmt.style.opacity = pos;
                      elmt.style.filter = "alpha(opacity=" + parseInt(pos * 100) + ")";

                      if (is_done && popupArg.timeClose)
                      {
                        _popup_do_time_close(elmt);
                      }

                      if (is_done)
                      {
                        elmt.style.opacity = "";
                        elmt.style.filter = "";
                      }
                    }

    bl_sys_tween(0, 1, popupArg.timeClose ? 1 : .35, container, tweenFunc, bl_sys_serp);
  } 
  else if (popupArg.timeClose)
  {
    _popup_do_time_close(container);
  }

  topWin.bl_kb_notifyPopupOpen(this);

  container.isOpen = true;
}

function _popup_do_time_close(container)
{
  var popupArg = container.popup_obj.popup_arg;

  var fade_func = function()
  {
    if (popupArg.fade)
    {

      container.onmousemoveOld = container.onmousemove;
      container.onmousemove = function(event)
      {
         bl_sys_remove_tween(container);
         container.style.opacity = "";
         container.style.filter = "";
         container.onmousemove = container.onmousemoveOld;
      }

      var tweenFunc = function (pos, elmt, is_done, interp)
                      {
                        elmt.style.opacity = pos;
                        elmt.style.filter = "alpha(opacity=" + parseInt(pos*100) + ")";

                        if (is_done)
                        {
                          container.popup_obj.close();
                        }
                      }

      bl_sys_tween(1, 0, 1.25, container, tweenFunc, bl_sys_serp);
    } 
    else
    {
      container.popup_obj.close();
    }
  }
  setTimeout(fade_func,popupArg.timeClose*1000);
}

function bl_port_popupHideVeil()
{
  var veil = document.getElementById("popup_veil");

  bl_port_openPopupCount--;

  if (veil)
  {  
    if (bl_port_openPopupCount < 1)
    {
      bl_port_openPopupCount = 0;
      
      with (veil.style)
      {
        left     = "-1px";
        top      = "-1px";
        fontSize = "1px";
        width    = "1px";
        height   = "1px";
        position = "absolute";
        zIndex   = "0";
        display  = "none";
      }
    }
    bl_port_adjustVeil(veil);
  }
}

function bl_port_sheetHideTween(pos, arg, is_done, interp)
{
  arg.style.opacity = pos;
  arg.style.filter = "alpha(opacity=" + parseInt(pos * 100) + ")";
  
  if (is_done && arg.parentNode)
  {
    arg.parentNode.removeChild(arg);
  }
}

function bl_port_popupClose()
{
  var topWin = cb_sys_getTopWindow();
  var el     = this.container;
  var args   = this.popup_arg;

  topWin.bl_kb_notifyPopupClosed(this);

  if (!el)  
  {
    return;
  }
  if (bl_browserInfo.firefox || bl_browserInfo.safari)
  {
    var tframeList = topWin.bl_port_getWindows(false);
    var len        = tframeList.length;
    var elFrame    = el.iframe.contentWindow;
    
    for (var i = 0; i < len; i++)
    {
      var frame = tframeList[i];
      
	    if (elFrame == frame)
	    {
	      elFrame.removeEventListener("mouseover", bl_port_capture_event, true);
	      elFrame.removeEventListener("mousedown", bl_port_capture_event, true);
	      elFrame.removeEventListener("mousemove", bl_port_capture_event, true);
	      elFrame.removeEventListener("mouseup", bl_port_capture_event, true);
	      elFrame.removeEventListener("mouseout", bl_port_capture_event, true);
	      elFrame.removeEventListener("click", bl_port_capture_event, true);
		    tframeList.splice(i, 1);
		    break;
	    }
    }
  }
  this.isOpen = false;

  if (!bl_browserInfo.firefox)
  {
    el.style.display = "none";
  } 
  else
  {
    // Setup a back reference to "this" so ff_crash_fix can work.
  	var self = this;

	  // Firefox will crash on win/linux/osx when setting display = "none"
	  // from within the context of an iframe on an element outside said iframe.
	  // This work around sets the display in the context of the top level window
	  // which fixes the crash.
    var ff_crash_fix = function()
    {
      if (!self.isOpen)
      {
        el.style.display = "none";
      }
      // Break back reference
      self = null;
    }

    topWin.setTimeout(ff_crash_fix,1);
  }

  if (el.sheet != undefined)
  {
    bl_sys_tween(parseFloat(el.sheet.style.opacity), 0, .3, el.sheet, bl_port_sheetHideTween, bl_sys_serp);
  }
  
  el.isOpen = false;
  
  if (args)
  {
    if (args.cleanUp && args.canDestroy)
    {
      args.cleanUp(this);
    }
  }

  if (args.useVeil)
  {
    topWin.bl_port_popupHideVeil();
  }
}

// create Popup Object 
function bl_port_createPopup(arg)
{
  var tlw = cb_sys_getTopWindow();

  // if the window that owns this popup goes away then so would the 
  // functions that is why we are assigning the top level windos functions
  // to this object show/hide members
  this.show      = tlw.bl_port_popupShow;
  this.close     = tlw.bl_port_popupClose;
  this.showState = 0;
  this.popup_arg = arg;
  this.isOpen    = false;
  this.container = bl_port_getPopupContainer(tlw, arg, this);

  tlw.popup_is_loading = true;
  
  if (!tlw.bl_tempPopups)
  {
    tlw.bl_tempPopups = new tlw.Array();
  }

  if (!tlw.bl_popupList)
  {
    tlw.bl_popupList = new tlw.Array();
  }

  tlw.bl_popupList.push(this);
  
  if (!arg.sticky)
  {
    tlw.bl_tempPopups.push(this);
  }
}

function _bl_port_resize(event, el)
{
  if (el.bl_mouseIsDown)
  {
    var container = bl_port_findPopupParent(el);
    var posx      = bl_port_getMouseX(event);
    var posy      = bl_port_getMouseY(event);
    
    if (event.bl_capturePos)
    {
      posx = event.bl_capturePos.x;
      posy = event.bl_capturePos.y;
    }
    else
    {
      posx = bl_port_getMouseX(event);
      posy = bl_port_getMouseY(event);
    }
    var w = posx - container.origPos.x;
    var h = posy - container.origPos.y;

    if (w < 50)
    {
      w = 50;
    }
    
    if (h < 50)
    {
      h = 50;
    }
    
    with (container.iframe.style)
    {
      width  = w + "px";
      height = h + "px";
    }
    if (container.tagName == "TABLE")
    {
      if (typeof(container.winIconsWidth) == "undefined")
      {
        try
        { // get the TD with the minimize maximize close icons
          var topTableCells = container.rows[0].cells[0].childNodes[0].rows[0].cells;
          // verify this is the minimize Restore Cancel TD
          if (topTableCells[2] && topTableCells[2].getAttribute("blid") == "MRC")
          {
            container.winIconsWidth = topTableCells[2].offsetWidth;
          }
        }
        catch(e)
        {
          container.winIconsWidth = 0;
        }
      }
      if (typeof(container.chromeCaption) == "undefined")
      {
        try
        { // get the TD with the window label. This element should size with the iframe so it is 
          // not causing the chrome to be larger than its contents.
          var topTableCells = container.rows[0].cells[0].childNodes[0].rows[0].cells;
          container.chromeCaption = topTableCells[1].childNodes[0];
        }
        catch(e)
        {
          container.chromeCaption = null;
        }
      }
      if (container.chromeCaption)
      { // we need to set the width on the caption TD so that it doesn't force the container to be too large
        container.chromeCaption.style.width = (w - container.winIconsWidth) + "px";
      }
    }
  }
}

function _bl_port_resizeBegin(event, el)
{
  var container = bl_port_findPopupParent(el);

  container.origPos = bl_sys_find_xy(container.iframe, null, false);

  if (!bl_browserInfo.ie)
  {
    bl_port_coverFrames(window, true);
  }

  bl_sys_img_freeze(el);
}

function bl_port_popupCloseTween(pos, el, is_done, interp)
{
  el.style.opacity = pos;
  el.style.filter  = "alpha(opacity=" + parseInt(pos*100) + ")";

  if (is_done)
  {
    var popit = el.popup_obj;
    
    popit.close();
    bl_sys_popupDestroy(popit, popit.popup_arg);
  }
}

function _bl_port_doClosePopup(event, el)
{
  var popupParent = bl_port_findPopupParent(el); 
  
  if (popupParent)
  {
    var obj = popupParent.popup_obj;
    
    if (obj.popup_arg.fade)
    {
      bl_sys_tween(1, 0, .4, popupParent, bl_port_popupCloseTween, bl_sys_serp);
    } 
    else
    {
      obj.close();
      bl_sys_popupDestroy(obj, obj.popup_arg);
    }
  }
}


/*****************************************************
 Function name   : bl_port_popupHideTween
 Description     : Don't destroy the popup so it can be reused once we are done fading out the popup
 Argument        : pos
 Argument        : el
 Argument        : is_done
 Argument        : interp
 *****************************************************/
 function bl_port_popupHideTween(pos, el, is_done, interp)
{
  el.style.opacity = pos;
  el.style.filter  = "alpha(opacity=" + parseInt(pos*100) + ")";

  if (is_done)
  {
    var popit = el.popup_obj;
    
    popit.close();
  }
}
/*****************************************************
 Function name   : _bl_port_HidePopup
 Description     : Don't destroy the popup when we are done "closing it"
 Argument        : event
 Argument        : el
 *****************************************************/
 function _bl_port_HidePopup(event, el)
{
  var popupParent = bl_port_findPopupParent(el); 
  
  if (popupParent)
  {
    var obj = popupParent.popup_obj;
    
    if (obj.popup_arg.fade)
    {
      bl_sys_tween(1, 0, .4, popupParent, bl_port_popupHideTween, bl_sys_serp);
    } 
    else
    {
      obj.close();
    }
  }
}


function _bl_port_resizeEnd(event, el)
{
  _bl_port_resize(event, el);

  if (!bl_browserInfo.ie)
  {
    bl_port_uncoverFrames(window);
  }

  bl_sys_img_thaw(el);
}

function bl_port_sheetShowTwean(pos, arg, is_done, interp)
{
  arg.style.opacity = pos;
  arg.style.filter = "alpha(opacity=" + parseInt(pos*100) + ")";
}

function bl_port_popupDown(event, el)
{
  if (event)
  {
    var popupObj = el.popup_obj;
    bl_kb_notifyPopupActive(popupObj);
  
    if (!bl_browserInfo.ie)
    {
      bl_port_coverFrames(window, true);
    }

    bl_port_setCapture(el);
    el.isDragging = true;
  	
  	// Popup was adjusted, put back into screen coords
    if (el.style.left == "") 
    {
      var windowWidth = bl_browserInfo.ie ? window.document.body.clientWidth : window.innerWidth;
	    el.style.right = "";
	    el.style.left = (windowWidth - parseInt(el.iframe.style.width)) + "px";
    }
  	
  	// Popup was adjusted, put back into screen coords
    if (el.style.top == "") 
    {
      var windowHeight = bl_browserInfo.ie ? window.document.body.clientHeight : window.innerHeight;
      el.style.bottom = "";
      
      // 2x the top border height (roughly)
      windowHeight -= 15 * 2; 
      el.style.top = (windowHeight - parseInt(el.style.height)) + "px";
    }
  	
    el.offx = parseInt(el.style.left) - bl_port_getMouseX(event);
    el.offy = parseInt(el.style.top) - bl_port_getMouseY(event);
  }  	
  return false;
}

function bl_port_popupMove(event, el)
{
  if (!el.isDragging)
  {
    return;
  }

  if (event)
  {
    var posx = bl_port_getMouseX(event);
    var posy = bl_port_getMouseY(event);
    
    posx += el.offx;
    posy += el.offy;

    if (posx < 0)
    {
      posx = 0;
    }
    
    if (posy < 0)
    {
      posy = 0;
    }

    var topWin       = cb_sys_getTopWindow();
    var body         = topWin.document.body;
    var windowWidth  = bl_browserInfo.ie ? body.clientWidth  : topWin.innerWidth;
    var windowHeight = bl_browserInfo.ie ? body.clientHeight : topWin.innerHeight;
    var elWidth      = parseInt(el.style.width);
    var elHeight     = parseInt(el.style.height);
    
    if (posx + elWidth > windowWidth)
    {
      posx = windowWidth - elWidth;
    }
    
    if (posy + elHeight + 19 > windowHeight)
    {
      posy = windowHeight - (elHeight + 19);
    }		
    
    el.style.left = posx + "px";
    el.style.top = posy + "px";

    if (!bl_browserInfo.ie)
    {
      bl_port_coverFrames(window, true);
    }
  }
}

function bl_port_popupUp(event, el)
{
  if (!bl_browserInfo.ie)
  {
    bl_port_uncoverFrames(window);
  }

  if (el.isDragging)
  {
    bl_port_releaseCapture(el);
  }
  el.isDragging = false;
}

function bl_port_defaultChrome()
{
  if (this.defaultChrome == undefined)
  {
    this.defaultChrome = "<div style='position:absolute;left:-1000px;top:-1000px;width:0px;visibility:hidden;'><iframe allowtransparency='true' style='border:none;width:0px;height:0px' scrolling='no' src='/"
                          + bl_version
                          + "/res/htm/bl_popup.htm' frameborder='0'></iframe></div>";
  }
  
  return this.defaultChrome;
}

function bl_port_computePopupId()
{
  if (window.bl_ids_nextPopup == undefined)
  {
    window.bl_ids_nextPopup = 0
  }
  
  return "popup_" + window.bl_ids_nextPopup++;
}

function bl_port_getPopupContainer(tlw, arg, popit)
{
  if (!arg.chrome || arg.chome == "")
  {
    arg.chrome = bl_port_defaultChrome();
  }
  
  var body = tlw.document.body
  
  // to avoid issues with ssl we need to create the iframe this way
  bl_port_insertAdjacentHTML(body, "beforeend", arg.chrome);

  var container = body.lastChild;
  var iframe    = null;
  
  container.popup_parent = window; 
  container.popup_obj    = popit;
  container.isOpen       = false;
  container.isPopup      = true;
  container.isDragging   = false;
  
  if (container.tagName == "TABLE")
  {
    iframe = container.firstChild.childNodes[1].childNodes[1].firstChild;
    
    with (iframe.style)
    {
      // Set the iframe size here so that the 100% size for the chrome doesn't get stuck too wide.
      width = arg.w + "px";
      height = arg.h + "px";
    }
  }
  else
  {
    iframe = container.firstChild;
  }
  iframe.id = tlw.bl_port_computePopupId();
  iframe.container = container;
  container.iframe = iframe;

  var contentWindow = iframe.contentWindow;
  
  contentWindow.isPopup = true;
  contentWindow.document.oncontextmenu = bl_sys_context_menu;


  if (tlw.bl_popupZOrder == undefined)
  {
    tlw.bl_popupZOrder = 10000;
  }

  container.style.zIndex = (tlw.bl_popupZOrder += 2);

  if ((arg.sheetColor != undefined && arg.sheetColor != "") || arg.isModal)
  {
    if (arg.sheetColor == undefined || arg.sheetColor == "")
    {
      arg.sheetAlpha = 0;
      arg.sheetColor = "#ffffff";
    }
	
    container.sheet = tlw.document.createElement("div");
    
    with (container.sheet.style)
    {
      position        = "absolute";
      top             = "0px";
      left            = "0px";

      try
      {
        backgroundColor = arg.sheetColor;
      } catch (_e)
      {
        backgroundColor = "";
      }

      opacity         = arg.sheetAlpha;
      filter          = "alpha(opacity=" + parseInt(arg.sheetAlpha*100) + ")";
      width           = "100%";
      height          = "100%";
      zIndex          = tlw.bl_popupZOrder-1;
    }

    body.appendChild(container.sheet);
    bl_sys_tween(0, arg.sheetAlpha/100, .4, container.sheet, bl_port_sheetShowTwean, bl_sys_serp);

  }

  // Stop flicker when container gets added to DOM
  if (arg.fade)
  {
    container.style.opacity = 0;
    container.style.filter = "alpha(opacity=0)";
  }

  return container;
}

function _bl_port_minimizePopup(event, el)
{
  var n            = bl_port_findPopupParent(el);
  var x            = parseInt(n.style.left);
  var y            = parseInt(n.style.top);
  var topWin       = cb_sys_getTopWindow();
  var windowHeight = bl_browserInfo.ie ? topWin.document.body.clientHeight : topWin.innerHeight;

  if (n.oldX == undefined)
  {
    // Make time to animate relative to distance
	  var t = Math.sqrt((x*x + (windowHeight - y)*(windowHeight - y)))/500; 
	  
    el.setAttribute("bl_selected", true);

	  if (t < .5)
	  {
	    t = .5;
	  }
	  if (t > .9)
	  {
      t = .9;
	  }
	  
    n.oldX = x;
    n.oldY = y;
    n.oldT = t;

    bl_sys_tween(x,0,t,n,move_x,bl_sys_serp2);
    bl_sys_tween(y,windowHeight - 32,t,n,move_y,bl_sys_serp2);
    bl_sys_tween(parseInt(n.iframe.style.height),0,t/2,n.iframe,min_adjust_height,bl_sys_serp);

    n.iframe.oldHeight = parseInt(n.iframe.style.height);
  } 
  else
  {
	  var t = n.oldT;
	  
    el.removeAttribute("bl_selected");
    
    bl_sys_tween(x,n.oldX,t,n,move_x,bl_sys_serp2);
    bl_sys_tween(y,n.oldY,t,n,move_y,bl_sys_serp2);
    bl_sys_tween(0,n.iframe.oldHeight,t,n.iframe,min_adjust_height,bl_sys_serp);

    n.oldX = undefined;
    n.oldY = undefined;
  }
}

function move_x(pos, arg, is_done, interp)
{
  arg.style.left = pos + "px";
}

function move_y(pos, arg, is_done, interp)
{
  arg.style.top = pos + "px";
}

function min_adjust_height(pos, arg, is_done, interp)
{
  arg.style.height = pos + "px";
}

function bl_port_findPopupParent(el)
{
  var container = el.bl_container;
  
  if (!container)
  {
    container = el; 
    
    while (container.popup_obj == undefined) 
    {
      container = container.parentNode; 
    }
    
    el.bl_container = container;
  }
  return container;
}

function bl_sys_loadPopup(item)
{
  var popit = null;
  var mpr   = bl_sys_get_mpr();
  
  if (mpr)
  {
    var dataNode = item.firstChild;
    
    if (dataNode)
    {
      var id = -1;
      var idAttr = dataNode.attributes.getNamedItem("id");
      
      if (idAttr)
      {
        id = parseInt(bl_port_get_text(idAttr));
      }
      
      var popupContext = mpr.pendingPopupContext;
      
      if (id == -2)
      {
        popupContext = new cb_sys_popup_context(null, null, "popup-statement", false, -2);
      }
      
      if (popupContext && popupContext.id == id)
      {
        var list = dataNode.childNodes;
        
        if (list && list.length)
        {
          var el = popupContext.el;
          var win = (el)? bl_port_docWindow(el.ownerDocument):window;
          popit = win.bl_sys_popupInvoke(new win.bl_ov_mprArg(dataNode.childNodes, popupContext, true, null));
        }
        mpr.setPopupContext(null, false);
      }
      else
      {
        var deadArg = new bl_sys_popupDeadArg(dataNode.childNodes)
        mpr.send(deadArg.windowId, bl_sys_shutDownMSG(deadArg.suspendId, 0, "Cancel"), deadArg.windowId, -1, BL_MPR_ASAP, true, -1);
      }
    }
  }
  return popit;
}

function bl_ov_computeSize(arg, doc)
{
  var h = arg.h;
  var w = arg.w;
  
  if (w <= 0 && arg.syncSizeToControl)
  {
    w = arg.el.offsetWidth;
  }
  
  if (w < 0 || h < 0)
  {
    var list   = doc.images;
    var len    = list.length;
    var hlen   = len;
    var maxCnt = arg.maxComputeCnt;
    
    if (h < 0)
    {
      h = 0;
    }
    if (w < 0)
    {
      w = 0;
    }
    
    if (maxCnt != undefined && maxCnt > 0 && maxCnt < len)
    {
      hlen = maxCnt;
    }
    
    var hcnt = 0;
    
    for (var i = 0; i < len; i++)
    {
      var el = list[i];
      
      if (el.style.display.toLowerCase() != "none" && !bl_port_hasAttribute(el, "bl_popup_ignore"))
      {
        if (bl_browserInfo.firefox || bl_browserInfo.safari)
        {
          var iw = parseInt(el.offsetWidth);
          var ih = parseInt(el.offsetHeight);
        }
        else
        {
          var imageS = bl_port_getComputedStyle(el);
          var iw     = parseInt(imageS.width);
          var ih     = parseInt(imageS.height);
        }
        
        if (iw)
        {
          w = Math.max(iw, w);
        }
        if (ih && hcnt < hlen)
        {
          h += ih;
          hcnt++;
        }
      }
    }
  }
  
  arg.computedHeight = h;
  arg.computedWidth  = w;
}

function bl_sys_popupDeadArg(itemDataList)
{
  window.eval(bl_port_get_text(itemDataList[1]));
}

function bl_ov_mprArg(itemDataList, context, canDestroy, onClickHook)
{
  this.html   = bl_port_get_text(itemDataList[0]);
  window.eval(bl_port_get_text(itemDataList[1]));
  this.chrome = bl_port_get_text(itemDataList[2]);

  if (context.isSystemContext)
  {
    var positionList = this.positionType.split(" ");

    this.positionType = positionList[0];
    
    if (positionList.length > 1)
    { // The position might be structured with a sub-index so we can position the popup on an item inside the control.
      // This is used for positioning popups on markers in the GoogleMap
      var positionList = positionList[1].split("_");
      var contextEl = bl_wn_findControl(positionList[0]);
        
      if (contextEl)
      {
        context.el = contextEl;
        if (positionList.length > 1)
        {
          this.itemIndex = positionList[1];
        }
      }
    }
    
    if (this.positionType == "at-mouse")
    {
      this.x += context.clX;
      this.y += context.clY;
    } 
    else if (this.positionType == "control")
    {
      this.el = context.el;
    }
  }
  else
  {
    // this means the context for the overlay is an actual element
    // the position type is 'control'
    this.positionType = "control";
    this.el           = context;
  }
  
  this.canDestroy   = canDestroy;
  this.cascadeClose = context.cascadeClose;
  this.cleanUp      = bl_sys_cleanUpPopup;
  this.onClickHook  = onClickHook;
  this.valid        = bl_sys_popupValid;
  
  // use the veil if not sticky (aka, a popup _dialog_)
  this.useVeil      = !this.sticky;
}

function bl_sys_popupValid(win)
{
  return (win.bl_pulseCoreLoaded);
}

function bl_sys_closeSysMsg(arg)
{
  if (arg && arg.doReload)
  {
    _bl_sys_shutdown_window(window);
    _bl_redirect(bl_deployurl);
    return false;
  }
  
  return true;
}

function _bl_sys_closeMsg(event, el)
{
  var arg = bl_sys_getThisPopupArg(window).popup_arg;
  
  if (!bl_sys_popupParent().bl_sys_closeSysMsg(arg))
  {
    bl_sys_closeThisPopup();
  }
}

var cb_sys_popup_context_id = 0;
function cb_sys_popup_context(el, event, type, cascadeClose, id)
{
  this.el = el;
  
  if (event)
  {
    this.clX = event.clientX;
    this.clY = event.clientY;
  }
  else
  {
    this.clX = 0;
    this.clY = 0;
  }
  
  if (el)
  {
    var topWindow    = cb_sys_getTopWindow();
    var parentWindow = bl_port_docWindow(el.ownerDocument)
    
    this.clX += (bl_port_getScreenLeft(parentWindow) - bl_port_getScreenLeft(topWindow));
    this.clY += (bl_port_getScreenTop(parentWindow) - bl_port_getScreenTop(topWindow));
  }
  
  if (id == undefined)
  {
    id = cb_sys_popup_context_id++;
  }
  
  this.id              = id;
  this.isSystemContext = true;
  this.cascadeClose    = cascadeClose;
}

function _bl_sys_rightClickCheck(event, el)
{
  bl_kb_focusOnElement(bl_port_getEventTarget(event));

  if (el != bl_port_get_activeElement(document) && bl_port_isRightDown(event))
  {
    el.setAttribute("bl_not_active", true);
  }
  else
  {
    el.removeAttribute("bl_not_active");
  }
  
  if (el.getAttribute("bl_list_logic") != null)
  {
    bl_sys_handleListLogic(el, event);
  }
}

function _bl_sys_rightClick(event)
{
  var el  = bl_port_getEventTarget(event);
  
  if (!cb_sys_isInput(el) || el.getAttribute("bl_not_active") != null)
  {
    el.removeAttribute("bl_not_active");
    
    while (el)
    {
      try
      {
        if (bl_port_hasAttribute(el, "bl_right_click") && !bl_port_hasAttribute(el, "bl_rcFrozen"))
        {
          bl_port_stop_event(event);
          
          var mpr = bl_sys_get_mpr();
          
          if (mpr)
          {
            var context = new cb_sys_popup_context(el, event, "right-click", true);
            var id      = el.id;
            
            if (el.tagName.toLowerCase() == "body")
            {
              id = window.bl_did;
            }

            bl_mpr_send("<right_click>" + context.id + "</right_click>", id, 1000);
            mpr.setPopupContext(context, true);
          }
          return false;
        }
      }
      catch (exception)
      {
      }
      el = el.parentNode;
    }
  }
  return true;
}

function bl_sys_findPopup(iframe)
{
  var pl = cb_sys_getTopWindow().bl_popupList;
  
  if (pl)
  {
    var len = pl.length;
    
    for (var i = 0; i < len; i++)
    {
      var popit = pl[i];
      
      if (popit.container.iframe == iframe)
      {
        return popit;
      }
    }
  }  

  return null;
}

function bl_sys_shutdownPopupList()
{
  var topWin = cb_sys_getTopWindow();
  
  if (topWin == window)
  {
    var pl = topWin.bl_popupList;
    
    if (pl)
    {
      var popit = pl.pop();
      
      while (popit)
      {
        var doc = bl_port_getOverLayDocument(popit);
        var arg = popit.popup_arg;

        if (arg.windowId)
        {
          var popitWin = bl_port_docWindow(doc);
          
          if (popitWin && popitWin.bl_did == "")
          {
            popitWin.bl_did = arg.windowId;
          }
          
          arg.deferSend = true;
          _bl_sys_shutdown_window(popitWin, arg);
          arg.windowId = null;
        }
        
        popit = pl.pop();
      } 
    }  
  }
}

function bl_sys_removeFromPopupList(popit)
{
  var topWin = cb_sys_getTopWindow();
  
  bl_removeFromList(topWin.bl_tempPopups, popit);
  bl_removeFromList(topWin.bl_popupList, popit);
}

function _bl_sys_popup_cleanup()
{
  var killList = window.bl_popupKillList;

  if (killList)
  {
    var container = killList.pop();
    
    while (container)
    {
      var parent = container.parentNode;
      
      try 
      {
        var doc = container.iframe.contentWindow.document;
        doc.open("text/html", "replace");
        doc.close();
      }
      catch (ex)
      {
        // there are time when firfox just fails to deal with 
        // closing the doc especially if the popit is closed before render is complete
      }
      
      if (parent)
      {
	      parent.removeChild(container);
      }
      
      container = killList.pop();
    }
    killList.timerID = undefined;
  }
}

function cb_sys_popup_close(cascadeClose)
{
  var popit = bl_sys_getPopupObj();

  bl_sys_setPopupObj(null);

  if (popit && !popit.isDead)
  {
    var popupArg = popit.popup_arg;
    
    popit.close();
    
    if (popupArg.canDestroy)
    {
      bl_sys_popupDestroy(popit, popupArg);
    }
    
    if (cascadeClose && window.bl_sys_isInPopup())
    {
      bl_sys_closeThisPopup();
    }	
  }
}

function bl_sys_popupDestroy(popit, arg)
{
  if (popit && popit.isDead == undefined)
  {
    var container = popit.container;
    var tlw       = cb_sys_getTopWindow();

    tlw.bl_sys_removeFromPopupList(popit);

    if (bl_sys_getPopupObj() == popit)
    {
      bl_sys_setPopupObj(null);
    }
    
    if (arg)
    {
      with (arg)
      {
        html        = null;
        customArg  = null;
        el          = null;
        cleanUp     = null;
        shutdown    = null;
        onClickHook = null;
        valid       = null;
      }
    }

    bl_kb_notifyPopupClosed(popit);

    popit.show      = null;
    popit.hide      = null;
    popit.isOpen    = false;
    popit.isDead    = true;
    popit.container = null;
    delete popit;

    var killList = tlw.bl_popupKillList;

    if (!killList)
    {
      tlw.bl_popupKillList = killList = [];
    }
    
    killList.push(container);
    
    if (killList.timerID == undefined)
    {
      killList.timerID = tlw.setTimeout("_bl_sys_popup_cleanup()", 6000);
    }
  }
}

function bl_sys_isInPopup()
{
  return bl_port_hasAttribute(document.body, "bl_isPopup");
}

function bl_sys_popupParent()
{
	var popupParent = null;
	
	try
	{
	  popupParent = window.frameElement.container.popup_parent;
	}
	catch (ex)
	{
	}
	
	return popupParent;
}

function bl_sys_getMyPopupArg()
{
  var ret = null;
  
  try
  {
    var popit = window.frameElement.container.popup_obj;
    
    if (popit)
    {
      ret = popit.popup_arg;
    }
  }
  catch (ex)
  {
  }
  
  return ret;
}

function bl_sys_getMyPopupObject()
{
  var ret = null;
  
  try
  {
    ret = window.frameElement.container.popup_obj;
  }
  catch (ex)
  {
  }
  
  return ret;
}

function bl_sys_getPopupObj()
{
  return window.bl_popupObj;
}

function bl_sys_setPopupObj(obj)
{
  window.bl_popupObj = obj;
}

function cb_sys_popup_renew(win, popit, arg)
{
  if (win && popit && !popit.isOpen)
  {
    if (arg.inited)
    {
      win.cb_sys_popup_close(false);
      bl_sys_setPopupObj(popit);
      bl_ov_computeSize(arg, bl_port_getOverLayDocument(popit));
      popit.show();
    }
  }
  return popit;
}

function bl_sys_popupComputeGeometry(popit, doc, arg)
{
  // initialize to start state waiting for valid 
  // body on the iframes doc
  var ret = 0;
  
  if (doc && doc.body)
  {
    bl_ov_computeSize(arg, doc);
    cb_sys_getTopWindow().popup_is_loading = false;
    
    if (arg.computedHeight <= 2 || arg.computedWidth <= 2)
    {
      if (!arg.sticky)
      {
        bl_sys_setPopupObj(null);
      }
      
      // return failed state
      ret = -1;
    }
    else
    {
      popit.show();
      
      // return that it is safe continue 
      ret = 1;
    }
  }
  
  return ret;
}

function _bl_sys_popupState()
{
  var pendingPopups = window.bl_pendingPopups;
  
  if (pendingPopups)
  {
    for (var i = pendingPopups.length - 1; i >= 0; i--)
    {
      try
      {
        var popit = pendingPopups[i];
          
        if (popit.isDead)
        {
          pendingPopups.splice(i, 1);
          continue;
        }
        
        var doc  = bl_port_getOverLayDocument(popit);
        var arg  = popit.popup_arg;

        if (popit.showState == 0)
        {
          popit.showState = bl_sys_popupComputeGeometry(popit, doc, arg)
        }
        
        if (popit.showState > 0)
        {
          var pwin = bl_port_docWindow(doc);

          if (!arg.valid || arg.valid(pwin))
          {
            arg.inited = true;
            
            if (arg.setHappened)
            {
              arg.setHappened = false;
              cb_sys_popup_close(false);
              if (arg && arg.onClickHook)
              {
                arg.onClickHook(arg);
              }
            }
            else if (arg.onFinalShowHook)
            {
              arg.onFinalShowHook(arg);
            }
            
            pendingPopups.splice(i, 1);
          }
        }
        else if (popit.showState < 0)
        {
          if (arg.windowId)
          {
            bl_sys_get_mpr().send(arg.windowId, bl_sys_shutDownMSG(arg.suspendId, 0, "Cancel"), arg.windowId, -1, BL_MPR_ASAP, true, -1);
          }
          
          bl_sys_popupDestroy(popit, arg);
          pendingPopups.splice(i, 1);
        }
      }
      catch(e)
      { /* continue on to the next popit window. It is possible to get a "Access denied" error when shutting down.*/
      }
    }
    
    if (pendingPopups.length > 0)
    {
      window.setTimeout("_bl_sys_popupState()", 50);
    }
  }
}

function bl_sys_popupInvoke(arg)
{
  var popit = null;
  
  if (arg)
  {
    var pendingPopups = window.bl_pendingPopups;
    
    if (!window.bl_pendingPopups)
    {
      window.bl_pendingPopups = pendingPopups = [];
    }

    popit = new bl_port_createPopup(arg);
    
    if (popit)
    {
      pendingPopups.push(popit);

      if (!arg.sticky) 
      {
        bl_sys_setPopupObj(popit);
      }
    }
  }
  
  return popit;
}

function bl_sys_getThisPopupArg(win)
{
  try
  {
    var iframe = win.frameElement;
    return iframe.container.popup_obj;
  }
  catch (ex)
  {
  }
  return null;
}

function bl_sys_closeThisPopup()
{
  var iframe = window.frameElement;

  try
  {
    var popit = iframe.container.popup_obj;
    
    if (popit && !popit.isDead)
    {
      popit.close();
      bl_sys_popupDestroy(popit, null);
    }
  }
  catch (ex)
  {
    // it is posible to have the ifame (in this case popup_parent)
    // that owned this go away.
    var popit = bl_sys_findPopup(iframe);
    
    if (popit && !popit.isDead)
    {
      popit.close();
      bl_sys_popupDestroy(popit, null);
    }
  }
}

function bl_sys_popupVeilMove(event)
{
  if (!event)
  {
    event = window.event;
  }
  
  bl_port_stop_event(event);
}

function bl_sys_popupVeilDown()
{
  var pl = cb_sys_getTopWindow().bl_tempPopups;
  
  if (pl && pl.length > 0)
  {
    try
    {
	    var popit = pl[pl.length - 1];
      
      popit.close();
      bl_sys_popupDestroy(popit, null);
    } 
    catch (E)
    {
      // pwned
    }
  }
}

function bl_port_getOverLayDocument(popit)
{
  return popit.container.iframe.contentWindow.document;
}

function bl_sys_cleanUpPopup(popit)
{
  if (popit)
  {
    var doc = bl_port_getOverLayDocument(popit);
    var arg = this;
    var el  = arg.el;
    
    if (el && el.cb_popup_cleanup)
    {
      el.cb_popup_cleanup(arg.el)
    }
    
    if (arg.windowId && arg.canDestroy)
    {
      var popitWin = bl_port_docWindow(doc);
      
      if (popitWin && popitWin.bl_did == "")
      {
        popitWin.bl_did = arg.windowId;
      }
      _bl_sys_shutdown_window(popitWin, arg);
      arg.windowId = null;
    }
  }
}

// we need to call close popup on the parent
// of the popup.
function _bl_sys_popupClose()
{
  cb_sys_popup_close(false);
  var popit = bl_sys_getMyPopupObject();
  
  if (popit && !popit.isDead)
  {
    var arg = popit.popup_arg;
    
    if (arg)
    {
      if (arg.onClickHook)
      {
        arg.onClickHook(arg);
      }
      bl_sys_closeThisPopup();
    }
    else
    {
      cb_sys_getTopWindow().bl_sys_popupVeilDown();
    }
  }
}

function _bl_sys_popupDown(event)
{
  cb_sys_popup_close(false);
}


//***********************************************************************
//***********************************************************************
//********                 bl_print.js                         *********
//***********************************************************************
//***********************************************************************

function cb_sys_print_loaded()
{
  window.onafterprint = cb_sys_print_done;
  window.print();
}

function cb_sys_print_done()
{
  if (!window.printCount)
  {
    window.printCount = 1;
    return;
  }
  window.close();
}


var bl_current_pr = null;

function _bl_pr_leave(event, el)
{
  el.bl_mouseIsIn = false;
  
  if (!cb_sys_disabled(el) && !el.bl_mouseIsDown)
  {
    bl_pr_setThumbSrc(el, bl_pr_getItem(el, "bl_thumb"), "en");
    bl_pr_hideTooltip(el);
  }
  bl_port_stop_event(event);
}

function bl_pr_getItem(el, type)
{
  var item = el.firstChild;
  
  while (item)
  {
    if (item.getAttribute(type) != null)
    {
      return item;
    }
    item = item.nextSibling;
  }
  
  return null;
}

function bl_pr_setThumbSrc(el, thumb, type)
{
  if (thumb)
  {
    var srcURL = thumb.getAttribute(type);
    
    if (type == "en")
    {
      var isFloat       = el.getAttribute("bl_float") != null;
      var valueActual;
      var minActual;
      var maxActual;
      
      if (isFloat)
      {
        valueActual = parseFloat(el.getAttribute("bl_progressVal"));
        minActual   = parseFloat(el.getAttribute("bl_rangeMin"));
        maxActual   = parseFloat(el.getAttribute("bl_rangeMax"));
      }
      else
      {
        valueActual = parseInt(el.getAttribute("bl_progressVal"));
        minActual   = parseInt(el.getAttribute("bl_rangeMin"));
        maxActual   = parseInt(el.getAttribute("bl_rangeMax"));
      }
      
      if (valueActual > maxActual || 
          valueActual < minActual ||
          (el.getAttribute("bl_zHide") != null && valueActual == minActual))
      {
        srcURL = "/" + bl_version + '/res/img/blank.gif';
      }
    }
    
    if (srcURL != null)
    {
      thumb.src = srcURL;
    }  
  }
}

function bl_pr_showTooltip(el, isVertical)
{
  var ttStyle = el.getAttribute("bl_tt_style");
  
  if (ttStyle != null)
  {
    var body     = document.body;
    var ttOp     = parseInt(el.getAttribute("bl_tt_op"));
    var tooltip  = body.bl_pr_tooltip;
    var enumData = el.getAttribute("bl_enum_list");
    
    if (enumData != null && !el.bl_enumList)
    {
      el.bl_enumList = enumData.split(";");
    }
    
    if (!tooltip)
    {
      var ttDIV = "<div style='" + ttStyle + "position:absolute;'></div>";
      
      bl_port_insertAdjacentHTML(body, "beforeend", ttDIV);
      
      body.bl_pr_tooltip = tooltip = body.lastChild;  
    }
    tooltip.style.visibility = "visible";
    bl_pr_computeTooltip(el, isVertical, (el.getAttribute("bl_reverse") != null), el.getAttribute("bl_progressVal"));
    cb_sys_startFilter(tooltip, false, 0, ttOp, 3, null, ttOp, null);
  }
}

function vl_pr_hideDone(tooltip)
{
  tooltip.style.visibility = "hidden";
}

function bl_pr_hideTooltip(el)
{
  if (el.getAttribute("bl_tt_style") != null)
  {
    var ttOp    = parseInt(el.getAttribute("bl_tt_op"));
    cb_sys_startFilter(document.body.bl_pr_tooltip, true, ttOp, 0, 3, null, 0, vl_pr_hideDone);
  }
}

function bl_pr_computeTooltip(el, isVertical, reverse, value)
{
  if (el.getAttribute("bl_tt_style") != null)
  {
    var body     = document.body;
    var tooltip  = body.bl_pr_tooltip;
    var style    = tooltip.style;
    var progress = bl_pr_getItem(el, "bl_progress");
    var thumb    = bl_pr_getItem(el, "bl_thumb");
    var tx       = 0;
    var ty       = 0;
    var x        = bl_sys_find_x(el, null, false);
    var y        = bl_sys_find_y(el, null, false);
    var isInset  = el.getAttribute("bl_inset") != null;
    var list     = el.bl_enumList;
    
    if (list)
    {
      var index = parseInt(value);
      
      if (index < 0)
      {
        value = list[0];
      }
      if (index > list.length)
      {
        value = list[list.length - 1];
      }
      else
      {
        value = list[index];
      }
    }

    bl_port_setInnerText(tooltip, value);
    
    if (isVertical)
    {
      tx = x - tooltip.offsetWidth - 5;
      ty = y - Math.floor(tooltip.offsetHeight/2);
      
      if (progress) 
      {
        ty += progress.offsetTop;
        
        if (!reverse)
        {
          ty += progress.offsetHeight;
        }
      }
      else if (thumb)
      {
        ty += thumb.offsetTop;
        
        if (isInset)
        {
          ty += Math.floor(thumb.offsetHeight/2);
        }
        else if (!reverse)
        {
          ty += thumb.offsetHeight;
        }
      }
      
      if (tx < 0)
      {
        tx = x + el.offsetWidth + 5;
      }

      if (ty < 0)
      {
        ty = 0;
      }
      if (ty + tooltip.offsetHeight > body.clientHeight)
      {
        ty = body.clientHeight - tooltip.offsetHeight;
      }
    }
    else
    {
      ty = y - tooltip.offsetHeight - 5;
      tx = x - Math.floor(tooltip.offsetWidth/2);
      
      if (progress) 
      {
        tx += progress.offsetLeft;
        
        if (!reverse)
        {
          tx += progress.offsetWidth;
        }
      }
      else if (thumb)
      {
        tx += thumb.offsetLeft;
        
        if (isInset)
        {
          tx += Math.floor(thumb.offsetWidth/2);
        }
        else if (!reverse)
        {
          tx += thumb.offsetWidth;
        }
      }
      
      if (ty < 0)
      {
        ty = y + el.offsetHeight + 5;
      }

      if (tx < 0)
      {
        tx = 0;
      }
      if (tx + tooltip.offsetWidth > body.clientWidth)
      {
        tx = body.clientWidth - tooltip.offsetWidth;
      }
    }

    style.left = tx + "px";
    style.top  = ty + "px";
  }
}

function _bl_pr_enter(event, el)
{
  with (bl_port_offsetToItem(event, bl_port_getEventTarget(event)))
  {
    if (x >= 0 && y >= 0 && x <= el.offsetWidth && y <= el.offsetHeight)
    {
      el.bl_mouseIsIn = true;
      
      if (!cb_sys_disabled(el) && !el.bl_mouseIsDown)
      {
        bl_pr_setThumbSrc(el, bl_pr_getItem(el, "bl_thumb"), "ov");
        bl_pr_showTooltip(el, (el.getAttribute("bl_isVertical") != null));
      }
      bl_port_stop_event(event);
    }
  }
}

function _bl_pr_down(event, el, moveFunc)
{
  if (!cb_sys_disabled(el) && bl_port_isLeftDown(event))
  {
    bl_kb_focusOnElement(bl_port_getEventTarget(event));
    bl_port_setCapture(el);
    bl_port_stop_event(event);
    bl_pr_setThumbSrc(el, bl_pr_getItem(el, "bl_thumb"), "do");
    el.bl_mouseIsDown = true;
    _bl_pr_move(event, el);
    bl_current_pr = el;
    bl_addEventListener(document.body, "keydown", _bl_pr_key_down, true)
  }
}

function bl_pr_computeNewValue(el, size, coordPos)
{
  var discreteCnt = el.getAttribute("bl_discreteCnt");
  var isFloat     = el.getAttribute("bl_float") != null;
  var doSnap      = false;
  var newValue; 

  var roundOff;
  var valueActual;
  var rangeActual;
  var minActual;
  var maxActual;
  
  if (isFloat)
  {
    valueActual = parseFloat(el.getAttribute("bl_progressVal"));
    rangeActual = parseFloat(el.getAttribute("bl_rangeVal"));
    minActual   = parseFloat(el.getAttribute("bl_rangeMin"));
    maxActual   = parseFloat(el.getAttribute("bl_rangeMax"));
    roundOff    = 10000.0;
  }
  else
  {
    rangeActual = parseInt(el.getAttribute("bl_rangeVal"));
    valueActual = parseInt(el.getAttribute("bl_progressVal"));
    minActual   = parseInt(el.getAttribute("bl_rangeMin"));
    maxActual   = parseInt(el.getAttribute("bl_rangeMax"));
    roundOff    = 10000;
  }
  
  doSnap = el.getAttribute("bl_snap") != null;
  if (discreteCnt != null)
  {
    var discreteCntActual = parseInt(discreteCnt);
    var chunk             = (size * 10000)/discreteCntActual; 
    var discretIndex      = Math.round((coordPos * 10000)/chunk); 
    
    newValue = (rangeActual/discreteCntActual) * discretIndex;
  }
  else
  {
    if (valueActual < roundOff)
    {
      var adjustedSize  = size * roundOff;
      var adjustedPos   = coordPos * roundOff;
      var adjustedRange = rangeActual * roundOff;

      newValue = (adjustedPos * adjustedRange)/adjustedSize;
      newValue /= roundOff;
    }
    else
    {
      newValue = (coordPos * rangeActual)/size;
    }
  }
  
  if (!isFloat)
  {
    newValue = Math.floor(newValue);    
  }

  
  newValue += minActual;
  
  if (newValue < minActual)
  {
    newValue = minActual;
  }
  if (newValue > maxActual)
  {
    newValue = maxActual;
  }
  
  el.bl_newValue = "" + newValue;
  return doSnap;
}

function _bl_pr_move(event, el)
{
  if (!cb_sys_disabled(el) && el.bl_mouseIsDown)
  {
    bl_port_stop_event(event);
    
    var isVertical = el.getAttribute("bl_isVertical") != null;
    var thumb      = bl_pr_getItem(el, "bl_thumb");
    var progress   = bl_pr_getItem(el, "bl_progress");
    var isInset    = el.getAttribute("bl_inset") != null;
    var reverse    = (el.getAttribute("bl_reverse") != null);
    
    var uiPos;
    var thumbSize;
    var size;
    var thumbPos;
    var progPos;
    
    if (isVertical)
    {
      uiPos      = event.screenY - cb_sys_getScreenTop() - bl_sys_find_y(el, null, false);
      thumbSize  = (thumb == null)? 0:thumb.offsetHeight;
      size       = el.offsetHeight;
    }
    else
    {
      uiPos      = event.screenX - cb_sys_getScreenLeft() - bl_sys_find_x(el, null, false);
      thumbSize  = (thumb == null)? 0:thumb.offsetWidth;
      size       = el.offsetWidth;
    }
    
    // compute thumb position
    if (reverse)
    {
      thumbPos = (size - uiPos) - (thumbSize/2);
    }
    else
    {
      thumbPos = uiPos - (thumbSize/2);

      // ie is off by 2 pixels 
      if (bl_browserInfo.ie)
      {
        thumbPos -= 2;
      }
    }

    // make sure that the thumb stay in the bounds of the control
    if (thumbPos < 0)
    {
      thumbPos = 0;
    }
    if (thumbPos + thumbSize > size)
    {
      thumbPos = size - thumbSize;
    }
    
    progPos = thumbPos;

    // now compute the progress position
    if (isInset)
    {
      size -= thumbSize;
    }
    else if (thumbPos > 0)
    {
      progPos += thumbSize;
    }

    if (bl_pr_computeNewValue(el, size, progPos))
    {
      bl_pr_resetPosition(el, isVertical, progress, el.bl_newValue, thumb);
    }
    else
    {
      if (isVertical)
      {
        if (thumb)
        {
          if (reverse)
          {
            thumb.style.bottom = thumbPos + "px";
          }
          else
          {
            thumb.style.top = thumbPos + "px";
          }
        }
        if (progress)
        {
          progress.style.height = progPos + "px";
        }
      }
      else
      {
        if (thumb)
        {
          if (reverse)
          {
            thumb.style.right = thumbPos + "px";
          }
          else
          {
            thumb.style.left = thumbPos + "px";
          }
        }
        if (progress)
        {
          progress.style.width = progPos + "px";
        }
      }
    }
    
    bl_pr_computeTooltip(el, isVertical, reverse, el.bl_newValue);
  }
}


function _bl_pr_up(event, el)
{
  el = bl_port_computeEventEl(el);
  
  bl_port_releaseCapture(el);
  bl_current_pr = null;
  bl_removeEventListener(document.body, "keydown", _bl_pr_key_down, true);
  el.bl_mouseIsDown = false;

  if (!cb_sys_disabled(el))
  {
    // call _bl_pr_move before bl_pr_setThumbSrc
    // so we can position the thumb right
    _bl_pr_move(event, el);
    el.setAttribute("bl_progressVal", el.bl_newValue);
    bl_pr_setThumbSrc(el, bl_pr_getItem(el, "bl_thumb"), (el.bl_mouseIsIn? "ov":"en"));
    
    var xmlStr  = '<progress>' + el.bl_newValue + '</progress>';
    bl_mpr_send(xmlStr, el.id, 0, bl_sys_readSendType(el));

    if (!el.bl_mouseIsIn)
    {
      bl_pr_hideTooltip(el);
    }
  }
  
  bl_port_stop_event(event);
}

function bl_pr_setProgress(el, value, send)
{
  var progressValue = el.getAttribute("bl_progressVal");
  
  if (progressValue != value)
  {
    el.setAttribute("bl_progressVal", value);
    bl_pr_resetPosition(el, 
                        el.getAttribute("bl_isVertical") != null, 
                        bl_pr_getItem(el, "bl_progress"), 
                        value, 
                        bl_pr_getItem(el, "bl_thumb"));
                        
    if (send)
    {
      var xmlStr  = '<progress>' + value + '</progress>';
      bl_mpr_send(xmlStr, el.id, 0, bl_sys_readSendType(el));
    }                      
  }
}

function bl_pr_setLoad(el, value, send)
{
  el.setAttribute("bl_loadVal", value);
  bl_pr_resetPosition(el, 
                      el.getAttribute("bl_isVertical") != null, 
                      bl_pr_getItem(el, "bl_load"), 
                      value, 
                      null);

  if (send)
  {
    var xmlStr  = '<load>' + value + '</load>';
    bl_mpr_send(xmlStr, el.id, 0, bl_sys_readSendType(el));
  }                      
}

function _bl_pr_key_down(event, el)
{
  if (!event)
  {
    event = window.event;
  }
  if (!el)
  {
    el = bl_current_pr;
  }
  if (bl_port_keyCode(event) == 27)
  {
    if (el)
    {
      var isVertical = el.getAttribute("bl_isVertical") != null;
      var thumb      = bl_pr_getItem(el, "bl_thumb");
      var pval       = el.getAttribute("bl_progressVal");
      
      bl_pr_resetPosition(el, isVertical, bl_pr_getItem(el, "bl_progress"), pval, thumb);
      bl_pr_computeTooltip(el, isVertical, (el.getAttribute("bl_reverse") != null), pval);
      
      if (!el.bl_mouseIsIn)
      {
        bl_pr_hideTooltip(el)
      }
      bl_removeEventListener(document.body, "keydown", _bl_pr_key_down, true);
      bl_port_releaseCapture(el);
      bl_current_pr = null;
      el.bl_mouseIsDown = false;
      bl_pr_setThumbSrc(el, thumb, (el.bl_mouseIsIn? "ov":"en"));
    }
    else
    {
      bl_removeEventListener(document.body, "keydown", _bl_pr_key_down, true);
    }
  }
}

function bl_pr_resetPosition(el, isVertical, item, value, thumb)
{
  if (thumb == null && item == null)
  {
    return ;
  }
  
  var size        = (isVertical)? el.offsetHeight:el.offsetWidth;
  var origSize    = size;
  var pos         = 0;
  var discreteCnt = el.getAttribute("bl_discreteCnt");
  var isFloat     = el.getAttribute("bl_float") != null;
  var isInset     = el.getAttribute("bl_inset") != null;
  var thumbSize   = 0;
  var roundOff;
  var valueActual;
  var rangeActual;
  var minActual;
  var maxActual;
  
  if (thumb)
  {
    thumbSize = (isVertical)? thumb.offsetHeight:thumb.offsetWidth;
  }
  else
  {
    var tempThumb = bl_pr_getItem(el, "bl_thumb");
    if (tempThumb)
    {
      thumbSize = (isVertical)? tempThumb.offsetHeight:tempThumb.offsetWidth;
    }
  }
  if (isInset)
  {
    size -= thumbSize;
  }
  
  if (isFloat)
  {
    valueActual = parseFloat(value);
    rangeActual = parseFloat(el.getAttribute("bl_rangeVal"));
    minActual   = parseFloat(el.getAttribute("bl_rangeMin"));
    maxActual   = parseFloat(el.getAttribute("bl_rangeMax"));
    roundOff    = 10000.0;
  }
  else
  {
    valueActual = parseInt(value);
    rangeActual = parseInt(el.getAttribute("bl_rangeVal"));
    minActual   = parseInt(el.getAttribute("bl_rangeMin"));
    maxActual   = parseInt(el.getAttribute("bl_rangeMax"));
    roundOff    = 10000;
  }
  
  if (valueActual < minActual)
  {
    valueActual = minActual;
  }
  if (valueActual > maxActual)
  {
    valueActual = maxActual;
  }

  valueActual -= minActual;
  
  if (discreteCnt != null)
  {
    var discreteCntActual = parseInt(discreteCnt);

    if (rangeActual < roundOff)
    {
      var discreteActual = (rangeActual * roundOff)/discreteCntActual;
      
      valueActual = discreteActual * Math.round((valueActual * roundOff)/discreteActual);
      valueActual /= roundOff;
    }
    else
    {
      var discreteActual    = rangeActual/discreteCntActual;
      
      valueActual = discreteActual * Math.round(valueActual/discreteActual);
    }
    
    if (!isFloat)
    {
      valueActual = Math.floor(valueActual);
    }
  }
  
  if (valueActual < roundOff)
  {
    var adjustedSize = size * roundOff;
    valueActual *= roundOff;
    rangeActual *= roundOff;

    adjustedSize = (valueActual * adjustedSize)/rangeActual;
    pos = Math.floor(adjustedSize/roundOff);
  }
  else
  {
    pos = Math.floor((valueActual * size)/rangeActual);
  }
  
  // If no range is set, or if the control is not bound to an actual value, pos will be NaN.
  if (isNaN(pos))
  {
    pos = 0;
  }
  
  if (item)
  {
    if (isVertical)
    {
      item.style.height = pos + "px";
    }
    else
    {
      item.style.width = pos + "px";
    }
  }
  
  if (thumb)
  {
    var reverse = (el.getAttribute("bl_reverse") != null);
    var thumPos = (isInset)? pos:Math.max(pos - thumbSize, 0);

    if (isVertical)
    {
      if (reverse)
      {
        thumb.style.bottom = thumPos + "px";
      }
      else
      {
        thumb.style.top = thumPos + "px";
      }
    }
    else
    {
      if (reverse)
      {
        thumb.style.right = thumPos + "px";
      }
      else
      {
        thumb.style.left = thumPos + "px";
      }
    }
    
    if (!el.bl_mouseIsIn && !el.bl_mouseIsDown)
    {
      bl_pr_setThumbSrc(el, thumb, "en");
    }
  }
}

function _bl_pr_resize(el, resizeQueue)
{
  var trough     = bl_pr_getItem(el, "bl_trough");
  var isVertical = el.getAttribute("bl_isVertical") != null;
  
  if (el.getAttribute("bl_inedit") == null)
  {
    bl_pr_resetPosition(el, isVertical, bl_pr_getItem(el, "bl_progress"), el.getAttribute("bl_progressVal"), bl_pr_getItem(el, "bl_thumb"));
    bl_pr_resetPosition(el, isVertical, bl_pr_getItem(el, "bl_load"), el.getAttribute("bl_loadVal"), null);
  }
  
  if (trough)
  {
    if (isVertical)
    {
      var troughSize = el.offsetHeight - (trough.offsetTop * 2);
      trough.style.height = troughSize + "px";
    }
    else
    {
      var troughSize = el.offsetWidth - (trough.offsetLeft * 2);
      trough.style.width = troughSize + "px";
    }
  }
}

function _bl_pr_handler(item, el)
{
  var cmd  = item.firstChild;
  var name = cmd.nodeName;
  
  if (name == "progress")
  {
    bl_pr_setProgress(el, bl_port_get_text(cmd), false)
  }
  else if (name == "load")
  {
    bl_pr_setLoad(el, bl_port_get_text(cmd), false)
  }
  else if (name == "ranges")
  {
    var list = bl_port_get_text(cmd).split(" ");
    
    if (list.length >= 3)
    {
      el.setAttribute("bl_rangeMin", list[0]);
      el.setAttribute("bl_rangeMax", list[1]);
      el.setAttribute("bl_rangeVal", list[2]);

      if (list.length >= 5)
      {
        el.setAttribute("bl_discreteCnt", list[3]);
        el.setAttribute("bl_discreteVal", list[4]);
      }
      
      var isVertical = el.getAttribute("bl_isVertical") != null;
      bl_pr_resetPosition(el, isVertical, bl_pr_getItem(el, "bl_progress"), el.getAttribute("bl_progressVal"), bl_pr_getItem(el, "bl_thumb"));
      bl_pr_resetPosition(el, isVertical, bl_pr_getItem(el, "bl_load"), el.getAttribute("bl_loadVal"), null);
    }
  }
}

function _bl_rdck_handler(item, el)
{
  var cmd = item.firstChild;
  
  if (cmd.nodeName == "checkChanged")
  {
    if (!el.firstChild)
    {
      // TODO: Figure out why this my occur.
      return;
    }
  
    var val  = bl_port_get_text(cmd.childNodes.item(1));
    var item = bl_rdck_findInput(el);
    
    // Set the name before assigning a value-- ensuring the other radios in the group stay correct.
    var name  = bl_port_get_text(cmd.childNodes.item(2));
    bl_rdck_setName(el,name);
    
    bl_rdck_setCheckedValue(item, (val == "true"), true);

  }
  else if (cmd.nodeName == "label")
  {
    var label = bl_rdck_findLabel(el);
    bl_port_setInnerText(label.firstChild, bl_port_get_text(item));
  }
}

function bl_rdck_setName(el,name)
{
  var input = bl_rdck_findInput(el);
  
  if (name)
  {
    input.setAttribute("name", name);
  }
  else
  {
    input.removeAttribute("name");
  }
}

function bl_rdck_setCheckedValue(item, checked, setOnItem)
{
  if (checked)
  {
    item.setAttribute("bl_selected", true);
  }
  else
  {
    item.removeAttribute("bl_selected");
  }
    
  if (setOnItem)
  {  
    item.checked = checked;
  }
}

/* Find the parent div tag that will handle the event for the radio button/ checkbox*/
function bl_rdck_getParentHandler(item)
{
  var parent = item.parentNode;
  var cb_tag;
  while (parent)
  {
    cb_tag = parent.getAttribute("cb_tag")
    if (cb_tag)
    {
      if (cb_tag == "CBX" || cb_tag == "RDO" || cb_tag == "DTA" || cb_tag == "CELL")
      {
        return parent;
      }
      // if we found a cb_tag but it wasn't for a radio button or checkbox, 
      // we have problems.
      throw ("poorly formed HTML ["+cb_tag+"] - bl_rdck_getParentHandler");
    }
    parent = parent.parentNode;
  }
}

function _bl_rdck_clicked(event, item)
{
  bl_rdck_itemChanged(bl_rdck_getParentHandler(item), item, true);
}

function _bl_rdck_press(event, el)
{
  if (event.virtualKey == "space")
  {
    if (event.type == "vku")
    {
      var input = bl_rdck_findInput(el);
      if (input)
      {
        if (!input.disabled && !input.readonly)
        {
          bl_rdck_itemChanged(el, input, true);
        }
      }
    }
    bl_port_killEvent(event);
  }
}

function bl_rdck_showFocus(el)
{
  var label = bl_rdck_findLabel(el);
  
  if (label)
  {
    var cs = bl_port_getComputedStyle(label);
    
    if (bl_port_getInnerText(label) != "")
    {
      label.firstChild.style.cssText = "border: 1px dotted "+cs["color"]+";";
    }
  }
}

function bl_rdck_hideFocus(el)
{
  var label = bl_rdck_findLabel(el);
  if (label)
  {
    label.firstChild.style.cssText = "margin: 1px;";
  }
}

function bl_rdck_findLabel(el)
{
  return (bl_rdck_findChildElm(el, "LABEL"));
}

function bl_rdck_findInput(el)
{
  return (bl_rdck_findChildElm(el, "INPUT"));
}

function bl_rdck_findChildElm(el, tagName)
{
  var elm = el.firstChild;
  var targetElm;
  if (elm.tagName == tagName)
  {
    return elm;
  }
  else if (elm.tagName == "TABLE")
  {
    // loop through the cells of the table to see where the targetElm field is
    for (var row = 0; row < elm.rows.length; row++)
    {
      for (var col = 0; col < elm.rows[row].cells.length; col++)
      {
        targetElm = elm.rows[row].cells[col].firstChild;
        if (targetElm.tagName == tagName)
        {
          return targetElm;
        }
      }
    }
  }
  else 
  {
    elm = el.lastChild;
    if (elm && elm.tagName == "DIV")
    {  // We might have DIV if we have the label on top so that the button can be centered.
      elm = elm.firstChild;
    }
    if (elm && elm.tagName == tagName)
    {
      return elm;
    }
  }
  return null;
}

// the assuption here is that the value coming in represent what the current set 
// value is.
function bl_rdck_itemChanged(el, item, setOnItem)
{
  var send = true;
  var selected = (item.getAttribute("bl_selected") != null);
  var checked  = selected;
  
  if (item.getAttribute("bl_toggle") != null)
  {
    // toggle the value
    checked = !checked;
  }
  else
  {
    // toggle only it was preveously seleced
    if (checked)
    {
      send = false;
    }
    else
    {
      checked = true;
    }
  }

  bl_rdck_setCheckedValue(item, checked, setOnItem);

  if (send)
  {  
    var msg = null;
    var valueAttr = item.getAttribute("bl_value");
    
    if (valueAttr)
    {
      msg = "<checked>"
          + valueAttr
          + "</checked>";
    }
    else
    {
      msg = (checked)? "<checked>true</checked>":"<checked>false</checked>";
    }

    // this could be in a DataEdit or a MCL so let's 
    // call the DataEdit send function
    // it will not affect the normal path to do so    
    bl_de_sendMessage(el, msg);
  }
}

function bl_sys_handleListLogic(el, event)
{
  var mouseItem = el;
  
  while (el && !el.selectMgr)
  {
    el = el.parentNode;
  }
  
  if (el)
  {
    var selectMgr = el.selectMgr;

    bl_port_focus(mouseItem);
    selectMgr.forceSendNow = true;
    _bl_sel_down(event, el);
    bl_port_stop_event(event);
    selectMgr.forceSendNow = false;

    var item = null;

    if (mouseItem.tagName == "INPUT")
    {
      item = mouseItem;
      mouseItem = bl_rdck_getParentHandler(mouseItem);
    }
    else
    {
      item = bl_rdck_findInput(el);
    }
    
    bl_rdck_itemChanged(mouseItem, item, false);
  }
}


//***********************************************************************
//***********************************************************************
//********                  bl_rich_text.js                     *********
//***********************************************************************
//***********************************************************************

var bl_fcked_config      = [];
var bl_fcked_lookupQueue = [];

function FCKeditor_OnLoadScripts(fcked)
{
  // This enables the word check engine.
  var path = "/" + bl_version + "/res/js/core/bl_wordcheck.js";

  // Relative paths should be in the context of the fck editor path
  fcked.Window.LoadScript(path);
}

function FCKeditor_OnComplete(fcked)
{
  var id         = fcked.Name;
  var tools      = bl_fcked_config[id]["toolbar"];
  var sendOnBlur = bl_fcked_config[id]["sendOnBlur"];
  var content    = bl_fcked_config[id]["content"];
  var spellcheck = bl_fcked_config[id]["spellcheck"];
  delete bl_fcked_config[id];

  fcked.Commands.RegisterCommand("Save",       new bl_fcked_saveCommandHandler(id));
  fcked.Commands.RegisterCommand("SpellCheck", new bl_fcked_spellcheckCommandHandler(id));

  fcked.Config["bl_sendOnBlur"] = sendOnBlur;
  fcked.Events.AttachEvent("OnBlur", bl_fcked_onBlur);
  if (tools.length > 0)
  {
    fcked.ToolbarSet.Load(tools);
  }
  else
  {
    if (spellcheck)
    {
      fcked.ToolbarSet.Load("BungeeSpell");
    }
    else
    {
      fcked.ToolbarSet.Load("Bungee");
    }
  }
  fcked.SetHTML(content);

  if (spellcheck)
  {
    setTimeout("bl_richtext_initSpell('"+id+"')",10);
  }
}

function bl_fcked_getSpellCheckContext(fckOrId)
{
  if (typeof fckOrId == "object")
  {
    return fckOrId.Window;
  }
  else
  {
    // Assume it's the ID.
    var fcked = FCKeditorAPI.GetInstance(fckOrId);
    return fcked.Window;
  }
}

function bl_fcked_saveCommandHandler(id)
{
  this.id = id;
}
function bl_fcked_saveCommandHandler_Execute()
{
  _bl_richtext_sendChanged(this.id);
}
function bl_fcked_saveCommandHandler_GetState()
{
  return FCK_TRISTATE_OFF;
}
bl_fcked_saveCommandHandler.prototype.Execute = bl_fcked_saveCommandHandler_Execute;
bl_fcked_saveCommandHandler.prototype.GetState = bl_fcked_saveCommandHandler_GetState;


function bl_fcked_spellcheckCommandHandler(id)
{
  this.id = id;
}
function bl_fcked_spellcheckCommandHandler_Execute()
{
  var spWin = bl_fcked_getSpellCheckContext(this.id);
  if (spWin.SpellCheckParser.ENABLED)
  {
    spWin.SpellCheckParser.disable();
  }
  else
  {
    spWin.SpellCheckParser.enable();
  }
}
function bl_fcked_spellcheckCommandHandler_GetState()
{
  var spWin = bl_fcked_getSpellCheckContext(this.id);
  
  if (spWin.SpellCheckParser.ENABLED)
  {
    return FCK_TRISTATE_ON;
  }
  return FCK_TRISTATE_OFF;
}
bl_fcked_spellcheckCommandHandler.prototype.Execute = bl_fcked_spellcheckCommandHandler_Execute;
bl_fcked_spellcheckCommandHandler.prototype.GetState = bl_fcked_spellcheckCommandHandler_GetState;


function bl_richtext_initSpell(id)
{
  var fcked          = FCKeditorAPI.GetInstance(id);
  var sp_win         = bl_fcked_getSpellCheckContext(fcked);
  var dict           = new sp_win.Dictionary(id);
  dict.performLookup = bl_fcked_performWordLookup;
  sp_win.SpellCheckParser.highlightStyle = "background-position:bottom left;background-image:url(/" 
                                         + bl_version 
                                         + "/res/img/squiggle.gif);background-repeat:repeat-x;";
  
  sp_win.SpellCheckParser.init(fcked,dict);
  sp_win.SpellCheckParser.enable();
}


function bl_fcked_performQueuedLookups()
{
  var cnt = 30;
  
  while (bl_fcked_lookupQueue.length > 0 && cnt > 0)
  {
    var obj = bl_fcked_lookupQueue.shift();
    cnt--;

    var editorId = obj.callback;
    var strToSend = "<sp><w>" + obj.text + "</w></sp>";
    // Defer until the packet is ready to send.
    var sendType  = ((bl_fcked_lookupQueue.length == 0 || cnt == 0) ? BL_MPR_ASAP: BL_MPR_DEFER);
  
    bl_mpr_send(strToSend, editorId, -1, sendType, true);
  }
  
  if (bl_fcked_lookupQueue.length > 0)
  {
    setTimeout("bl_fcked_performQueuedLookups()",1000);
  }
}

function bl_fcked_performWordLookup(text,callback)
{
  var obj = { text:text, callback:callback };
  if (bl_fcked_lookupQueue.length == 0)
  {
    setTimeout("bl_fcked_performQueuedLookups()",10);
  }

  bl_fcked_lookupQueue.push( obj );
}

function _bl_richtext_handler(item, element)
{
  var value = item.firstChild;
  var fcked = FCKeditorAPI.GetInstance(element.id);
  var el = document.getElementById(element.id + "_value");

  if (value.nodeName == "sp")
  {
    //spell check return
    var fckwin   = bl_fcked_getSpellCheckContext(fcked);
    var dict     = fckwin.SpellCheckParser.DICT;
    var cNodes   = value.childNodes;
    var word     = bl_port_get_text(cNodes.item(0));
    var wordIsOk = bl_port_get_text(cNodes.item(1))=="1"; // "0" or "1"
    if (wordIsOk)
    {
      // TODO: Use correct constant from the wordcheck library
      dict.addWord(word,"good");
    }
    else
    {
      // TODO: Use correct constant from the wordcheck library
      var wordStatus = "bad";
      var suggestions = bl_port_get_text(cNodes.item(2));
      if (suggestions != "")
      {
        dict.addWord(word,wordStatus,suggestions.split(";"));
      }
      else
      {
        dict.addWord(word,wordStatus,[]);
      }
    }
  }
  else if (value.nodeName == "spDisable")
  {
    // This happens when the spell checker has been disabled on the server.
    bl_fcked_getSpellCheckContext(fcked).SpellCheckParser.disable();
  }
  else if (value.nodeName == "value")
  {
    fcked.SetHTML(unescape(bl_port_get_text(value)), true);
  }
  else if (value.nodeName == "textType")
  {
    var textType = bl_port_get_text(value); // Enumeration: "html", "text"
    element.setAttribute("cb_type", textType);
  }
}

function bl_richtext_cleanup(el)
{
  var id = el.id;

  var fcked          = FCKeditorAPI.GetInstance(id);
  if (!fcked)
  {
    // This sometime happens if the item is loaded/reloaded too many times.
    // Warning: This could be a potential memory leak that would cause
    // performance degradation in your app. If you're looking at this, I
    // suggest you put the RichText editor into it's own IFrame:
    //   1) Put the RichText control on it's own form.
    //   2) Put a DynamicForm control on the form where you want the
    //      RichText editor to appear.
    //   3) Point the DynamicForm control at the RichText form.
    //   4) Select the "IFrame" option on the DynamicForm control.
    return;
  }
  
  var sp_win         = bl_fcked_getSpellCheckContext(fcked);
  if (sp_win && sp_win.SpellCheckParser)
  {
    if (sp_win.SpellCheckParser.DICT)
    {
      sp_win.SpellCheckParser.DICT.performLookup = null;  
    }
    sp_win.SpellCheckParser.cleanup();
  }
  delete FCKeditorAPI.__instances[28];
}

function _bl_richtext_init(id)
{
  if (!bl_richtext_loadFCK())
  {
    window.setTimeout("_bl_richtext_init('"+id+"')",10);
    return;
  }
  
  var el = document.getElementById(id);
  if (el)
  {
      
    var fcked        = new FCKeditor(id);
    fcked.BasePath   = "/" + bl_version + "/res/js/fckeditor_2_4_x/";

    bl_sys_addCleanUpCall(el, bl_richtext_cleanup);

    // Un-comment this to use the debug version, rather than the compressed version.
    //fcked.EditorFile = "fckeditor.html";
    // This version should run faster as it has been compressed/optimized.
    fcked.EditorFile = "fckeditor_compressed.html";
    fcked.ToolbarSet = "Empty";
    fcked.Height     = "100%";
    fcked.Width      = "100%";
    
    if (!bl_fcked_config[id])
    {
      // If the configuration has not yet been set, assume it's because the browser didn't
      // execute the <SCRIPT> node when it was injected into the DOM. Assume the script is
      // still there, and ready for execution.

      // The initialization script is contained within el.childNodes[0]
      var initScript = bl_port_get_text(el.childNodes[0]);
      eval(initScript);
    }
    el.innerHTML = fcked.CreateHtml();

    var XMLData = document.getElementById(id + "_Data");
    var content = null;

    if (XMLData)
    {
      var XMLDocument = bl_port_get_XMLDocument(XMLData,true);

      var contentNode = bl_port_selectSingleNode(XMLDocument,"sdata");
      content = bl_port_get_text(contentNode);
      
      var fcked = null;
      if (typeof FCKeditorAPI != "undefined" && (fcked = FCKeditorAPI.GetInstance(id)) && typeof fcked.EditingArea != "undefined")
      {
        fcked.SetHTML(content);
      }
      else if (bl_fcked_config[id])
      {
        bl_fcked_config[id]["content"] = content;
      }

      // We don't want this potentially large XML to stay around in the DOM consuming resources
      XMLData.parentElement.removeChild(XMLData);
    }
  }
}

function bl_fcked_onBlur(fcked)
{
  if (fcked.Config["bl_sendOnBlur"])
  {
    _bl_richtext_sendChanged(fcked.Name);
  }
}

function _bl_richtext_sendChanged(id)
{
  var fcked   = FCKeditorAPI.GetInstance(id);
  if (fcked.IsDirty())
  {
    var content = fcked.GetHTML();
    xmlStr = "<changed><value><![CDATA[" + content + "]]></value></changed>";  
    bl_mpr_send(xmlStr, id);
  }
}

function bl_richtext_loadFCK()
{
  if (typeof bl_richtext_loadFCK.loaded == "undefined")
  {
    bl_richtext_loadFCK.loaded = "started";
    
    var scriptEl = document.createElement("SCRIPT");
    scriptEl.setAttribute("src","/" + bl_version + "/res/js/fckeditor_2_4_x/fckeditor.js");
    scriptEl.setAttribute("type","text/javascript");
    scriptEl.setAttribute("onload","bl_richtext_loadFCK.loaded='complete';");
    document.getElementsByTagName("HEAD")[0].appendChild(scriptEl);
    
    return false;
  }
  else if (bl_richtext_loadFCK.loaded == "complete")
  {
    return true;
  }
  else
  {
    if (typeof window.FCKeditor_IsCompatibleBrowser == "function")
    {
      bl_richtext_loadFCK.loaded = "complete";
    }
    return false;
  }
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this 
// file has been loaded.
function _bl_richtext_last()
{
  var x = 0;
}


//***********************************************************************
//***********************************************************************
//********                 bl_select.js                         *********
//***********************************************************************
//***********************************************************************

function bl_sel_createMgr(el, 
                          sigSelect, 
                          list, 
                          isMulti, 
                          supportsRemove, 
                          closeOnDblClk, 
                          rowIndex, 
                          row, 
                          findRow, 
                          keyDown, 
                          mouseDown, 
                          itemSelected, 
                          getLength, 
                          getMargin)
{
  var mgrList = [];
  
  el.selectMgr     = this;
  el.onselectstart = bl_sel_onSelectStart;
  el.onmousewheel  = bl_sel_wheelEvent;


  this.elID                 = el.id;
  this.computeRowIndex      = rowIndex;
  this.computeRow           = row;
  this.findRow              = findRow;
  this.keyOverRide          = keyDown;
  this.mouseOverRide        = mouseDown;
  this.itemSelected         = itemSelected;
  this.getLength            = getLength;
  this.getMargin            = getMargin;
  this.removeAll            = bl_sel_removeAll;
  this.deselectAll          = bl_sel_sendDeselectAll;
  this.selectAll            = bl_sel_sendSelectAll;
  this.selectRows           = bl_sel_selectRows;
  this.deselectRows         = bl_sel_deselectRows;
  this.selectRow            = bl_sel_selectRowIndex;
  this.findSubText          = bl_sel_findRowWithSubText;
  this.getElement           = bl_sel_getEL;
  this.acceptSelect         = bl_sel_acceptSelect;
  this.acceptAdjust         = bl_sel_removeAdjust;
  this.ancoreIndex          = -1;
  this.isActive             = false;
  this.asyncCurrent         = null;
  this.pendingSingleSelect  = -1;
  this.pendingSelectRemoves = false;
  this.pendingRow           = null;
  this.keyDownIndex         = -1;
  this.startIndex           = -1;
  this.endIndex             = -1;
  this.firstSelect          = true;
  this.forceSendNow         = false;
  this.isMulti              = isMulti;
  this.supportsRemove       = supportsRemove;
  this.closeOnDblClk        = closeOnDblClk;
  this.ancoreIndex          = -1;
  this.ancoreRow            = null;
  this.list                 = mgrList;
  
  if (list)
  {
    var len   = list.length;
    var elLen = this.getLength(el);
    
    for (var i = 0; i < len; i++)
    {
      var val = parseInt(list[i]);
      
      if (val >= 0 && val < elLen)
      {
        mgrList.push(val);
      }
    }
  }
  
  mgrList.sort(function (i1, i2) { return i1 - i2; });
  
  if (el.bl_sys_gs_subText)
  {
    this.removeAll();
    this.findSubText(this, el, el.bl_sys_gs_subText);
    el.bl_sys_gs_subText = undefined;
  }
  else
  {
    bl_sel_setActive(this, el, false);
    this.sigSelect = sigSelect;
    
    if (sigSelect >= 0)
    {
      this.sigRow = this.computeRow(el, sigSelect);
      
      if (this.sigRow)
      {
        cb_sel_setAncore(this, this.sigRow, sigSelect);
      }
      else
      {
        this.sigSelect = -1;
      }
    }
    
    if (mgrList.length > 0)
    {
      bl_sys_checkDialogSelect(el);
    }
  }
  
  //onfocusin and out not supported in 5.5
  if (bl_browserInfo.ie5_5)  
  {
    el.ondeactivate = bl_sel_focusOut;
    el.onactivate   = bl_sel_focusIn;
  }
  else
  {
    el.onfocusout = bl_sel_focusOut;
    el.onfocusin  = bl_sel_focusIn;
  }
}

function cb_sel_indexAdded(index, mgr)
{
  if (index <= mgr.ancoreIndex)
  {
    mgr.ancoreIndex++;
  }
  if (index <= mgr.pendingSingleSelect)
  {
    mgr.pendingSingleSelect++;
  }
  
  var list = mgr.list;
  var len  = list.length;
  var i    = cb_sel_findInsertion(list, index)
  
  if (i >= 0)
  {
    for (; i < len; i++)
    {
      var val = list[i];
      list[i] = val + 1;
    }
  }
}

function cb_sel_indexRemoved(index, mgr)
{
  if (index < mgr.ancoreIndex)
  {
    mgr.ancoreIndex--;
  }
  else if (index == mgr.ancoreIndex)
  {
    mgr.ancoreIndex = -1;
  }
  if (index < mgr.pendingSingleSelect)
  {
    mgr.pendingSingleSelect--;
  }
  else if (index == mgr.pendingSingleSelect)
  {
  	bl_sel_clearPend(mgr);
  }
  
  mgr.acceptAdjust(index);
  
  var list = mgr.list;
  var len  = list.length;
  var i    = cb_sel_findInsertion(list, index)
  
  if (i >= 0)
  {
    var val = list[i];
    if (val == index)
    {
      list.splice(i, 1);
    }
    
    for (; i < len; i++)
    {
      val = list[i];
      if (val != undefined)
      {
        list[i] = val - 1;
      }
    }
  }
}

function cb_sel_indexSet(index, mgr, findFocus)
{
  var el  = mgr.getElement();
  var i   = cb_sel_findSelect(mgr.list, index, false);
  var row = mgr.computeRow(el, index);
  
  if (i >= 0)
  {
    bl_sel_selectRow(el, row);
  }
  
  if (findFocus && mgr.isActive)
  {
    var index = mgr.cb_childIndex;
    if (index >= 0 && index < row.childNodes.length)
    {
      if (cb_sel_searchForFocus(row.childNodes[index]))
      {
        return ;
      }
    }
    
    cb_sel_searchForFocus(row);
  }
}

function cb_sel_searchForFocus(item)
{
  if (cb_sel_isFocusInput(item))
  {
    if (item.tagName != "SELECT")
    {
      bl_port_focus(item);
    }
    if (item.tagName == "INPUT" && item.type == "text")
    {
      item.select();
    }
    return true;
  }
  var ch = item.firstChild;
  
  while (ch)
  {
    if (cb_sel_searchForFocus(ch))
    {
      return true;
    }
    ch = ch.nextSibling;
  }
  return false;
}

function _bl_sel_clearSelect(el)
{
  var mgr = el.selectMgr;
  
  if (mgr)
  {
    mgr.deselectAll(mgr, true);
  }
}

function bl_sel_getEL()
{
  return document.getElementById(this.elID);
}

function bl_sel_findRowWithSubText(mgr, el, subText)
{
  var text       = subText.toLowerCase();
  var computeRow = mgr.computeRow;
  var len        = mgr.getLength(el);
  
  for (var i = 0; i < len; i++)
  {
    var row     = computeRow(el, i);
    var rowText = bl_port_getInnerText(row).toLowerCase();
    
    if (rowText.indexOf(text) >= 0)
    {
      mgr.selectRow(mgr, el, row, i, true);
      return i;
    }
  }
  
  mgr.deselectAll(mgr, true);
  
  return -1;
}

function bl_sel_selectRowIndex(mgr, el, row, index, send)
{
  if (index != mgr.sigSelect)
  {
    cb_sel_deselectAllRows(mgr, el, mgr.list, mgr.computeRow, true);
    bl_sel_selectRow(el, row);
    mgr.list.push(index);
    if (send)
    {
      cb_sel_sendSingleSelect(el, mgr, row, index, "");
    }
    cb_sel_setAncore(mgr, row, index);
    cb_sel_scrollInView(mgr, row);
  }
}

function bl_sel_selectRows(mgr, rowList, selectRemoves, send, sigs)
{
  var computeRow = mgr.computeRow;
  var indexes    = rowList.split(" ");
  var len        = indexes.length;
  var list       = mgr.list;
  var el         = mgr.getElement();
  var listLen    = mgr.getLength(el);
  
  if (selectRemoves)
  {
    cb_sel_deselectAllRows(mgr, el, list, computeRow);
    mgr.ancoreIndex = -1;
  }
  
  var index = -1;
  var row   = null;
  for (var i = len - 1; i >= 0; i--)
  {
    index = parseInt(indexes[i]);
    row   = computeRow(el, index);
    if (row)
    {
      var listIndex = cb_sel_findInsertion(list, index);
      
      if (mgr.ancoreIndex < 0)
      {
        mgr.ancoreIndex = index;
      }
      
      if (listIndex >= 0 && listIndex < listLen && list[listIndex] != index)
      {
        list.splice(listIndex, 0, index);
      }
      else if (listIndex < 0)
      {
        list.push(index);
      }
      else
      {
        indexes.splice(i, 1);
      }
      bl_sel_selectRow(el, row);
      if (sigs)
      {
        mgr.sigSelect = index;
        mgr.sigRow    = row;
      }
    }
    else
    {
      indexes.splice(i, 1);
    }
  }
  
  if (send)
  {
    var sendType = (selectRemoves)? BL_MPR_ASAP:BL_MPR_APPEND;
    var selr = (selectRemoves) ? "true" : "false";
    var msg  = "<multipleSelect selectRemoves='" + selr + "'><indexes>" + indexes.join(" ") + "</indexes></multipleSelect>";
    bl_mpr_send(msg, mgr.elID, 3, sendType);
  }
  else if (row)
  {
    cb_sel_scrollInView(mgr, row);
  }
}

function bl_sel_deselectRows(mgr, rowList, send)
{
  var computeRow = mgr.computeRow;
  var indexes    = rowList.split(" ");
  var len        = indexes.length;
  var list       = mgr.list;
  var el         = mgr.getElement();
  
  for (var i = len - 1; i >= 0; i--)
  {
    var index = parseInt(indexes[i]);
    var row   = computeRow(el, index);
    
    if (row)
    {
      var listIndex = cb_sel_findInsertion(list, index);
      
      if (listIndex >= 0 && list[listIndex] == index)
      {
        list.splice(listIndex, 1);
      }
      else
      {
        indexes.splice(i, 1);
      }
      cb_sel_deselect(el, row);
    }
    else
    {
      indexes.splice(i, 1);
    }
  }
  
  if (send)
  {
    var msg = '<multipleDeselect"><indexes>' + indexes.join(" ") + '</indexes></multipleDeselect>';
    bl_mpr_send(msg, mgr.elID, 3);
  }
}
function _bl_sel_sendDeselectAll(id)
{
  var el  = document.getElementById(id);
  var mgr = el.selectMgr;
  if (mgr)
  {
    mgr.deselectAll(mgr, true);
  }
}
function bl_sel_sendDeselectAll(mgr, send)
{
  cb_sel_deselectAllRows(mgr, mgr.getElement(), mgr.list, mgr.computeRow);
  
  if (send)
  {
    bl_mpr_send("<deselectAll/>", mgr.elID, 3);
    mgr.cb_waitMore = false;
    mgr.cb_xmlStr   = null;
  }
}

function bl_sel_sendSelectAll(mgr, send)
{
  if (!this.isMulti)
  {
    return;
  }
  var list = mgr.list;
  var el   = mgr.getElement();
  
  cb_sel_doSelection(0, list, el, mgr.computeRow, 0, mgr.getLength(el) - 1);
  
  if (send)
  {
    bl_mpr_send("<selectAll/>", mgr.elID);
    mgr.cb_waitMore = false;
    mgr.cb_xmlStr   = null;
  }
}

function bl_sel_removeAll()
{
  this.ancoreIndex = -1;
  this.list.splice(0, this.list.length);
}

function bl_sel_checkPending(row, editor, mgr)
{
  if (mgr.pendingSingleSelect >= 0)
  {
    var selRem         = (mgr.pendingSelectRemoves) ? "" : "selectRemoves='false'";
    var resetSigSelect = false;
    
    if (mgr.pendingDeselectAll)
    {
      if (mgr.pendingSingleSelect == mgr.sigSelect && mgr.list.length == 1)
      {
        resetSigSelect = true;
        mgr.list.pop();
      }
      else
      {
        cb_sel_deselectAllRows(mgr, editor, mgr.list, mgr.computeRow);
      }
      
      if (mgr.pendingRow)
      {
        mgr.list.push(mgr.pendingSingleSelect);
        bl_sel_selectRow(editor, mgr.pendingRow);
      }
      if (resetSigSelect)
      {
        mgr.sigSelect = mgr.pendingSingleSelect;
      }
    }
    
    if (mgr.pendingRow)
    {
      cb_sel_sendSingleSelect(editor, mgr, mgr.pendingRow, mgr.pendingSingleSelect, selRem);
      cb_sel_scrollInView(mgr, mgr.pendingRow);
    }
    
    bl_sel_clearPend(mgr);
  }
}

function cb_sel_setAncore(mgr, row, index)
{
  if (mgr.ancoreRow)
  {
    cb_sel_hideFocus(mgr.ancoreRow)
  }
  
  mgr.ancoreIndex = index;
  mgr.ancoreRow   = row;
  
  if (mgr.ancoreRow)
  {
    cb_sel_showFocus(mgr.ancoreRow)
  }
}

function cb_sel_setFocus(mgr, setFocus)
{
  if (mgr.ancoreRow)
  {
    if (setFocus)
    {
      cb_sel_showFocus(mgr.ancoreRow)
    }
    else
    {
      cb_sel_hideFocus(mgr.ancoreRow)
    }
  }
}

function cb_sel_showFocus(row)
{
  /*
  if (row.tagName == "TR" && row.firstChild)
  {
    row.firstChild.style.borderLeft = "1px solid darkblue";
    row.lastChild.style.borderRight = "1px solid darkblue";
  }
  else
  {
    row.style.borderLeft = "1px solid darkblue";
  }
  */
}

function cb_sel_hideFocus(row)
{
  /*
  if (row.tagName == "TR" && row.firstChild)
  {
    row.firstChild.style.borderLeft = "none";
    row.lastChild.style.borderRight = "none";
  }
  else
  {
    row.style.borderLeft = "none";
  }
  */
}

function bl_sel_selectRow(el, row)
{
  if (row && bl_port_hasAttribute(el, "bl_selectType"))
  {
    var mgr = el.selectMgr;

    bl_sys_checkDialogSelect(el);    
    row.bl_isSelected = true;
    mgr.itemSelected(el, row, true, mgr.isActive, false, true);
  }
}

function cb_sel_deselect(el, row)
{
  if (row && bl_port_hasAttribute(el, "bl_selectType"))
  {
    row.bl_isSelected = false;
    el.selectMgr.itemSelected(el, row, false, false, false, true);
  }
}

function cb_sel_isFocusInput(el)
{
  if (el.tagName == undefined           ||
      el.isContentEditable == undefined ||
      el.getAttribute == undefined)
  {
    return false;
  }
  return ((el.tagName == "INPUT" && el.type == "text") ||
          el.tagName == "SELECT" ||
          el.isContentEditable);
}

function bl_sel_onSelectStart(event)
{
  if (!event)
  {
    event = window.event;
  }

  if (!cb_sys_isInput(bl_port_getEventTarget(event)))
  {
    bl_port_stop_event(event);
  }
}

function cb_sel_findSelect(list, sel, reti)
{
  var lo = 0;
  var hi = list.length - 1;
  var i  = -1;
  
  while (hi >= lo)
  {
    i = Math.floor((lo + hi)/2);
    var val = list[i];
    
    if (sel == val)
    {
      return i;
    }
    else if (val > sel)
    {
      hi = i - 1;
    }
    else
    {
      lo = i + 1;
    }
  }
  if (!reti)
  {
    i = -1;
  }
  return i;
}

function cb_sel_computeShiftStart(ancoreIndex, list)
{
  var ret = ancoreIndex;
  var len = list.length;
  
  if (len > 0)
  {
    var i = cb_sel_findSelect(list, ancoreIndex, false);
    
    if (i >= 0)
    {
      if (i == (len - 1) || (i < (len - 1) && list[i + 1] != (list[i] + 1)))
      {
        while (i > 0)
        {
          if (list[i - 1] != (list[i] - 1))
          {
            break;
          }
          i--;
        }
      }
      else if (i == 0 || (i > 0 && list[i - 1] != (list[i] - 1)))
      {
        while (i < len - 1)
        {
          if (list[i + 1] != (list[i] + 1))
          {
            break;
          }
          i++;
        }
      }
      ret = list[i];
    }
  }
  return ret;
}


function cb_sel_findInsertion(list, val)
{
  var i = cb_sel_findSelect(list, val, true);
  
  if (i >= 0)
  {
    var len = list.length;
    if (i < len)
    {
      while (i < len && list[i] < val)
      {
        i++;
      }
      while (i > 0 && list[i - 1] > val)
      {
        i--;
      }
    }
    if (i >= len)
    {
      i = -1;
    }
  }
  return i;
}

function cb_sel_doSelection(i, list, el, computeRow, start, end)
{
  if (i >= 0)
  {
    for (;i < list.length && start <= end; start++)
    {
      if (list[i] != start)
      {
        list.splice(i, 0, start);
        bl_sel_selectRow(el, computeRow(el, start));
      }
      i++;
    }
  }
  for (; start <= end; start++)
  {
    list.push(start);
    bl_sel_selectRow(el, computeRow(el, start));
  }
}

function cb_sel_insertSelect(list, el, computeRow, start, end)
{
  cb_sel_doSelection(cb_sel_findInsertion(list, start), list, el, computeRow, start, end);
}

function cb_sel_multiSelect(mgr, start, end, addSelect, send)
{
  var el   = mgr.getElement();
  var list = mgr.list;
  var selectRemoves = "false";
  
  if (!addSelect)
  {
    selectRemoves = "true";
    cb_sel_deselectAllRows(mgr, el, list, mgr.computeRow);
  }
  
  if (send)
  {
    cb_sel_insertSelect(list, el, mgr.computeRow, start, end);
    
    var msg      = "<selectRange selectRemoves='" + selectRemoves + "'><start>" + start + "</start><end>" + end + "</end></selectRange>";
    var sendType = (addSelect)? BL_MPR_APPEND:BL_MPR_ASAP;

    bl_mpr_send(msg, mgr.elID, 3, sendType);
  }
}

function bl_sel_clearPend(mgr)
{
  if (mgr)
  {
    cb_sel_setPend(mgr, -1, null, false, false);
  }
}

function bl_sel_aboutToDrop(ddObj)
{
  //clear possible select in source let server/dev select in dest
	bl_sel_clearPend(this.selectMgr);
}

function cb_sel_setPend(mgr, index, row, rems, desel)
{
  mgr.pendingSingleSelect  = index;
  mgr.pendingRow           = row;
  mgr.pendingSelectRemoves = rems;
  mgr.pendingDeselectAll   = desel;
}

function cb_sel_addSelect(mgr, index)
{
  var list   = mgr.list;
  var i      = cb_sel_findInsertion(list, index);
  var xmlStr = new String();
  var el     = mgr.getElement();
  var row    = mgr.computeRow(el, index);
  
  if (i >= 0)
  {
    if (list[i] == index)
    {
      list.splice(i, 1);
      cb_sel_deselect(el, row);
      xmlStr = '<deselect><index>' + index + '</index></deselect>';
      
      if (mgr.sigSelect == index)
      {
        if (list.length)
        {
          cb_sel_setPend(mgr, list[0], row, false, false);
        }
        else
        {
          cb_sel_setPend(mgr, -2, null, false, false);
        }
      }
    }
    else
    {
      list.splice(i, 0, index);
      bl_sel_selectRow(el, row);
      xmlStr = "<select selectRemoves='false'><index>" + index + "</index></select>";
    }
  }
  else
  {
    list.push(index);
    bl_sel_selectRow(el, row);
    if (list.length == 1)
    {
      cb_sel_setPend(mgr, index, row, false, false);
    }
    xmlStr = "<select selectRemoves='false'><index>" + index + "</index></select>";
  }
  
  bl_mpr_send(xmlStr, mgr.elID, 3, BL_MPR_APPEND);
}

function cb_sel_isSelected(row)
{
  return (row && row.bl_isSelected != undefined && row.bl_isSelected);
}

function _bl_sel_move(event, el)
{
  var mgr   = el.selectMgr;
  var srcEl = bl_port_getEventTarget(event);

  if (mgr && srcEl && srcEl.getAttribute)
  {
    var last = el.bl_lastFlyover;
    var row = mgr.findRow(el, srcEl);

    if (row != last)
    {
      // select the row if we are supposed to select on FlyOver
      if (bl_port_hasAttribute(el, "bl_selectOnFlyOver"))
      {
        if (row)
        {
          var index = mgr.computeRowIndex(el, row);
          cb_sel_deselectAllRows(mgr, el, mgr.list, mgr.computeRow);
          bl_sel_selectRow(el, row);
          mgr.list.push(index);
          cb_sel_sendSingleSelect(el, mgr, row, index, "");
          cb_sel_scrollInView(mgr, row);
        }
        else
        { // the current flyover row is empty. Clear out the selection
          mgr.deselectAll(mgr, true);
        }
      }
      else
      {
        if (last)
        {
          mgr.itemSelected(el, last, last.bl_isSelected, mgr.isActive, false, false);
        }
        
        if (row)
        {
          if (row.bl_isSelected)
          {
            mgr.itemSelected(el, row, true, true, false, false);
          }
          else
          {
            mgr.itemSelected(el, row, false, mgr.isActive, true, false);
          }
        }
      }
      el.bl_lastFlyover = row;
      bl_port_stop_event(event);
    }
  }
}

function _bl_sel_leave(event, el)
{
  var last = el.bl_lastFlyover;
  
  if (last && el.selectMgr)
  {
    var mgr = el.selectMgr;
    if (bl_port_hasAttribute(el, "bl_selectOnFlyOver"))
    {
      mgr.deselectAll(mgr, true);
    }
    mgr.itemSelected(el, last, last.bl_isSelected, mgr.isActive, false, false);
    el.bl_lastFlyover = null;
  }
}

function _bl_sel_enter(event, el)
{
  _bl_sel_move(event, el);
}

function _bl_sel_down(event, el)
{
  var mgr   = el.selectMgr;
  var srcEl = bl_port_getEventTarget(event);
  bl_kb_focusOnElement(srcEl)
  
  if (srcEl && srcEl.getAttribute)
  {
    if (!mgr.mouseOverRide || !mgr.mouseOverRide(event, el))
    {
      var row = mgr.findRow(el, srcEl);
      
      if (row)
      {
        var index          = mgr.computeRowIndex(el, row);
        var doDetectNotify = false;
        
        if (!cb_sel_isSelected(row))
        {
          if (mgr.isMulti && (event.shiftKey || event.ctrlKey))
          {
            if (event.shiftKey)
            {
              var start = cb_sel_computeShiftStart(mgr.ancoreIndex, mgr.list);
              
              if (start >= index)
              {
                cb_sel_multiSelect(mgr, index, start, event.ctrlKey, true);
              }
              else
              {
                cb_sel_multiSelect(mgr, start, index, event.ctrlKey, true);
              }
              
              if (!event.ctrlKey && mgr.list.length > 0)
              {
                if (index != mgr.sigSelect)
                {
                  cb_sel_setPend(mgr, index, mgr.computeRow(el, index), false, false);
                }
              }
            }
            else
            {
              cb_sel_addSelect(mgr, index);
            }
          }
          else
          {
            var deselectPend = false;
            if (cb_sel_isSelected(row))
            {
              doDetectNotify = deselectPend = true;
            }
            else
            {
              cb_sel_deselectAllRows(mgr, el, mgr.list, mgr.computeRow);
              bl_sel_selectRow(el, row);
              
              mgr.list.push(index);
            }
            
            if (el.getAttribute("bl_selectBeforeDrag") != null)
            {
              cb_sel_sendSingleSelect(el, mgr, row, index, "");
              cb_sel_scrollInView(mgr, row);
            }
            else
            {
              cb_sel_setPend(mgr, index, row, true, deselectPend);
            }
          }
        }
        else if (mgr.isMulti && event.ctrlKey)
        {
          cb_sel_addSelect(mgr, index);
        }
        else if (!bl_port_isRightDown(event))
        {
          if (cb_sys_isInput(srcEl))
          {
            bl_port_stop_event(event);
            return;
          }
          cb_sel_setPend(mgr, index, row, true, true);
        }
        
        cb_sel_setAncore(mgr, row, index);
        bl_sel_dragDetect(el, row, index, event, doDetectNotify);
        bl_port_stop_event(event);
      }
    }
  }
}

function cb_sel_findTopChild(event, row)
{
  var ch = bl_port_getEventTarget(event);
  
  while (ch && ch != row)
  {
    if (ch.parentNode == row)
    {
      var list = row.childNodes;
      var len  = list.length;
      for (var i = 0; i < len; i++)
      {
        if (list[i] == ch)
        {
          return i;
        }
      }
    }
    ch = ch.parentNode;
  }
  
  return -1;
}

function bl_sel_dragEnd(source, item, dragStarted)
{
  bl_sel_checkPending(item, source, source.selectMgr);
}

function bl_sel_dragDetect(el, row, index, event, doDetectNotify)
{
  var mgr = el.selectMgr;
  
  if (row && el && el.getAttribute("bl_zone") != null && !cb_sys_isInput(bl_port_getEventTarget(event)) && bl_port_isLeftDown(event))
  {
    mgr.cb_childIndex = cb_sel_findTopChild(event, row);
    
    var list = mgr.list;
    
    if (list.length)
    {
      var notifyFunc = doDetectNotify? bl_sel_inDragNotify:null;
      var srcContext = { source:el, 
                         item:row, 
                         did:window.bl_did,
                         itemIndex:index,
                         indexes:list, 
                         computeShadow:bl_sel_computeDragInner,
                         dragEnd:bl_sel_dragEnd, 
                         detectNotify:notifyFunc
                       };

      if (bl_dd_detect(event, srcContext))
      {
        return true;
      }
    }
  }
  
  if (!mgr.forceSendNow)
  {
    mgr.forceSendNow = (!bl_port_isLeftDown(event) || bl_sys_isInPopup());
  }
  
  bl_sel_checkPending(row, el, mgr);
  mgr.forceSendNow = false;
  return false;
}

function bl_sel_inDragNotify(source, item)
{
  bl_sel_clearPend(source.selectMgr);
}

function cb_sel_deselectAllRows(mgr, el, list, computeRow)
{
  var ind = list.pop();
  
  mgr.sigSelect = -1;
  
  while (ind != undefined)
  {
    cb_sel_deselect(el, computeRow(el, ind));
    ind = list.pop();
  }
}

function _bl_deferSend(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    var mgr = el.selectMgr;
    
    if (mgr && mgr.cb_xmlStr)
    {
      if (mgr.cb_waitMore)
      {
        mgr.cb_waitMore = false;
        window.setTimeout('_bl_deferSend("' + id + '")', 200);
      }
      else
      {
        bl_mpr_send(mgr.cb_xmlStr, mgr.elID, 3, BL_MPR_ASAP, true);
        mgr.cb_waitMore = false;
        mgr.cb_xmlStr   = null;
      }
    }
  }
}

function cb_sel_sendSingleSelect(el, mgr, row, index, attr)
{
  //always fire single select for event handling.
  mgr.firstSelect = false;
  mgr.sigSelect   = index;
  mgr.sigRow      = row;
  
  // now tell the server to select
  var exeWait   = (mgr.cb_xmlStr) ? false : true;
  mgr.cb_xmlStr = '<singleSelect ' + attr + '><index>' + index + '</index></singleSelect>';

  if (mgr.forceSendNow)
  {
    bl_mpr_send(mgr.cb_xmlStr, mgr.elID, 3);
    mgr.cb_waitMore = false;
    mgr.cb_xmlStr   = null;
  }
  else
  {
    if (exeWait)
    {
      mgr.cb_waitMore = false;
      window.setTimeout('_bl_deferSend("' + el.id + '")', 200);
    }
    else
    {
      mgr.cb_waitMore = true;
    }
  }
}

function _bl_sel_dbl_clk(event, el)
{
  var mgr = el.selectMgr;
  var row = mgr.findRow(el, bl_port_getEventTarget(event));
  
  if (row)
  {
    var index  = mgr.computeRowIndex(el, row);
    var xmlStr = new String();
    xmlStr     = "<dblclicked><index>" + index + "</index></dblclicked>";
    
    if (mgr.cb_xmlStr)
    {
      mgr.cb_xmlStr += xmlStr
    }
    else
    {
      bl_mpr_send(xmlStr, el.id, 1);
    }
    
    if (mgr.closeOnDblClk)
    {
      window._bl_sys_closeWindow('Ok');
    }
    bl_port_stop_event(event);
  }
}

function _bl_sel_key_up(event, el)
{
  bl_sel_handleKeyUp(event, el)
}

function _bl_sel_key_down(event, el)
{
  bl_sel_handleKeyDown(event, el);
}

function bl_sel_wheelEvent(event)
{
  if (!event)
  {
    event = window.event;
  }
  
  var p = bl_port_getEventTarget(event);
  
  while (p && !p.selectMgr)
  {
    p = p.parentNode;
  }
  
  p = cb_sel_findOffsetParent(p);
  
  if (p)
  {
    if (p.scrollHeight > p.offsetHeight)
    {
      var stop = p.scrollTop - event.wheelDelta;
      
      if (stop < 0)
      {
        stop = 0;
      }
      p.scrollTop = stop;
      bl_port_stop_event(event);
    }
    else if (p.scrollWidth > p.offsetWidth)
    {
      var sleft = p.scrollLeft - event.wheelDelta;
      
      if (sleft < 0)
      {
        sleft = 0;
      }
      p.scrollLeft = sleft;
      bl_port_stop_event(event);
    }
  }
}

function cb_sel_detect_sc_mode(el, kcode)
{
  if (el.getAttribute("cb_sc_mode") != null &&
      (kcode == 13  ||
       kcode == 35  ||
       kcode == 36  ||
       kcode == 37  ||
       kcode == 39  ||
       kcode == 32))
  {
    return true;
  }
  
  return false;
}

function bl_sel_setActive(mgr, el, val)
{
  var list       = mgr.list;
  var len        = list.length;
  var computeRow = mgr.computeRow;
  mgr.isActive   = val;
  
  if (!mgr.supress_select || !val)
  {
    for (var i = 0; i < len; i++)
    {
      var row = computeRow(el, parseInt(list[i]));
      row.bl_isSelected = true;
      mgr.itemSelected(el, row, true, val, false, false);
    }
  }
  
  mgr.supress_select = false;
}

function bl_sel_focusOut(event)
{
  if (!event)
  {
    event = window.event;
  }
  
  if (bl_port_contains(this, bl_port_get_activeElement(document), true) == false)
  {
    var mgr = this.selectMgr;

    if (mgr && mgr.isActive)
    {
      bl_sel_setActive(mgr, this, false);
      cb_sel_setFocus(mgr, false);
    }
  }
}

function bl_sel_focusIn(event)
{
  var mgr = this.selectMgr;
  
  if (mgr && !mgr.isActive)
  {
    bl_sel_setActive(mgr, this, true);
    cb_sel_setFocus(mgr, true);
  }
}

function cb_sel_computeRowViewable(mgr, el)
{
  var row = mgr.computeRow(el, 0);
  
  if (row)
  {
    return Math.floor(el.offsetParent.offsetHeight/row.offsetHeight);
  }
  
  return -1;
}

function cb_sel_handle_enter_key(el, index)
{
  var xmlStr = "<dblclicked><index>" + index + "</index></dblclicked>";
  bl_mpr_send(xmlStr, el.id, 1);
}

function cb_sel_compute_2d_index(el, kcode, cIndex, isVertical)
{
  var row         = null;
  var retIndex    = -1;
  var nextOffset  = -1;
  var mgr         = el.selectMgr;
  var computeRow  = mgr.computeRow;
  var curIndex    = (cIndex != undefined ? cIndex : mgr.ancoreIndex);
  var curRow      = computeRow(el, curIndex);
  var direction   = (kcode == 37 || kcode == 38 ? 'left' : 'right')
  var startIndex  = (direction == 'left' ? curIndex - 1 : curIndex + 1);
  
  if (curRow)
  {
    var curOffset   = (isVertical ? curRow.offsetTop  : curRow.offsetLeft);
    var curPos      = (isVertical ? curRow.offsetLeft : curRow.offsetTop);
    do
    {
      row = computeRow(el, startIndex);
      if (row != null)
      {
        var rowOffset = (isVertical ? row.offsetTop   : row.offsetLeft);
        var rowPos    = (isVertical ? row.offsetLeft  : row.offsetTop);
        var rowDim    = (isVertical ? row.offsetHeight : row.offsetWidth);
        if (direction == 'left')
        {
          if ((rowOffset <= curOffset) && (rowPos < curPos))
          {
            retIndex = startIndex;
          }
        }
        else
        {
          if (rowPos > curPos && (nextOffset == -1))
          {
            nextOffset = rowPos;
          }
          if (rowPos == nextOffset)
          {
            if (rowOffset == curOffset || (rowOffset + rowDim > curOffset))
            {
              retIndex = startIndex;
              break;
            }
            else if ((rowOffset > curOffset) ||
                    ((rowPos > nextOffset) && (nextOffset != -1)))
            {
              retIndex = startIndex - 1;
              break;
            }
          }
        }
        
        startIndex = (direction == 'left' ? startIndex - 1 : startIndex + 1);
      }
      //row is null
      else if (nextOffset != -1)
      {
        retIndex = startIndex - 1;
        break;
      }
    } while ((retIndex == -1) && (row != null))
  }
  
  return retIndex;
}

function bl_sel_handleKeyDown(event, el)
{
  var mgr   = el.selectMgr;
  var kcode = bl_port_keyCode(event);
  var srcEl = bl_port_getEventTarget(event);
  
  mgr.cb_childIndex = -1;
  
  if ((!mgr.keyOverRide || !mgr.keyOverRide(event, el, kcode)) &&
      (!cb_sys_isInput(srcEl) || kcode == 40 || kcode == 38 || kcode == 33 || kcode == 34 ||
       (kcode == 13 && srcEl && srcEl.tagName == "INPUT" && srcEl.getAttribute("bl_cancelEnter") != null)))
  {
    if (kcode == 65 && event.ctrlKey)
    {
      mgr.selectAll(mgr, true);
      bl_port_killEvent(event);
      return;
    }
    else if (kcode==13) //enter key, should open item.
    {
      if (mgr.ancoreIndex >=0)
      {
        cb_sel_handle_enter_key(el, mgr.ancoreIndex);
        bl_port_killEvent(event);
        return;
      }
    }
    else if (kcode == 46 || kcode == 8)// delete/backspace
    {
      // Fix for bug #5476
      if ((bl_browserInfo.firefox || bl_browserInfo.safari) && cb_sys_isInput(srcEl))
      {
        bl_port_killEvent(event);
        return;
      }
      if (mgr.supportsRemove)
      {
        var xmlStr = new String();
        var sStr   = (event.shiftKey) ? 'shiftDown="true"' : 'shiftDown="false"';
        xmlStr     = '<removeSelected ' + sStr + '></removeSelected>';
        
        bl_mpr_send(xmlStr, el.id, 2);
        bl_port_killEvent(event);

        // Make the dynamic form list the active element so further
        // keypresses will be sent to the right place.
        bl_kb_activate(el,el);
      }
    }
    else if (mgr.ancoreIndex >= 0)
    {
      var row      = null;
      var index    = -1;
      var containLayout   = bl_contain_getLayout(el);
      var flowType        = (containLayout ? containLayout.type : bl_contain_type_vertical);
      
      if (kcode == 37) //left
      {
        if (flowType == bl_contain_type_2dVertical)
        {
          index = cb_sel_compute_2d_index(el, kcode, mgr.ancoreIndex, true);
        }
        else
        {
          index = mgr.ancoreIndex - 1;
        }
      }
      if (kcode == 39) //right
      {
        if (flowType == bl_contain_type_2dVertical)
        {
          index = cb_sel_compute_2d_index(el, kcode, mgr.ancoreIndex, true);
        }
        else
        {
          index = mgr.ancoreIndex + 1;
        }
      }
      else if (kcode == 38) //up
      {
        if (flowType == bl_contain_type_2dHorizontal)
        {
          index = cb_sel_compute_2d_index(el, kcode, mgr.ancoreIndex, false);
        }
        else
        {
          index = mgr.ancoreIndex - 1;
        }
      }
      else if (kcode == 40) //down
      {
        if (flowType == bl_contain_type_2dHorizontal)
        {
          index = cb_sel_compute_2d_index(el, kcode, mgr.ancoreIndex, false);
        }
        else
        {
          index = mgr.ancoreIndex + 1;
        }
      }
      else if (kcode == 36)  //hm
      {
        index = 0;
      }
      else if (kcode == 35) //end
      {
        index = mgr.getLength(el) - 1;
      }
      else if (kcode == 34)  //pgdn
      {
        var lastIndex = mgr.getLength(el) - 1;
        index = mgr.ancoreIndex + cb_sel_computeRowViewable(mgr, el);
        if (index > lastIndex)
        {
          index = lastIndex;
        }
      }
      else if (kcode == 33) //pgup
      {
        index = mgr.ancoreIndex - cb_sel_computeRowViewable(mgr, el);
        if (index < 0)
        {
          index = 0;
        }
      }
      else if (kcode == 32)
      {
        index = mgr.ancoreIndex;
      }
      row = mgr.computeRow(el, index);
      
      if (row)
      {
        if (mgr.isMulti && event.shiftKey)
        {
          var start = cb_sel_computeShiftStart(mgr.ancoreIndex, mgr.list);
          if (start >= index)
          {
            cb_sel_multiSelect(mgr, index, start, false, true);
          }
          else
          {
            cb_sel_multiSelect(mgr, start, index, false, true);
          }
        }
        else
        {
          if (!event.ctrlKey)
          {
            if (index != mgr.sigSelect)
            {
              cb_sel_deselectAllRows(mgr, el, mgr.list, mgr.computeRow, true);
              bl_sel_selectRow(el, row);
              mgr.list.push(index);
              
              if (mgr.keyDownIndex < 0)
              {
                mgr.keyDownIndex = index;
                cb_sel_sendSingleSelect(el, mgr, row, index, "");
              }
            }
          }
        }
        if (bl_port_hasAttribute(el,"bl_allowTabInto") && !bl_kb_isFocusInside(row))
        {
          if (!bl_kb_activateFromTab(row,true))
          {
            // The new row contains no controls that can be focused.
            // Select the actual list itself.
            bl_kb_activate(el,el);
          }
        }
        cb_sel_setAncore(mgr, row, index);
        cb_sel_scrollInView(mgr, row);
        bl_port_killEvent(event);
      }
    }
  }
}

function cb_sel_findOffsetParent(p)
{
  var body = document.body;
  while (p && p != body)
  {
    if (p.scrollHeight > p.offsetHeight || p.scrollWidth > p.offsetWidth)
    {
      break;
    }
    p = p.parentNode;
  }
  
  if (p  && p != body && p.scrollHeight <= p.offsetHeight && p.scrollWidth <= p.offsetWidth)
  {
    while (p && p != body)
    {
      if (p.scrollHeight > p.offsetHeight || p.scrollWidth > p.offsetWidth)
      {
        break;
      }
      
      var newp = p.parentNode;
      if (bl_port_hasAttribute(newp,"cb_tag"))
      {
        break ;
      }
      
      p = newp;
    }
  }
  return p;
}

function cb_sel_scrollInView(mgr, row)
{
  if (row)
  {
    var p   = cb_sel_findOffsetParent(row.parentNode);
    var el  = (mgr ? mgr.getElement() : null);
    
    if (p)
    {
      var stop  = p.scrollTop;
      var sleft = p.scrollLeft;
      var rtop  = (bl_sys_real_y(row, null, false) - bl_sys_real_y(p, null, false));
      var rleft = (bl_sys_real_x(row, null, false) - bl_sys_real_x(p, null, false));
      
      var roww = row.offsetWidth;
      var rowh = row.offsetHeight;
      var tmar = 0;
      var lmar = 0;
      
      if (mgr && mgr.getMargin)
      {
        tmar = mgr.getMargin(el, rtop < rowh);
        lmar = mgr.getMargin(el, rleft < roww);
      }
      
      if (stop > 0 && rtop < stop)
      {
        p.scrollTop = rtop - tmar;
      }
      else
      {
        var parh = p.clientHeight;
        if (((rtop + rowh) > parh + stop) && rowh <= parh)
        {
          p.scrollTop += ((rtop + rowh) - (parh + stop) + tmar);
        }
      }
      if (sleft > 0 && rleft < sleft)
      {
        p.scrollLeft = rleft - lmar;
      }
      else if (el)
      {
        var containLayout = bl_contain_getLayout(el);
        var layoutType    = (containLayout ? containLayout.type : bl_contain_type_vertical);
        if (layoutType == bl_contain_type_2dHorizontal || 
            layoutType == bl_contain_type_2dVertical)
        {
          var parw = p.clientWidth;
          if (((rleft + roww) > parw + sleft) && roww <= parw)
          {
            p.scrollLeft += ((rleft + roww) - (parw + sleft) + lmar);
          }
        }
      }
    }
  }
}

function bl_sel_handleKeyUp(event, el)
{
  var mgr   = el.selectMgr;
  var kcode = bl_port_keyCode(event);
  
  if (mgr.keyDownIndex >= 0)
  {
    var index = mgr.ancoreIndex;
    var row   = mgr.computeRow(el, index);
    
    if (kcode == 38 ||
        kcode == 37 ||
        kcode == 40 ||
        kcode == 39 ||
        kcode == 34 ||
        kcode == 33)
    {
      row = mgr.computeRow(el, index);
      if (row && mgr.keyDownIndex != index)
      {
        if (mgr.isMulti && event.shiftKey)
        {
          var start = cb_sel_computeShiftStart(mgr.ancoreIndex, mgr.list);
          if (start >= index)
          {
            cb_sel_multiSelect(mgr, index, start, false, true);
          }
          else
          {
            cb_sel_multiSelect(mgr, start, index, false, true);
          }
        }
        else
        {
          if (!event.ctrlKey)
          {
            cb_sel_sendSingleSelect(el, mgr, row, index, "");
          }
        }
      }
      bl_port_stop_event(event);
    }
    mgr.keyDownIndex = -1;
  }
}

function bl_sel_computeDragInner(event)
{
  var index   = this.itemIndex
  var el      = this.source;
  var mgr     = el.selectMgr;
  var screenX = event.screenX;
  
  if (mgr && mgr.list && mgr.list.length > 0)
  {
    var list  = mgr.list;
    var len   = list.length;
    var i     = cb_sel_findSelect(list, index, true);
    var start = i - 10;
    var end   = i + 10;
    
    if (start  <  0)
    {
      end  += (-start);
      start = 0;
    }
    if (end >= len)
    {
      start -= (end - len + 1);
      end    = len - 1;
      
      if (start  <  0)
      {
        start = 0;
      }
    }
    
    var computeRow = mgr.computeRow;
    var w          = 0;
    var h          = 0;
    var ox         = 0;
    var oy         = 0;
    var firstDone  = false;
    var str        = "";
    var x          = 0;
    var y          = 0;
    var extraHTML  = "";
    
    i = 0;

    if (el.getAttribute("cb_tag") == "MCL")
    {
      var headCG = blu_getChild(el, "COLGROUP", "HEADERGROUP");
      
      if (headCG)
      {
        extraHTML = bl_port_getOuterHTML(headCG);
      }
    }
    
    while (start <= end)
    {
      var val = list[start];
      var row = computeRow(el, val);
      
      if (row)
      {
        if (firstDone)
        {
          x = row.offsetLeft - ox;
          y = row.offsetTop - oy;
          w = x + row.offsetWidth;
          h = y + row.offsetHeight;
        }
        else
        {
          firstDone = true;
          x  = 0;
          ox = row.offsetLeft;
          y  = 0;
          oy = row.offsetTop;
          w  = row.offsetWidth;
          h  = row.offsetHeight;
        }
        if (val == index)
        {
          mgr.dragIndex = i;
          mgr.dragXPer  = (screenX - (bl_sys_find_x(row, null, false) + cb_sys_getScreenLeft()))/w;
        }
        
        var tname = (row.tagName == "TR") ? "TABLE" : "SPAN";
        var html  = "";
        
        if (row.style.position == "absolute")
        {
          var tmpSPNode = window.bl_node_cloner_span;
          var tmpNode   = null;
          
          if (!tmpSPNode)
          {
            window.bl_node_cloner_span = tmpSPNode = document.createElement("span");
          }
          
          tmpSPNode.innerHTML    = bl_port_getOuterHTML(row);
          tmpNode                = tmpSPNode.firstChild;
          tmpNode.style.position = "";
          
          tmpNode.style.top  = "";
          tmpNode.style.left = "";
          
          if (tmpNode.tagName != "TABLE")
          {
            tmpNode.innerHTML = row.innerHTML;
          }
          
          html = bl_port_getOuterHTML(tmpNode);
          tmpSPNode.innerHTML = "";
        }
        else
        {
          html = bl_port_getOuterHTML(row);
        }
        str += "<" 
            + tname 
            + " cellSpacing=0 cellPadding=0 border=0 style='position:absolute;width:" 
            + w 
            + "px;left:" 
            + x 
            + "px;top:" 
            + y 
            + "px;'>"
            + extraHTML 
            + html 
            + "</" 
            + tname 
            + ">";
      }
      
      start++;
      i++
    }
    
    return "<div style='width:" + w + "px;height:" + h + "px;'>" + str + "</div>";
  }
  
  return "<span></span>";
}

function cb_sel_adjustMessage(msg, index)
{
  var current = 0;
  var msgRet  = "";
  
  do
  {
    var start = msg.indexOf("<index>", current);
    
    if (start >= 0)
    {
      start  += 7;
      msgRet += msg.substr(current, start - current);
      var end = msg.indexOf("</index>", start);
      var selIndex = parseInt(msg.substr(start, end - start));
      
      if (selIndex > index)
      {
        selIndex--;
      }
      msgRet += selIndex;
      current = end;
    }
    else
    {
      start = msg.indexOf("<indexes>", current);
      if (start >= 0)
      {
        start   += 9;
        msgRet  += msg.substr(current, start - current);
        var end  = msg.indexOf("</indexes>", start);
        var list = msg.substr(start, end - start).split(" ");
        var len  = list.length;
        
        for (var i = 0; i < len; i++)
        {
          var ival = parseInt(list[i]);
          
          if (ival > index)
          {
            ival--;
          }
          msgRet += ival + " ";
        }
        current = end;
      }
      else
      {
        start = msg.indexOf("<start>", current);
        if (start >= 0)
        {
          start  += 7;
          msgRet += msg.substr(current, start - current);
          
          var end    = msg.indexOf("</start>", start);
          var start2 = msg.indexOf("<end>", end);
          start2    += 5;
          var end2   = msg.indexOf("</end>", start);
          
          var startVal = parseInt(msg.substr(start, end - start));
          var endVal   = parseInt(msg.substr(start2, end2 - start2));
          
          if (startVal > index)
          {
            startVal--;
          }
          
          if (endVal > index)
          {
            endVal--;
          }
          
          msgRet += startVal + msg.substr(end, start2 - end) + endVal;
          current = end2;
        }
        else
        {
          msgRet += msg.substr(current);
          start   = -1;
        }
      }
    }
  } while (start >= 0)
  return msgRet
}


function bl_sel_removeAdjust(index)
{
  var msg = this.cb_xmlStr;
  if (msg)
  {
    this.cb_xmlStr = cb_sel_adjustMessage(msg, index);
  }
  
  var mpr = bl_sys_get_mpr(window);
  
  if (mpr)
  {
    var item = mpr.findMessage(this.elID, 3);
    
    if (item)
    {
      item.msg = cb_sel_adjustMessage(item.msg, index);
    }
  }
}

function bl_sel_acceptSelect()
{
  if (this.cb_xmlStr)
  {
    var msg = this.cb_xmlStr;
    
    if (msg.indexOf("singleSelect") >= 0 || msg.indexOf("selectRemoves='true'") >=0)
    {
      return false;
    }
  }
  
  var mpr = bl_sys_get_mpr(window);
  
  if (mpr)
  {
    var item = mpr.findMessage(this.elID, 3);
    
    if (item)
    {
      var msg = item.msg;
      
      if (msg.indexOf("singleSelect") >= 0 || msg.indexOf("selectRemoves='true'") >=0)
      {
        return false;
      }
    }
  }
  return true;
}

function bl_sel_invalidate(el, cmd)
{
  var tableBody = document.createElement("BODY");
  tableBody.innerHTML = bl_port_get_text(cmd);
  
  var selectMgr = el.selectMgr;
  var parent    = el.parentNode;
  var isActive  = (selectMgr && selectMgr.isActive);
  
  bl_port_insertAdjacentElement(el, "BeforeBegin", tableBody.firstChild);
  
  var newEl          = el.previousSibling;
  var elStyle        = el.style;
  var prevLeft       = elStyle.left;
  var prevTop        = elStyle.top;
  var prevWidth      = elStyle.width;
  var prevHeight     = elStyle.height;
  var prev_bl_max_w  = el.bl_max_w;
  var prev_bl_min_w  = el.bl_min_w;
  var prev_bl_max_h  = el.bl_max_h;
  var prev_bl_min_h  = el.bl_min_h;
  var prev_bl_width  = el.bl_width;
  var prev_bl_height = el.bl_height;
  
  bl_port_removeComplexEl(el, parent);
  bl_sys_procInitTags(cmd);
  
  if (newEl.selectMgr)
  {
    newEl.selectMgr.isActive = isActive;
  }
  
  with (newEl.style)
  {
    left     = prevLeft;
    top      = prevTop;
    width    = prevWidth;
    height   = prevHeight;
  }
  
  newEl.bl_max_w  = prev_bl_max_w;
  newEl.bl_min_w  = prev_bl_min_w;
  newEl.bl_max_h  = prev_bl_max_h;
  newEl.bl_min_h  = prev_bl_min_h;
  newEl.bl_width  = prev_bl_width;
  newEl.bl_height = prev_bl_height;
}

// bl_sel_handler return true ifthe geometry needs to be pinged  
function bl_sel_handler(el, name, cmd, removeIndexFunc, insertFunc, setFunc, moveFunc)
{
  var mgr          = el.selectMgr;
  var pingGeometry = false;
  
  if (name == "insert")
  {
    var index = insertFunc(el, cmd, true);
    
    if (mgr)
    {
      cb_sel_indexAdded(index, mgr);
    }
    pingGeometry = true;
  }
  else if (name == "remove")
  {
    var index = parseInt(bl_port_get_text(cmd.childNodes.item(0)));
    removeIndexFunc(el, index, true);
    
    if (mgr)
    {
      cb_sel_indexRemoved(index, mgr);
    }
    pingGeometry = true;
  }
  else if (name == "removeselect")
  {
    var list = bl_port_get_text(cmd).split(" ");
    var len  = list.length;
    
    for (var i = 0; i < len; i++)
    {
      var last  = i == len - 1;
      var index = parseInt(list[i]);
      
      removeIndexFunc(el, index, last);
      
      if (mgr)
      {
        cb_sel_indexRemoved(index, mgr);
      }
    }
    mgr.ancoreIndex = -1;
    mgr.ancoreRow   = null;
    pingGeometry = true;
  }
  else if (name == "set")
  {
    var edsAttr = cmd.attributes.getNamedItem("eds");
    var eds     = (edsAttr) ? (edsAttr.nodeValue == "true") : false;
    var index   = setFunc(el, cmd);
    
    if (mgr)
    {
      cb_sel_indexSet(index, mgr, eds);
    }
    pingGeometry = true;
  }
  else if (name == "insertCollection")
  {
    var nodes = cmd.childNodes;
    var len   = nodes.length;
    for (var i = 0;i < len;i++)
    {
      var last  = i == len - 1;
      var cmd   = nodes[i];
      var index = insertFunc(el, cmd, last);
      
      if (mgr)
      {
        cb_sel_indexAdded(index, mgr);
      }
    }
    pingGeometry = true;
  }
  else if (name == "removeAll")
  {
    if (mgr)
    {
      mgr.removeAll();
    }
  }
  else if (name == "select")
  {
    if (mgr && mgr.acceptSelect())
    {
      var selr          = cmd.attributes.getNamedItem("selectRemoves");
      var selectRemoves = (selr) ? (selr.nodeValue == "true") : false;
      var sigs          = cmd.attributes.getNamedItem("sigSelect");
      var sigSelect     = (sigs) ? (sigs.nodeValue == "true") : false;
      
      bl_sel_selectRows(mgr, bl_port_get_text(cmd), selectRemoves, false, sigSelect);
    }
  }
  else if (name == "deselect")
  {
    if (mgr && mgr.acceptSelect())
    {
      bl_sel_deselectRows(mgr, bl_port_get_text(cmd, false));
    }
  }
  else if (name == "move")
  {
    var oldIndex = parseInt(bl_port_get_text(cmd.childNodes.item(0)));
    var newIndex = parseInt(bl_port_get_text(cmd.childNodes.item(1)));
    moveFunc(el, oldIndex, newIndex);
    

    if (mgr)
    {    
      var list     = mgr.list;
      var i        = cb_sel_findInsertion(list, oldIndex);
      var selected = (i >= 0 && list[i] == oldIndex);

      cb_sel_indexRemoved(oldIndex, mgr);
      cb_sel_indexAdded(newIndex, mgr);
    
      if (selected)
      {
        bl_sel_selectRows(mgr, bl_port_get_text(cmd.childNodes.item(1)), false, false, false);
      }
    }
  }
  
  return pingGeometry;
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_sel_last()
{
  var x = 0;
}

var bl_scl_nextSeekIsLeft   = false;
var bl_scl_lastCursorParent = null;
var bl_scl_selectedEl       = null;
var bl_scl_lastCursorPos    = 0;

// Functions that start with "__" are for debugging.
function __bl_scl_insertIframe(id,width,height,text)
{
  var splatEl = document.getElementById("splat");
  splatEl.style.width=width+"px";
  splatEl.style.height=height+"px";

  text = text
        .replace(/&/g,"&amp;")
        .replace(/</g,"&lt;")
        .replace(/>/g,"&gt;")
        .replace(/"/g,"&quot;")
        .replace(/'/g,"&#39;");

  var html = "<iframe id='"+id+"' bl_text=\""+text+"\" frameborder='0' width='100%' height='100%' src='about:blank' onload=\"_bl_scl_init(this)\"></iframe>";
  splatEl.innerHTML = html;
}

function __bl_scl_status(msg)
{return;
    document.getElementById("status").innerHTML = msg;
}

function __bl_scl_renderCursor(win)
{return;
  var html = __bl_scl_renderNode(win.document.body,bl_scl_lastCursorParent);
  document.getElementById("cursor").innerHTML = html;
}

function __bl_scl_renderNode(node,nodeToMatch)
{
  var html = "";
  if (node.nodeName == "#text")
  {
    try
    {
      html += "\"" + node.nodeValue + "\"";
    }
    catch(e)
    {
      html += "<font color=yellow>error: "+e.message+"</font>";
    }
  }
  else
  {
    html += node.nodeName;
  }

  if (node.nodeType == 1)
  {
    if (node.getAttribute("bl_type"))
    {
      html += " <font color=green>"+node.getAttribute("bl_type")+"</font>";
    }
    if (node.id)
    {
      html += " <font color=red>"+node.id+"</font>";
    }
    html += " <font color=blue>"+node.contentEditable+"</font>";
  }

  if (node == nodeToMatch)
  {
    html += " <b>&lt;-- Match!</b>";
  }

  if (node.childNodes.length > 0)
  {
    html += "<ol>";
    for (var i=0; i<node.childNodes.length; i++)
    {
      html += "<li>" + __bl_scl_renderNode(node.childNodes[i],nodeToMatch) + "</li>";
    }
    html += "</ol>";
  }

  return html;
}


function _bl_scl_init(el)
{
    // el should be an IFRAME element.
  if (el.getAttribute("bl_initialized") == "true")
  {
    return;
  }
  el.setAttribute("bl_initialized","true");

  var win = el.contentWindow;
  var doc = win.document;

  doc.open();
  if (bl_browserInfo.firefox3 || bl_browserInfo.ie)
  {
    doc.write("<html><head></head><body style=\"margin:0px;padding:0px;font:12px arial;color:black;background-color:transparent;width:100%;height:100%;overflow:hidden\"><div style=\"height:100%;width:100%;\" contentEditable></div></body></html>");
  }
  else
  {
    doc.write("<html><head></head><body style=\"margin:0px;padding:0px;min-height:15px;font:12px arial;color:black;background-color:transparent;width:100%;height:100%\" contentEditable></body></html>");
  }
  doc.close();
  
  if (bl_browserInfo.firefox && !bl_browserInfo.firefox3)
  {
    doc.designMode="on";
  }

  bl_scl_finishInit(el);
}

function bl_scl_onFocus(el)
{
  bl_port_docWindow(el.ownerDocument).bl_kb_focusOnElement(el);
  if (bl_browserInfo.ie)
  {
    var root = bl_scl_getRootEditableFromEl(el);
    root.contentEditable = true;
  }
}

function bl_scl_focus(el)
{
  var root = bl_scl_getRootEditableFromEl(el);
  if (bl_browserInfo.ie)
  {
    root.contentEditable = true;
  }

  if (el.afterBlurTimer)
  {
    var win = bl_port_docWindow(el.ownerDocument);
    win.clearTimeout(el.afterBlurTimer);
    el.afterBlurTimer = 0;
  }

  bl_scl_onFocus(el);
  el.contentWindow.focus();
  bl_scl_util_positionCursor(root,"beforeend");
}

function bl_scl_hideFocus(el)
{
  var root = bl_scl_getRootEditableFromEl(el);
  if (bl_browserInfo.ie)
  {
    root.contentEditable = false;
  }
  
  var win = bl_port_docWindow(el.ownerDocument);
  // Uncomment the following line if you want a delay between when the user blurs the control to when it updates.
  el.afterBlurTimer = win.setTimeout("_bl_scl_updateAfterBlur('"+el.id+"')",100);
  // If the previous line is uncommented, the following line should be commented.
  //win._bl_scl_updateAfterBlur(el.id);
}

function bl_scl_getRootEditableFromEl(el)
{
  if (bl_browserInfo.firefox3)
  {
    return el.contentWindow.document.body.firstChild;
  }
  else
  {
    return el.contentWindow.document.body;
  }
}

function bl_scl_getRootEditableFromDoc(doc)
{
  if (bl_browserInfo.firefox3)
  {
    return doc.body.firstChild;
  }
  else
  {
    return doc.body;
  }
}

function bl_scl_finishInit(el)
{
  var win  = el.contentWindow;
  var doc  = win.document;
  var root = bl_scl_getRootEditableFromDoc(doc);

  if (!root)
  {
    setTimeout(function(){bl_scl_finishInit(el)},10);
    return;
  }

  var initialValue = el.getAttribute("bl_text");
  el.setAttribute("bl_text","");
  el.style.border = "1px solid #7f9db9";
  root.innerHTML = initialValue;

  if (el.style.font)
  {
    root.style.font  = el.style.font;
  }
  if (el.style.color)
  {
    root.style.color = el.style.color;
  }
  
  el.cb_sys_gs_set      = bl_scl_doInsert;
  el.cb_sys_gs_getValue = bl_scl_getValue;
  el.cb_sys_gs_setValue = bl_scl_setValue;
  
  if (doc.attachEvent)
  {
    doc.attachEvent("ondragstart",bl_scl_handleDragstart);
    doc.attachEvent("onmousedown",bl_scl_handleMousedown);
    doc.attachEvent("onclick",    bl_scl_handleClick);
    doc.attachEvent("ondoubleclick",bl_scl_handleClick);
    doc.attachEvent("onmouseup",  bl_scl_handleMouseup  );
    doc.attachEvent("onkeydown",  bl_scl_handleKeydown  );
    doc.attachEvent("onkeyup",    bl_scl_handleKeyup    );
    doc.attachEvent("onkeypress", bl_scl_handleKeypress );
  }
  else
  {
    doc.addEventListener("mousedown",bl_scl_handleMousedown,false );
    doc.addEventListener("mouseup",  bl_scl_handleMouseup,  false );
    doc.addEventListener("click",    bl_scl_handleClick,    false );
    doc.addEventListener("doubleclick",bl_scl_handleClick,    false );
    doc.addEventListener("keydown",  bl_scl_handleKeydown,  false );
    doc.addEventListener("keyup",    bl_scl_handleKeyup,    false );
    doc.addEventListener("keypress", bl_scl_handleKeypress, false );
  }

  bl_scl_util_positionCursor(root,"beforeend");
  bl_scl_normalizeNode(root);
  bl_scl_formatEntryNodes(root);

  var contentEl = bl_scl_util_seekNode(root,"content",false,"childrenOnly",false);
  while (contentEl)
  {
    contentEl.style.cssText = "font-weight:bold;text-decoration:underline;";
    contentEl.contentEditable = false;
    contentEl = bl_scl_util_seekNode(contentEl,"content",false,"childrenFirst",false);
  }
}

function bl_scl_getValue(el)
{
  var doc  = el.contentWindow.document;
  var info = bl_scl_expandToItem(bl_scl_getRootEditableFromDoc(doc),";",true);
  if (info)
  {
    return bl_scl_util_trim(info.text,";");
  }
  
  return "";  
}

function bl_scl_setValue(el,value)
{
  var doc = el.contentWindow.document;
  
  bl_scl_getRootEditableFromDoc(doc).innerHTML = initialValue;
  bl_scl_util_positionCursor(bl_scl_getRootEditableFromDoc(doc),"beforeend");
  bl_scl_normalizeNode(bl_scl_getRootEditableFromDoc(doc));
  bl_scl_formatEntryNodes(bl_scl_getRootEditableFromDoc(doc));
}

function bl_scl_handleDragstart(e)
{
  bl_port_killEvent(e);
  return false;
}

function bl_scl_handleClick(e)
{
  bl_port_killEvent(e);
  return false;
}

function bl_scl_handleMousedown(e)
{
  var targetEl = bl_port_getEventTarget(e);
  var win      = bl_port_docWindow(targetEl.ownerDocument);

  bl_scl_onFocus(win.frameElement);

  var contentEl = bl_scl_util_seekParentNode(targetEl,"content");
  if (contentEl)
  {
    bl_scl_util_selectNode(contentEl);
    bl_port_killEvent(e);
  }
  
  bl_scl_trackCursorPos(win);
}

function bl_scl_handleMouseup(e)
{
  var targetEl = bl_port_getEventTarget(e);
  var win      = bl_port_docWindow(targetEl.ownerDocument);

  var contentEl = bl_scl_util_seekParentNode(targetEl,"content");
  if (contentEl)
  {
    bl_scl_util_selectNode(contentEl);
    bl_port_killEvent(e);
  }
  bl_scl_trackCursorPos(win);
//  bl_scl_enforceCursorPos(win);
}

function bl_scl_handleClick(e)
{
}

function bl_scl_handleDoubleclick(e)
{
  bl_port_killEvent(e);
}

function bl_scl_handleKeydown(e)
{
  var targetEl = bl_port_getEventTarget(e);
  var doc      = targetEl.ownerDocument;
  var win      = bl_port_docWindow(doc);
  var el       = win.frameElement;
  var kcode    = bl_port_keyCode(e);

  if (kcode == 13)
  {
    bl_port_killEvent(e);
  }

  var cursorParent = bl_scl_util_getCursorParent(win);
  if (cursorParent == null)
  {
    return;
  }
  
  var cursorInfo   = bl_scl_util_getCursorInfo(cursorParent,"StartToStart");
  var virtKey      = bl_port_getVirtualKey(kcode);
  
  switch(virtKey)
  {
    // Action keys -- Don't start the timer
    case "enter":  case "esc":    case "tab":

    // Movement keys -- Don't start the timer
    case "up":     case "down":   case "left":    case "right":
    case "home":   case "end":    case "pgup":    case "pgdn":

    // Meta keys -- Don't start the timer
    case "shift":  case "ctrl":   case "alt":
      bl_port_killEvent(e);
      break;

    // Any other key -- Start the timer
    default:
      bl_sys_gs_startTimer(el);
  }

  bl_scl_nextSeekIsLeft = (virtKey == "left" || virtKey == "home");

  if (virtKey == "bksp")
  {
    if (cursorInfo.pos == 0)
    {
      var prev      = bl_scl_util_seekNode(cursorParent,"any",true,"noChildren",false);
      var contentEl = bl_scl_util_seekParentNode(prev,"content");
      if (contentEl)
      {
        bl_scl_removeNode(el,contentEl);
        bl_port_killEvent(e);
      }
    }
    else
    {
      var contentEl = bl_scl_util_seekParentNode(cursorParent,"content");
      if (contentEl)
      {
        bl_scl_removeNode(el,contentEl);
        bl_port_killEvent(e);
      }
      else if (bl_browserInfo.ie)
      {
        // IE has an error sometimes that causes it to put a text node into an
        // invalid state. Manually overriding the backspace behavior when inside
        // a text node seems to alleviate the issue.
        var loc = bl_scl_util_getTextNodeAtPos(cursorParent,cursorInfo.pos,"nextEditable");
        loc.node.replaceData(loc.pos-1,1,"");
        bl_scl_util_setCursorPos(cursorParent,cursorInfo.pos-1,0);
        bl_port_killEvent(e);
      }
    }
  }
  else if (virtKey == "del")
  {
    var text = bl_scl_util_getText(cursorParent);
    if (cursorInfo.pos >= text.length)
    {
      var next = bl_scl_util_seekNode(cursorParent,"any",false,"noChildren",false);
      if (bl_scl_util_seekParentNode(next,"content"))
      {
        bl_scl_removeNode(el,next);
        bl_port_killEvent(e);
      }
    }
    else if ((text == " " || text == "\xA0") && cursorInfo.pos == 0)
    {
        bl_scl_util_positionCursor(cursorParent,"beforeend");
        bl_port_killEvent(e);
    }
  }
  else if (virtKey == "home" || (e.ctrlKey && virtKey == "left"))
  {
    var entryEl = bl_scl_util_seekNode(bl_scl_getRootEditableFromDoc(doc),"entry");
    if (entryEl)
    {
      bl_scl_util_positionCursor(entryEl,"afterstart");
    }
    bl_port_killEvent(e);
  }
  else if (virtKey == "end" || (e.ctrlKey && virtKey == "right"))
  {
    var entryEl = bl_scl_util_seekNode(bl_scl_getRootEditableFromDoc(doc),"entry",true);
    if (entryEl)
    {
      bl_scl_util_positionCursor(entryEl,"beforeend");
    }
    bl_port_killEvent(e);
  }
  else if (virtKey == "left")
  {
    bl_scl_moveCursor(cursorParent,cursorInfo,-1,false);
    bl_port_killEvent(e);
  }
  else if (virtKey == "right")
  {
    bl_scl_moveCursor(cursorParent,cursorInfo,1,false);
    bl_port_killEvent(e);
  }
  else
  {
    var virtEvent   = bl_kb_createVirtualKeyEvent("vkd",e);
    virtEvent.srcEl = el;
    bl_sys_gs_edit_handleKeyDown(virtEvent, el);

    if (virtKey == "tab")
    {
      var topWin = parent.cb_sys_getTopWindow();
      topWin.bl_kb_doTab(!e.shiftKey);
      bl_port_killEvent(e);
    }
  }

  bl_scl_enforceCursorPos(win);
//  var info = bl_scl_expandToItem(bl_scl_getRootEditableFromDoc(doc),";");
}

function bl_scl_handleKeyup(e)
{
  var targetEl = bl_port_getEventTarget(e);
  var doc      = targetEl.ownerDocument;
  var win      = bl_port_docWindow(doc);
  var el       = win.frameElement;

  var topWin      = cb_sys_getTopWindow();
  var virtEvent   = bl_kb_createVirtualKeyEvent("vku",e);
  virtEvent.srcEl = el;
  bl_sys_gs_edit_handleKeyUp(virtEvent, el, el.cb_sys_gs_getValue(el));
  if (virtEvent.defaultPrevented)
  {
    bl_port_preventDefault(e);
  }
  
  var root = bl_scl_getRootEditableFromEl(el);
  var p    = bl_scl_util_getCursorInfo(root,"StartToStart");

  bl_scl_lastCursorPos = p.pos;
}

function bl_scl_handleKeypress(e)
{
  var targetEl = bl_port_getEventTarget(e);
  var doc      = targetEl.ownerDocument;
  var win      = bl_port_docWindow(doc);

//  __bl_scl_renderCursor(win);
}

function bl_scl_moveCursor(cursorParent,cursorInfo,delta,doSelect)
{
  var goLeft, position, needsToSeek;
  if (delta <= 0)
  {
    goLeft      = true;
    needsToSeek = cursorInfo.pos <= 0;
  }
  else
  {
    goLeft      = false;
    needsToSeek = cursorInfo.pos >= bl_scl_util_getText(cursorParent).length;
  }

  if (bl_scl_util_seekParentNode(cursorParent,"content"))
  {
    var entryEl = bl_scl_util_seekNode(cursorParent,"entry",goLeft,"noChildren",false);
    needsToSeek = true;
  }
  
  if (needsToSeek)
  {
    var entryEl = bl_scl_util_seekNode(cursorParent,"entry",goLeft,"noChildren",false);
    if (entryEl)
    {
      if (goLeft)
      {
        bl_scl_util_setCursorPos(entryEl,bl_scl_util_getText(entryEl).length);
      }
      else
      {
        bl_scl_util_setCursorPos(entryEl,0);
      }
    }
  }
  else
  {
    bl_scl_util_setCursorPos(cursorParent,cursorInfo.pos + delta);
  }
}

function _bl_scl_handler(item, el)
{
  var cmd          = item.firstChild;
  var name         = cmd.nodeName;
  
  if (name == "scset")
  {
    var text   = bl_port_get_text(cmd);
    var index  = parseInt(cmd.getAttribute("index"));
    var insert = cmd.getAttribute("insert")=="true";
    var isHtml = cmd.getAttribute("html")=="true";

    if (insert)
    {
      bl_scl_insertText(el,index,text,isHtml);
    }
    else
    {
      bl_scl_replaceText(el,index,text,isHtml);
    }    
  }
  else if (name == "scdel")
  {
    var index = parseInt(cmd.getAttribute("index"));
    bl_scl_removeIndex(el,index);
  }
  else if (name == "invalidate")
  {
    bl_sel_invalidate(el,cmd);
  }
  else
  {
    _bl_sc_handler(item, el);
  }
}

function bl_scl_getNodeByIndex(el,index)
{
  var win  = el.contentWindow;
  var doc  = win.document;
  var body = bl_scl_getRootEditableFromDoc(doc);

  function matchIndex(node)
  {
    return bl_scl_util_isContent(node) && parseInt(node.getAttribute("bl_index")) == index;
  }
  
  var result =  bl_scl_util_seekNode(body,matchIndex);
  return result?result:null;
  
}

function bl_scl_incrementIndexes(refNode,inc)
{
  var node = bl_scl_util_seekNode(refNode,"content",false,"childrenFirst",false);
  while (node)
  {
    var newIndex = parseInt(node.getAttribute("bl_index"))+inc;
    node.setAttribute("bl_index",newIndex);
    node = bl_scl_util_seekNode(node,"content",false,"noChildren",false);
  }
}

function bl_scl_replaceText(el,index,text,isHtml)
{
  var contentEl = bl_scl_getNodeByIndex(el,index);
  if (contentEl)
  {
    if (isHtml)
    {
      contentEl.innerHTML = text;
    }
    else
    {
      while (contentEl.firstChild)
      {
        contentEl.removeChild(contentEl.firstChild);
      }
      contentEl.appendChild(contentEl.ownerDocument.createTextNode(text));
    }
  }
}

function bl_scl_insertText(el,index,text,isHtml)
{
  var win  = el.contentWindow;
  var doc  = win.document;
  var body = bl_scl_getRootEditableFromDoc(doc);
  
  var newContentEl = bl_scl_createContentNode(doc,text,isHtml);
  newContentEl.setAttribute("bl_index",index);
  
  var oldContentEl = bl_scl_getNodeByIndex(el,index);
  body.insertBefore(newContentEl,oldContentEl);
  bl_scl_incrementIndexes(newContentEl,1);
  
  bl_scl_normalizeNode(body);
}

function bl_scl_removeIndex(el,index)
{
  var contentEl = bl_scl_getNodeByIndex(el,index);
  if (contentEl)
  {
    bl_scl_incrementIndexes(contentEl,-1);
    contentEl.parentNode.removeChild(contentEl);
    
    var body = bl_scl_getRootEditableFromEl(el);
    bl_scl_normalizeNode(body);
    bl_scl_formatEntryNodes(body);
  }
}

function bl_scl_removeNode(el,node)
{
  if (bl_port_hasAttribute(node,"bl_index"))
  {
    var index  = node.getAttribute("bl_index");

    bl_scl_incrementIndexes(node,-1)    
    node.parentNode.removeChild(node);
    
    bl_scl_sendRemove(el,index);
  }
}

function bl_scl_sendRemove(el,index)
{
  var xmlStr = '<toremove index="' + index + '"/>';
  bl_mpr_send(xmlStr, el.id, 0);
}

function _bl_scl_updateAfterBlur(id)
{
  var el = document.getElementById(id);
  if (el)
  {
    el.afterBlurTimer = 0;

    var doc  = el.contentWindow.document;
    var root = bl_scl_getRootEditableFromDoc(doc);
    bl_scl_normalizeNode(root);
    bl_scl_formatEntryNodes(root);

    var node = root.firstChild;
    while (node)
    {
      if (node.getAttribute("bl_type") == "entry")
      {
        var text = bl_scl_util_getText(node);
        text     = bl_scl_util_trim(text,";");
        if (text != "")
        {
          bl_scl_util_setCursorPos(node,1,0);
          bl_scl_doInsert(el,-1,"",true,BL_MPR_DEFER);
          
          // The DOM has changed. We need to start over at the beginning.
          node = root.firstChild;
        }
      }
      node = node.nextSibling;
    }

    bl_mpr_send("<noop/>", el.id, 0, BL_MPR_ASAP, true);
  }
}

function bl_scl_doInsert(el,selectIndex,selectText,selectWholeOverride,mprSendType)
{
  if (arguments.length < 4)
  {
    selectWholeOverride = false;
  }
  if (arguments.length < 5)
  {
    mprSendType = BL_MPR_ASAP;
  }

  var doc       = el.contentWindow.document;
  var info      = bl_scl_expandToItem(bl_scl_getRootEditableFromDoc(doc),";",(selectIndex>=0 || selectWholeOverride));
  
  var entryEl   = info.entry;
  var text      = bl_scl_util_trim(info.text,";");
  var selectText= bl_scl_util_trim(selectText);
  var contentEl = null;
  
  if (text != "" || selectText != "")
  {
    bl_scl_sendInsert(el,info.index,text,selectIndex,selectText,mprSendType);
  
    if (text == "")
    {
      contentEl = bl_scl_createContentNode(doc,selectText);
    }
    else
    {
      contentEl = bl_scl_createContentNode(doc,text);
    }
    contentEl.setAttribute("bl_index",info.index);

    entryEl.parentNode.insertBefore(bl_scl_createEntryNode(doc,info.leftText),entryEl);
    entryEl.parentNode.insertBefore(contentEl,entryEl);
    entryEl.parentNode.insertBefore(bl_scl_createEntryNode(doc,info.rightText),entryEl);
    bl_scl_incrementIndexes(contentEl,1);

    entryEl.parentNode.removeChild(entryEl);

    bl_scl_formatEntryNodes(bl_scl_getRootEditableFromDoc(doc));
    bl_scl_util_setCursorPos(contentEl.nextSibling,2);
  }
}

function bl_scl_sendInsert(el,index,text,selectIndex,selectText,mprSendType)
{
  var xmlStr = '<toinsert index="' 
             + index 
             + '" selectindex="' 
             + selectIndex 
             + '"><text>' 
             + bl_port_encodeXml(text) 
             + '</text><seltext>' 
             + bl_port_encodeXml(selectText) 
             + '</seltext></toinsert>';
             
  bl_mpr_send(xmlStr, el.id, -1, mprSendType, true);
}

function bl_scl_trackCursorPos(win)
{
  var ce = null;
  try
  {
    ce = bl_scl_util_getCursorParent(win);
  }
  catch(e)
  {
  }

  if (bl_scl_lastCursorParent != ce)
  {
    bl_scl_lastCursorParent = ce;
    var entryEl = bl_scl_util_seekParentNode(ce,"entry");

    if (entryEl)
    {
      bl_scl_selectedEl = entryEl;
    }
    else
    {
        var contentEl = bl_scl_util_seekParentNode(ce,"content");
        if (contentEl)
        {
          bl_scl_selectedEl = contentEl;
        }
    }
  }

  __bl_scl_renderCursor(win);
}

function bl_scl_enforceCursorPos(win)
{
  bl_scl_normalizeNode(bl_scl_getRootEditableFromDoc(win.document));
  bl_scl_trackCursorPos(win);
  if (bl_scl_lastCursorParent)
  {
    if (bl_scl_util_seekParentNode(bl_scl_lastCursorParent,"content"))
    {
      var entryEl = bl_scl_util_seekNode(bl_scl_lastCursorParent,"entry",bl_scl_nextSeekIsLeft,"noChildren",false);
      if (entryEl)
      {
        if (bl_scl_nextSeekIsLeft)
        {
          bl_scl_util_positionCursor(entryEl,"beforeend");
          bl_scl_nextSeekIsLeft = false;
        }
        else
        {
          bl_scl_util_setCursorPos(entryEl,0);
        }
      }
      else
      {
        bl_scl_util_positionCursor(bl_scl_getRootEditableFromDoc(win.document),"beforeend");
      }
      bl_scl_trackCursorPos(win);
    }
  }
}

function bl_scl_createEntryNode(doc,text)
{
  var node = doc.createElement("SPAN");
  if (bl_browserInfo.safari)
  {
    //node.style.whiteSpace = "pre-wrap";
  }
  node.setAttribute("bl_type","entry");
  node.appendChild(doc.createTextNode(text));
  return node;
}

function bl_scl_createContentNode(doc,text,isHtml)
{
  var node = doc.createElement("SPAN");
  node.setAttribute("bl_type","content");
  node.style.cssText = "font-weight:bold;text-decoration:underline;";
  node.contentEditable = false;
  if (isHtml)
  {
    node.innerHTML = text;
  }
  else
  {
    node.appendChild(doc.createTextNode(text));
  }
  return node;
}




function bl_scl_normalizeNode(rootNode)
{
  // Normalizes the children of a node by placing everything that is not in a
  // content node into an entry node. Ensures that there is an entry node as
  // the first child of the root node, and one following every content node
  // (including the lastcontent node).
  //
  // Any data preceeding the first content node will be coalesced into the
  // first entry node, and any data following the last content node will be
  // coalesced into the last entry node.

  var doc = rootNode.ownerDocument;

  var cursorPos   = bl_scl_util_getCursorInfo(rootNode).pos;
  var lastEntryEl = null;
  var lastType    = "none";
  var buffer      = "";

  var node     = rootNode.firstChild;
  while (node)
  {
    var nextNode = node.nextSibling;
    var blType   = (node.nodeType == 1)?node.getAttribute("bl_type"):null;

    if (blType == "content")
    {
      if (lastType != "entry")
      {
        lastEntryEl = bl_scl_createEntryNode(doc," ");
        rootNode.insertBefore(lastEntryEl,node);
      }

      lastType = "content";
    }
    else if (blType == "entry" && lastType != "entry")
    {
      if (buffer != "")
      {
        node.insertBefore(doc.createTextNode(buffer),node.firstChild);
        buffer = "";
      }

      if (lastEntryEl)
      {
        bl_scl_util_condenseTextNodes(lastEntryEl);
      }

      lastType       = "entry";
      lastEntryEl    = node;
    }
    else
    {
      if (node.nodeType == 1 && node.nodeName != "STYLE")
      {
        buffer += bl_scl_util_getText(node);
      }
      else if (node.nodeType == 3)
      {
        buffer += node.nodeValue;
      }

      if (lastType == "entry" && buffer != "")
      {
        lastEntryEl.appendChild(doc.createTextNode(buffer));
        buffer = "";
      }
      rootNode.removeChild(node);
    }

    node = nextNode;
  }

  if (lastType != "entry")
  {
    lastEntryEl = bl_scl_createEntryNode(doc,"\xA0");
    rootNode.appendChild(lastEntryEl);
  }

  if (buffer != "")
  {
    lastEntryEl.appendChild(doc.createTextNode(buffer));
  }

  bl_scl_util_condenseTextNodes(lastEntryEl);

  if (bl_scl_util_getCursorInfo(rootNode).pos != cursorPos)
  {
    bl_scl_util_setCursorPos(rootNode,cursorPos);
  }
}

function bl_scl_formatEntryNodes(rootNode)
{
  // Corrects any formatting irregularities in the document. This includes
  // removing spaces between a content element and delimiter, and splitting
  // or condensing entry nodes as needed.
  //
  // This requires a normalized DOM to function correctly. This function
  // may cause the cursor to move within the document.

  function createEntries(text,refNode,emptyText,prefix)
  {
    var entryEl = null;
    text        = bl_scl_util_trim(text,";");
    var newText = "";
    if (text != "")
    {
      var entries = text.split(new RegExp(";","i"));

      for (var i=0; i<entries.length; i++)
      {
          var entry = bl_scl_util_trim(entries[i],";");
          if (entry)
          {
            newText += entry + "; ";
          }
      }
    }
    
    if (newText == "")
    {
      newText = emptyText;
    }
    else
    {
      newText = prefix + newText;
    }

    entryEl = bl_scl_createEntryNode(rootNode.ownerDocument,newText);
    rootNode.insertBefore(entryEl,refNode);
  }

  var firstContent = true;
  var lastType     = "none";
  var buffer       = "";

  var node     = rootNode.firstChild;
  while (node)
  {
    var nextNode = node.nextSibling;
    var blType   = (node.nodeType == 1)?node.getAttribute("bl_type"):null;

    if (blType == "entry")
    {
      buffer += bl_scl_util_getText(node);
      rootNode.removeChild(node);
    }
    else if (blType == "content")
    {
      if (firstContent)
      {
        createEntries(buffer,node,"\xA0","");
        firstContent = false;
      }
      else
      {
        createEntries(buffer,node,"; ","; ");
      }
      buffer = "";
    }
    else
    {
      throw "Found unknown node ["+node.nodeName+":\""+bl_scl_util_getText(node)+"] in normalized document!";
    }

    node = nextNode;
  }

  if (firstContent)
  {
    createEntries(buffer,null,"\xA0","");
  }
  else
  {
    createEntries(buffer,null,"; ","; ");
  }
}

function bl_scl_expandToItem(refEl,delim,selectWhole)
{
  bl_scl_normalizeNode(refEl);

  var doc = refEl.ownerDocument;
  var win = bl_port_docWindow(doc);

  var contentEl = null;
  var found     = false;
  var node      = refEl.firstChild;
  var buffer    = "";

  var cursorPar = bl_scl_util_getCursorParent(win);
  if (cursorPar == null)
  {
    bl_scl_util_setCursorPos(refEl,bl_scl_lastCursorPos,0);
    cursorPar = bl_scl_util_getCursorParent(win);
    if (cursorPar == null)
    {
      return;
    }
  }

  var cursorInfo = bl_scl_util_getCursorInfo(cursorPar);
  var cursorLoc  = bl_scl_util_getTextNodeAtPos(cursorPar,cursorInfo.pos,"nextEditable");
  if (cursorLoc == null)
  {
    return;
  }
  var cursorNode = cursorLoc.node;

  while (node)
  {
    if (node.nodeType == 1 && node.getAttribute("bl_type") == "content")
    {
      if (found)
      {
        break;
      }
      contentEl = node;
      buffer    = "";
    }
    else
    {
      var nodeText = bl_scl_util_getText(node);
      if (bl_scl_util_contains(node,cursorNode,true))
      {
        found = true;
      }
      buffer += nodeText;
    }
    node = node.nextSibling;
  }

  if (found)
  {
    if (contentEl)
    {
      var psuedoIndex = parseInt(contentEl.getAttribute("bl_index")) + 1;
      var cursorRefEl = contentEl.nextSibling;
    }
    else
    {
      var psuedoIndex = 0;
      var cursorRefEl = refEl.firstChild;
    }

    var pos = bl_scl_util_getCursorInfo(cursorRefEl,"StartToStart").pos;

    var leftDelimPos  = buffer.lastIndexOf(delim,pos-1);
    var rightDelimPos = selectWhole ? buffer.indexOf(delim,pos) : pos;

    if (rightDelimPos == -1)
    {
      rightDelimPos = buffer.length;
    }

    if (leftDelimPos == -1)
    {
      leftDelimPos = 0;
    }
    else
    {
      leftDelimPos += delim.length;
    }

    var result = {
      index:     psuedoIndex,
      entry:     bl_scl_util_seekNode(cursorRefEl,"entry"),
      text:      buffer.substring(leftDelimPos,rightDelimPos),
      leftText:  buffer.substring(0,leftDelimPos),
      rightText: buffer.substring(rightDelimPos)
    }
    return result;
  }
}


















function bl_scl_util_trim(str,delim)
{
  if (str != undefined)
  {
    // "\xA0", is character #160 (which is &nbsp;). It is not included in the
    // list of whitespace characters.
  
    var r = new RegExp("^[\\s\xA0"+(delim!=undefined?delim:"")+"]*");
    str = str.replace(r,"");
  
    r = new RegExp("[\\s\xA0"+(delim!=undefined?delim:"")+"]*$");
    str = str.replace(r,"");
  }
  return str;
}

function bl_scl_util_getCursorParent(win)
{
  // This assumes there is no selection, just a single point cursor.
  
  if (!win) win = window;

  if (win.getSelection)
  {
    if (win.getSelection().rangeCount < 1)
    {
      return null;
    }

    var selRange = win.getSelection().getRangeAt(0);
    var ctr = selRange.startContainer;
    while (ctr && ctr.nodeType != 1)
    {
      ctr = ctr.parentNode;
    }
    return ctr;
  }
  else
  {
    var sel = win.document.selection.createRange().parentElement();
    if (sel.ownerDocument != win.document)
    {
      // IE doesn't really care where the range is.
      sel = null;
    }
    return sel;
  }
}

function bl_scl_util_selectNode(node)
{
  if (arguments.length < 2)
  {
    select = true;
  }

  var range;

  var doc = node.ownerDocument;
  var win = bl_port_docWindow(doc);

  if (win.getSelection)
  {
    var sel = win.getSelection();
    range = win.document.createRange();

    range.selectNodeContents(node);
    sel.removeAllRanges();
    sel.addRange(range);
  }
  else
  {
    win.document.body.createTextRange();
    range.moveToElementText(node);

    var oldCanEdit = node.contentEditable;
    node.contentEditable = "Inherit";
    range.select();
    node.contentEditable = oldCanEdit;
  }

}

// Positions the cursor in relation to the specified node.
function bl_scl_util_positionCursor(node,relation)
{
  // ASSERT node.parentNode != null
  // ASSERT (node.nodeType == 1)
  //   WHEN (relation="afterstart" OR relation="beforeend")

  var doc = node.ownerDocument;
  var win = bl_port_docWindow(doc);
  
  var posNode;
  if (win.getSelection)
  {
    posNode = doc.createTextNode(" ");
  }
  else
  {
    posNode = doc.createElement("SPAN");
    posNode.innerHTML = "&nbsp;";
  }

  switch (relation.toLowerCase())
  {
    case "before":
    case "beforestart":
    case "beforebegin":
      node.parentNode.insertBefore(posNode,node);
      break;
    
    case "afterstart":
    case "afterbegin":
      node.insertBefore(posNode,node.firstChild);
      break;
      
    case "beforeend":
      node.appendChild(posNode);
      break;
      
    case "after":
    case "afterend":
      node.parentNode.insertBefore(posNode,node.nextSibling);
      break;
  }
  
  if (win.getSelection)
  {
    var sel = win.getSelection();
    var range = win.document.createRange();
    range.setStartBefore(posNode);
    range.setEndAfter(posNode);
    range.collapse(true);

    sel.removeAllRanges();
    sel.addRange(range);
  }
  else
  {
    range = win.document.body.createTextRange();
    range.moveToElementText(posNode);
    range.collapse(true);
    range.select();
  }
  
  posNode.parentNode.removeChild(posNode);
}

function bl_scl_util_isEntry(node)
{
  return (node.nodeType == 1 && node.getAttribute("bl_type") == "entry");
}

function bl_scl_util_isContent(node)
{
  return (node.nodeType == 1 && node.getAttribute("bl_type") == "content");
}

function bl_scl_util_isTextNode(node)
{
  return (node.nodeType == 3);
}

function bl_scl_util_isAnyNode(node)
{
  return true;
}

function bl_scl_util_seekParentNode(el,test)
{
  switch (test)
  {
    case "entry":   test = bl_scl_util_isEntry; break;
    case "content": test = bl_scl_util_isContent; break;
    case "any":     test = bl_scl_util_isAnyNode; break;
    case "text":    test = bl_scl_util_isTextNode; break;
  }

  while (el && el.getAttribute)
  {
    if (test(el))
    {
      return el;
    }
    el = el.parentNode;
  }

  return false;
}

function bl_scl_util_seekNode(refNode,test,reverse,seekPolicy,allowRefNode)
{
  // seekPolicy is a parameter that describes how the tree should be searched.
  // Allowed values are:
  //    childrenFirst - Searches the children of the refNode, and then the
  //                    parents of the refNode.
  //    childrenOnly  - Searches the children of the refNode, but not the parents.
  //    noChildren    - Searches only the parents of the refNode.

  switch (arguments.length)
  {
    case 0:
    case 1:
      throw "bl_scl_util_seekNode requires at least 2 parameters: refNode and testFunction";
    case 2:
      reverse = false;
    case 3:
      seekPolicy = "childrenFirst";
    case 4:
      allowRefNode = true;
  }

  switch (test)
  {
    case "entry":   test = bl_scl_util_isEntry; break;
    case "content": test = bl_scl_util_isContent; break;
    case "any":     test = bl_scl_util_isAnyNode; break;
    case "text":    test = bl_scl_util_isTextNode; break;
  }

  var seekIn = (seekPolicy == "childrenFirst" || seekPolicy == "childrenOnly");
  var seekUp = (seekPolicy == "childrenFirst" || seekPolicy == "noChildren");

  var node = refNode;

  while (node)
  {
    if (test(node))
    {
      if (allowRefNode || node != refNode)
      {
        return node;
      }
    }
  
    if (seekIn)
    {
      var child = reverse?node.lastChild:node.firstChild;
  
      if (child)
      {
        var found = bl_scl_util_seekNode(child,test,reverse,"childrenOnly",true);
        if (found)
        {
          return found;
        }
      }
    }
    else
    {
      // seekIn only applies to the first node passed.
      seekIn = true;
    }
    node = reverse?node.previousSibling:node.nextSibling;
  }
  
  if (seekUp && refNode)
  {
    var par = refNode.parentNode;
    while (par)
    {
      var parentSib = reverse?par.previousSibling:par.nextSibling;
      if (parentSib)
      {
        var found = bl_scl_util_seekNode(parentSib,test,reverse,"childrenFirst",true);
        if (found)
        {
          return found;
        }
        break;
      }
      par = par.parentNode;
    }
  }

  return false;
}

// Gets the cursor position (in characters) from the specified reference
// element. The comparison is based on the "how" parameter. This parameter
// can be one of the following:
//
//   StartToStart - Start of the reference element to the Start of the
//                  selection. This is the default.
//   EndToEnd     - End of the reference element to the End of the selection.
//   EndToStart   - End of the reference element to the Start of the selection.
//   StartToEnd   - Start of the reference element to the End of the selection.
//
// Note: In IE, the cursor info will be calculated and will be innacurate if
// the selection is to the left of the reference element.
function bl_scl_util_getCursorInfo(refEl,how)
{
  var range;
  var text = "";
  var pos  = -1;
  var doc  = refEl.ownerDocument;
  var win  = bl_port_docWindow(doc);

  if (!how)
  {
    how = "StartToStart";
  }

  var toStart   = (how.match(/ToStart$/i));
  var fromStart = (how.match(/^StartTo/i));

  try
  {
    if (win.getSelection && win.getSelection().rangeCount > 0)
    {
      range = win.getSelection().getRangeAt(0).cloneRange();
      range.collapse(toStart);
      range.setStart(refEl,fromStart?0:refEl.childNodes.length);
      text  = range.toString();
      pos   = text.length;
      range.detach();
    }
    else if (doc.selection)
    {
      range   = doc.selection.createRange();
      var r2  = bl_scl_getRootEditableFromDoc(doc).createTextRange();
      r2.moveToElementText(refEl);
      r2.collapse(fromStart);
      r2.setEndPoint((toStart?"EndToStart":"EndToEnd"),range);
      text = r2.text;
      pos  = text.length;
    }
  }
  catch (e)
  {
    // Exceptions can be thrown when dealing with ranges for a large number
    // of reasons. Feel free to comment out this try-catch block if you wish
    // to see which ones we're letting through.
    // alert("getCursor exception: "+e.message);
  }

  return  { pos: pos, text: text };
}

// Note: For FireFox, the entire selection must exist within the same text node.
function bl_scl_util_setCursorPos(refEl,pos,len)
{
  var range;
  var doc = refEl.ownerDocument;
  var win = bl_port_docWindow(doc);

  if (arguments.length < 3)
  {
    len = 0;
  }

  try
  {
    var loc = bl_scl_util_getTextNodeAtPos(refEl,pos,"nextEditable");
    if (loc)
    {
      var node = loc.node;
      pos      = loc.pos;

      if (win.getSelection)
      {
        range = doc.createRange();
        range.selectNode(node);
        range.setStart(node,pos);
        range.setEnd(node,pos+len);

        var sel = win.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        
        var r = sel.getRangeAt(0);
      }
      else
      {
        var oldCanEdit = node.parentNode.contentEditable;
        node.parentNode.contentEditable = "Inherit";

        range = bl_scl_getRootEditableFromDoc(doc).createTextRange();
        range.moveToElementText(node.parentNode);
        range.collapse(true);
        range.move("character",pos);
        if (len > 0)
        {
          range.expand("character",len);
        }
        range.select();

        node.parentNode.contentEditable = oldCanEdit;
      }
      return true;
    }
  }
  catch (e)
  {
    // Exceptions can be thrown when dealing with ranges for a large number
    // of reasons. Feel free to comment out this try-catch block if you wish
    // to see which ones we're letting through.
    // alert("setCursor exception: "+e.message);
  }
  return false;
}

// param canEditPolicy - This parameter controls the behavior of the function
// when a node flagged as non-editable is the target node. Allowed values are
// "allow" and "nextEditable".
function bl_scl_util_getTextNodeAtPos(refEl,pos,canEditPolicy)
{
  var doc = refEl.ownerDocument;
  var win = bl_port_docWindow(doc);
  var node = refEl.firstChild;
  while (node)
  {
    var nodeText   = bl_scl_util_getText(node);
    var nodeLength = nodeText.length;
    if (nodeLength >= pos)
    {
      if (node.nodeType == 3)
      {
        // This is THE node that will contain the specified position.
        var canEdit = true;
        if (canEditPolicy != "allow")
        {
          var p = node.parentNode;
          while (p)
          {
            if (typeof p.contentEditable != "undefined" && p.contentEditable != "inherit")
            {
              canEdit = (p.contentEditable == "true");
              break;
            }
            p = p.parentNode;
          }
        }

        if (!canEdit)
        {
          // Seek to the next text node
          node = bl_scl_util_seekNode(node,"text",false,"noChildren",false);
          pos  = 0;
        }
        
        if (node)
        {
          var result = { node: node, pos: pos };
          return result;
        }
        else
        {
          return null;
        }
      }
      else
      {
        node = node.firstChild;
      }
    }
    else
    {
      pos -= nodeLength;
      if (!node.nextSibling)
      {
        node = bl_scl_util_seekNode(node,"any",false,"noChildren",false);
      }
      else
      {
        node = node.nextSibling;
      }
    }
  }
  return null;
}

function bl_scl_util_condenseTextNodes(el)
{
  // Forces the specified element to contain a single text node.
  // Does NOT store the cursor position.
  // Returns: True if the DOM structure was modified.

  var condensed = false;

  if (el.childNodes.length == 0)
  {
    el.innerHTML = "&nbsp;";
    condensed = true;
  }
  else if (el.childNodes.length > 1 || el.firstChild.nodeType != 3)
  {
    if (el.childNodes.length == 2 && el.firstChild.nodeType == 3 && el.lastChild.nodeName == "BR" && el.nextSibling == null)
    {
      // The browser is allowed to remove all spaces at the beginning and end
      // of each line. Because of this, FireFox browser will add a BR element
    }
    else
    {
      var text = bl_scl_util_getText(el);
      while (el.childNodes.length > 0)
      {
        el.removeChild(el.firstChild);
      }

      var textNode = el.ownerDocument.createTextNode(text);
      el.appendChild(textNode);
      text         = el.innerHTML;
      el.innerHTML = text.replace(/ /g,"&nbsp;");
      condensed = true;
    }
  }
  
  return condensed;
}

function bl_scl_util_getText(node)
{
  if (node.nodeType == 3)
  {
    return node.nodeValue;
  }
  else if (node.nodeType == 1)
  {
    if (typeof node.textContent != "undefined")
    {
      return node.textContent;
    }
    else
    {
      return bl_port_getInnerText(node);
    }
  }
  return "";
}

function bl_scl_util_setText(node,text)
{
  if (node.nodeType == 3)
  {
    node.nodeValue = text;
  }
  else if (node.nodeType == 1)
  {
    if (bl_browserInfo.ie)
    {
      bl_port_setInnerText(node, text);
    }
    else
    {
      while (node.firstChild)
      {
        node.removeChild(node.firstChild);
      }
      node.appendChild(node.ownerDocument.createTextNode(text));
    }
  }
  else
  {
    throw "Unable to set text of node "+node.nodeName+" (nodeType="+node.nodeType+")";
  }
}

function bl_scl_util_contains(parentNode,childNode,canContainSelf)
{
  if (arguments.length < 3)
  {
    canContainSelf = false;
  }

  if (canContainSelf && parentNode == childNode)
  {
    return true;
  }

  while (childNode = childNode.parentNode)
  {
    if (childNode == parentNode)
    {
      return true;
    }
  }
  
  return false;
}


function bl_sys_gs_findPopupWindow(el)
{
  var arg, popup;

  if (el && (arg = el.bl_gs_arg) && (popup = el.bl_gs_popit) && !popup.isDead)
  {
    var pwin = bl_port_docWindow(bl_port_getOverLayDocument(popup));
    
    if (arg.valid(pwin))
    {
      return pwin;
    }
  }
  
  return null;
}

//the assumtion here is that it is called under the
// popup's window contect
function bl_sys_gs_popup_find(subText)
{
  var arg = bl_sys_getMyPopupArg();
  
  if (arg && arg.buddyId)
  {
    var el = document.getElementById(arg.buddyId);
    
    if (el && el.selectMgr)
    {
      var mgr = el.selectMgr;
      return mgr.findSubText(mgr, el, subText);
    }
  }
  return -1;
}

//the assumtion here is that it is called under the
// popup's window contect
function bl_sys_gs_popup_scrollIntoView()
{
  var arg = bl_sys_getMyPopupArg();
  if (arg && arg.buddyId)
  {
    var el = document.getElementById(arg.buddyId);
    
    if (el && el.selectMgr)
    {
      var mgr = el.selectMgr;
      if (mgr.sigRow)
      {
        cb_sel_scrollInView(mgr, mgr.sigRow);
      }
    }
  }
}

//the assumtion here is that it is called under the
// popup's window contect
function bl_sys_gs_popup_deselect()
{
  var arg = bl_sys_getMyPopupArg();
  
  if (arg && arg.buddyId)
  {
    var el = document.getElementById(arg.buddyId);
    
    if (el && el.selectMgr)
    {
      var mgr = el.selectMgr;
      mgr.deselectAll(mgr, true);
    }
  }
}

function bl_sys_gs_doSet()
{
  var arg = bl_sys_getMyPopupArg();
  
  if (arg && arg.buddyId && arg.el.cb_sys_gs_set)
  {
    var el = document.getElementById(arg.buddyId);
    
    if (el && el.selectMgr)
    {
      var mgr   = el.selectMgr;
      var index = mgr.sigSelect;
      var text  = "";
      
      if (index >= 0)
      {
        text = bl_port_getInnerText(mgr.computeRow(el, index));
        mgr.deselectAll(mgr,true);
      }
      arg.el.cb_sys_gs_set(arg.el, index, text);
      frameElement.container.popup_obj.close();
    }
  }
}

function bl_sys_gs_getSelected(item)
{
  var arg = bl_sys_getMyPopupArg();
  
  if (arg && arg.buddyId && arg.el.cb_sys_gs_set)
  {
    var el = document.getElementById(arg.buddyId);
    
    if (el && el.selectMgr)
    {
      var mgr   = el.selectMgr;
      var index = mgr.sigSelect;
      var text  = null;
      
      if (index >= 0)
      {
        text = bl_port_getInnerText(mgr.computeRow(el, index));
      }
      
      item.cb_sys_gs_index = index;
      item.cb_sys_gs_index = text;
    }
  }
}

function bl_sys_gs_processGet(el, item)
{
  item.cb_sys_gs_index = -1;
  item.cb_sys_gs_index = null;
  var pwin = bl_sys_gs_findPopupWindow(el);
  if (pwin)
  {
    pwin.bl_sys_gs_getSelected(item);
  }
}

// this is the on click hook function for
// when the popup get clicked on
function bl_sys_gs_processSet(arg)
{
  var pwin = bl_sys_gs_findPopupWindow(arg.el);
  if (pwin)
  {
    pwin.bl_sys_gs_doSet();
  }
}

function bl_sys_gs_sizePopupToInput(el)
{
  var popup = el.bl_gs_popit;
  if (popup && popup.container)
  {
    var width = el.offsetWidth;
    popup.container.iframe.style.width = width+"px";
  }
}

function bl_sys_gs_finalShowHandler(popupArg)
{

  var el = popupArg.el;
  var subText = popupArg.newSubText = el.cb_sys_gs_getValue(el);
  
  if (popupArg.syncSizeToControl)
  {
    bl_sys_gs_sizePopupToInput(el);
  }
  bl_sys_gs_checkPopupText(el, subText);
}

function bl_sys_gs_popup_handler(el, subText, name, cmd)
{
  bl_sys_gs_setCursor("default");

  if (name == "cb_sc_popup")
  {
    var list = cmd.childNodes;
    
    if (list && list.length)
    {
      el.bl_pending_get = false;
      if (el.bl_gs_popit)
      {
        bl_sys_gs_popup_clear(el);
      }

      // Find the list buddy node      
      var listBuddyNode = cmd.nextSibling;
      while (listBuddyNode && listBuddyNode.nodeName.toLowerCase() != "listbuddy")
      {
        listBuddyNode = listBuddyNode.nextSibling;
      }
      var buddyId = null;
      var arg     = new bl_ov_mprArg(cmd.childNodes, el, false, bl_sys_gs_processSet);

      if (arg.w <= 0)
      {
        el.setAttribute("bl_resize","bl_sys_gs_sizePopupToInput");
        arg.syncSizeToControl = true;
      }
 
      arg.onFinalShowHook = bl_sys_gs_finalShowHandler;
      
      arg.isLive      = true;
      el.bl_gs_popit  = window.bl_sys_popupInvoke(arg);
      el.bl_gs_arg    = arg;
      
      if (el.cb_cleanup_register == undefined)
      {
        bl_sys_addCleanUpCall(el, bl_sys_gs_popup_clear);
        el.cb_cleanup_register = true;
      }
      
      if (listBuddyNode && el.bl_gs_popit)
      {
      // setting to not send shutdown
        bl_port_docWindow(bl_port_getOverLayDocument(el.bl_gs_popit)).bl_close_type = 2;
        arg.buddyId     = bl_port_get_text(listBuddyNode);
        arg.subText     = subText;
        arg.setHappened = el.setHappened;
        
        var buddyEl = bl_port_getOverLayDocument(el.bl_gs_popit).getElementById(arg.buddyId);
        
        if (buddyEl)
        {
          buddyEl.bl_sys_gs_subText = subText;
        }
      }
    }
  }
  else if (name == "get_strings_done")
  {
    var arg     = el.bl_gs_arg;
    arg.newSubText    = null;
    el.bl_pending_get = false;
    
    bl_sys_gs_checkPopupText(el, subText);
    
    
    if (arg.setHappened)
    {
      arg.setHappened = false;
      cb_sys_popup_close(false);
      var pwin = bl_sys_gs_findPopupWindow(el);
      if (pwin)
      {
        pwin.bl_sys_gs_doSet();
      }
    }
  }
  else if (name == "value")
  {
    if (el.bl_gs_popit && el.bl_gs_popit.isOpen)
    {
      bl_sys_gs_checkPopupText(el, subText);
    }
  }
  else if (name == "kill_popup")
  {
    bl_sys_gs_popup_clear(el);
  }
  else
  {
    return false
  }
  return true;
}

function bl_sys_gs_popup_clear(el)
{
  var popit = el.bl_gs_popit;
  el.bl_gs_popit = null;
  
  cb_sys_popup_close(false);
  if (popit && !popit.isDead)
  {
    var pwin = bl_port_docWindow(bl_port_getOverLayDocument(popit));
    
    if (pwin.bl_did)
    {
      _bl_sys_shutdown_window(pwin);
    }
    bl_sys_popupDestroy(popit, el.bl_gs_arg);
  }
  
  el.cb_gs_seed = null;
  el.bl_gs_arg  = null;
}

function bl_sys_gs_setCursor(txt)
{
  document.body.style.cursor = txt;
  if (window.frameElement)
  {
    try
    {
      window.frameElement.style.cursor = txt;
    }
    catch (exception)
    {
    }
  }
}

function bl_sys_gs_clearTimer()
{
  var f = bl_sys_gs_onTimer;
  if (f.timer)
  {
    clearTimeout(f.timer);
    f.timer   = null;
    f.element = null;
  }
}

function bl_sys_gs_onTimer()
{
  var f  = bl_sys_gs_onTimer;
  var el = f.element;
  f.timer   = null;
  f.element = null;
  
  var arg = el.bl_gs_arg;
  if (arg && arg.setHappened)
  {
    arg.setHappened = false;
  }
  else
  {
    var text       = el.cb_sys_gs_getValue(el);
    var triggerCnt = bl_sys_gs_triggerCnt(el);
    if (text.length >= triggerCnt)
    {
      bl_sys_gs_getPopup(el,text);
    }
  }
}

function bl_sys_gs_startTimer(el)
{
  bl_sys_gs_clearTimer();

  var f = bl_sys_gs_onTimer;
  if (el)
  {
    var delay = bl_sys_gs_triggerDelay(el);
  
    f.element = el;
    f.timer = setTimeout(bl_sys_gs_onTimer,delay);
  }
}

function bl_sys_gs_getPopup(el, txt)
{
  var popitExists   = (el.bl_gs_popit && !el.bl_gs_popit.isDead);
  if (!popitExists || el.cb_gs_seed != txt)
  {
    var xmlStr        = '<togetstrings popitExists="' + (popitExists?"true":"false") + '">' + bl_port_encodeXml(txt) + '</togetstrings>';
    el.cb_gs_seed     = txt;
    el.bl_pending_get = true;
    
    if (!window.bl_sys_isInPopup())
    {
      bl_sys_gs_setCursor("wait");
    }
    bl_mpr_send(xmlStr, el.id, 0, BL_MPR_APPEND, true);
  }
}

function bl_sys_gs_triggerCnt(el)
{
  var triggerCntStr = el.getAttribute("cb_sc_count");
  return (triggerCntStr) ? parseInt(triggerCntStr) : 2;
}

function bl_sys_gs_triggerDelay(el)
{
  var triggerDelayStr = el.getAttribute("bl_trigger_delay");
  return (triggerDelayStr) ? parseInt(triggerDelayStr) : 500;
}

function bl_sys_gs_popup_handleKey(event, iskeyup)
{
  var arg   = bl_sys_getMyPopupArg();
  var kcode = bl_port_keyCode(event);
  
  if (arg && arg.buddyId)
  {
    var el = document.getElementById(arg.buddyId);
    if (kcode != 13 &&
        kcode != 37 &&
        kcode != 39 &&
        kcode != 32)
    {
      if (el && el.selectMgr)
      {
        if (iskeyup)
        {
          bl_sel_handleKeyUp(event, el)
        }
        else
        {
          bl_sel_handleKeyDown(event, el)
        }
      }
    }
  }
  if (kcode == 38 || kcode == 40)
  {
    bl_port_stop_event(event);
  }
}


function bl_sys_gs_edit_handleKeyDown(event, el)
{
  var virtKey = event.virtualKey;
  
  try
  {
    if (virtKey == "enter" || virtKey == "tab")
    {
      if (virtKey != "tab")
      {
        bl_port_stop_event(event);
      }
      
      var arg = el.bl_gs_arg;
      arg.setHappened = true;

      var pwin = bl_sys_gs_findPopupWindow(el);
      if (pwin)
      {
        pwin.bl_sys_gs_doSet();
      }
      cb_sys_popup_close(false);
    }
    else
    {
      // it is posible that the popup does not exist yet but we don't have to worry
      // about finding select in this case because when the popup comes up
      // will will do that for us.  so we are catching any errors here and continuing on
      var pwin = bl_sys_gs_findPopupWindow(el);
      if (pwin)
      {
        pwin.bl_sys_gs_popup_handleKey(event, false);
      }
    }
  }
  catch (exception)
  {
    if (virtKey == "enter")
    {
      if (el.bl_pending_get)
      {
        el.setHappened = true;
      }
      else if (el.cb_sys_gs_set)
      {
        el.cb_sys_gs_set(el, -1, "");
        try
        {
          el.bl_gs_popit.close();
        }
        catch (e)
        {
        }
      }
      bl_port_stop_event(event);
    }
  }
}

function bl_sys_gs_edit_handleKeyUp(event, el, subText)
{
  var virtKey = event.virtualKey;
  
  if (virtKey == "shift" || virtKey == "ctrl" || virtKey == "alt")
  {
    // Ignore these meta key strokes.
    return;
  }
  else if (virtKey == "esc")
  {
    cb_sys_popup_close(true);
  }

  var movementKeys = {
    left: true,    up: true,    right: true,    down: true,
    pgup: true,    pgdn: true,    end: true,    home: true
  };

  if (!movementKeys[virtKey] &&
      virtKey != "enter" &&
      virtKey != "tab")
  {
    var clear = false;
    
    if (virtKey == "bksp" || virtKey == "del")
    {
      var cnt = bl_sys_gs_triggerCnt(el);
      var len = subText.length;
      if (len < cnt)
      {
        clear = true;
      }
    }
    
    if (clear)
    {
      // it is posible that the popup does not exist yet but we don't have to worry
      // about finding select in this case because when the popup comes up
      // will will do that for us.  so we are actching any errors here and continuing on
      var pwin = bl_sys_gs_findPopupWindow(el);
      if (pwin)
      {
        pwin.bl_sys_gs_popup_deselect();
        pwin.frameElement.container.popup_obj.close();
      }
    }
    else
    {
      bl_sys_gs_checkPopupText(el, subText);
    }
  }
  else
  {
    // it is posible that the popou does not exist yet but we don't have to worry
    // about finding select in this case because when the popup comes up
    // will will do that for us.  so we are actching any errors here and continuing on
    var pwin = bl_sys_gs_findPopupWindow(el);
    if (pwin)
    {
      pwin.bl_sys_gs_popup_handleKey(event, true);
    }
  }
}

function bl_sys_gs_checkPopupText(el, subText)
{
  try
  {
    var arg   = el.bl_gs_arg;
    var popup = el.bl_gs_popit;
    var doc   = bl_port_getOverLayDocument(popup);
    var cnt   = bl_sys_gs_triggerCnt(el);

    // it is posible that the popou does not exist yet but we don't have to worry
    // about finding select in this case because when the popup comes up
    // will will do that for us.  so we are actching any errors here and continuing on
    if (!el.bl_pending_get    &&
        arg.inited            &&
        subText.length >= cnt &&
        bl_port_docWindow(doc).bl_sys_gs_popup_find(subText) > -1)
    {
      cb_sys_popup_renew(window, popup, arg);
      bl_port_docWindow(doc).bl_sys_gs_popup_scrollIntoView();
    }
    else
    {
      if (!arg.inited || el.bl_pending_get)
      {
        arg.newSubText = subText;
      }
      else
      {
        cb_sys_popup_close(false);
      }
    }
  }
  catch (exception)
  {
  }
}

function bl_sc_getValue(el)
{
  return el.value;
}

function bl_sc_setValue(el,text)
{
  el.value = text;
  el.setAttribute("bl_old_value", text);
}

function _bl_sc_init(id)
{
  var el = document.getElementById(id);
  if (el)
  {
    el.cb_sys_gs_set      = cb_sc_send_set;
    el.cb_sys_gs_getValue = bl_sc_getValue;
    el.cb_sys_gs_setValue = bl_sc_setValue;
  }
}

function _bl_sc_handler(item, el)
{
  var cmd          = item.firstChild;
  var name         = cmd.nodeName;
  
  if (name == "value")
  {
    var text = bl_port_get_text(cmd);
    
    el.cb_sys_gs_setValue(el,text);
  }
  bl_sys_gs_popup_handler(el, el.cb_sys_gs_getValue(el), name, cmd);
}

function _bl_sc_key_up(event, el)
{
  bl_sys_gs_edit_handleKeyUp(event, el, el.cb_sys_gs_getValue(el));
  bl_port_stopPropagation(event);
}

function _bl_sc_key_down(event, el)
{
  bl_sys_gs_edit_handleKeyDown(event, el);
  switch(event.virtualKey)
  {
    // Action keys -- Don't start the timer
    case "enter":  case "esc":    case "tab":
        break;

    // Movement keys -- Don't start the timer
    case "up":     case "down":   case "left":    case "right":
    case "home":   case "end":    case "pgup":    case "pgdn":
        break;

    // Meta keys -- Don't start the timer
    case "shift":  case "ctrl":   case "alt":
        break;

    // Any other key -- Start the timer
    default:
      bl_sys_gs_startTimer(el);
  }
  bl_port_stopPropagation(event);
}

function _bl_sc_mouse_down(event, el)
{
/*
  if (!el.getAttribute("disabled"))
  {
    var fname = el.getAttribute("cb_sc_edit_class");
    if (fname)
    {
      el.className = fname;
    }
    el.cb_sc_in_edit_mode = true
  }
*/
}

function cb_sc_send_set(el, selectIndex, selectText)
{
  var text     = el.cb_sys_gs_getValue(el);
  var oldVal   = el.getAttribute("bl_old_value");
  var send     = (!oldVal || oldVal != text || selectText != oldVal? true : false);
  
  if (send)
  {
    if (text == "")
    {
      send = (el.getAttribute("bl_send_empty_str") != null);
    }
  }
  
  if (send)
  {
    var xmlStr  = '<toset selectindex="' 
                + selectIndex 
                + '"><text>' 
                + bl_port_encodeXml(text) 
                + '</text><seltext>' 
                + bl_port_encodeXml(selectText) 
                + '</seltext></toset>';
                
    bl_mpr_send(xmlStr, el.id, 0);
  }
}


//tab control
function bl_remove_all_tabs(tabEl)
{
  if (tabEl)
  {
    var xmlStr = "<removeAll>-1</removeAll>";
    bl_mpr_send(xmlStr, tabEl.id);
  }
}

function bl_remove_other_tabs(tabEl)
{
  if (tabEl)
  {
    var xmlStr = "<removeOther>-1</removeOther>";
    bl_mpr_send(xmlStr, tabEl.id);
  }
}

function _bl_tabClose()
{
  var arg = bl_sys_getMyPopupArg();
  if (arg)
  {
    var el = arg.customArg;
    el.bl_remove_tab(null, el);
    _bl_sys_popupClose();
  }
}

function _bl_tab_closeOthers(event, el)
{
  var arg = bl_sys_getMyPopupArg();
  if (arg)
  {
    var el = arg.customArg;
    el.bl_remove_other_tabs(el);
    _bl_sys_popupClose();
  }
}

function _bl_tab_closeAll(event, el)
{
  var arg = bl_sys_getMyPopupArg();
  
  if (arg)
  {
    var el = arg.customArg;
    el.bl_remove_all_tabs(el);
    _bl_sys_popupClose();
  }
}

function _bl_tab_show_right_click(event, tabItem)
{
  if (!event)
  {
    event = window.event;
  }

  var item = (tabItem ? tabItem : this);
  var el   = cb_tab_get_element(item);

  if (el && !el.getAttribute("disabled"))
  {
    var src           = bl_port_getEventTarget(event);
    var width         = 194;
    var moreThanOne   = el.firstChild.firstChild.firstChild.childNodes.length > 2;

    var height        = (moreThanOne ? 56 : 20);
    var attributes    = " width=192 height=18 "

    var imageHTML     = bl_sys_button_html("CLOSETAB", "img/rc_close_tab_", "Closes selected tab.", false, "_bl_tabClose", attributes, false, null);
    
    if (moreThanOne)
    {
      imageHTML   += bl_sys_button_html("CLOSEOTHERTABS", 'img/rc_close_other_tabs_', "Closes all tabs, except currently selected.", false, "_bl_tab_closeOthers", attributes, false, null);
      imageHTML   += bl_sys_button_html("CLOSEALLTABS", 'img/rc_close_all_tabs_', "Closes all tabs.", false, "_bl_tab_closeAll", attributes, false, null);
    }
    
    var html = "<script language='javascript'>var bl_version='"
               + bl_version
               + "';</script><div style='overflow:hidden;padding:0px;margin:0px;border:1px solid #9F9F9F;'>";
    html += imageHTML
    html += "</div>";
    
    el.bl_remove_tab        = _bl_tab_delete;
    el.bl_remove_all_tabs   = bl_remove_all_tabs;
    el.bl_remove_other_tabs = bl_remove_other_tabs;

    var argData = { html:html,
                    customArg:el,
                    x:event.clientX,
                    y:event.clientY,
                    w:width,
                    h:height,
                    canDestroy:true,
                    useVeil:true,
                    positionType:"left-top"
                  };

    window.bl_sys_popupInvoke(argData);
    bl_port_killEvent(event);
  }
}

function _bl_tab_ddSelect(id, index)
{
  var el      = document.getElementById(id);
  var ddIndex = el.bl_tab_ddIndex;
  
  if (el.getAttribute("bl_selected") != index && ddIndex != undefined)
  {
    if (ddIndex != index)
    {
      window.setTimeout("_bl_tab_ddSelect('" + id + "'," + ddIndex + ")", 1000);
    }
    else
    {
      var trParent  = el.firstChild.firstChild.firstChild;
      cb_tab_select_item(el, trParent.childNodes.item(index), true, false, false);
      el.bl_tab_ddIndex = undefined;
    }
  }
}

function cb_tab_set_src(item, lsrc, csrc, rsrc)
{
  if (bl_browserInfo.ie && !window.bl_bk_cache)
  {
    /* This IE specific branch is required to prevent the browser from making
     * lots of repeated requests to the server for CSS background image requests.
     * For more info see:
     *   http://misterpixel.blogspot.com/2006/09/forensic-analysis-of-ie6.html
     */
    try 
    {
      window.bl_bk_cache = true;
      document.execCommand("BackgroundImageCache", false, true);
    } 
    catch(err) 
    {
    }
  }

  var list = item.firstChild.firstChild.firstChild.childNodes;
  list[0].firstChild.src         = lsrc;
  list[2].firstChild.src         = rsrc;
  list[1].style.backgroundImage  = "url(" + csrc + ")";
}

function _bl_tab_drop(event, tabItem)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {
    if (!event)
    {
      event = window.event;
    }

    if (!tabItem)
    {
      tabItem = this;
    }
    
    var el = cb_tab_get_element(tabItem);

    if (tabItem && el)
    {
      var index = bl_port_get_cellIndex(tabItem);
      
      if (!ddObj.isTopLeft)
      {
        index++;
      }
      
      var target = { id:el.id, index:index };

      el.bl_indexSent = el.getAttribute("bl_selected");
      bl_dd_procDrop(target);
      ddObj.setHint(null);
      bl_port_killEvent(event);
    }
  }
}

function bl_tab_dragEnd(source, item, dragStarted)
{
  var index         = bl_port_get_cellIndex(item);
  var selectedIndex = source.getAttribute("bl_selected");
  
  if (index != selectedIndex || selectedIndex != source.bl_indexSent)
  {
    cb_tab_select_item(source, item, true, true, true);
  }
}

function bl_tab_inItem(event, item)
{
  if (item)
  {
    var srcEl     = bl_port_getEventTarget(event);
    var top       = event.clientY;
    var left      = event.clientX;
    var itemTop   = bl_sys_real_y(item, null, false);
    var itemLeft  = bl_sys_real_x(item, null, false);
    var el        = cb_tab_get_element(item, false);
    var elLeft    = bl_sys_real_x(el, null, false);
    
    if (left < itemLeft + item.offsetWidth &&
        left > itemLeft                    &&
        top < itemTop + item.offsetHeight  &&
        top > itemTop                      &&
        (elLeft + el.scrollLeft) < left    &&
        (elLeft + el.offsetWidth + el.scrollLeft) > left)
    {
      // This IE branch grabs the IE-specific "toElement" value
      // from the event. This value is later used as an extra check
      // ensure that it isn't inside itself.
      var toEl = (bl_browserInfo.ie ? event.toElement : null);
      
      if (toEl)
      {
        if (!bl_port_contains(item, toEl, false))
        {
          return false;
        }
      }
      return true;
    }
  }
  return false;
}

function _bl_tab_showHide(el, retainSpace, isHide)
{
  var tabElement = _bl_tab_get_editor(el);
  
  if (isHide)
  {
    bl_sys_hide(tabElement);
  }
  else
  {
    bl_sys_show(tabElement);
  }
}

function _bl_tab_enable(el, enable)
{
  var tabElement = _bl_tab_get_editor(el);
  
  if (enable)
  {
    bl_sys_enable(tabElement);
  }
  else
  {
    bl_sys_disable(tabElement);
  }
}

function _bl_tab_ddOut(event, tabItem)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {    
    if (!event)
    {
      event = window.event;
    }

    if (!tabItem)
    {
      tabItem = this;
    }

    var el = cb_tab_get_element(tabItem);
    
    if (bl_tab_inItem(event, el))
    {
      _bl_tab_ddOver(event, tabItem);
    }
    else
    {
      ddObj.clearEffect();
      ddObj.setHint(null);
      cb_tab_mouse(el, tabItem, tabItem, event, "dragleave");
    }
  }
}

function _bl_tab_ddHintDrop(event, hintImage)
{
  _bl_tab_drop(event, this.child);
}

function _bl_tab_ddOver(event, tabItem)
{
  if (!event)
  {
    event = window.event;
  }

  if (!tabItem)
  {
    tabItem = this;
  }

  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {
    var el = cb_tab_get_element(tabItem);
    
    if (el && !bl_port_contains(ddObj.srcContext.item, tabItem, false))
    {
      if (!el.getAttribute("disabled"))
      {
        _bl_tab_mouse(event, tabItem);
        
        if (el.getAttribute("cb_drag_select"))
        {
          var index = bl_port_get_cellIndex(tabItem);
          
          if (el.getAttribute("bl_selected") != index)
          {
            if (el.bl_tab_ddIndex == undefined)
            {
              window.setTimeout("_bl_tab_ddSelect('" + el.id + "'," + index + ")", 1000);
            }
            
            el.bl_tab_ddIndex = index;
          }
        }
        
        if (bl_dd_checkList(ddObj, event, el.getAttribute("bl_zone_list")))
        {
          var clientX = event.clientX;
          var clientY = event.clientY;
          var body    = document.body;
          var offsetX = body.scrollLeft + clientX;
          var offsetY = body.scrollTop + clientY;
          var left    = bl_sys_real_x(el, null, false);

          var hintContext = { child:tabItem,
                              hintDrop:_bl_tab_ddHintDrop,
                              dimension:2,
                              size:tabItem.offsetHeight,
                              x:clientX,
                              y:clientY
                            };

          ddObj.setHint(hintContext);
          
          if (offsetX < left + 30 && el.scrollLeft > 0)
          {
            el.scrollLeft = el.scrollLeft - 30;
          }
          else if (offsetX > ((left + el.offsetWidth) - 30))
          {
            el.scrollLeft = el.scrollLeft + 30;
          }
        }
        
        bl_port_killEvent(event);
        return ;
      }
    }
  
    ddObj.clearEffect();
  }
}

function cb_tab_get_tab_width(el)
{
  var attr = el.getAttribute("cb_tab_width");
  return (attr)? attr:0;
}

function cb_tab_get_cap_width(el)
{
  var attr = el.getAttribute("cb_tab_cap_width");
  return (attr)? attr:5;
}

function cb_tab_get_tab_height(el)
{
  var attr = el.getAttribute("cb_tab_height");
  return (attr)? attr:21;
}

function cb_tab_get_font_style(el)
{
  var attr = el.getAttribute("cb_tab_font");
  return (attr)? attr:"";
}

function cb_tab_get_font_over_style(el)
{
  var attr = el.getAttribute("cb_tab_font_over");
  return (attr)? attr:"";
}

function cb_tab_get_font_selected_style(el)
{
  var attr = el.getAttribute("cb_tab_font_selected");
  return (attr)? attr:"";
}

function cb_tab_get_image(el, name, defaultVal)
{
  var attr = el.getAttribute(name);
  return (attr)? attr:("/" + bl_version + "/res/img/" + defaultVal);
}

function cb_tab_clear_tab(item, el)
{
  cb_tab_set_src(item,
                 cb_tab_get_image(el, "l_tab_en", "tab_left_i.gif"),
                 cb_tab_get_image(el, "c_tab_en", "tab_cent_i.gif"),
                 cb_tab_get_image(el, "r_tab_en", "tab_right_i.gif"));
  var divEl = cb_tab_get_div_from_tab(item);
  divEl.style.cssText = cb_tab_get_font_style(el);
}

function _bl_tab_mouse_over(event, tabItem)
{
  if (!event)
  {
    event = window.event;
  }

  var srcEl = bl_port_getEventTarget(event);
  var item  = (tabItem ? tabItem : this);

  if (item)
  {
    if (bl_port_contains(item, srcEl, true))
    {
      _bl_tab_mouse(event, item);
    }
    else
    {
      cb_tab_mouse(cb_tab_get_element(item), item, srcEl, event, "mouseout");
    }
  }
}

function _bl_tab_mouse_leave(event, tabItem)
{
  if (!event)
  {
    event = window.event;
  }

  var item  = (tabItem ? tabItem : this);
  
  if (!bl_tab_inItem(event, item))
  {
    _bl_tab_mouse(event, item);
  }
}

function cb_tab_mouse(el, item, srcEl, event, type)
{
  if (el && !el.getAttribute("disabled") && cb_tab_get_selected(el) != item && (item && item.getAttribute("bl_dropTab") == null))
  {
    if (!item.cb_tab_over && (type == "dragover" ||
                              type == "dragenter" || 
                              type == "mouseover" || 
                              type == "mousemove"))
    {
      item.cb_tab_over = true;
      cb_tab_set_src(item,
                     cb_tab_get_image(el, "l_tab_ov", "tab_left_io.gif"),
                     cb_tab_get_image(el, "c_tab_ov", "tab_cent_io.gif"),
                     cb_tab_get_image(el, "r_tab_ov", "tab_right_io.gif"));
      
      var divEl = cb_tab_get_div_from_tab(item);
      divEl.style.cssText = cb_tab_get_font_over_style(el);
    }
    else if (item.cb_tab_over && (type == "mouseout" || type == "dragleave") && !bl_tab_inItem(event, item))
    {
      item.cb_tab_over = false;
      cb_tab_clear_tab(item, el);
    }
  }
}

function _bl_tab_mouse(event, tabItem)
{
  var srcEl = bl_port_getEventTarget(event);
  var item  = (tabItem ? tabItem : this);
  var el    = cb_tab_get_element(item);
  if (el)
  {
    cb_tab_mouse(el, item, srcEl, event, event.type);
  }
}

function _bl_tab_get_editor(ed)
{
  var edTag = ed.getAttribute("cb_tag");
  while (ed && !edTag)
  {
    ed    = ed.parentNode;
    edTag = ed.getAttribute("cb_tag");
  }
  return ed;
}

function _bl_tab_key_down(event, tabItem)
{
  var el    = cb_tab_get_element(bl_port_getEventTarget(event));
  var kcode = bl_port_keyCode(event);
  var ed    = _bl_tab_get_editor(tabItem);
  
  if (kcode == 46 && (ed && ed.getAttribute("bl_supressDel") == null))
  {
    if (el.cb_focus == undefined)
    {
      el.cb_focus = 0;
    }
    el.cb_focus++;
    _bl_tab_delete(null, el);
  }
  else if (kcode == 39)
  {
    cb_tab_move_select(el, true);
  }
  else if (kcode == 37)
  {
    cb_tab_move_select(el, false);
  }
  
  bl_port_stop_event(event);
}

function cb_tab_move_select(el, moveDown)
{
  var selected = cb_tab_get_selected(el);
  if (selected)
  {
    var newSelect = null;
    if (moveDown)
    {
      if (selected.nextSibling)
      {
        newSelect = selected.nextSibling;
        if (newSelect.firstChild && newSelect.firstChild.tagName == "IMG")
        {
          newSelect = null;
        }
      }
    }
    else
    {
      newSelect = selected.previousSibling;
    }
    if (newSelect && newSelect.childNodes.length)
    {
      cb_tab_select_item(el, newSelect, true, false, true);
    }
  }
}

function bl_tab_dragInner(event)
{
  var item    = this.item;
  var tabDiv  = cb_tab_get_div_from_tab(item);

  return "<div style='white-space:nowrap;width:" 
        + item.offsetWidth 
        + "px;height=" 
        + item.offsetHeight 
        + "px'>" 
        + tabDiv.innerHTML 
        + "</div>";
}

function _bl_tab_mouse_down(event, tabItem)
{
  if (!event)
  {
    event = window.event;
  }

  var item = (tabItem ? tabItem : this);
  var el   = cb_tab_get_element(item);
  
  bl_kb_focusOnElement(bl_port_getEventTarget(event));

  if (el && !el.getAttribute("disabled") && item.getAttribute("bl_dropTab") == null)
  {
    item.cb_tab_over = false;
    
    bl_port_stop_event(event);
    
    var selected = cb_tab_get_selected(el);
    
    if (bl_port_isLeftDown(event) && el.getAttribute("bl_zone") != null)
    {
      var cellIndex  = bl_port_get_cellIndex(item);
      var srcContext = { source:el, 
                         item:item,
                         did:window.bl_did,
                         indexes:[cellIndex], 
                         dragEnd:bl_tab_dragEnd, 
                         computeShadow:bl_tab_dragInner
                       };
                       
      if (bl_dd_detect(event, srcContext))
      {
        if (selected != item)
        {
          cb_tab_set_selected(el, item, true);
        }
        else
        {
          el.bl_indexSent = cellIndex;
        }
      }
    }
    else if (selected != item)
    {
      cb_tab_select_item(el, item, true, false, true);
    }
  }
}

function _bl_tab_delete(event, el)
{
  if (el)
  {
    var xmlStr = "<delete>-1</delete>";
    bl_mpr_send(xmlStr, el.id);
  }
}

function _bl_tab_resize(tableEl)
{
  var divId = tableEl.getAttribute("bl_tab_id");
  var divEl = document.getElementById(divId);
  bl_tab_checkScrollButtons(divEl);
}

function bl_tab_checkScrollButtons(divEl)
{
  var id      = divEl.id;
  var leftEl  = document.getElementById(id+"ScrollLeft");
  var rightEl = leftEl.nextSibling;

  if (divEl.scrollWidth <= divEl.clientWidth)
  {
    leftEl.style.visibility  = "hidden";
    rightEl.style.visibility = "hidden";
    divEl.scrollLeft         = 0;
  }
  else
  {
    leftEl.style.visibility  = "visible";
    rightEl.style.visibility = "visible";
  }
}

function _bl_tab_scroll(event, el)
{
  var isLeft    = el.getAttribute("bl_scroll_left") != null;
  var stepSize  = parseInt(el.getAttribute("bl_scroll_step"));
  var divEl     = null;
  
  if (el.parentNode.tagName == "DIV")
  {
    divEl = el.parentNode.parentNode.parentNode.firstChild.firstChild;
  }
  else
  {
    divEl = el.parentNode.parentNode.firstChild.firstChild;
  }
  
  if (divEl)
  {
    if (isLeft)
    {
      divEl.scrollLeft = divEl.scrollLeft - stepSize;
    }
    else
    {
      divEl.scrollLeft = divEl.scrollLeft + stepSize;
    }
  }
}

function cb_tab_get_tab_div(el)
{
  while (el && !el.onmouseover)
  {
    el = el.parentNode;
  }
  return el;
}

function cb_tab_get_selected(el)
{
  var index    = el.getAttribute("bl_selected");
  var selected = null;
  
  if (index != null)
  {
    var childList = el.firstChild.firstChild.firstChild.childNodes;
    
    if (index >= 0 && index < childList.length-1)
    {
      selected = childList[index];
    }
  }
  return selected;
}

function cb_tab_set_selected(el, item, focus)
{
  var selected = cb_tab_get_selected(el);
  
  if (selected)
  {
    cb_tab_clear_tab(selected, el);
  }
  cb_tab_set_src(item,
                 cb_tab_get_image(el, "l_tab_do", "tab_left_a.gif"),
                 cb_tab_get_image(el, "c_tab_do", "tab_cent_a.gif"),
                 cb_tab_get_image(el, "r_tab_do", "tab_right_a.gif"));
  
  var divEl = cb_tab_get_div_from_tab(item);
  divEl.style.cssText = cb_tab_get_font_selected_style(el);
  el.setAttribute("bl_selected", bl_port_get_cellIndex(item));
  if (item.offsetLeft < el.scrollLeft)
  {
    item.firstChild.scrollIntoView(true);
  }
  else if ((item.offsetLeft + item.offsetWidth) > ((el.offsetLeft + el.offsetWidth) + el.scrollLeft))
  {
    el.scrollLeft += (item.offsetLeft + item.offsetWidth) - ((el.offsetLeft + el.offsetWidth) + el.scrollLeft)
  }
  if (focus)
  {
    bl_port_focus(el);
  }
}

function cb_tab_select_item(el, item, sendToServer, force, focus)
{
  if (el)
  {
    var tabElement = _bl_tab_get_editor(el);
    item = cb_tab_get_tab_div(item);
    if (force || (!tabElement.getAttribute("disabled") && cb_tab_get_selected(el) != item))
    {
      cb_tab_set_selected(el, item, focus);
      
      if (item.getAttribute("bl_dropTab") == null && sendToServer)
      {
        var cellIndex = bl_port_get_cellIndex(item);
        var xmlStr = "<changed>" + cellIndex + "</changed>";
        el.bl_indexSent = cellIndex;
        bl_mpr_send(xmlStr, el.id, 1);
      }
    }
  }
}

function cb_tab_get_element(item)
{
  var el = item;
  if (item && item.tagName != "DIV")
  {
    el = item.parentNode;
    if (item.tagName == "IMG")
    {
      el = el.parentNode;
    }
    
    while (el && el.tagName != "DIV")
    {
      el = el.parentNode;
    }
  }
  
  return el;
}

function cb_tab_get_tab(el, index)
{
  var returnVal = null;
  try
  {
    var tableEl = el.firstChild;
    var row     = tableEl.firstChild.firstChild;
    returnVal   = row.childNodes.item(index);
  }
  catch (exception)
  {
  }
  return returnVal;
}

function cb_tab_get_div_from_tab(item)
{
  return item.firstChild.firstChild.firstChild.childNodes[1].firstChild;
}

function cb_tab_tooltip_changed(el, item)
{
  var index = parseInt(bl_port_get_text(item.lastChild));
  var el    = cb_tab_get_tab(el, index);
  
  if (el)
  {
    el.title = bl_port_get_text(item.firstChild);
  }
}

function cb_tab_label_changed(el, item)
{
  var index = parseInt(bl_port_get_text(item.lastChild));
  var el    = cb_tab_get_tab(el, index);
  
  if (el)
  {
    var divEl         = cb_tab_get_div_from_tab(el);
    var img           = divEl.firstChild;
    var contentLength = blu_setElContent(divEl, item.firstChild);
    
    if (img && img.tagName == "IMG")
    {
      img.style.marginRight = (contentLength)? "3px":"0px";
      bl_port_insertAdjacentElement(divEl, "afterbegin", img);  
    }
  }
}

function cb_tab_icon_changed(el, item)
{
  var index = parseInt(bl_port_get_text(item.lastChild));
  var el    = cb_tab_get_tab(el, index);
  cb_tab_change_icon(el, bl_port_get_text(item.firstChild));
}

function cb_tab_change_icon(el, icon)
{
  if (el)
  {
    var divEl = cb_tab_get_div_from_tab(el);
    var img   = divEl.firstChild;
    
    if (img && img.tagName == "IMG")
    {
      if (icon.length)
      {
        var height       = img.height;
        img.src          = icon;
        img.style.height = height;
      }
      else
      {
        divEl.removeChild(img);
      }
    }
    else
    {
      var img   = document.createElement("<img>");
      var style = img.style;
      
      img.src = icon;
      
      if (bl_port_getInnerText(divEl).length)
      {
        style.marginRight = "3px";
      }
      
      style.verticalAlign = "middle";
      bl_port_insertAdjacentElement(divEl, "afterBegin", img);
    }
  }
}

function cb_tab_set(el, item)
{
  var index = parseInt(bl_port_get_text(item.lastChild));
  var el    = cb_tab_get_tab(el, index);
  if (el)
  {
    var data     = item.firstChild.childNodes;
    var divEl    = cb_tab_get_div_from_tab(el);
    var iconText = bl_port_get_text(data[1]);
    
    el.title = bl_port_get_text(data[2]);
    blu_setElContent(divEl, data[0]);
    
    if (iconText.length)
    {
      cb_tab_change_icon(el, bl_port_get_text(data[1]));
    }
  }
}

function bl_tab_add(el, item, index, dropLabel, allowDel)
{
  var row         = el.firstChild.firstChild.firstChild;
  var localIndex  = -1;
  
  if (dropLabel == null)
  {
    var firstNode = cb_tab_get_tab(el, 0);
    var lastChild = item.lastChild;
    var selIndex  = el.getAttribute("bl_selected");
    
    if (firstNode && firstNode.getAttribute("bl_dropTab") != null)
    {
      cb_tab_remove(el, null, true);
    }
    localIndex = (lastChild.tagName == "index" ? parseInt(bl_port_get_text(lastChild)) : -1);
  }
  
  if (index != undefined)
  {
    localIndex = index;
  }
  
  if (localIndex < 0)
  {
    localIndex = row.childNodes.length - 1;
  }
  else if (selIndex >= localIndex)
  {
    el.setAttribute("bl_selected", ++selIndex);
  }
  
  var label   = null;
  var icon    = null;
  var tooltip = null;
  var cell    = row.insertCell(localIndex);
  
  if (dropLabel != null)
  {
    label = dropLabel;
    cell.setAttribute("bl_dropTab", "");
  }
  else
  {
    var data = item.firstChild.childNodes;
    
    label   = bl_port_get_text(data[0]);
    icon    = bl_port_get_text(data[1]);
    tooltip = bl_port_get_text(data[2]);
  }
  
  var tabWidth   = cb_tab_get_tab_width(el);
  var tabHeight  = cb_tab_get_tab_height(el);
  var cellStyle  = cell.style;
  
  cellStyle.height = tabHeight + "px";
  
  if (tabWidth)
  {
    cellStyle.width = tabWidth + "px";
  }
  
  cellStyle.whiteSpace   = 'nowrap';
  if (tooltip && tooltip.length)
  {
    cell.title = tooltip;
  }

  if (bl_browserInfo.safari)
  {
    // Safari doesn't support the expando mouse events on TD elements,
    // so we have to use setAttribute.
    cell.setAttribute("onmouseover","_bl_tab_mouse_over(event,this)");
    cell.setAttribute("onmouseout", "_bl_tab_mouse_leave(event,this)");
    cell.setAttribute("onmousedown","_bl_tab_mouse_down(event,this)");
  
    if (allowDel != undefined)
    {
      cell.setAttribute("oncontextmenu","_bl_tab_show_right_click(event,this)");
    }
  
    cell.setAttribute("ondragleave","_bl_tab_ddOut(event,this)");
    cell.setAttribute("ondragover", "_bl_tab_ddOver(event,this)");
    cell.setAttribute("ondrop",     "_bl_tab_drop(event,this)");
    cell.setAttribute("ondragenter","_bl_tab_ddOver(event,this)");
  }
  else
  {
    cell.onmouseover = _bl_tab_mouse_over;
    cell.onmouseout  = _bl_tab_mouse_leave;
    cell.onmousedown = _bl_tab_mouse_down;
    if (allowDel != undefined)
    {
      cell.oncontextmenu = _bl_tab_show_right_click; 
    }
    cell.ondragleave    = _bl_tab_ddOut;
    cell.ondragover     = _bl_tab_ddOver;
    cell.ondrop         = _bl_tab_drop;
    cell.ondragenter    = _bl_tab_ddOver;
  }

  var leftImg   = cb_tab_get_image(el, "l_tab_en", "tab_left_i.gif");
  var rightImg  = cb_tab_get_image(el, "r_tab_en", "tab_right_i.gif");
  var centerImg = cb_tab_get_image(el, "c_tab_en", "tab_cent_i.gif");
  var fontStyle = cb_tab_get_font_style(el);
  var innerHTML = "<table unselectable style='height:100%;width:";
  
  if (tabWidth)
  {
    innerHTML += tabWidth + "px";
  }
  else
  {
    innerHTML += "100%";
  }
  
  innerHTML += "' cellspacing='0' cellpadding='0'><tbody><tr><td><img cb_tab_left=true src='" 
             + leftImg 
             + "' height='" 
             + tabHeight 
             + "px'/></td><td style='white-space:nowrap;background-repeat:repeat-x;background-image:url(" 
             + centerImg 
             + ");height:" 
             + tabHeight 
             + "px'><div unselectable style='" 
             + fontStyle 
             + "' class='bl_tab_Text'>";
  
  if (icon && icon.length)
  {
    innerHTML += "<img unselectable style='vertical-align:middle;";
    
    if (label && label.length)
    {
      innerHTML += "margin-right:3px;";
    }
    
    innerHTML += "' src='" 
               + icon 
               + "'/>";
  }
  
  if (label && label.length)
  {
    innerHTML += label;
  }
  
  innerHTML += "</div></td><td><img cb_tab_right=true src=\"" 
             + rightImg 
             + "\" height='"  
             + tabHeight 
             + "px'/></td></tr></tbody></table>";
                 
  cell.innerHTML = innerHTML;
  
  if (dropLabel != null)
  {
    cb_tab_set_selected(el, cell);
  }
}

function cb_tab_remove(el, item, isDrop)
{
  var index     = (isDrop ? 0 : parseInt(bl_port_get_text(item)));
  var selIndex  = el.getAttribute("bl_selected");
  var recompute = false;
  
  if (selIndex > index)
  {
    selIndex--;
    el.setAttribute("bl_selected", selIndex);
  }
  else if (selIndex == index)
  {
    el.setAttribute("bl_selected", -1);
  }
  
  var tabToRemove = cb_tab_get_tab(el, index);
  var tr = null;
  
  if (tabToRemove)
  {
    tr = tabToRemove.parentNode;
    tr.removeChild(tabToRemove);
    
    // If the user is viewing a portion of the tab control beyond it's scrollWidth,
    // we need to scroll the user to the left until they can only see the contents
    // of the tab control.
    var div = tr.parentNode.parentNode.parentNode;
    if (div.scrollLeft + div.offsetWidth > div.scrollWidth)
    {
      div.scrollLeft = div.scrollWidth - div.offsetWidth;
    }
  }
  if (tr && tr.childNodes.length == 1)
  {
    el.setAttribute("bl_selected", -1);
    
    if (!isDrop)
    {
      bl_tab_add(el, null, 0, bl_port_get_text(item.nextSibling), true);
    }
  }
}

function cb_tab_removeAll(el, item, addDropItem)
{
  var trParent  = el.firstChild.firstChild.firstChild;
  var nodes     = trParent.childNodes;
  var length    = nodes.length - 1;
  
  for (var i = length - 1; i >= 0; i--)
  {
    trParent.deleteCell(i);
  }
  
  el.setAttribute("bl_selected", -1);
  
  if (addDropItem)
  {
    // No need to adjust scrolling here, because adding a default NULL tab
    // should cause the scrolling to occur.
    bl_tab_add(el, null, 0, bl_port_get_text(item), true);
  }
}

function cb_tab_move(el, item)
{
  var oldIndex = parseInt(bl_port_get_text(item.firstChild));
  var newIndex = parseInt(bl_port_get_text(item.lastChild));
  var selIndex = el.getAttribute("bl_selected");
  
  if (selIndex == oldIndex)
  {
    selIndex = newIndex;
  }
  else if (oldIndex > selIndex && newIndex <= selIndex)
  {
    selIndex++;
  }
  else if (oldIndex < selIndex && newIndex > selIndex)
  {
    selIndex--;
  }
  if (oldIndex < newIndex)
  {
    newIndex++;
  }
  el.setAttribute("bl_selected", selIndex);
  var tabToMove = cb_tab_get_tab(el, oldIndex);
  var newIndex  = cb_tab_get_tab(el, newIndex);
  if (tabToMove)
  {
    tabToMove.parentNode.removeChild(tabToMove);
    bl_port_insertAdjacentElement(newIndex, "beforeBegin", tabToMove);
  }
}

function bl_tab_addList(el, item)
{
  var lastChild   = item.lastChild;
  var childNodes  = item.childNodes;
  var len         = childNodes.length;
  var index       = -1;
  
  if (lastChild.tagName == "index")
  {
    index  = parseInt(bl_port_get_text(lastChild));
    len   -= 1;
  }
  
  for (var i = 0; i < len; i++)
  {
    var current      = childNodes.item(i);
    var allowDelete  = current.getAttribute("bl_allowDel") != null;
    var currentIndex = (index >= 0)? index++:-1;

    bl_tab_add(el, current, currentIndex, null, allowDelete);
  }
}

function bl_tab_sizeScrollDelete(scdlParent)
{
  var node = scdlParent.firstChild;
  var width = 0;
  while (node)
  {
    if (node.style.display != "none")
    {
      width += node.offsetWidth;
    }
    node = node.nextSibling;
  }
  
  while (scdlParent.nodeName != "TD")
  {
    scdlParent.style.width = width+"px";
    scdlParent             = scdlParent.parentNode;
  }
  scdlParent.style.width = width+"px";
}

function bl_tab_scrollCh(el, item)
{
  var id        = bl_port_get_text(item.firstChild);
  var show      = parseInt(bl_port_get_text(item.lastChild));
  var scrollBut = document.getElementById(id);
  
  if (scrollBut)
  {
    var leftStyle   = scrollBut.style;
    var rightStyle  = scrollBut.nextSibling.style;
    
    if (show)
    {
      rightStyle.display = 'inline';
      leftStyle.display  = 'inline';
    }
    else
    {
      rightStyle.display = 'none';
      leftStyle.display  = 'none';
    }
    
    bl_tab_sizeScrollDelete(scrollBut.parentNode);
  }
}

function bl_tab_deleteCh(el, item)
{
  var id     = bl_port_get_text(item.firstChild);
  var show   = parseInt(bl_port_get_text(item.lastChild));
  var delBut = document.getElementById(id);
  
  if (delBut)
  {
    delBut.style.display = (show)? 'inline':'none';
    bl_tab_sizeScrollDelete(delBut.parentNode);
  }
}

function _bl_tab_handler(item, el)
{
  var val   = item.firstChild;
  var name  = val.nodeName;
  
  if (name == "value")
  {
    var index = parseInt(bl_port_get_text(val), 10);
    var childList = el.firstChild.firstChild.firstChild.childNodes;
    
    if (index >= 0 && index < childList.length)
    {
      el.bl_indexSent = index;
      cb_tab_set_selected(el, childList[index], el.cb_focus);
      if (el.cb_focus)
      {
        el.cb_focus--;
      }
    }
  }
  else if (name == "clearSelect")
  {
    var index = parseInt(bl_port_get_text(val), 10);
    var childList = el.firstChild.firstChild.firstChild.childNodes;
    
    if (index >= 0 && index < childList.length)
    {
      if (el.getAttribute("bl_selected") == index)
      {
        el.setAttribute("bl_selected", -1);
      }
      cb_tab_clear_tab(childList[index], el);
    }
  }
  else if (name == "deleteCh")
  {
    bl_tab_deleteCh(el, val);
  }
  else if (name == "scrollCh")
  {
    bl_tab_scrollCh(el, val);
  }
  else if (name == "toolTipChanged")
  {
    cb_tab_tooltip_changed(el, val);
  }
  else if (name == "labelChanged")
  {
    cb_tab_label_changed(el, val);
  }
  else if (name == "iconChanged")
  {
    cb_tab_icon_changed(el, val);
  }
  else if (name == "add")
  {
    var allowDelete = val.getAttribute("bl_allowDel") != null;
    bl_tab_add(el, val, undefined, null, allowDelete);
  }
  else if (name == "set")
  {
    cb_tab_set(el, val);
  }
  else if (name == "remove")
  {
    cb_tab_remove(el, val, false);
  }
  else if (name == "removeAll")
  {
    cb_tab_removeAll(el, val, true);
  }
  else if (name == "invalidate")
  {
    el.setAttribute("bl_selected", -1);
    cb_tab_removeAll(el, item, false);
    bl_tab_addList(el, item);
  }
  else if (name == "move")
  {
    cb_tab_move(el, val);
  }
  else if (name == "addList")
  {
    bl_tab_addList(el, val, false);
  }
  else if (name == "removeList")
  {
    var childNodes = item.childNodes;
    for (var i = 0; i < childNodes.length; i++)
    {
      cb_tab_remove(el, childNodes.item(i), false);
    }
  }
  bl_tab_checkScrollButtons(el);
}

function _bl_tab_init(id)
{
  var divEl = document.getElementById(id);
  if (divEl)
  {
    bl_tab_checkScrollButtons(divEl);
  }
}


function _bl_timer_handler(item, el)
{
  var cmd     = item.firstChild;
  var cmdName = cmd.nodeName;

  if (cmdName == "frequency")
  {
    el.setAttribute("cb_timer_freq", bl_port_get_text(cmd));
  }
  else if (cmdName == "timerShowState")
  {
    el.setAttribute("cb_timer_state", bl_port_get_text(cmd));
  }
  else if (cmdName == "count")
  {
    el.setAttribute("cb_timer_count", bl_port_get_text(cmd));
  }
}

function _bl_timer_fire(id)
{
  var el = document.getElementById(id);

  if (el)
  {
    var count = cb_timer_computeCount(el, false);
    
    if (!el.getAttribute("disabled"))
    {
      var isShowing = false;
      var xmlStr    = "<timerFired>" + count + "</timerFired>";
      
      if (el.getAttribute("cb_timer_state") != null && el.getAttribute("cb_timer_show") != null)
      {
        isShowing = true;
        if (el.getAttribute("bl_retainspace") != null)
        {
          el.style.visibility = "visible";
        }
        else
        {
          el.style.display = "inline";
        }
      }
      
      bl_mpr_send(xmlStr, id, 0, BL_MPR_ASAP, true);
      
      if (isShowing)
      {
        if (el.getAttribute("bl_retainspace") != null)
        {
          el.style.visibility = "hidden";
        }
        else
        {
          el.style.display = "none";
        }
      }
    }
    
    cb_timer_startTimer(el, id, count);
  }
}

function cb_timer_computeCount(el, isInit)
{
  var countStr = el.getAttribute("cb_timer_count");
  var count    = (countStr == null)? -1:parseInt(countStr);
  
  if (count > 0)
  {
    if (!isInit)
    {
      count--;
    }
    countStr = "" + count;
    el.setAttribute("cb_timer_count", countStr);
  }
  
  return count;
}

function cb_timer_startTimer(el, id, count)
{
  if (count != 0)
  {
    var freqStr  = el.getAttribute("cb_timer_freq");
    var freq     = (freqStr == null) ? 60000 : parseInt(freqStr);
    window.setTimeout("_bl_timer_fire(" + id + ")", freq);
  }
}

function _bl_timer_init(id)
{
  var el = document.getElementById(id);
  
  if (el)
  {
    cb_timer_startTimer(el, id, cb_timer_computeCount(el, true));
  }
}


//***********************************************************************
//***********************************************************************
//********                     bl_tree.js                       *********
//***********************************************************************
//***********************************************************************
function cb_tree_get_parent(element)
{
  var retVal = null;
  var el = (element.getAttribute("bl_is_root") != null ? element.parentNode: element.parentNode.parentNode);
  if (el.getAttribute("bl_tree_node") != null)
  {
    retVal = el;
  }
  else
  {
    var rootChild = el.firstChild;
    if (rootChild.getAttribute("bl_is_root") != null)
    {
      retVal = rootChild;
    }
  }
  return retVal;
}

function cb_tree_get_item(element)
{
  while (element && !bl_port_hasAttribute(element,"bl_tree_node"))
  {
    element = element.parentNode;
  }
  return element;
}

function cb_tree_ex_icon_child(item)
{
  return item.childNodes[0];
}

function cb_tree_icon_child(item)
{
  return item.childNodes[1];
}

function cb_tree_text_child(item)
{
  return item.childNodes[2];
}

function cb_tree_span_child(item)
{
  if (item.getAttribute("bl_is_root") != null && item.getAttribute("bl_show_root") == null)
  {
    return item.parentNode.lastChild;
  }
  return item.childNodes[3];
}

function cb_tree_remove_span(item)
{
  var span = cb_tree_span_child(item);
  if (span)
  {
    if (item.getAttribute("bl_is_root") != null && item.getAttribute("bl_show_root") == null)
    {
      item.parentNode.removeChild(span);
    }
    else
    {
      item.removeChild(span);
    }
  }
  return span;
}

function cb_tree_get_context(childID)
{
  var child = document.getElementById(childID);
  while (child && child.getAttribute("bl_is_root") == null)
  {
    if (child.getAttribute("bl_root_parent") != null)
    {
      child = child.firstChild;
    }
    else
    {
      child = child.parentNode;
    }
  }
  return child;
}

function bl_tree_getStyleType(node)
{
  if (node == cb_tree_getCurrentNode(node.id))
  {
    return 1;
  }
  return 0;
}

function cb_tree_clearHilight(id)
{
  var root = cb_tree_get_context(id);

  if (root)
  {
    var cur = root.treeCurrentHilight;
    if (cur)
    {
      var type = (root.currentNode == cur)? 1:0;
      
      bl_tree_setStyle(cur, type, root.hasFocus);
    }
    root.treeCurrentHilight = null;
  }
}

function cb_tree_getSendExpand(childID)
{
  var root = cb_tree_get_context(childID);
  return (root ? root.getAttribute("bl_expand_notify") != null : false);
}

function cb_tree_getHasFocus(childID)
{
  var root = cb_tree_get_context(childID);
  return (root ? root.hasFocus : false);
}

function bl_tree_setCurrentHilight(childID, current)
{
  var root = cb_tree_get_context(childID);
  if (root)
  {
    root.treeCurrentHilight = current;
  }
}

function bl_tree_getCurrentHilight(childID)
{
  var root = cb_tree_get_context(childID);
  return (root ? root.treeCurrentHilight : null);
}

function bl_tree_setCurrentNode(node, value, contextId)
{
  var id   = (contextId != undefined ? contextId : node.id);
  var root = cb_tree_get_context(id);
  if (root)
  {
    root.currentNode  = value;
  }
}

function cb_tree_getCurrentNode(childID)
{
  var root = cb_tree_get_context(childID);
  return (root ? root.currentNode : null);
}

function cb_tree_setCurrentFocusNode(node)
{
  var root = cb_tree_get_context(node.id);
  if (root)
  {
    root.currentFocusNode = node;
  }
}

function cb_tree_getCurrentFocusNode(childID)
{
  var root = cb_tree_get_context(childID);
  return (root ? root.currentFocusNode : null);
}

function cb_tree_setMouseDownNode(id, node)
{
  var root = cb_tree_get_context(id);
  if (node)
  {
    node.sendToServer = true;
  }
  if (root)
  {
    root.mouseDownNode = node;
  }
}

function bl_tree_mouseDownNode(id)
{
  var root = cb_tree_get_context(id);
  return (root ? root.mouseDownNode : null);
}

function cb_tree_setFocus(node)
{
  var root = cb_tree_get_context(node.id);
  if (root)
  {
    root.currentNode = node;
    bl_port_focus(root.parentNode);
  }
}

function cb_tree_setCurrentRightClickNode(id, node)
{
  var root = cb_tree_get_context(id);
  if (root)
  {
    if (node)
    {
      root.rCount++;
    }
    else
    {
      root.rCount = 0;
    }
    if (!node || root.rCount == 1)
    {
      root.currentRightClickNode = node;
    }
  }
}

function cb_tree_getCurrentRightClickNode(childID)
{
  var root = cb_tree_get_context(childID);
  return root.currentRightClickNode;
}

function bl_tree_focus_changed(event, el, focusIn)
{
  if (!event)
  {
    event = window.event;
  }
  
  var src      = bl_port_getEventTarget(event);
  var node     = cb_tree_get_item(src);
  var rootNode = null;
  
  if (node)
  {
    rootNode = cb_tree_get_context(node.id);
  }
  else
  {
    var rNode = el.firstChild;
    
    if (rNode && rNode.parentNode == src)
    {
      rootNode = rNode;
    }
  }
  
  if (rootNode)
  {
    rootNode.hasFocus = focusIn;
    var current       = rootNode.currentNode;
  
    if (current)
    {
      // we are setting it to a selected state
      bl_tree_setStyle(current, 1, focusIn);
    }
  }
}

function _bl_tree_parent_focus_out(event, el)
{
  bl_tree_focus_changed(event, el, false);
}

function _bl_tree_parent_focus(event, el)
{
  bl_tree_focus_changed(event, el, true);
}

function _bl_tree_context_menu(event, el)
{
  if (!event)
  {
    event = window.event;
  }
  
  var treeNode  = cb_tree_get_item(bl_port_getEventTarget(event));
  if (treeNode)
  {
    var cNode = cb_tree_getCurrentNode(treeNode.id);
    
    if (cNode && cNode.getAttribute("bl_show_context") == null)
    {
      bl_port_stop_event(event);
    }
  }
}

function cb_tree_getObjectID(elementID, singleInstance)
{
  var val    = new String(elementID);
  var index  = val.indexOf(".");
  if (index != -1)
  {
    val = val.substring(index + 1, val.length);
  }
  if (singleInstance)
  {
    index = val.indexOf("_");
    if (index != -1)
    {
      val = val.substring(0, index);
    }
  }
  return val;
}

function _bl_tree_on_sel_start(event, el)
{
  if (!event)
  {
    event = window.event;
  }
  
  bl_port_stop_event(event);
}

function cb_tree_sendRemove(event, tNode)
{
  if (event && tNode)
  {
    var id      = tNode.id;
    var xmlStr  = '<remove shiftDown="'
                + (event.shiftKey ? 'true"' : 'false"')
                + '><id>'
                + cb_tree_getObjectID(id, true)
                + '</id></remove>';
    
    // send the data to the server
    var par = cb_tree_get_context(id).parentNode;
    
    //async done, forced to async, dirty flag false
    bl_mpr_send(xmlStr, par.id);
  }
}

function _bl_tree_item_dbl_click(event, el, isReturn)
{
  if (!event)
  {
    event = window.event;
  }
  
  var src     = bl_port_getEventTarget(event);
  var item    = cb_tree_get_item(src);
  var handled = false;
  var tNode   = (item ? cb_tree_getCurrentNode(item.id) : null);
  if (tNode)
  {
    var tChild = cb_tree_text_child(tNode);
    
    if ((tNode == item || 
         bl_port_contains(tChild, src, true) || 
         src == cb_tree_icon_child(tNode)) && src != cb_tree_ex_icon_child(tNode))
    {
      handled = true;
      
      // send the data to the server
      var id              = tNode.id;
      var root            = cb_tree_get_context(id);
      var par             = root.parentNode;
      var closeOnDblClick = root.getAttribute("bl_dbl_click_close") != null;
      var parent          = cb_tree_get_parent(tNode);
      
      if (!closeOnDblClick && root.getAttribute("bl_exp_dbl_click") != null)
      {
        cb_tree_ex_image_node_clicked(tNode, event);
      }
      
      var xmlStr  = "<dblclick><id>"
                  + cb_tree_getObjectID(id, true)
                  + "</id>";
      
      if (parent)
      {
        xmlStr += "<parentId>";
        xmlStr += cb_tree_getObjectID(parent.id, true);
        xmlStr += "</parentId>";
      }
      
      xmlStr += "</dblclick>";
      
      //async done, forced to async, dirty flag false
      bl_mpr_send(xmlStr, par.id);
      if (closeOnDblClick)
      {
        window._bl_sys_closeWindow('Ok');
      }
    }
  }
  if (!handled && item && !bl_browserInfo.firefox)
  {
    var exNode = cb_tree_ex_icon_child(item);
    
    if (src == exNode)
    {
      cb_tree_ex_image_node_clicked(item, event);
    }
  }
  bl_port_stop_event(event);
}

function bl_tree_getDragContext(dragNode, id, ddObj)
{
  var xmlStr      = "<dragNodeId>";
  var parTreeNode = cb_tree_get_parent(dragNode);
  var dropType    = null;
  
  if (bl_tree_getCurrentHilight(id) != null)
  {
    dropType = "on";
  }
  else
  {
    dropType = (ddObj && ddObj.isTopLeft)? "before":"after";
  }
  
  xmlStr  += cb_tree_getObjectID(dragNode.id, true);
  xmlStr  += "</dragNodeId><path>";
  xmlStr  += cb_tree_getSelectPath(dragNode);
  xmlStr  += "</path>";
  
  if (parTreeNode)
  {
    xmlStr += "<dragNodeParentId>";
    xmlStr += cb_tree_getObjectID(parTreeNode.id, true);
    xmlStr += "</dragNodeParentId>";
  }
  if (dropType.length)
  {
    xmlStr += "<dropType>";
    xmlStr += dropType;
    xmlStr += "</dropType>";
  }
  return xmlStr;
}

function _bl_tree_move(event, el)
{
  var srcEl = bl_port_getEventTarget(event);
  
  if (srcEl)
  {
    var last = el.bl_lastFlyover;
    var root = el.firstChild;
    var item = cb_tree_get_item(srcEl);
    
    if (item != last)
    {
      if (last)
      {
        var type = (root.currentNode == last)? 1:0;
        bl_tree_setStyle(last, type, root.hasFocus);
      }
      
      if (item)
      {
        var span   = cb_tree_span_child(item);
        var expand = item.getAttribute("bl_expand") != null;

        el.bl_lastFlyover = item;
        
        var type = (root.currentNode == item)? 1:2;
        bl_tree_setStyle(item, type, (root.hasFocus || type == 1));
      }
      else
      {
        el.bl_lastFlyover = null;
      }
      
      bl_port_stop_event(event);
    }
  }
}

function _bl_tree_leave(event, el)
{
  var last = el.bl_lastFlyover;
  var root = el.firstChild;
  
  if (last)
  {
    var type = (root.currentNode == last)? 1:0;
    bl_tree_setStyle(last, type, root.hasFocus);
    el.bl_lastFlyover = null;
  }
}

function _bl_tree_item_clicked(event, el)
{
  if (!event)
  {
    event = window.event;
  }
  
  bl_kb_focusOnElement(bl_port_getEventTarget(event));
  
  var src           = bl_port_getEventTarget(event);
  var selectElement = true;
  var item          = cb_tree_get_item(src);
  
  if (item)
  {
    var span       = cb_tree_span_child(item);
    var exNode     = cb_tree_ex_icon_child(item);
    var text       = cb_tree_text_child(item);
    var icon       = cb_tree_icon_child(item);
    var id         = item.id;
    var expand     = item.getAttribute("bl_expand") != null;
    var root       = cb_tree_get_context(id);
    var editorNode = root.parentNode;
    
    if (exNode == src)
    {
      selectElement = bl_port_hasAttribute(root,"bl_select_on_expand");
      cb_tree_ex_image_node_clicked(item, event);
    }
    else if (src == span || (expand && bl_port_offsetToItem(event, src).y > span.offsetTop))
    {
      selectElement = false;
    }
    else if (bl_port_isLeftDown(event) && bl_port_hasAttribute(editorNode,"bl_zone"))
    {
      var rClickNode = cb_tree_getCurrentRightClickNode(id);
      
      if (rClickNode && item == cb_tree_getCurrentNode(id))
      {
        bl_tree_setCurrentNode(item, null);
      }
      
      cb_tree_setMouseDownNode(id, item);
      cb_tree_setCurrentRightClickNode(id, null);
      
      var srcContext = { source:editorNode, 
                         item:item, 
                         did:window.bl_did,
                         indexes:[0], 
                         dragEnd:bl_tree_dragEnd, 
                         computeShadow:bl_tree_dragInner,
                         dragContext:bl_tree_getDragContext(item, "", null)
                       };
      
      if (!bl_dd_detect(event, srcContext))
      {
        cb_tree_setMouseDownNode(id, null);
      }
    }
    
    if (selectElement)
    {
      var rightClickId = (bl_port_isRightDown(event) ? id : undefined);
      
      if (item)
      {
        if (rightClickId == undefined)
        {
          bl_sys_checkDialogSelect(el);    
        }
        cb_tree_nodeChangeSelect(item, true, rightClickId);
      }
    }
    bl_port_stop_event(event);
  }
}

function bl_tree_dragInner(event)
{
  var item  = this.item;
  var str   = "";
  var image = cb_tree_icon_child(item);
  var text  = cb_tree_text_child(item);
  
  if (image)
  {
    str = bl_port_getOuterHTML(image);
  }
  
  if (text)
  {
    str += bl_port_getOuterHTML(text);
  }
  
  return str;
}

function _bl_tree_key_down(event, el)
{
  if (!event)
  {
    event = window.event;
  }
  
  var node    = el.firstChild.currentNode;
  var handle  = false;
  
  if (node)
  {
    var expand = node.getAttribute("bl_expand") != null;
    var root   = cb_tree_get_context(node.id);
    var kcode  = bl_port_keyCode(event);
    
    if (root && root.getAttribute("bl_remove") != null && kcode == 46)
    {
      cb_tree_sendRemove(event, node);
      handle = true;
    }
    else if (kcode == 13)
    {
      _bl_tree_item_dbl_click(event, node, true);
      handle = true;
    }
    else if (kcode == 38)
    {
      if (node.getAttribute("bl_is_root") != null)
      {
        if (expand)
        {
          cb_tree_expandClicked(node, true);
        }
      }
      else
      {
        cb_tree_nodeSelect(node, 1);
      }
      handle = true;
    }
    else if (kcode == 40)
    {
      if (node.getAttribute("bl_is_root") != null && !expand)
      {
        cb_tree_expandClicked(node, true);
      }
      else
      {
        cb_tree_nodeSelect(node, 0);
      }
      handle = true;
    }
    else if (kcode == 32 || (kcode == 39 && !expand) || (kcode == 37 && expand))
    {
      cb_tree_expandClicked(node, true);
      handle = true;
    }
  }
  if (handle)
  {
    bl_port_killEvent(event);
  }
}

function cb_tree_ex_image_node_clicked(node, event)
{
  cb_tree_expandClicked(node, true);
  bl_port_stopPropagation(event);
}

function cb_tree_clean_node(node, contextId, childrenOnly)
{
  var cNode = cb_tree_getCurrentNode(contextId);
  if (node == cNode)
  {
    bl_tree_setCurrentNode(node, null, contextId);
  }
  var span = cb_tree_span_child(node);
  if (span)
  {
    var list  = span.childNodes;
    var len   = list.length;
    for (var i = 0; i < len; i++)
    {
      cb_tree_clean_node(list[i], contextId, false);
    }
  }
}

function cb_tree_nodeRemove(item, index)
{
  var span = cb_tree_span_child(item);
  if (span)
  {
    cb_tree_node_remove_obj(item, span.childNodes.item(index), true);
  }
}

function cb_tree_clear_expand(node, span)
{
  var isRoot    = node.getAttribute("bl_is_root") != null;
  var showRoot  = node.getAttribute("bl_show_root") != null;
  if (!isRoot || showRoot)
  {
    span.style.display = "none";
    node.removeAttribute("bl_expand");
  }
}

function cb_tree_node_remove_obj(item, nodeToRemove, permanent)
{
  var prevNode  = nodeToRemove.previousSibling;
  var nextNode  = nodeToRemove.nextSibling;
  var parent    = cb_tree_get_parent(nodeToRemove);
  if (nodeToRemove.getAttribute("bl_is_root") == null)
  {
    var parSpan = cb_tree_span_child(parent);
    if (parSpan)
    {
      parSpan.removeChild(nodeToRemove);
      cb_tree_nodeComputeExImage(parent);
      if (parSpan.childNodes.length == 0)
      {
        parent.className = 'bl_tree';
        cb_tree_clear_expand(parent, parSpan);
      }
    }
  }
  else
  {
    parent.removeChild(nodeToRemove);
  }
  if (prevNode)
  {
    cb_tree_nodeComputeExImage(prevNode);
  }
  if (nextNode)
  {
    cb_tree_nodeComputeExImage(nextNode);
  }
  if (permanent)
  {
    cb_tree_clean_node(nodeToRemove, parent.id, false);
  }
}

function cb_tree_moveElement(item, oldIndex, newIndex)
{
  var span      = cb_tree_span_child(item);
  var nodes     = (span ? span.childNodes : null);
  if (nodes)
  {
    var childItem = nodes.item(oldIndex);
    if (childItem != null)
    {
      cb_tree_node_remove_obj(item, childItem, false);
      cb_tree_node_insert(item, childItem, "", newIndex);
      if (childItem.getAttribute("bl_expand") != null)
      {
        if (!childItem.nextSibling)
        {
          childItem.className = "bl_tree";
        }
        else
        {
          childItem.className = "bl_treeEx";
        }
      }
    }
  }
}

function cb_tree_node_insert(item, node, html, index)
{
  var prevNode  = null;
  var nextNode  = null;
  var root      = (item.getAttribute("bl_is_root") != null ? item : cb_tree_get_context(item.id));
  var span      = cb_tree_span_child(item);
  if (span)
  {
    var nodes     = span.childNodes;
    var prevLen   = nodes.length;
    if (index >= 0 && prevLen > index)
    {
      nextNode  = nodes.item(index);
      prevNode  = nextNode.previousSibling;
    }
    else
    {
      prevNode = (prevLen ? nodes.item(prevLen - 1) : null);
      nextNode = null;
    }
    if (node)
    {
      if (index >= 0 && nextNode)
      {
        span.insertBefore(node, nextNode);
      }
      else
      {
        span.appendChild(node);
      }
    }
    else
    {
      if (index >= 0 && nextNode)
      {
        bl_port_insertAdjacentHTML(nextNode, "beforebegin", html);
      }
      else
      {
        bl_port_insertAdjacentHTML(span, "beforeend", html);
      }
    }
    if (prevNode)
    {
      var exState = prevNode.getAttribute("bl_expand") != null;
      if (exState)
      {
        prevNode.className = 'bl_treeEx';
      }
      cb_tree_nodeComputeExImage(prevNode);
    }
    if (nextNode)
    {
      cb_tree_nodeComputeExImage(nextNode);
    }
    if (node)
    {
      cb_tree_nodeComputeExImage(node);
    }
    if (nodes.length == 1)
    {
      cb_tree_nodeComputeExImage(item);
    }
  }
}

function cb_tree_nodeSelect(item, up)
{
  if (up)
  {
    if (item.getAttribute("bl_is_root") == null)
    {
      var prevSib = item.previousSibling;
      if (prevSib)
      {
        var prevSpan  = cb_tree_span_child(prevSib);
        var nodes     = (prevSpan ? prevSpan.childNodes : null);
        if (prevSib.getAttribute("bl_expand") != null && (nodes && nodes.length))
        {
          node     = nodes.item(nodes.length - 1);
          var span = cb_tree_span_child(node);
          nodes    = (span ? span.childNodes : null);
          while (node.getAttribute("bl_expand") != null && (nodes && nodes.length))
          {
            node  = nodes.item(nodes.length - 1);
            span  = cb_tree_span_child(node);
            nodes = (span ? span.childNodes : null);
          }
          cb_tree_nodeChangeSelect(node, true);
        }
        else
        {
          cb_tree_nodeChangeSelect(prevSib, true);
        }
      }
      else
      {
        cb_tree_nodeChangeSelect(cb_tree_get_parent(item), true);
      }
    }
  }
  else
  {
    var span  = cb_tree_span_child(item);
    var nodes = (span ? span.childNodes : null);
    if (item.getAttribute("bl_expand") != null && (nodes && nodes.length))
    {
      cb_tree_nodeChangeSelect(nodes.item(0), true);
    }
    else
    {
      if (item.nextSibling)
      {
        cb_tree_nodeChangeSelect(item.nextSibling, true);
      }
      else
      {
        var node = cb_tree_get_parent(item);
        while (node && !node.nextSibling && node != cb_tree_get_context(node.id))
        {
          node = cb_tree_get_parent(node);
        }
        var next = node.nextSibling;
        if (next && next.id != "")
        {
          cb_tree_nodeChangeSelect(next, true);
        }
      }
    }
  }
}

function bl_tree_setChildStyle(child, textColor, saveOff, top)
{
  if (!top)
  {
    var color = child.style.color; 
    
    if (saveOff)
    {
      if (color != "" || color != textColor)
      {
        if (child.bl_oldColor == undefined)
        {
          child.bl_oldColor  = color;
        }
        child.style.color  = textColor;
      }
    }
    else
    {
      if (child.bl_oldColor != undefined)
      {
        child.style.color = child.bl_oldColor;
      }
    }
  }
  var list  = child.childNodes;
  var len   = list.length;
  for (var i = 0; i < len; i++)
  {
    if (!bl_port_isTextNode(list[i]))
    {
      bl_tree_setChildStyle(list[i], textColor, saveOff, false);
    }
  }
}

function cb_tree_nodeChangeSelect(node, sendToServer, rightClickId)
{
  var rightClick = false;
  if (node.getAttribute("bl_is_root") == null || node.getAttribute("bl_show_root") != null)
  {
    var hasFocus = cb_tree_getHasFocus(node.id);
    var cNode    = cb_tree_getCurrentNode(node.id);
    var root     = cb_tree_get_context(node.id);
    
    cb_tree_setCurrentRightClickNode(node.id, null); 
    if (rightClickId != undefined)
    {
      cb_tree_setCurrentRightClickNode(node.id, cNode);
      rightClick = true;
    }
    
    if (cNode && cNode != node)
    {
      // we are setting it to a non selected state
      bl_tree_setStyle(cNode, 0, hasFocus);
    }
    
    // we are setting it to a selected state
    bl_tree_setStyle(node, 1, hasFocus);
    
    bl_tree_setCurrentNode(node, node);
    if (node.parentNode.style.display != "none")
    {
      cb_tree_scroll_into(node);
    }
    if (!bl_tree_mouseDownNode(node.id) && sendToServer)
    {
      node.sendToServer = false;
      cb_tree_sendSelectToServer(node, rightClick);
    }
  }
}

function cb_tree_scroll_into(node)
{
  var textChild     = cb_tree_text_child(node);
  cb_sel_scrollInView(null, textChild);
}

function bl_tree_setStyle(node, type, hasFocus)
{
  var textChild = cb_tree_text_child(node);
  
  if (textChild)
  {
    var root    = cb_tree_get_context(node.id);
    var saveOff = false;
    
    if (type == 0)
    {
      textChild.style.cssText = "margin-left:3px;";
    }
    else if (type == 1)
    {
      if (hasFocus)
      {
        textChild.style.cssText = root.parentNode.getAttribute("bl_active");
        saveOff                 = true;
      }
      else
      {
        textChild.style.cssText = root.parentNode.getAttribute("bl_inactive");
      }
    }
    else if (type == 2)
    {
      textChild.style.cssText = root.parentNode.getAttribute("bl_flyover");
      saveOff                 = true;
    }
    
    bl_tree_setChildStyle(textChild, textChild.style.color, saveOff, true);
  }
}

function cb_tree_nodeRemoveAllChildren(node, inRecur)
{
  var span  = cb_tree_span_child(node);
  var nodes = (span ? span.childNodes : null);
  if (nodes)
  {
    for (var i = nodes.length - 1; i >= 0; i--)
    {
      var cNode = nodes[i];
      cb_tree_nodeRemoveAllChildren(cNode, true);
      cb_tree_node_remove_obj(node, cNode, true);
    }
  }
  if (!inRecur)
  {
    cb_tree_nodeComputeExImage(node);
  }
}

function cb_tree_nodeRemoveAll(item)
{
  cb_tree_clean_node(item, item.id, true);
  var span = cb_tree_span_child(item);
  if (span)
  {
    span.lastChild.innerHTML = "";
  }
  cb_tree_nodeComputeExImage(item);
}

function cb_tree_expandClicked(currElem, notifyExpandState)
{
  if (currElem)
  {
    var id = currElem.id;
    if (!currElem.cb_expand_requested)
    {
      if (currElem.getAttribute("bl_loaded") == null)
      {
        currElem.cb_expand_requested = true;
        cb_tree_sendToServer(currElem, "expand", false);
      }
      else
      {
        var span = cb_tree_span_child(currElem);
        if (span && span.childNodes.length)
        {
          var exState = currElem.getAttribute("bl_expand") != null;
          if (exState)
          {
            currElem.className = 'bl_tree';
            span.style.display = "none";
          }
          else
          {
            if (currElem.nextSibling)
            {
              currElem.className = 'bl_treeEx';
            }
            span.style.display = "block";
          }
          if (cb_tree_getSendExpand(id) && notifyExpandState)
          {
            cb_tree_sendToServer(currElem, (exState ? "collapseState" : "expandState"), true);
          }
          
          if (exState)
          {
            currElem.removeAttribute("bl_expand");
          }
          else
          {
            currElem.setAttribute("bl_expand", true);
          }
        }
        else
        {
          currElem.removeAttribute("bl_expand");
        }
        cb_tree_nodeComputeExImage(currElem);
        currElem.expanding = false;
      }
    }
  }
}

function cb_tree_nodeComputeExImage(item)
{
  var imageName;
  if (item.getAttribute("bl_is_root") != null)
  {
    imageName = cb_tree_nodeComputeExImageName(item, "_begin");
  }
  else
  {
    var node = cb_tree_get_parent(item);
    var prev = item.previousSibling;
    if (node && node.getAttribute("bl_is_root") != null && node.getAttribute("bl_show_root") == null && (!prev || prev.tagName == "IMG"))
    {
      if (!item.nextSibling)
      {
        imageName = cb_tree_nodeComputeExImageName(item, "_begin");
      }
      else
      {
        imageName = cb_tree_nodeComputeExImageName(item, "_no_root");
      }
    }
    else
    {
      if (!item.nextSibling)
      {
        imageName = cb_tree_nodeComputeExImageName(item, "_end");
      }
      else
      {
        imageName = cb_tree_nodeComputeExImageName(item, "");
      }
    }
  }
  var exImage = cb_tree_ex_icon_child(item);
  if (exImage)
  {
    exImage.src = imageName;
  }
}

function cb_tree_nodeComputeExImageName(item, subName)
{
  var str;
  var root      = (item.getAttribute("bl_is_root") != null ? item : cb_tree_get_context(item.id));
  var span      = cb_tree_span_child(item);
  var showLines = root.getAttribute("bl_show_lines") != null;
  var nodes     = (span ? span.childNodes : null);
  
  if (!showLines)
    item.style.backgroundImage = "none";

  if ((nodes && nodes.length) || item.getAttribute("bl_loaded") == null)
  {
    if (item.getAttribute("bl_expand") != null)
    {
      if (!showLines)
      {
        str = "/" + bl_version + "/res/img/contract_node_no_edge.gif";
      }
      else
      {
        str = "/" + bl_version + "/res/img/contract_node" + subName + ".gif";
      }
    }
    else
    {
      if (!showLines)
      {
        str = "/" + bl_version + "/res/img/expand_node_no_edge.gif";
      }
      else
      {
        str = "/" + bl_version + "/res/img/expand_node" + subName + ".gif";
      }
    }
  }
  else
  {
    if (!showLines)
    {
      str = "/" + bl_version + "/res/img/node_empty.gif";
    }
    else
    {
      str = "/" + bl_version + "/res/img/node" + subName + ".gif";
    }
  }
  return str;
}

function cb_tree_expandSelectPath(item)
{
  var id      = item.id;
  if (item.getAttribute("bl_is_root") == null)
  {
    item = cb_tree_get_parent(item);
    while (item.getAttribute("bl_is_root") == null)
    {
      var span = cb_tree_span_child(item);
      if (span && span.childNodes.length)
      {
        if (item.nextSibling)
        {
          item.className = 'bl_treeEx';
        }
        span.style.display = "block";
        item.setAttribute("bl_expand", true);
        cb_tree_nodeComputeExImage(item);
      }
      item    = cb_tree_get_parent(item);
    }
    var span = cb_tree_span_child(item);
    if (span && span.childNodes.length)
    {
      span.style.display = "block";
      item.setAttribute("bl_expand", true);
      cb_tree_nodeComputeExImage(item);
    }
  }
}

function cb_tree_getSelectPath(item)
{
  var id      = item.id;
  var selPath = new String(cb_tree_getObjectID(id, true));
  if (item.getAttribute("bl_is_root") == null)
  {
    item = cb_tree_get_parent(item);
    while (item.getAttribute("bl_is_root") == null)
    {
      selPath = cb_tree_getObjectID(item.id, true) + "." + selPath;
      item    = cb_tree_get_parent(item);
    }
    selPath = cb_tree_getObjectID(item.id, true) + "." + selPath;
  }
  return selPath;
}

function _bl_tree_clearSelect(el)
{
  var rootNode = el.firstChild;
  
  if (rootNode)
  {
    var current = rootNode.currentNode;
  
    if (current)
    {
      // we are setting it to a non selected state
      bl_tree_setStyle(current, 0, false);
      rootNode.currentNode = null;
      bl_mpr_send("<deselectAll/>", el.id, 0);
    }
  }
}

function cb_tree_sendSelectToServer(item, isRightClick)
{
  var xmlStr = "<select><path>"
              + cb_tree_getSelectPath(item)
              + "</path><id>"
              + cb_tree_getObjectID(item.id, true)
              + "</id>";
              
  if (isRightClick)
  {
    xmlStr += "<rClk>true</rClk>"
  }
  
  var itemParent = cb_tree_get_parent(item);
  
  if (itemParent)
  {
    xmlStr += "<parentId>";
    xmlStr += cb_tree_getObjectID(itemParent.id, true);
    xmlStr += "</parentId>";
  }
  
  xmlStr += "</select>";
  
  var el = cb_tree_get_context(item.id).parentNode
  
  bl_mpr_send(xmlStr, el.id, 0);
}

function cb_tree_sendToServer(element, message, singleInstance)
{
  var xmlStr  = "<" 
              + message 
              + ">"
              + cb_tree_getObjectID(element.id, singleInstance)
              + "</" 
              + message 
              + ">";
  
  // send the data to the server
  var par = cb_tree_get_context(element.id).parentNode;
  
  bl_mpr_send(xmlStr, par.id);
}

function cb_tree_handle_insert(el)
{
  var nodes     = el.childNodes;
  var parentId  = bl_port_get_text(nodes.item(0));
  var item      = bl_port_get_text(nodes.item(1));
  var index     = parseInt(bl_port_get_text(nodes.item(2)));
  
  var element   = document.getElementById(parentId);
  if (element)
  {
    cb_tree_node_insert(element, null, item, index);
  }
}

function cb_tree_handle_remove(el, element)
{
  var node            = el.childNodes[0];
  var id              = bl_port_get_text(node);
  var element         = document.getElementById(id);
  if (element)
  {
    var tEl             = null;
    var current         = cb_tree_getCurrentNode(id);
    var currentRClick   = cb_tree_getCurrentRightClickNode(id);
    if (cb_tree_getCurrentNode(element.id) == element)
    {
      tEl = element.nextSibling;
      if (tEl && !element.nextSibling)
      {
        //tEl.className = 'tree';
      }
      if (!tEl)
      {
        tEl = element.previousSibling;
      }
      if (!tEl)
      {
        tEl = cb_tree_get_parent(element);
      }
    }
    cb_tree_node_remove_obj(null, element, true);
    if (tEl && (current == currentRClick || !element.firstChild.rCount))
    {
      cb_tree_nodeChangeSelect(tEl, true);
    }
  }
}

function bl_tree_select_item_timeout(id)
{
  var item = document.getElementById(id);
  if (item)
  {
    var body = document.body;
    if (body.clientWidth == 0 || body.clientHeight == 0)
    {
      window.setTimeout("bl_tree_select_item_timeout('" + item.id + "')", 1);
      return null;
    }
    
    // we are seting it to a selected state
    bl_tree_setStyle(item, 1, cb_tree_getHasFocus(item.id));
    bl_tree_setCurrentNode(item, item);
    cb_tree_scroll_into(item);
    bl_sys_checkDialogSelect(cb_tree_get_context(id).parentNode);    
  }
}

function _bl_tree_check_select(id)
{
  var imageChild = document.getElementById(id);
  
  if (imageChild)
  {
    var item = cb_tree_get_item(imageChild);
    if (item)
    {
      window.setTimeout("bl_tree_select_item_timeout('" + item.id + "')", 1);
    }
  }
}

function cb_tree_compute_child_set(childElement, html)
{
  var exImageSrc    = cb_tree_ex_icon_child(childElement).src;
  
  html              = html.replace(/cb_replace_set/g, exImageSrc);
  
  var isRoot        = childElement.getAttribute("bl_is_root") != null;
  var noShowRoot    = childElement.getAttribute("bl_show_root") == null;
  
  if (isRoot && noShowRoot)
  {
    childElement.parentNode.innerHTML = html;
  }
  else
  {
    bl_port_setOuterHTML(childElement, html);
  }
}

function cb_tree_handle_set(el, element)
{
  var nodes     = el.childNodes;
  var parentId  = bl_port_get_text(nodes.item(0));
  var item      = bl_port_get_text(nodes.item(1));
  var index     = parseInt(bl_port_get_text(nodes.item(2)));
  
  if (parentId.length > 0 && index >= 0)
  {
    var treeElement = document.getElementById(parentId);
    if (treeElement)
    {
      var span        = cb_tree_span_child(treeElement);
      var nodes       = (span ? span.childNodes : null);
      if (nodes && nodes.length > index)
      {
        cb_tree_compute_child_set(nodes[index], item)
      }
    }
  }
}

function cb_tree_handle_setId(el, element)
{
  var nodes     = el.childNodes;
  var id        = bl_port_get_text(nodes.item(0));
  var item      = bl_port_get_text(nodes.item(1));
  var type      = bl_port_get_text(nodes.item(2));
  
  var treeElement = document.getElementById(id);
  if (treeElement)
  {
    if (type == "text")
    {
      bl_port_setOuterHTML(cb_tree_text_child(treeElement), item);
      
      if (treeElement == cb_tree_getCurrentNode(treeElement.id))
      {
        cb_tree_nodeChangeSelect(treeElement, false);
      }
    }
    else if (type == "icon")
    {
      bl_port_setOuterHTML(cb_tree_icon_child(treeElement), item);
    }
    else
    {
      cb_tree_compute_child_set(treeElement, item);
    }
  }
}

function cb_tree_handle_children_changed(el, element)
{
  var parentID    = el.firstChild;
  var idText      = bl_port_get_text(parentID);
  var isExpand    = el.nodeName == "expand";
  var listChanged = el.nodeName == "listChanged";
  var treeElement = document.getElementById(idText);
  
  if (treeElement)
  {
    if (treeElement.getAttribute("bl_loaded") == null || listChanged)
    {
      var root = cb_tree_get_context(idText);
      
      if (bl_port_contains(treeElement, root.currentNode, false))
      {
        // The 'currentNode' is within the nodes being replaced. After this
        // method is complete, it will not point to a valid node within the DOM
        root.currentNode = null;
      }
      
      var selectedId    = "";
      treeElement.setAttribute("bl_loaded", true);
      var sel           = el.lastChild;
      if (sel.tagName == "selected")
      {
        selectedId = bl_port_get_text(sel);
      }
      if (listChanged)
      {
        cb_tree_remove_span(treeElement);
      }
      var isRoot   = treeElement.getAttribute("bl_is_root") != null;
      var noShowRoot = treeElement.getAttribute("bl_show_root") == null;
      
      if (isRoot && noShowRoot)
      {
        bl_port_insertAdjacentHTML(treeElement, "afterend", bl_port_get_text(parentID.nextSibling));
      }
      else
      {
        bl_port_insertAdjacentHTML(treeElement, "beforeend", bl_port_get_text(parentID.nextSibling));
      }
      if (listChanged)
      {
        var span    = cb_tree_span_child(treeElement);
        var exState = treeElement.getAttribute("bl_expand") != null;
        if (!exState && span)
        {
          treeElement.className = 'bl_tree';
          span.style.display    = "none";
        }
        cb_tree_nodeComputeExImage(treeElement);
      }
      else
      {
        treeElement.cb_expand_requested = false;
        cb_tree_expandClicked(treeElement, false);
      }
      if (selectedId.length)
      {
        var element = document.getElementById(selectedId);
        if (element)
        {
          cb_tree_nodeChangeSelect(element, false);
        }
      }
    }
    else if (treeElement.getAttribute("bl_loaded") != null && treeElement.getAttribute("bl_expand") == null)
    {
      treeElement.className = 'bl_tree';
      cb_tree_expandClicked(treeElement, false);
    }
  }
}

function cb_tree_handle_tooltip_changed(el, element)
{
  var parentID    = el.firstChild;
  var idText      = bl_port_get_text(parentID);
  var toolTip     = bl_port_get_text(el.lastChild);
  var treeElement = document.getElementById(idText);
  if (treeElement)
  {
    var textChild = cb_tree_text_child(treeElement);
    var iconChild = cb_tree_icon_child(treeElement);
    if (textChild)
    {
      textChild.title = toolTip;
    }
    if (iconChild)
    {
      iconChild.title = toolTip;
    }
  }
}

function cb_tree_handle_has_children(el, element)
{
  var parentID    = el.firstChild;
  var hasChild    = parseInt(bl_port_get_text(el.lastChild));
  var idText      = bl_port_get_text(parentID);
  var treeElement = document.getElementById(idText);
  if (treeElement)
  {
    if (hasChild)
    {
      treeElement.removeAttribute("bl_loaded");
    }
    else
    {
      treeElement.setAttribute("bl_loaded", true);
    }
    cb_tree_nodeComputeExImage(treeElement);
  }
}

function cb_tree_handle_move(el)
{
  var node        = el.childNodes[0];
  var treeElement = document.getElementById(bl_port_get_text(node));
  if (treeElement)
  {
    cb_tree_moveElement(treeElement, parseInt(bl_port_get_text(el.childNodes[1])), parseInt(bl_port_get_text(el.childNodes[2])));
  }
}

function cb_tree_handle_revert_select(element)
{
  var rightClickNode = element.firstChild.currentRightClickNode;
  if (rightClickNode)
  {
    var current = --element.firstChild.rCount;
    if (!current)
    {
      if (rightClickNode && rightClickNode.parentNode)
      {
        var root = rightClickNode;
        while (root && bl_port_hasAttribute("bl_is_root"))
        {
          root = root.parentNode;
        }
        if (root)
        {
          cb_tree_nodeChangeSelect(rightClickNode, false);
        }
      }
      element.firstChild.currentRightClickNode = null;
    }
  }
}

function cb_tree_handle_add_collection(el)
{
  for (var i = 0; i < el.childNodes.length; i++)
  {
    cb_tree_handle_insert(el.childNodes.item(i));
  }
}

function cb_tree_handle_remove_all(el)
{
  var parentID    = el.firstChild;
  var treeElement = document.getElementById(bl_port_get_text(parentID));
  if (treeElement)
  {
    cb_tree_nodeRemoveAllChildren(treeElement, false);
  }
}

function cb_tree_handle_select(el, send)
{
  var node            = el.childNodes[0];
  var id              = bl_port_get_text(node);
  var element         = document.getElementById(id);
  if (element)
  {
    cb_tree_expandSelectPath(element);
    cb_tree_nodeChangeSelect(element, send);
  }
}

function no_cb_tree_handler(item, element)
{
  var el = item.firstChild;
  if (el.nodeName == "expand" || el.nodeName == "listChanged")
  {
    cb_tree_handle_children_changed(el, element);
  }
  else if (el.nodeName == "TooltipChanged")
  {
    cb_tree_handle_tooltip_changed(el, element);
  }
  else if (el.nodeName == "revertSelect")
  {
    cb_tree_handle_revert_select(element);
  }
  else if (el.nodeName == "select")
  {
    cb_tree_handle_select(el, false);
  }
  else if (el.nodeName == "hasChildren")
  {
    cb_tree_handle_has_children(el, element);
  }
  else if (el.nodeName == "insert")
  {
    cb_tree_handle_insert(el);
  }
  else if (el.nodeName == "addColl")
  {
    cb_tree_handle_add_collection(el);
  }
  else if (el.nodeName == "move")
  {
    cb_tree_handle_move(el);
  }
  else if (el.nodeName == "set")
  {
    cb_tree_handle_set(el, element);
  }
  else if (el.nodeName == "setId")
  {
    cb_tree_handle_setId(el, element);
  }
  else if (el.nodeName == "remove")
  {
    cb_tree_handle_remove(el, element);
  }
  else if (el.nodeName == "removeAll")
  {
    cb_tree_handle_remove_all(el);
  }
}

function _bl_tree_ddOver(event, el)
{
  bl_tree_computeDrag(bl_dd_getDragDropObj(), event, cb_tree_get_item(bl_port_getEventTarget(event)));
}

function _bl_tree_expandTreeCall(childId)
{
  var node = document.getElementById(childId);
  if (node)
  {
    if (node == bl_tree_getCurrentHilight(childId))
    {
      cb_tree_expandClicked(node, true);
    }
    else
    {
      node.expanding = false;
    }
  }
}

function bl_tree_computeDrag(ddObj, event, node)
{
  if (ddObj && node)
  {
    var textChild = cb_tree_text_child(node);
    var childId   = node.id;
    var src       = bl_port_getEventTarget(event);
    var rootNode  = cb_tree_get_context(childId);
    var cur       = rootNode.treeCurrentHilight;
    var hasFocus  = rootNode.hasFocus;

    ddObj.setDragOverNotify(rootNode, bl_tree_dragEnd);
    
    if (bl_dd_checkList(ddObj, event, rootNode.parentNode.getAttribute("bl_zone_list")))
    {
      if (bl_port_contains(textChild, src, false) || rootNode.getAttribute("bl_drop_on") != null)
      {
        if (cur != node)
        {
          cb_tree_clearHilight(childId);
          bl_tree_setCurrentHilight(childId, node);
          ddObj.setHint(null);
          
          // we are setting it to a drop hint state
          bl_tree_setStyle(node, 2, hasFocus);
          
          if (node.getAttribute("bl_expand") == null && !node.expanding)
          {
            node.expanding = true;
            window.setTimeout("_bl_tree_expandTreeCall('" + childId + "')", 1000);
          }
        }
      }
      else
      {
        cb_tree_clearHilight(childId);

        var hintContext = { child:node,
                            hintDrop:bl_tree_ddHintDrop,
                            dimension:3,
                            size:50,
                            x:event.clientX,
                            y:event.clientY,
                            isVertical:true
                          };
        
        ddObj.setHint(hintContext);
      }
      
      bl_port_killEvent(event);
      return ;
    }
  }

  if (ddObj)
  {
    ddObj.clearEffect();
  }
}

function _bl_tree_ddOut(event, el)
{
  var ddObj = bl_dd_getDragDropObj();

  if (ddObj)
  {
    var treeNode = cb_tree_get_item(bl_port_getEventTarget(event));
    
    if (treeNode)
    {
      var clientx = event.clientX;
      var clienty = event.clientY;
      var pos     = bl_sys_find_xy(treeNode, null, false);
      
      if (pos.x <= clientx && 
          clientx <= pos.x + treeNode.offsetWidth && 
          pos.y <= clienty && 
          clienty <= pos.y + treeNode.offsetHeight)
      {
        bl_tree_computeDrag(ddObj, event, treeNode);
      }
      else
      {
        ddObj.setHint(null);
        ddObj.clearEffect();
        cb_tree_clearHilight(treeNode.id);
      }
    }
    else
    {
      ddObj.setHint(null);
      ddObj.clearEffect();
      cb_tree_clearHilight(treeNode.id);
    }
  }
}

function bl_tree_procDrop(event, treeNode)
{
  var ddObj = bl_dd_getDragDropObj();
  
  if (treeNode && ddObj)
  {
    var id = treeNode.id;
    
    if (bl_tree_mouseDownNode(id))
    {
      cb_tree_setMouseDownNode(id, null);
    }
    
    var rootNode  = cb_tree_get_context(id);
    var ddContext = bl_tree_getDragContext(treeNode, id, ddObj);
    var target    = { id:rootNode.parentNode.id, index:-1, dropContext:ddContext };
    
    bl_dd_procDrop(target);
    bl_tree_dragEnd(treeNode, rootNode, false);
    bl_port_killEvent(event);
  }
}

function bl_tree_ddHintDrop(event, hintImage)
{
  bl_tree_procDrop(event, this.child);
}

function _bl_tree_drop(event, el)
{
  bl_tree_procDrop(event, cb_tree_get_item(bl_port_getEventTarget(event)));
}

function bl_tree_dragEnd(source, item, dragStarted)
{
  var id    = item.id;
  var mNode = bl_tree_mouseDownNode(id);
  
  if (mNode)
  {
    cb_tree_setMouseDownNode(id, null);
    cb_tree_nodeChangeSelect(mNode, mNode.sendToServer);
  }
  cb_tree_clearHilight(id);
}

// This function needs to be the last function.
// It serves as a flag to indicate the script for this
// file has been loaded.
function _bl_tree_last()
{
  var x = 0;
}

//***********************************************************************
//***********************************************************************
//********                   bl_rth.js                          *********
//***********************************************************************
//***********************************************************************
// Real Time Histogram Control

function _bl_rth_handler(itemNode, el)
{
  var cmd    = itemNode.childNodes.item(0);
  var name   = cmd.nodeName;
  var result = false;
  
  try
  {
    // the iframe may not be rendered yet so if it is not an exception will be thrown 
    // if it does and the message is a set then store off the value for when it is ready
    var iframeWindow = el.contentWindow;
    
    if (iframeWindow.bl_ready)
    {
      if (name == "add")
      {
        iframeWindow.bl_addPoints(bl_port_get_text(itemNode));
      }
      else if (name == "set")
      {
        iframeWindow.bl_setPoints(bl_port_get_text(itemNode))
      }
      result = true;
    }
  }
  catch (e){}
  
  if (result == false && name == "set")
  {
    el.setAttribute("bl_d", bl_port_get_text(itemNode));
  }
}



window.bl_pulseCoreLoaded = true;

