/* function for finding the absolute bounds of a node (both inline and block) */
function findAbsoluteBounds(node)
{
    var bounds = node.getBoundingClientRect();
    return {
        left: bounds.left,
        top: bounds.top,
        width: bounds.right - bounds.left,
        height: bounds.bottom - bounds.top
    };
}

function nodeToString(node)
{
    if (node === undefined)
        return 'undefined';
    if (node === null)
        return 'null';
    if (!node.nodeName)
        return 'not a node';
    if (node.nodeType == 3)
        return "'"+node.nodeValue+"'";
    return node.nodeName + (node.id ? ('#' + node.id) : '');
}

function boundsToString(bounds)
{
    return "("+bounds.left+","+bounds.top+")x("+bounds.width+","+bounds.height+")";
}

function pointToString(point)
{
    return "("+point.x+","+point.y+")";
}


function shouldBeNode(adjustedNode, targetNode) {
    if (typeof targetNode == "string") {
        var adjustedNodeString = nodeToString(adjustedNode);
        if (targetNode == adjustedNodeString) {
            testPassed("adjusted node was " + targetNode + ".");
        }
        else {
            testFailed("adjusted node should be " + targetNode  + ". Was " + adjustedNodeString + ".");
        }
        return;
    }
    if (targetNode == adjustedNode) {
        testPassed("adjusted node was " + nodeToString(targetNode) + ".");
    }
    else {
        testFailed("adjusted node should be " + nodeToString(targetNode)  + ". Was " + nodeToString(adjustedNode) + ".");
    }
}

function shouldBeWithin(adjustedPoint, targetArea) {
    if (adjustedPoint.x >= targetArea.left && adjustedPoint.y >= targetArea.top
        && adjustedPoint.x <= (targetArea.left + targetArea.width)
        && adjustedPoint.y <= (targetArea.top + targetArea.height)) {
        testPassed("adjusted point was within " + boundsToString(targetArea));
    } else {
        testFailed("adjusted node should be within " + boundsToString(targetArea)  + ". Was " + pointToString(adjustedPoint));
    }
}

function testTouchPoint(touchpoint, targetNode, allowTextNodes)
{
    var adjustedNode = internals.touchNodeAdjustedToBestClickableNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    if (!allowTextNodes && adjustedNode && adjustedNode.nodeType == 3)
        adjustedNode = adjustedNode.parentNode;
    shouldBeNode(adjustedNode, targetNode);
}

function testTouchPointContextMenu(touchpoint, targetNode, allowTextNodes)
{
    var adjustedNode = internals.touchNodeAdjustedToBestContextMenuNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    if (!allowTextNodes && adjustedNode && adjustedNode.nodeType == 3)
        adjustedNode = adjustedNode.parentNode;
    shouldBeNode(adjustedNode, targetNode);
}

function adjustTouchPoint(touchpoint)
{
    var adjustedPoint = internals.touchPositionAdjustedToBestClickableNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    return adjustedPoint;
}

function adjustTouchPointContextMenu(touchpoint)
{
    var adjustedPoint = internals.touchPositionAdjustedToBestContextMenuNode(touchpoint.left, touchpoint.top, touchpoint.width, touchpoint.height);
    return adjustedPoint;
}

function touchPoint(x, y, radiusX, radiusY)
{
    if (!radiusY)
        radiusY = radiusX;

    return {
        left: x - radiusX,
        top: y - radiusY,
        width: radiusX * 2,
        height: radiusY * 2,
        get x() { return this.left + this.width/2; },
        get y() { return this.top + this.height/2; }
    };
}

function offsetTouchPoint(bounds, relativePosition, touchOffset, touchRadiusX, touchRadiusY)
{
    if (!touchRadiusY)
        touchRadiusY = touchRadiusX;

    // Start with the center of the touch at the top-left of the bounds.
    var touchpoint = touchPoint(bounds.left, bounds.top, touchRadiusX, touchRadiusY);
 
    // Adjust the touch point as requested.
    switch (relativePosition) {
    case 'center':
        touchpoint.left += bounds.width / 2;
        touchpoint.top += bounds.height / 2;
        break;
    case 'left':
        touchpoint.left -= touchOffset;
        touchpoint.top += bounds.height / 2;
        break;
    case 'right':
        touchpoint.left += bounds.width + touchOffset;
        touchpoint.top +=  bounds.height / 2;
        break;
    case 'top-left':
        touchpoint.left -= touchOffset;
        touchpoint.top -= touchOffset;
        break;
    case 'top-right':
        touchpoint.left += bounds.width + touchOffset;
        touchpoint.top -= touchOffset;
        break;
    case 'bottom-left':
        touchpoint.left -= touchOffset;
        touchpoint.top += bounds.height + touchOffset;
        break;
    case 'bottom-right':
        touchpoint.left += bounds.width + touchOffset;
        touchpoint.top += bounds.height + touchOffset;
        break;
    case 'top':
        touchpoint.left += bounds.width / 2;
        touchpoint.top -= touchOffset;
        break;
    case 'bottom':
        touchpoint.left += bounds.width / 2;
        touchpoint.top += bounds.height + touchOffset;
    }

    return touchpoint;
}
