/**
 * EditorView.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2016 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

define(
  'tinymce.core.EditorView',
  [
    'ephox.katamari.api.Fun',
    'ephox.sugar.api.node.Element',
    'ephox.sugar.api.properties.Css',
    'ephox.sugar.api.search.Traverse'
  ],
  function (Fun, Element, Css, Traverse) {
    var getProp = function (propName, elm) {
      var rawElm = elm.dom();
      return rawElm[propName];
    };

    var getComputedSizeProp = function (propName, elm) {
      return parseInt(Css.get(elm, propName), 10);
    };

    var getClientWidth = Fun.curry(getProp, 'clientWidth');
    var getClientHeight = Fun.curry(getProp, 'clientHeight');
    var getMarginTop = Fun.curry(getComputedSizeProp, 'margin-top');
    var getMarginLeft = Fun.curry(getComputedSizeProp, 'margin-left');

    var getBoundingClientRect = function (elm) {
      return elm.dom().getBoundingClientRect();
    };

    var isInsideElementContentArea = function (bodyElm, clientX, clientY) {
      var clientWidth = getClientWidth(bodyElm);
      var clientHeight = getClientHeight(bodyElm);

      return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;
    };

    var transpose = function (inline, elm, clientX, clientY) {
      var clientRect = getBoundingClientRect(elm);
      var deltaX = inline ? clientRect.left + elm.dom().clientLeft + getMarginLeft(elm) : 0;
      var deltaY = inline ? clientRect.top + elm.dom().clientTop + getMarginTop(elm) : 0;
      var x = clientX - deltaX;
      var y = clientY - deltaY;

      return { x: x, y: y };
    };

    // Checks if the specified coordinate is within the visual content area excluding the scrollbars
    var isXYInContentArea = function (editor, clientX, clientY) {
      var bodyElm = Element.fromDom(editor.getBody());
      var targetElm = editor.inline ? bodyElm : Traverse.documentElement(bodyElm);
      var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);

      return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);
    };

    return {
      isXYInContentArea: isXYInContentArea
    };
  }
);
