/* Integer ducks script
 * Puts an equal, integer number of semi-random ducks
 * to the left and right of the text of the first H2
 * in the element with ID #ducks-stuff.
 */
 function trim_ducks() {
  var duckWidth = 35    // width of a duck in the duck image
  var duckHeight = 31;  // height of the duck image
  var numDucks = 10;     // number of ducks in the duck image


  // return whether the browser supports any
  // of the methods this function knows about
  function canGetElementDimensions(element) {
    return (window.getComputedStyle || element.currentStyle
            || (element.offsetWidth && element.offsetHeight));
  }


  // get the computed width of an element
  function getElementWidth(element) {
    // first try with a CSS2Properies object
    if(window.getComputedStyle) {
      var elementStyle = window.getComputedStyle(element, null);
    } else if(element.currentStyle) {
      var elementStyle = element.currentStyle;
    } else {
      elementStyle = null;
    }
    if(elementStyle) {
      var elementInternalWidth = elementStyle.width;
      elementInternalWidth = elementInternalWidth.substring(0, elementInternalWidth.length-2);  // crop the 'px' units
      if(parseInt(elementInternalWidth)==elementInternalWidth) {
        var elementPaddingLeft = elementStyle.paddingLeft;
        elementPaddingLeft = elementPaddingLeft.substring(0, elementPaddingLeft.length-2);
        if(parseInt(elementPaddingLeft)==elementPaddingLeft) {
          var elementPaddingRight = elementStyle.paddingRight;
          elementPaddingRight = elementPaddingRight.substring(0, elementPaddingRight.length-2);
          if(parseFloat(elementPaddingRight)==elementPaddingRight)
            return Number(elementPaddingLeft) + Number(elementInternalWidth) + Number(elementPaddingRight);
        }
      }
    }

    // next try an IE-specific property - note that this value
    // includes padding, where the previous method does not
    if(element.offsetWidth) {
      var elementWidth = element.offsetWidth;
      if(parseInt(elementWidth)==elementWidth)
        return elementWidth;
    }

    // if we've got this far, then we're stuck
    // - return 0, just to be safe
    return 0;
  }


  // get the computed height of an element
  function getElementHeight(element) {
    // first try with a CSS2Properies object
    if(window.getComputedStyle) {
      var elementStyle = window.getComputedStyle(element, null);
    } else if(element.currentStyle) {
      var elementStyle = element.currentStyle;
    } else {
      elementStyle = null;
    }
    if(elementStyle) {
      var elementInternalHeight = elementStyle.height;
      elementInternalHeight = elementInternalHeight.substring(0, elementInternalHeight.length-2);  // crop the 'px' units
      if(parseInt(elementInternalHeight)==elementInternalHeight) {
        var elementPaddingTop = elementStyle.paddingTop;
        elementPaddingTop = elementPaddingTop.substring(0, elementPaddingTop.length-2);
        if(parseInt(elementPaddingTop)==elementPaddingTop) {
          var elementPaddingBottom = elementStyle.paddingBottom;
          elementPaddingBottom = elementPaddingBottom.substring(0, elementPaddingBottom.length-2);
          if(parseFloat(elementPaddingBottom)==elementPaddingBottom)
            return Number(elementPaddingTop) + Number(elementInternalHeight) + Number(elementPaddingBottom);
        }
      }
    }

    // next try an IE-specific property
    if(element.offsetHeight) {
      var elementHeight = element.offsetHeight;
      if(parseInt(elementHeight)==elementHeight)
        return elementHeight
    }

    // if we've got this far, then we're stuck
    // - guess that it's the height of the duck image
    return duckHeight;
  }


  // get the computed bottom margin of an element
  function getElementMarginBottom(element) {
    // first try with a CSS2Properies object
    if(window.getComputedStyle) {
      var elementStyle = window.getComputedStyle(element, null);
    } else if(element.currentStyle) {
      var elementStyle = element.currentStyle;
    } else {
      elementStyle = null;
    }
    if(elementStyle) {
      var elementMarginBottom = elementStyle.marginBottom;
      var units = elementMarginBottom.substring(elementMarginBottom.length-2, elementMarginBottom.length);
      elementMarginBottom = elementMarginBottom.substring(0, elementMarginBottom.length-2);  // crop the 'px' units
      if(units=='em')  // convert this value to px
        elementMarginBottom = elementMarginBottom*pixelsPerEm;
      if(parseFloat(elementMarginBottom)==elementMarginBottom)
        return Number(elementMarginBottom);
    }

    // if we've got this far, then we're stuck
    // - return 0, since we don't know any better
    return 0;
  }

  // find the ducks DIV
  var containingElement = null;
  if(document.getElementById) {
    containingElement = document.getElementById("ducks-stuff");
  } else if(document.all) {
    containingElement = document.all["ducks-stuff"];
  }


  if(containingElement && containingElement.style
     && canGetElementDimensions(containingElement)) {
    // find the first H2 in the containingElement
    var realHeading = null;
    for(position=0; position<containingElement.childNodes.length; position++) {
      realHeading = containingElement.childNodes[position];
      if(realHeading.tagName=='H2')
        break;
      realHeading = null;
    }

    if(realHeading!=null) {
      // find out how big 1em is in px (used by getElementMarginBottom())
      // - do this by making a copy of the heading and changing it's text
      // to 'm' (which should be 1em wide)
      var emHeading = realHeading.cloneNode(true);
      emHeading.style.position = "absolute";
      emHeading.style.visibility = "hidden";
      emHeading.style.paddingLeft = 0;
      emHeading.style.paddingRight = 0;
      var emHeadingText = document.createTextNode('m');
      emHeading.replaceChild(emHeadingText, emHeading.firstChild);
      // get the width of the heading - unfortunately we have to
      // insert it into the document tree to do this
      containingElement.insertBefore(emHeading, containingElement.firstChild);
      var pixelsPerEm = getElementWidth(emHeading);
      containingElement.removeChild(emHeading);

      // make a copy of the heading, then absolutely position it
      // so that we can find out how wide the text is
      var heading = realHeading.cloneNode(true);
      heading.style.position = "absolute";
      heading.style.visibility = "hidden";

      // get the width and height of the heading
      // - unfortunately we have to insert it into
      // the document tree to do this
      containingElement.insertBefore(heading, containingElement.firstChild);
      var headingWidth = getElementWidth(heading);
      var headingHeight = getElementHeight(heading);
      var headingMarginBottom = getElementMarginBottom(heading);
      var totalHeadingHeight = headingHeight + headingMarginBottom;
      containingElement.removeChild(heading);

      // get the width of the containing element too
      var containerWidth = getElementWidth(containingElement);

      // work out how much space our ducks have to fill
      maxDuckWidth = (containerWidth-headingWidth)/2;

      // add some ducks if necessary
      var ducksLeft = document.getElementById('ducks-left');
      if(ducksLeft==null) {
        var ducksLeft = document.createElement('div');
        ducksLeft.id = 'ducks-left';
        containingElement.insertBefore(ducksLeft, realHeading.nextSibling);
      }
      var ducksRight = document.getElementById('ducks-right');
      if(ducksRight==null) {
        var ducksRight = document.createElement('div');
        ducksRight.id = 'ducks-right';
        containingElement.insertBefore(ducksRight, realHeading.nextSibling);
      }

      // set some style properties - further
      // styles are applied in the stylesheet
      ducksRight.style.marginBottom = headingMarginBottom+'px';  // don't do this for the left ducks
      ducksLeft.style.marginTop = '-'+totalHeadingHeight+'px';
      ducksRight.style.marginTop = '-'+totalHeadingHeight+'px';
      ducksLeft.style.height = headingHeight+'px';
      ducksRight.style.height = headingHeight+'px';

      // randomly position the background images
      var backgroundPos = duckWidth*Math.round(Math.random()*(numDucks-1));
      ducksLeft.style.backgroundPosition = backgroundPos+'px';
      backgroundPos = duckWidth*Math.round(Math.random()*(numDucks-1));
      ducksRight.style.backgroundPosition = backgroundPos+'px';

      // shorten the ducks DIVs so that there's an integer number of ducks
      // by subtracting the width of the part-ducks at the end
      var newDuckWidth = maxDuckWidth - (maxDuckWidth%duckWidth);
      if(newDuckWidth<0)
        newDuckWidth = 0;
      ducksRightLeftValue = containerWidth - newDuckWidth;
      ducksLeft.style.width = newDuckWidth+"px";
      ducksRight.style.width = newDuckWidth+"px";
      ducksRight.style.left = ducksRightLeftValue+"px";
    }
  }
}

// event handlers for trim_ducks();
window.onload=trim_ducks;
window.onresize=trim_ducks;
