         @initTips()
 
     initEvents: () ->
-        # For handling hide/show of annotations and instructions
-        @annotationsHidden = false
+        # Initialize toggle handlers for the instructions and annotations sections
+        [@annotationsHidden, @instructionsHidden] = [false, false]
         @$(@toggleAnnotationsSelector).bind 'click', @onClickToggleAnnotations
-
-        @instructionsHidden = false
         @$(@toggleInstructionsSelector).bind 'click', @onClickToggleInstructions
 
-        # For handling 'reply to annotation' events that scroll to the associated capa problem.
-        # These are contained in the tooltips, which should be rendered somewhere in the wrapper
-        # (see the qtip2 options, this must be set explicitly, otherwise they render in the body).
-        @$(@wrapperSelector).delegate @replySelector, 'click', @onClickReply
+        # Initialize handler for 'reply to annotation' events that scroll to
+        # the associated problem. The reply buttons are part of the tooltip
+        # content. It's important that the tooltips be configured to render
+        # as descendants of the annotation module and *not* the document.body.
+        @$el.delegate @replySelector, 'click', @onClickReply
 
-        # For handling 'return to annotation' events from capa problems. Assumes that:
+        # Initialize handler for 'return to annotation' events triggered from problems.
         #   1) There are annotationinput capa problems rendered on the page
-        #   2) Each one has an embedded "return to annotation" link (from the capa problem template).
-        # The capa problem's html is injected via AJAX so this just sets a listener on the body and
-        # handles the click event there.
+        #   2) Each one has an embedded return link (see annotation capa problem template).
+        # Since the capa problem injects HTML content via AJAX, the best we can do is
+        # is let the click events bubble up to the body and handle them there. 
         $('body').delegate @problemReturnSelector, 'click', @onClickReturn
   
     initTips: () ->
-        @savedTips = []
+        # tooltips are used to display annotations for highlighted text spans
         @$(@spanSelector).each (index, el) =>
-            $(el).qtip(@getTipOptions el)
+            $(el).qtip(@getSpanTipOptions el)
 
-    getTipOptions: (el) ->
+    getSpanTipOptions: (el) ->
         content:
             title:
                 text: @makeTipTitle(el)

    createReplyLink: (problem_id) ->
        $("<a class=\"annotatable-reply\" href=\"javascript:void(0);\" data-problem-id=\"#{problem_id}\">Reply to Annotation</a>")

    openSavedTips: () ->
        @showTips @savedTips

    closeAndSaveTips: () ->
        @savedTips = @findVisibleTips()
        @hideTips @savedTips

    findVisibleTips: () ->
        visible = []
        @$(@spanSelector).each (index, el) ->
            api = $(el).qtip('api')
            tip = $(api?.elements.tooltip)
            if tip.is(':visible')
                visible.push [el, tip.offset()]
        visible

    hideTips: (pairs) ->
        elements = (pair[0] for pair in pairs)
        $(elements).qtip('hide')

    showTips: (pairs) ->
        $.each pairs, (index, pair) ->
            [el, offset] = pair
            $(el).qtip('show')
            api = $(el).qtip('api')
            $(api?.elements.tooltip).offset(offset)

    constrainTipHorizontally: (tip, mouseX) ->
        win_width = $(window).width()
        tip_center = $(tip).width() / 2 # see position setting of tip
        tip_offset = $(tip).offset()

        if (tip_center + mouseX) > win_width
          adjust_left = '-=' + (tip_center + mouseX - win_width)
        else if (mouseX - tip_center) < 0
          adjust_left = '+=' + (tip_center - mouseX)

        $(tip).animate({ left: adjust_left }) if adjust_left?

    _once: (fn) ->
        done = false

        position:
            my: 'bottom center' # of tooltip
            at: 'top center' # of target
            target: $(el) # where the tooltip was triggered (i.e. the annotation span)
            container: @$el
            adjust:
                y: -5
        show:
            event: 'click mouseenter'
            solo: true
        hide:
            event: 'click mouseleave'
            delay: 500,
            fixed: true # don't hide the tooltip if it is moused over
        style:
            classes: 'ui-tooltip-annotatable'
        events:
            show: @onShowTip

    onClickToggleAnnotations: (e) => @toggleAnnotations()

