function PopMyDiv( element, bodyElement, className, defaultContentClassName, linkClassName ) {
	
	if( $( '#' + element ).length != 0 && $( '#' + bodyElement ).length != 0 && typeof className === "string"  && typeof defaultContentClassName === "string" && typeof linkClassName === "string" ) {
		this.init( $( '#' + element )[0], $( '#' + bodyElement )[0], className, defaultContentClassName, linkClassName );
	}
	
};

PopMyDiv.prototype = {
	
	init : function( _element, _bodyElement, _className, _defaultContentClassName, _linkClassName ) {
		
		// Featured area for content.
		var element = _element;
		// Default content element.
		var defaultEl = $( '.' + _defaultContentClassName )[0];
		// Default html content.
		var defaultHTMLContent = defaultEl.innerHTML;
		// Element containing popable elements.
		var bodyElement = _bodyElement;
		// Classname of content to feature.
		var className = _className;
		// Classname of content to pop via link.
		var linkClassName = _linkClassName;
		// Last candidate.
		var lastCandidate = null;
		// Last candidate's parent offsetTop.
		var lastCandidatesParentOffsetTop = null;
		
		// Return feature area element.
		this.getElement = function() {
			return element;
		};
		
		// Return default element.
		this.getDefaultEl = function() {
			return defaultEl;
		};
		
		// Return default html content.
		this.getDefaultHTMLContent = function() {
			return defaultHTMLContent;
		};
		
		// Return element containing popable elements.
		this.getBodyElement = function() {
			return bodyElement;
		};
		
		// Return classname of content to feature.
		this.getClassName = function() {
			return className;
		};
		
		// Return classname of content to feature via link.
		this.getLinkClassName = function() {
			return linkClassName;
		};
		
		// Return last candidate element.
		this.getLastCandidate = function() {
			return lastCandidate;
		};
		
		// Set last candidate element.
		this.setLastCandidate = function( candidate ) {
			lastCandidate = candidate;
		};
		
		// Return last target element.
		this.getLastCandidatesParentOffsetTop = function() {
			return lastCandidatesParentOffsetTop;
		};
		
		// Set last candidate element.
		this.setLastCandidatesParentOffsetTop = function( offsetTop ) {
			lastCandidatesParentOffsetTop = offsetTop;
		};
		
		// Bind events.
		$( '#' + bodyElement.id ).bind( 'scroll', this, this.popContent );
		$( '.' + linkClassName ).bind( 'click', this, this.popLinkContent );
		
	},
	
	// Pops the content into the featured element.
	popContent : function( event ) {

		// Set scope.
		var that = event.data;

		// Get bottom threshold of bodyElement.
		var bodyEl = $( that.getBodyElement() )[0];
		var bodyElementThreshold = bodyEl.scrollTop + bodyEl.offsetHeight;		

		// Gather popable elements that exist within the current clientHeight space.
		var popableElements = $( '.' + that.getClassName() );

		// Pick last popable element withing current clientHeight space.
		var popableCandidates = [];
		for( var i = 0; i < popableElements.length; i++ ) {
		
			var popable = popableElements[i];
			var popableParent = popable.parentNode;
		
			if( popableParent.offsetTop >= bodyEl.scrollTop && popableParent.offsetTop <= bodyElementThreshold ) {
				popableCandidates.push( popable );
			}

		}
		
		var candidate = popableCandidates[popableCandidates.length-1];
		that.setLastCandidate( popableCandidates[popableCandidates.length-1] );

		if( bodyEl.scrollTop == 0 ) { // Show default content (again) if scrolled to the top.

			var defaultEl = that.getDefaultEl();
			
			that.setLastCandidate( defaultEl );
			
			var setDefaultHTML = function() {
				that.getElement().innerHTML = that.getDefaultHTMLContent();
			};
		
			$( '#' + that.getElement().id ).animate( { opacity : 0 }, { duration: 500, complete : setDefaultHTML } );
			$( '#' + that.getElement().id ).animate( { opacity : 1, width : defaultEl.getAttribute( 'width' ), height : defaultEl.getAttribute( 'height' ) }, 500 );
		
		} else {
			
			// Prevent repeat animations.
			if( that.getLastCandidate() != null && ( that.getLastCandidate().innerHTML == candidate.innerHTML && that.getLastCandidatesParentOffsetTop() != candidate.parentNode.offsetTop ) ) {
		
				that.setLastCandidate( popableCandidates[popableCandidates.length-1] );
				that.setLastCandidatesParentOffsetTop( that.getLastCandidate().parentNode.offsetTop );
				
				// Display content in featured area (via copy not move).
				if( popableCandidates.length > 0 ) {

					candidate = that.getLastCandidate();

					// Ensure that we're not moving the same candidate as before.
					if( jQuery.trim( candidate.innerHTML ) != that.getElement().innerHTML ) {
			
						var setHTML = function() {
							that.getElement().innerHTML = jQuery.trim( candidate.innerHTML );
						};
			
						$( '#' + that.getElement().id ).animate( { opacity : 0 }, 500, null, setHTML );
						$( '#' + that.getElement().id ).animate( { opacity : 1, width : candidate.getAttribute( 'width' ), height : candidate.getAttribute( 'height' ) }, 500 );
			
					}
				}
		
			}
		}
	
	},
	
	popLinkContent : function( event ) {
		
		var that = event.data;

		// Get content from link elements span.
		var popLinkEl = event.currentTarget.children[0];
		// Populate content from link elements span into featured content area.
		that.getElement().innerHTML = popLinkEl.innerHTML;
		
	}
	
};