(function($) {
  $.fn.toggleTop = function(opts, fn) {
    return this.each(function() {
      var $this = $(this);
      var $original = $this.data('ontopCloneOf');
      var $clone = $this.data('ontopClone');
      if ($clone) {
        $original = $this;
      } else if ($original) {
        $clone = $this;
      }
      if ($clone && $original) {
        $original.unTop(opts, fn);
      } else {
        $this.onTop(opts, fn);
      }
    });
  };

  $.fn.onTop = function(opts, fn) {
    var $body = $('body');
    return this.each(function() {
      // Check if this guy has been already topped.
      var $this = $(this);
      var $original = $this.data('ontopCloneOf');
      var $clone = $this.data('ontopClone');
      if (!$original && !$clone) {
        $original = $this;
        $clone = $original.clone(true);

        $original.data('ontopClone', $clone);
        $clone.data('ontopCloneOf', $original);

        var offset = $original.offset();
        var width = $original.width();
        var height = $original.height();

        // Figure out the original css
        var css = $.extend({
          position : 'absolute',
          top : offset.top,
          left : offset.left,
          height : height,
          width : width,
          marginTop : 0,
          marginLeft : 0
        }, opts);

        var data = {};
        for ( var n in css) {
          $clone.data("ontopCss" + n, $original.css(n));
          $original.css(n, css[n]);
        }

        // Hide and insert the clone -- so we don't mess with existing page size
        $clone.css("visibility", "hidden");
        $clone.insertBefore($original);
        $body.append($original.detach());

        if (fn) {
          fn(this);
        }

        return $original;
      }
    });
  };
  $.fn.unTop = function(opts, fn) {
    return this.each(function() {
      var $this = $(this);
      var $original = $this.data('ontopCloneOf');
      var $clone = $this.data('ontopClone');
      if ($clone) {
        $original = $this;
      } else if ($original) {
        $clone = $this;
      }
      if ($clone && $original) {
        $original.insertBefore($clone);
        for ( var n in $clone.data()) {
          if (n.substring(0, 8) == "ontopCss") {
            $original.css(n.substring(8), $clone.data(n));
          }
        }
        $original.removeData('ontopClone');
        $clone.remove();

        if (fn) {
          fn(this);
        }

        return $original;
      }
    });
  };
})(jQuery)

