  var CurrentInfoBalloon = null;
  
  function InfoBalloon(attachTo,titleBar,contentFrom, showCloseLink)
  {
    if(CurrentInfoBalloon) 
    {
      document.body.removeChild(CurrentInfoBalloon);
      CurrentInfoBalloon = null; 
    }
    
    function pageWidth() {
     return window.innerWidth != null? window.innerWidth : document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;
    }
    
    function pageHeight() {
     return window.innerHeight != null? window.innerHeight : document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body != null? document.body.clientHeight : null;
    }
    
    function posLeft() {
     return typeof window.pageXOffset != 'undefined' ? window.pageXOffset :document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;
    }
    
    function posTop() {
     return typeof window.pageYOffset != 'undefined' ? window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;
    
    }
    
    function posRight() {
     return posLeft()+pageWidth();
    }
    
    function posBottom() {
     return posTop()+pageHeight();
    }
    
    function getposOffset(overlay, offsettype)
    {
     var totaloffset=(offsettype=="left")? overlay.offsetLeft : overlay.offsetTop;
     var parentEl=overlay.offsetParent;
     while (parentEl!=null){
     totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop;
     parentEl=parentEl.offsetParent;
     }
     return totaloffset;
    }

    var Balloon = document.createElement('div');
    Balloon.className= 'InfoBalloon';
    
    var Header  = document.createElement('div');
    Header.className = 'Header';
    Header.appendChild(document.createTextNode(titleBar));
    Balloon.appendChild(Header);
    
    var Body = document.createElement('div');
    Body.className = 'Body';
    Body.innerHTML = contentFrom.innerHTML;
    if(showCloseLink) Body.innerHTML += '<a class="CloseWindow" href="#" onclick="if(CurrentInfoBalloon) { document.body.removeChild(CurrentInfoBalloon); CurrentInfoBalloon = null; } return false;">Close Window</a>';;//appendChild(contentFrom.cloneNode(true));    
    Balloon.appendChild(Body);
   
    var Footer = document.createElement('div');
    Footer.className = 'Footer';
    Footer.innerHTML = '&nbsp;';
    Balloon.appendChild(Footer);
          
    var Tail = document.createElement('div');
    Tail.className = 'Tail';
    Balloon.appendChild(Tail);
    
    var XBuffer = 20;
    var YBuffer = 0;
      
    Balloon.style.visibility = "hidden";
    document.body.appendChild(Balloon);    
    CurrentInfoBalloon = Balloon;
    
    var balloonWidth = Balloon.offsetWidth;
    var balloonHeight = Balloon.offsetHeight;
    
    ObjLeft   = getposOffset(attachTo, 'left');
    ObjRight  = getposOffset(attachTo, 'left') + attachTo.offsetWidth;
    
    ObjTop    = getposOffset(attachTo, 'top');
    ObjBottom = getposOffset(attachTo, 'top') + attachTo.offsetHeight;
    
    
    // Determing horizontal co-ordinate and tail
    if(ObjRight+XBuffer+balloonWidth < pageWidth())
    { // It will fit on the right, so the tail points left
      XCoord = ObjRight+XBuffer;
      Tail.className += ' Left';
    }
    else if(ObjLeft-XBuffer-balloonWidth > 0)
    { // It will fit on the left, so the tail points right
      XCoord = ObjLeft-XBuffer - balloonWidth;
      Tail.className += ' Right';
    }
    else
    {
      // we have to peg at the right or left side, so which has more room, left or right
      if((pageWidth() - ObjRight) > ObjLeft)
      {
        // The right side, the tail points left        
        XCoord = XBuffer;
        Tail.className += ' Left';
      }
      else
      {
        // The left side, the tail points right
        XCoord = XBuffer + balloonWidth;
        Tail.className += ' Right';
      }            
    }
    
    // Determin vertical co-ordinate and tail
    if(ObjTop-balloonHeight + YBuffer > posTop())
    { // Fits above, tail points to bottom
      YCoord = ObjTop - balloonHeight + YBuffer;            
      Tail.className += ' Bottom';     
    }
    else if(ObjTop - Math.floor(balloonHeight / 2) + YBuffer > posTop())
    { // Fits beside, tail points middle
      YCoord = ObjTop - Math.floor(balloonHeight / 2) + YBuffer;
      Tail.className += ' Middle';
      Tail.style.top = (Math.floor(balloonHeight / 2) - 24) + 'px';
    }
    else
    { // have to go below
      YCoord = ObjBottom-YBuffer;      
      Tail.className += ' Top';      
    }
        
    Balloon.style.left=XCoord+"px";
    Balloon.style.top=YCoord+"px";    
    Balloon.style.visibility = "visible";     

  }

  function CloseBalloon()
  {
    if(CurrentInfoBalloon) 
    {
      document.body.removeChild(CurrentInfoBalloon);
      CurrentInfoBalloon = null; 
    }
  }
  
  // IE Sucks, we have to output this into the stream so that IE will not fuck up on loading
  // the images from the CSS file, without this, it will randomly not load the images.
  function BalloonSetup()
  {
    document.write('<div class="InfoBalloon" style="right:1px;top:1px;height:1px;width:1px;visibility:hidden;overflow:crop;"><div class="Header">&nbsp;</div><div class="Body">&nbsp;</div><div class="Footer">&nbsp;</div><div class="Tail Left Bottom">&nbsp;</div><div class="Tail Left Middle">&nbsp;</div><div class="Tail Left Top">&nbsp;</div></div>');                   
  }
  
  BalloonSetup();
  