// window.B2_top.Circle(Widget.GREEN, true, 20, 10, 50);
// window.B2_top.category = Widget.CATEGORY_ENTITY;
// CATEGORY_UNSEL_ALL
// CATEGORY_SEL_ALL// - green
// CATEGORY_UPDATE
// GETEGORY_GENERIC_2 //latent
import {
add_new_occupant,
filter_version_drop_down,
gui,
set_selected_widget_item,
update_occupant_names_combobox
} from "../../pre/pre_automotive_assessment.js";
import { OccupantVersion } from "./occupant_version.mjs";
import { ProtocolVehicle, VehicleOccupant } from "./vehicle.mjs";
import { WorkflowOccupant } from "./workflow_occupant.mjs";
export { VehicleGUI };
//AddVehicleToGUI(window,95,16);
class VehicleGUI {
/**
* Class to define a Vehicle GUI and button behaviour with a name supplier product and version number
* to extract the data for the measurement
* @param {any} window Window to place vehicle gui on
* @param {number} x left coordinate of vehicle (on parent window)
* @param {number} y top coordinate of vehicle (on parent window)
* @param {string} [drive_side = VehicleOccupant.LHD] left hand drive (VehicleOccupant.LHD) by default or right hand drive (VehicleOccupant.RHD).
* @example
* let vehicle = new VehicleGUI(gui.wdw_pre_automotive, 97, 16);
*/
constructor(window, x, y, drive_side = VehicleOccupant.LHD) {
this.window = window;
this.x = x;
this.y = y;
this.drive_side = drive_side;
VehicleGUI.AddVehicleToGUI(window, x, y); //should only be called once so put in constructor
this.Update();
}
/**
* occupant buttons are set based on the current protocol selected and the existing
* occupant(s) defined.
*
*
*/
Update(vehicle) {
if (vehicle) {
this.UpdateOccupantButtons(vehicle);
} else {
ErrorMessage(`Gui not updated`);
}
}
/**
*
* @param {ProtocolVehicle} vehicle Protocol vehicle
*/
UpdateOccupantButtons(vehicle) {
// Message(`vehicle ${Object.keys(vehicle)}`);
// Message(`vehicle JSON ${JSON.stringify(vehicle, null, 4)}`);
for (let vehicle_occupant of vehicle.Occupants()) {
let button = this.GetButton(vehicle_occupant.GetSide(this.drive_side), vehicle_occupant.front_rear);
// Ignore squiggles below because Widget objects can have user defined properties added
// @ts-ignore
button.vehicle_occupant = vehicle_occupant;
let category = this.GetCategory(vehicle_occupant);
Message(
`Category = ${category}, side = ${vehicle_occupant.GetSide(this.drive_side)}, front_rear = ${
vehicle_occupant.front_rear
}`
);
VehicleGUI.UpdateOccupantButton(button, category);
}
}
/**
* get the category of the button based on if an existing occupant has been defined for the
* corresponding seat and if it is a valid (and supported) occupant
* @param {VehicleOccupant} vehicle_occupant
* @returns {string}
*/
GetCategory(vehicle_occupant) {
//first check if there is an occupant defined for the current seat
for (let wf_occupant of gui.occupants) {
if (
//wf_occupant.position == vehicle_occupant.position &&
wf_occupant.side == vehicle_occupant.GetSide(this.drive_side) &&
wf_occupant.front_rear == vehicle_occupant.front_rear
) {
//now check if the seat should be empty
if (vehicle_occupant.Empty()) return Category.NOT_REQUIRED;
//now check if defined occupant is of the correct type
var valid_occupant_names = OccupantVersion.GetOnly(
"ALL",
vehicle_occupant.product,
vehicle_occupant.physiology
);
//once we have a list of valid occupant names we check if the name of the occupant
//defined for the current seat is in the list - if so it is valid, else it is invlaid
if (valid_occupant_names.indexOf(wf_occupant.name) != -1) {
return Category.VALID;
} else {
return Category.INVALID;
}
}
}
//if no occupant is defined for the current seat then it should either be empty or latent
if (vehicle_occupant.Empty()) return Category.EMPTY;
else return Category.LATENT;
}
/**
* returns the button widget based on the seat side and row
* @param {string} side
* @param {string} front_rear
* @returns {Widget}
*/
GetButton(side, front_rear) {
// FRONT
if (front_rear == WorkflowOccupant.FRONT) {
if (side == WorkflowOccupant.LEFT) return this.window.B_FrontL;
return this.window.B_FrontR;
} //REAR
else {
if (side == WorkflowOccupant.LEFT) return this.window.B_RearL;
if (side == WorkflowOccupant.RIGHT) return this.window.B_RearR;
return this.window.B_RearM;
}
}
/**
* @param {any} window gui window on which to place the vehicle gui
* @param {number} x left coordinate of vehicle (on parent window)
* @param {number} y top coordinate of vehicle (on parent window)
*/
static AddVehicleToGUI(window, x, y) {
let bonnet = 12;
let boot = 12;
let mid_space = 4;
let side_space = 2;
let tween_space = 1;
let size = 7;
let driver_row = y + bonnet;
let rear_row = driver_row + mid_space + size;
let left_col = x + side_space;
let mid_col = left_col + size + tween_space;
let right_col = mid_col + size + tween_space;
//vehicle outer body
//10,10 to 60,100
window.L_CAR = new Widget(window, Widget.LABEL, x, right_col + size + side_space, y, rear_row + size + boot);
// window.L_CAR.Rectangle(Widget.BLACK, false, 0, 0, 100, 100);
window.L_CAR.xResolution = 1000;
window.L_CAR.yResolution = 1000;
window.L_CAR.lineWidth = 1;
window.L_CAR.Polygon(
Widget.WHITE,
true,
200,
0, //top left
800,
0, //top right
950,
50, //top right corner
1000,
300, //right top
1000,
700, //right bottom
950,
950, //bottom right corner
800,
1000, //bottom right
200,
1000, //bottom left
50,
950, //bottom left corner
0,
700, //left bottom
0,
300, //left top
50,
50, //left top corner
200,
0 //top left
);
//left light
window.L_CAR.Polygon(
Widget.YELLOW,
true,
200,
0, //top left
220,
30, //light corner 2
90,
60, //left bot corner 2
50,
50, //left top corner
200,
0 //top left
);
//right light
window.L_CAR.Polygon(
Widget.YELLOW,
true,
1000 - 200,
0, //top left
1000 - 220,
30, //light corner 2
1000 - 90,
60, //left bot corner 2
1000 - 50,
50, //left top corner
1000 - 200,
0 //top left
);
window.L_CAR.Line(
Widget.GREY,
0,
300, //left top
90,
60 //left bot corner 2
);
window.L_CAR.Line(
Widget.GREY,
90,
60, //left bot corner 2
220, //light corner 2
30
);
window.L_CAR.Line(
Widget.GREY,
220, //light corner 2
30,
1000 - 220, //left bot corer 2
30
);
window.L_CAR.Line(
Widget.GREY,
1000 - 220, //left bot corer 2
30,
1000 - 90,
69
);
window.L_CAR.Line(
Widget.GREY,
1000 - 90,
69,
1000 - 0,
300 //right top
);
window.B_FrontL = new Widget(window, Widget.BUTTON, left_col, left_col + size, driver_row, driver_row + size);
window.B_FrontR = new Widget(window, Widget.BUTTON, right_col, right_col + size, driver_row, driver_row + size);
window.B_RearL = new Widget(window, Widget.BUTTON, left_col, left_col + size, rear_row, rear_row + size);
window.B_RearR = new Widget(window, Widget.BUTTON, right_col, right_col + size, rear_row, rear_row + size);
window.B_RearM = new Widget(window, Widget.BUTTON, mid_col, mid_col + size, rear_row, rear_row + size);
//set button side
window.B_FrontL.side = WorkflowOccupant.LEFT;
window.B_FrontR.side = WorkflowOccupant.RIGHT;
window.B_RearL.side = WorkflowOccupant.LEFT;
window.B_RearR.side = WorkflowOccupant.RIGHT;
window.B_RearM.side = WorkflowOccupant.MIDDLE;
//assign onClick callbacks
window.B_FrontL.onClick = OccupantButtonOnClick;
window.B_FrontR.onClick = OccupantButtonOnClick;
window.B_RearL.onClick = OccupantButtonOnClick;
window.B_RearR.onClick = OccupantButtonOnClick;
window.B_RearM.onClick = OccupantButtonOnClick;
}
static UpdateOccupantButton(widget, category = Category.EMPTY) {
widget.Clear();
Category.SetButtonCategory(widget, category);
if (!widget.vehicle_occupant.Empty()) {
//draw passenger
widget.xResolution = 500;
widget.yResolution = 500;
widget.Circle(Widget.GREY, true, 250, 370, 180);
widget.Rectangle(Widget.GREY, true, 0, 0, 100, 400);
widget.Rectangle(Widget.GREY, true, 400, 0, 500, 400);
if (widget.vehicle_occupant.position == WorkflowOccupant.DRIVER) {
widget.Rectangle(Widget.BLACK, true, 50, 0, 450, 75);
}
widget.hover += ` (${widget.vehicle_occupant.product}-${widget.vehicle_occupant.physiology})`;
}
gui.wdw_pre_automotive.Redraw();
}
}
/**
* update the filters on the occupant window to only allow valid occupants
*/
function OccupantButtonOnClick() {
let wdw = gui.wdw_occupant;
let button = this;
let vehicle_occupant = button.vehicle_occupant;
if (vehicle_occupant && vehicle_occupant.product && vehicle_occupant.physiology) {
wdw.cbx_occupant_name.active = true;
wdw.cbx_occupant_supplier.active = true;
wdw.cbx_occupant_product.active = true;
wdw.cbx_occupant_physiology.active = true;
set_selected_widget_item(wdw.cbx_occupant_supplier, "all");
Message(`Sellected supplier: ${wdw.cbx_occupant_supplier.text}`);
set_selected_widget_item(wdw.cbx_occupant_product, vehicle_occupant.product);
set_selected_widget_item(wdw.cbx_occupant_physiology, vehicle_occupant.physiology);
set_selected_widget_item(wdw.cbx_occupant_position, vehicle_occupant.position);
set_selected_widget_item(wdw.cbx_occupant_side, button.side);
set_selected_widget_item(wdw.cbx_occupant_front_rear, vehicle_occupant.front_rear);
//once all the widget items have been set call update filters to update the drop-down
//list of occupant names
let occupant_names = filter_version_drop_down();
update_occupant_names_combobox(occupant_names);
add_new_occupant();
}
}
class Category {
/** empty - no occupant defined and no occupant required
* @type {string} */
static get EMPTY() {
return "empty";
}
/** not empty - occupant is defined for this seat but is not required (should be empty)
* @type {string} */
static get NOT_REQUIRED() {
return "not required";
}
/** valid - occupant is defined and matched required tyoed
* @type {string} */
static get VALID() {
return "valid";
}
/** invalid - occupant defined but not valid (for selected protocol)
* @type {string} */
static get INVALID() {
return "invalid";
}
/** latent - occupant should be defined
* @type {string} */
static get LATENT() {
return "latent";
}
static SetButtonCategory(widget, category_status, seat_status) {
switch (category_status) {
case Category.EMPTY:
widget.hover = category_status;
widget.category = Widget.CATEGORY_GENERIC_2;
break;
case Category.NOT_REQUIRED:
widget.hover = category_status;
widget.category = Widget.NO_CATEGORY;
widget.background = Widget.RED;
break;
case Category.VALID:
widget.hover = category_status;
widget.category = Widget.NO_CATEGORY;
// widget.foreground = Widget.BLACK;
widget.background = Widget.GREEN;
break;
case Category.INVALID:
widget.hover = category_status;
widget.category = Widget.NO_CATEGORY;
widget.background = Widget.RED;
break;
case Category.LATENT:
widget.hover = category_status;
widget.category = Widget.NO_CATEGORY;
widget.background = Widget.ORANGE;
break;
default:
Message(`Category "${category_status}" is not supported.`);
break;
}
}
}