// If true, don't do anything when the resize function is called.
var joomsayerDoNotResize = false;

if( window.addEventListener )
{
  window.addEventListener( 'load', joomsayerPushDown, false );
  window.addEventListener( 'resize', joomsayerResize, false );
}
else if( window.attachEvent )
{
  window.attachEvent( 'onload', joomsayerPushDown );
  window.attachEvent( 'onresize', joomsayerResize );
}


function joomsayerPushDown( )
{
  var divs = document.getElementsByTagName( "div" );

  for( var i = 0; i < divs.length; i++ )
  {
    // For each div class=joomsayer, locate its div class=end.
    if( divs[ i ].className && divs[ i ].className == 'joomsayer' )
    {
      var joomsayer = divs[ i ];

      var joomsayerDivs = joomsayer.getElementsByTagName( "div" );
      // Within the joomsayer div, find the end div.
      for( var j = 0; j < joomsayerDivs.length; j++ )
      {
        if( joomsayerDivs[ j ].className && joomsayerDivs[ j ].className == 'end' )
	{
	  // Insert a "push" div before the end div.
          var endDiv = joomsayerDivs[ j ];
	  joomsayerInsertPushDiv( endDiv, joomsayer );
	  break;
	}
      }
    }
  }

  joomsayerResize( );
}


function joomsayerResize( )
{
  if( joomsayerDoNotResize )
  {
    return;
  }

  var divs = document.getElementsByTagName( "div" );

  for( var i = 0; i < divs.length; i++ )
  {
    // For each div class=joomsayer, adjust the height.
    if( divs[ i ].className && divs[ i ].className == 'joomsayer' )
    {
      var joomsayer = divs[ i ];
      joomsayerAdjustHeight( joomsayer );
      joomsayerAlignContentVertically( joomsayer );
    }
  }
}


function joomsayerAdjustHeight( joomsayer )
{
  joomsayerDoNotResize = true;

  // Get the "end" div and reset its top padding.
  var endDiv = joomsayerGetNamedDiv( joomsayer, 'end' );
  endDiv.style.paddingTop = '0px';

  // Get the "push" div.
  var pushDiv = joomsayerGetNamedDiv( joomsayer, 'push' );

  // Get the "content" div and its height.
  var contentDiv = joomsayerGetNamedDiv( joomsayer, 'content' );
  var contentHeight = contentDiv.clientHeight;
  if( contentHeight == 0 )
  {
    // IE7 is causing trouble, because for some reason it won't return a valid
    // clientHeight of the "content" div. Ideally we could use the "content"
    // div to determine the proper height. Instead, reset the "push" height and
    // measure the height of the joomsayer div.
    pushDiv.style.height = "0px";
    var joomsayerHeight = joomsayer.clientHeight;
    contentHeight = joomsayerHeight;
  } 

  // Calculate the new height.
  var endHeight = endDiv.clientHeight;
  var height = Math.max( contentHeight - endHeight, 0 );
  // Set the height.
  pushDiv.style.height = height + 'px';

  // At this time, we're in trouble: placing the "end" div may cause the last
  // word to wrap around to the next line, and the "end" div will no longer be
  // on the last line. However, if we push it down again, the last word will
  // jump back. The solution is to extend the top padding of the "end" div.
  var contentNewHeight = contentDiv.clientHeight;
  if( contentNewHeight == 0 )
  {
    // Get the height of the joomsayer if the content heigth wasn't available.
    // Yes, that's IE7 again.
    var joomsayerHeight = joomsayer.clientHeight;
    contentNewHeight = joomsayerHeight;
  }
  if( contentNewHeight != contentHeight )
  {
    var paddingTop = Math.max( contentNewHeight - contentHeight, 0 );
    endDiv.style.paddingTop = paddingTop + 'px';
    // Calculate the new height.
    var height = Math.max( contentHeight - endHeight, 0 );
    // Set the height.
    pushDiv.style.height = height + 'px';
  }

  joomsayerDoNotResize = false;
}


// For very short quotations, the content div should be centered vertically
// within the joomsayer.
function joomsayerAlignContentVertically( joomsayer )
{
  // Prevent the resize function from being called.
  joomsayerDoNotResize = true;

  // Calculate the height of the content.
  var contentDiv = joomsayerGetNamedDiv( joomsayer, 'content' );
  contentDiv.style.paddingTop = '0px';
  var contentHeight = contentDiv.offsetHeight;
  // Calculate the height of the joomsayer.
  var joomsayerHeight = joomsayer.offsetHeight;

  // Move the content to the middle of the joomsayer if necessary.
  if( contentHeight < joomsayerHeight - 2 )
  {
    var padding = parseInt( ( joomsayerHeight - contentHeight ) / 2 ) - 1;
    contentDiv.style.paddingTop = padding + 'px';
  }

  joomsayerDoNotResize = false;
}


function joomsayerGetNamedDiv( joomsayer, divName )
{
  var namedDiv = null;
  var joomsayerDivs = joomsayer.getElementsByTagName( "div" );

  // Within the joomsayer div, find the specified div.
  for( var j = 0; j < joomsayerDivs.length; j++ )
  {
    if( joomsayerDivs[ j ].className && joomsayerDivs[ j ].className == divName )
    {
      namedDiv = joomsayerDivs[ j ];
      break;
    }
  }

  return namedDiv;
}


function joomsayerInsertPushDiv( sibling, joomsayer )
{
  // Create a div class=push, which is inserted right before the sibling.
  var pushDiv = document.createElement( 'DIV' );
  pushDiv.className = 'push';
  pushDiv.style.cssFloat = 'right';
  // For standards non-compliant browsers (i.e, IE), use styleFloat instead
  // of cssFloat.
  pushDiv.style.styleFloat = 'right';
  pushDiv.style.width = '1px';
  sibling.parentNode.insertBefore( pushDiv, sibling );
}
