"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.rgb)); } else { var ratio = 0; var promiseColor = null; if (elementOverlay.value !== undefined && elementOverlay.value !== null) { if (elementOverlay.value < 0) { ratio = -elementOverlay.value; promiseColor = ServerConnector.getMinOverlayColorInt(); } else { ratio = elementOverlay.value; promiseColor = ServerConnector.getMaxOverlayColorInt(); } } else { ratio = 1; promiseColor = ServerConnector.getSimpleOverlayColorInt(); } 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); }); } }; 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;