define(function(require) {

$.extend(KhanUtil, {
    doParabolaInteraction: function(func, vertex, directrix) {
        var graph = KhanUtil.currentGraph;

        var vertexLine = KhanUtil.bogusShape;
        var directrixLine = KhanUtil.bogusShape;
        var lineEndcap = KhanUtil.bogusShape;
        var highlighted = false;

        // Attach an onMove handler that gets called whenever the mouse hovers over
        // the parabola
        func.onMove = function(coordX, coordY) {
            vertexLine.remove();
            directrixLine.remove();
            lineEndcap.remove();
            graph.style({ strokeWidth: 1.5, stroke: KhanUtil.GREEN, opacity: 0.0 });
            var vertexDistance = KhanUtil.getDistance([coordX, coordY], vertex.coord);

            // Draw a line from the vertex to the highlighted point on the parabola
            vertexLine = graph.line([coordX, coordY], vertex.coord);
            // Draw the horizontal line from the highlighted point on the parabola towards the directrix
            if (directrix.coordA[1] < coordY) {
                directrixLine = graph.line([coordX, coordY], [coordX, coordY - vertexDistance]);
                lineEndcap = graph.line([coordX - 0.05, coordY - vertexDistance], [coordX + 0.05, coordY - vertexDistance]);
            } else {
                directrixLine = graph.line([coordX, coordY], [coordX, coordY + vertexDistance]);
                lineEndcap = graph.line([coordX - 0.05, coordY + vertexDistance], [coordX + 0.05, coordY + vertexDistance]);
            }
            vertexLine.toBack();
            directrixLine.toBack();
            if (!highlighted) {
                vertexLine.animate({opacity: 1.0}, 100);
                directrixLine.animate({opacity: 1.0}, 100);
                lineEndcap.animate({opacity: 1.0}, 100);
            } else {
                vertexLine.attr({ opacity: 1.0 });
                directrixLine.attr({ opacity: 1.0 });
                lineEndcap.attr({ opacity: 1.0 });
            }
            highlighted = true;
        };

        // Attach an onLeave handler that gets called whenever the mouse moves away from the parabola
        func.onLeave = function(coordX, coordY) {
            vertexLine.animate({opacity: 0.0}, 100);
            directrixLine.animate({opacity: 0.0}, 100);
            lineEndcap.animate({ opacity: 0.0 }, 100);
            highlighted = false;
        };

    },

    doHyperbolaInteraction: function(func, focus1, focus2) {
        var graph = KhanUtil.currentGraph;
        var focusLine1 = KhanUtil.bogusShape;
        var focusLine2 = KhanUtil.bogusShape;
        var highlighted = false;

        func.onMove = function(coordX, coordY) {
            focusLine1.remove();
            focusLine2.remove();

            // Draw a line from each focus to the highlighted point on the hyperbola
            graph.style({ strokeWidth: 1.5, stroke: KhanUtil.GREEN, opacity: 0.0 });
            focusLine1 = graph.line([coordX, coordY], focus1.coord);
            graph.style({ stroke: KhanUtil.RED });
            focusLine2 = graph.line([coordX, coordY], focus2.coord);

            focusLine1.toBack();
            focusLine2.toBack();

            if (!highlighted) {
                focusLine1.animate({opacity: 1.0}, 100);
                focusLine2.animate({opacity: 1.0}, 100);
                $('#problemarea div.focus-instructions').hide();
                $('#problemarea div.focus-distances').show();
            } else {
                focusLine1.attr({ opacity: 1.0 });
                focusLine2.attr({ opacity: 1.0 });
            }

            highlighted = true;
            this.writeDistances(coordX, coordY);
        };

        func.onLeave = function(coordX, coordY) {
            focusLine1.animate({opacity: 0.0}, 100);
            focusLine2.animate({opacity: 0.0}, 100);
            $('#problemarea div.focus-instructions').show();
            $('#problemarea div.focus-distances').hide();
            highlighted = false;
        };
    },

    doEllipseInteraction: function(ellipse, focus1, focus2) {
        var graph = KhanUtil.currentGraph;
        var focusLine1 = KhanUtil.bogusShape;
        var focusLine2 = KhanUtil.bogusShape;
        var highlighted = false;

        ellipse.onMove = function(coordX, coordY) {
            focusLine1.remove();
            focusLine2.remove();

            // Draw a line from each focus to the highlighted point on the ellipse
            graph.style({ strokeWidth: 1.5, stroke: KhanUtil.GREEN, opacity: 0.0 });
            focusLine1 = graph.line([coordX, coordY], focus1.coord);
            graph.style({ stroke: KhanUtil.RED });
            focusLine2 = graph.line([coordX, coordY], focus2.coord);

            focusLine1.toBack();
            focusLine2.toBack();

            if (!highlighted) {
                focusLine1.animate({opacity: 1.0}, 100);
                focusLine2.animate({opacity: 1.0}, 100);
                $('#problemarea div.focus-instructions').hide();
                $('#problemarea div.focus-distances').show();
            } else {
                focusLine1.attr({ opacity: 1.0 });
                focusLine2.attr({ opacity: 1.0 });
            }

            highlighted = true;
            this.writeDistances(coordX, coordY);
        };

        ellipse.onLeave = function(coordX, coordY) {
            focusLine1.animate({opacity: 0.0}, 100);
            focusLine2.animate({opacity: 0.0}, 100);
            $('#problemarea div.focus-instructions').show();
            $('#problemarea div.focus-distances').hide();
            highlighted = false;
        };
    }

});

});
