Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Functions.js 7.96 KiB
"use strict";

var Promise = require("bluebird");

/* exported logger */

var logger = require('./logger');

var Functions = {};

/**
 * Bounds value between opt_min and opt_max (result will be not smaller than
 * opt_min and not bigger than opt_max).
 */
Functions.bound = function(value, minVal, maxVal) {
  if (minVal !== null && minVal !== undefined) {
    value = Math.max(value, minVal);
  }
  if (maxVal !== null && maxVal !== undefined) {
    value = Math.min(value, maxVal);
  }
  return value;
};

Functions.degreesToRadians = function(deg) {
  return deg * (Math.PI / 180);
};

Functions.radiansToDegrees = function(rad) {
  return rad / (Math.PI / 180);
};

Functions.intToColorString = function(value) {
  /* jslint bitwise: true */
  var timmedValue = (value & 0xFFFFFF);
  var colorStr = timmedValue.toString(16);
  while (colorStr.length < 6) {
    colorStr = "0" + colorStr;
  }
  return '#' + colorStr;
};

/**
 * Returns stack trace.
 * 
 * @returns stack trace
 */
Functions.stackTrace = function() {
  var err = new Error();
  return err.stack;
};

/**
 * Returns the position of the element on html page.
 * 
 * @param element
 *          element for which we want to get the position (top left corner)
 * 
 * @return coordinates of the element
 * 
 */
Functions.getPosition = function(element) {
  var xPosition = 0;
  var yPosition = 0;

  while (element) {
    xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
    yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
    element = element.offsetParent;
  }
  return {
    x : xPosition,
    y : yPosition
  };
};

/**
 * Checks if the point given as a first argument belongs to a polygon defined as
 * a second parameter. Both: point and polygon should use google.map.point
 * class.
 * 
 * @param point
 *          point which we want to check
 * 
 * @param polygon
 *          polygon where we check the point
 */

Functions.pointInsidePolygon = function(point, polygon) {
  var x = point.x;
  var y = point.y;

  var inside = false;
  for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    var xi = polygon[i].x, yi = polygon[i].y;
    var xj = polygon[j].x, yj = polygon[j].y;
    var intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
    if (intersect) {
      inside = !inside;
    }
  }
  return inside;
};

/**
 * In a browser variable we store inforamtion about browser user is currently
 * using. Right now only IE is suppoerted.
 */
Functions.browser = {
  init : function() {

    this.name = "Unknown";
    this.version = "Unknown";

    if (typeof navigator !== 'undefined') {
      // Get the user agent string
      var ua = navigator.userAgent;
      this.compatibilityMode = false;
      var re;
      if (navigator.appName === 'Microsoft Internet Explorer') {
        this.name = "IE";
        re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) !== undefined && re.exec(ua) !== null) {
          this.version = parseFloat(RegExp.$1);
        }
        if (ua.indexOf("MSIE 7.0") > -1) {
          this.compatibilityMode = true;
        }
      } else if (navigator.appName === 'Netscape') {
        this.name = "Other";
        ua = navigator.userAgent;
        re = new RegExp("Trident/.*rv[ :]*([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) !== undefined && re.exec(ua) !== null) {
          this.version = parseFloat(RegExp.$1);
        }
      }
    }
  }
};
Functions.browser.init();

/**
 * Returns true if parameter is integer, false otherwise.
 * 
 * @param n
 *          object to check
 */
Functions.isInt = function(n) {
  return Number(n) === n && n % 1 === 0;
};

/**
 * Returns true if parameter is a DOM element, false otherwise.
 * 
 * @param o
 *          object to check
 */
Functions.isDomElement = function(o) {
  if (!o) {
    return false;
  }
  return (typeof HTMLElement === "object" ? o instanceof HTMLElement : // DOM2
  o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string");
};

Functions.overlayToColor = function(elementOverlay) {
  var self = this;
  /* jslint bitwise: true */
  if (elementOverlay === null || elementOverlay === undefined) {
    return Promise.reject("elementOverlay cannot be null!");
  } else if (elementOverlay.color !== undefined && elementOverlay.color !== null) {
    return Promise.resolve(self.intToColorString(elementOverlay.color.value));
  } else if (elementOverlay.value !== undefined && elementOverlay.value !== null) {
    var ratio = 0;
    var promiseColor = null;
    if (elementOverlay.value < 0) {
      ratio = -elementOverlay.value;
      promiseColor = ServerConnector.getMinOverlayColorInt();
    } else {
      ratio = elementOverlay.value;
      promiseColor = ServerConnector.getMaxOverlayColorInt();
    }
    return promiseColor.then(function(color) {

      ratio = 1 - ratio;
      var MAX_RED = 0xFF0000;
      var MAX_GREEN = 0x00FF00;
      var MAX_BLUE = 0x0000FF;

      var red = color & MAX_RED;

      red = red + (MAX_RED - red) * ratio;
      red = parseInt(red);
      red = red & 0xFF0000;

      var green = color & MAX_GREEN;
      green = green + (MAX_GREEN - green) * ratio;
      green = parseInt(green);
      green = green & MAX_GREEN;

      var blue = color & MAX_BLUE;
      blue = blue + (MAX_BLUE - blue) * ratio;
      blue = parseInt(blue);
      blue = blue & MAX_BLUE;

      color = red | green | blue;
      return self.intToColorString(color);
    });
  } else {
    return Promise.reject("elementOverlay doesn't have neither color nor value set!");
  }
};

Functions.getElementByName = function(element, name) {
  if (element !== undefined) {
    if (element.getAttribute("name") === name) {
      return element;
    }
    var children = element.children;
    for (var i = 0; i < children.length; i++) {
      var child = children[i];
      var res = this.getElementByName(child, name);
      if (res !== undefined) {
        return res;
      }
    }
  }
  return undefined;
};

Functions.createElement = function(params) {
  var result = document.createElement(params.type);
  if (params.id !== null && params.id !== undefined) {
    result.id = params.id;
  }
  if (params.name !== null && params.name !== undefined) {
    result.setAttribute("name", params.name);
  }
  if (params.className !== null && params.className !== undefined) {
    result.className = params.className;
  }
  if (params.inputType !== null && params.inputType !== undefined) {
    result.type = params.inputType;
  }
  if (params.content !== null && params.content !== undefined) {
    result.innerHTML = params.content;
  }
  if (params.style !== null && params.style !== undefined) {
    result.style.cssText = params.style;
  }
  if (params.onclick !== null && params.onclick !== undefined) {
    result.onclick = params.onclick;
  }
  if (params.href !== null && params.href !== undefined) {
    result.href = params.href;
  }
  if (params.src !== null && params.src !== undefined) {
    result.src = params.src;
  }
  return result;
};

function sqr(x) {
  return x * x;
}

function dist2(v, w) {
  return sqr(v.x - w.x) + sqr(v.y - w.y);
}

function distToSegmentSquared(p, v, w) {
  var l2 = dist2(v, w);

  if (l2 === 0) {
    return dist2(p, v);
  }

  var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
  if (t < 0) {
    return dist2(p, v);
  }
  if (t > 1) {
    return dist2(p, w);
  }

  return dist2(p, new google.maps.Point(v.x + t * (w.x - v.x), v.y + t * (w.y - v.y)));
}
Functions.distance = function(p1, el2) {
  if (el2 instanceof google.maps.Point) {
    var p2 = el2;
    return Math.sqrt((Math.pow(p1.x - p2.x, 2)) + (Math.pow(p1.y - p2.y, 2)));
  } else {
    return Math.sqrt(distToSegmentSquared(p1, el2.start, el2.end));
  }
};
module.exports = Functions;