/* Copyright (c) 2017-2018 Red Hat, Inc. */ var fsm = require('./fsm.js'); var button = require('./button.fsm.js'); var util = require('./util.js'); var animation_fsm = require('./animation.fsm.js'); function Device(id, name, x, y, type, host_id) { this.id = id; this.host_id = host_id ? host_id: 0; this.name = name; this.x = x; this.y = y; this.height = type === "host" ? 20 : 37.5; this.width = 37.5; this.size = 37.5; this.type = type; this.selected = false; this.remote_selected = false; this.moving = false; this.icon = false; this.tasks = []; this.shape = type === "router" ? "circular" : "rectangular"; this.interface_seq = util.natural_numbers(0); this.interfaces = []; this.interfaces_by_name = {}; this.variables = {}; } exports.Device = Device; Device.prototype.toJSON = function () { return {id: this.id, name: this.name, x: this.x, y: this.y, type: this.type, interfaces: this.interfaces.map(function (x) { return x.toJSON(); }), variables: this.variables }; }; Device.prototype.is_selected = function (x, y) { return (x > this.x - this.width && x < this.x + this.width && y > this.y - this.height && y < this.y + this.height); }; Device.prototype.describeArc = util.describeArc; function Interface(id, name) { this.id = id; this.name = name; this.link = null; this.device = null; this.edit_label = false; this.dot_x = null; this.dot_y = null; } exports.Interface = Interface; Interface.prototype.toJSON = function () { return {id: this.id, name: this.name}; }; Interface.prototype.is_selected = function (x, y) { if (this.link === null || this.device === null) { return false; } var d = Math.sqrt(Math.pow(x - this.device.x, 2) + Math.pow(y - this.device.y, 2)); return this.link.is_selected(x, y) && (d < this.dot_d + 30); }; Interface.prototype.dot_distance = function () { this.dot_d = Math.sqrt(Math.pow(this.device.x - this.dot_x, 2) + Math.pow(this.device.y - this.dot_y, 2)); }; Interface.prototype.dot = function () { if (this.link === null || this.device === null) { return; } if (this.link.to_device === null || this.link.from_device === null) { return; } var p; if (this.device.shape === "circular") { var theta = this.link.slope_rads(); if (this.link.from_interface === this) { theta = theta + Math.PI; } p = {x: this.device.x - this.device.size * Math.cos(theta), y: this.device.y - this.device.size * Math.sin(theta)}; this.dot_x = p.x; this.dot_y = p.y; this.dot_distance(); return; } var x1; var y1; var x2; var y2; var x3; var y3; var x4; var y4; var param1; var param2; x3 = this.link.to_device.x; y3 = this.link.to_device.y; x4 = this.link.from_device.x; y4 = this.link.from_device.y; x1 = this.device.x - this.device.width; y1 = this.device.y - this.device.height; x2 = this.device.x + this.device.width; y2 = this.device.y - this.device.height; p = util.intersection(x3, y3, x4, y4, x1, y1, x2, y2); param1 = util.pCase(p.x, p.y, x1, y1, x2, y2); param2 = util.pCase(p.x, p.y, x3, y3, x4, y4); if (param1 >= 0 && param1 <= 1 && param2 >= 0 && param2 <= 1) { this.dot_x = p.x; this.dot_y = p.y; this.dot_distance(); return; } x1 = this.device.x - this.device.width; y1 = this.device.y + this.device.height; x2 = this.device.x + this.device.width; y2 = this.device.y + this.device.height; p = util.intersection(x3, y3, x4, y4, x1, y1, x2, y2); param1 = util.pCase(p.x, p.y, x1, y1, x2, y2); param2 = util.pCase(p.x, p.y, x3, y3, x4, y4); if (param1 >= 0 && param1 <= 1 && param2 >= 0 && param2 <= 1) { this.dot_x = p.x; this.dot_y = p.y; this.dot_distance(); return; } x1 = this.device.x + this.device.width; y1 = this.device.y - this.device.height; x2 = this.device.x + this.device.width; y2 = this.device.y + this.device.height; p = util.intersection(x3, y3, x4, y4, x1, y1, x2, y2); param1 = util.pCase(p.x, p.y, x1, y1, x2, y2); param2 = util.pCase(p.x, p.y, x3, y3, x4, y4); if (param1 >= 0 && param1 <= 1 && param2 >= 0 && param2 <= 1) { this.dot_x = p.x; this.dot_y = p.y; this.dot_distance(); return; } x1 = this.device.x - this.device.width; y1 = this.device.y - this.device.height; x2 = this.device.x - this.device.width; y2 = this.device.y + this.device.height; p = util.intersection(x3, y3, x4, y4, x1, y1, x2, y2); param1 = util.pCase(p.x, p.y, x1, y1, x2, y2); param2 = util.pCase(p.x, p.y, x3, y3, x4, y4); if (param1 >= 0 && param1 <= 1 && param2 >= 0 && param2 <= 1) { this.dot_x = p.x; this.dot_y = p.y; this.dot_distance(); return; } }; function Link(id, from_device, to_device, from_interface, to_interface) { this.id = id; this.from_device = from_device; this.to_device = to_device; this.from_interface = from_interface; this.to_interface = to_interface; this.selected = false; this.remote_selected = false; this.status = null; this.edit_label = false; this.name = ""; } exports.Link = Link; Link.prototype.toJSON = function () { return {from_device_id: this.from_device.id, to_device_id: this.to_device.id, from_interface_id: this.from_interface.id, to_interface_id: this.to_interface.id, name: this.name}; }; Link.prototype.is_selected = function (x, y) { // Is the distance to the mouse location less than 25 if on the label side // or 5 on the other from the shortest line to the link? if (this.to_device === null) { return false; } var d = util.pDistance(x, y, this.from_device.x, this.from_device.y, this.to_device.x, this.to_device.y); if (util.cross_z_pos(x, y, this.from_device.x, this.from_device.y, this.to_device.x, this.to_device.y)) { return d < 10; } else { return d < 10; } }; Link.prototype.slope_rads = function () { //Return the slope in degrees for this link. var x1 = this.from_device.x; var y1 = this.from_device.y; var x2 = this.to_device.x; var y2 = this.to_device.y; return Math.atan2(y2 - y1, x2 - x1); }; Link.prototype.slope = function () { //Return the slope in degrees for this link. var x1 = this.from_device.x; var y1 = this.from_device.y; var x2 = this.to_device.x; var y2 = this.to_device.y; return Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI + 180; }; Link.prototype.pDistanceLine = function (x, y) { var x1 = this.from_device.x; var y1 = this.from_device.y; var x2 = this.to_device.x; var y2 = this.to_device.y; return util.pDistanceLine(x, y, x1, y1, x2, y2); }; Link.prototype.length = function () { //Return the length of this link. var x1 = this.from_device.x; var y1 = this.from_device.y; var x2 = this.to_device.x; var y2 = this.to_device.y; return Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)); }; Link.prototype.plength = function (x, y) { //Return the length of this link. var x1 = this.from_device.x; var y1 = this.from_device.y; var x2 = this.to_device.x; var y2 = this.to_device.y; return util.pDistance(x, y, x1, y1, x2, y2); }; function ContextMenu(name, x, y, width, height, callback, enabled, buttons, tracer) { this.name = name; this.x = x; this.y = y; this.width = width; this.height = height; this.callback = callback; this.is_pressed = false; this.mouse_over = false; this.enabled = false; this.buttons = buttons; this.fsm = new fsm.FSMController(this, "button_fsm", enabled ? button.Start : button.Disabled, tracer); } exports.ContextMenu = ContextMenu; ContextMenu.prototype.is_selected = function (x, y) { return (x > this.x && x < this.x + this.width && y > this.y && y < this.y + this.height); }; function ContextMenuButton(name, x, y, width, height, callback, tracer, type) { this.name = name; this.x = x; this.y = y; this.width = width; this.height = height; this.callback = callback; this.is_pressed = false; this.mouse_over = false; this.enabled = true; this.type = type; this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer); } exports.ContextMenuButton = ContextMenuButton; ContextMenuButton.prototype.is_selected = function (x, y) { return (x > this.x && x < this.x + this.width && y > this.y && y < this.y + this.height); }; function ToolBox(id, name, type, x, y, width, height) { this.id = id; this.name = name; this.type = type; this.x = x; this.y = y; this.width = width; this.height = height; this.items = []; this.spacing = 200; this.scroll_offset = 0; this.selected_item = null; this.enabled = true; } exports.ToolBox = ToolBox; function Test(name, event_trace, fsm_trace, pre_test_snapshot, post_test_snapshot) { this.name = name; this.event_trace = event_trace; this.fsm_trace = fsm_trace; this.pre_test_snapshot = pre_test_snapshot; this.post_test_snapshot = post_test_snapshot; } exports.Test = Test; function TestResult(id, name, result, date, code_under_test) { this.id = id; this.name = name; this.result = result; this.date = date; this.code_under_test = code_under_test; } exports.TestResult = TestResult; function Animation(id, steps, data, scope, tracer, callback) { this.id = id; this.steps = steps; this.active = true; this.frame_number_seq = util.natural_numbers(-1); this.frame_number = 0; this.data = data; this.data.updateZoomBoolean = data.updateZoomBoolean !== undefined ? data.updateZoomBoolean : true; this.callback = callback; this.scope = scope; this.interval = null; this.frame_delay = 17; this.fsm = new fsm.FSMController(this, "animation_fsm", animation_fsm.Start, tracer); } exports.Animation = Animation;