// Imports
import {generateUUID, htmlOlCommandsOperations} from './../../main';
import {
getOperationTypeByValue, getOperatorByHash,
getOperatorTypeByValue,
htmlAssignVariableScheme,
htmlOperationKindScheme, htmlOperationTypeSelect, htmlOperatorValueInputScheme,
htmlOperatorVariablesSelectScheme,
operationScheme, Operators, operatorScheme, printOperationScheme
} from "./operations-schemes";
import {getVariableByHash, variables} from "../variables/variables";
// Imports
export const operations = [];
// Creating operation
export function createOperation () {
let operation = Object.assign({}, operationScheme);
operation.hash = generateUUID().replaceAll('-', '');
// TODO: Fix
operation.assignedVariable = variables[0];
operation.operators = [];
operations.push(operation);
let htmlOperation = htmlAssignVariableScheme();
htmlOperation = htmlOperation.replaceAll('', operation.hash);
htmlOlCommandsOperations.insertAdjacentHTML('beforeend', htmlOperation);
document.getElementById(`operation${operation.hash}AssignVariableSelect`).addEventListener('change', ev => {
updateOperationAssignValue(ev.target.getAttribute('operation-id'), ev.target.value);
});
document.getElementById(`operation${operation.hash}Delete`).addEventListener('click', ev => {
deleteOperation(ev.target.getAttribute('operation-id'));
});
addOperatorKind(operation.hash);
updateResume(operation.hash);
// Changing focus to the variable type after creation for screen readers
document.getElementById(`operation${operation.hash}AssignVariableSelect`).focus();
}
// Add operator kind to the operation
export function addOperatorKind (hash) {
let operation = getOperationByHash(hash);
console.log(operation);
let htmlOperationKind = htmlOperationKindScheme(operation);
document.getElementById(`operation${operation.hash}OperatorsDiv`).insertAdjacentHTML('beforeend', htmlOperationKind);
document.getElementById(`operation${operation.hash}KindSelect`).addEventListener('change', ev => {
selectedOperationKind(ev.target.getAttribute('operation-id'));
});
}
// Function to be trigger when the operator kind is selected
export function selectedOperationKind (operationHash) {
let operation = getOperationByHash(operationHash);
console.log(operation);
let kindSelect = document.getElementById(`operation${operation.hash}KindSelect`);
// TODO: think into an way to make this dynamic
if (kindSelect.value === 'VARIABLE') {
insertVariableAfterOperationKind(kindSelect, operation);
} else if (kindSelect.value === 'VALUE') {
insertValueAfterOperationKind(kindSelect, operation);
}
}
// Insert variable after operator kind select
export function insertVariableAfterOperationKind (kindSelect, operation) {
let operator = Object.assign({}, operatorScheme);
operator.hash = generateUUID().replaceAll('-', '');
// TODO: Fix ?
operator.variable = variables[0];
operator.type = getOperatorTypeByValue('VARIABLE');
let operatorVariableSelect = htmlOperatorVariablesSelectScheme(operation, operator);
operation.operators.push(operator);
kindSelect.parentElement.parentElement.insertAdjacentHTML('beforeend', operatorVariableSelect);
kindSelect.parentElement.remove();
insertOperationTypeAtEndOfOperation(operation, operator);
document.getElementById(`operation${operation.hash}Operator${operator.hash}VariableSelect`).addEventListener('change', ev => {
updateOperationOperator(ev.target.getAttribute('operation-id'), ev.target.getAttribute('operator-id'), ev.target.value)
});
updateResume(operation.hash);
// Changing focus to the variable select after select for screen readers
document.getElementById(`operation${operation.hash}Operator${operator.hash}VariableSelect`).focus();
}
// Insert value after operator kind select
export function insertValueAfterOperationKind (kindSelect, operation) {
let operator = Object.assign({}, operatorScheme);
operator.hash = generateUUID().replaceAll('-', '');
operator.type = getOperatorTypeByValue('VALUE');
let operatorValueInput = htmlOperatorValueInputScheme(operation, operator);
operation.operators.push(operator);
kindSelect.parentElement.parentElement.insertAdjacentHTML('beforeend', operatorValueInput);
kindSelect.parentElement.remove();
insertOperationTypeAtEndOfOperation(operation, operator);
document.getElementById(`operation${operation.hash}Operator${operator.hash}ValueInput`).addEventListener('change', ev => {
updateOperationOperator(ev.target.getAttribute('operation-id'), ev.target.getAttribute('operator-id'), ev.target.value)
});
updateResume(operation.hash);
// Changing focus to the input value after select for screen readers
document.getElementById(`operation${operation.hash}Operator${operator.hash}ValueInput`).focus();
}
// Add final operation type end of the operation
export function insertOperationTypeAtEndOfOperation (operation, afterOperator) {
let operator = Object.assign({}, operatorScheme);
operator.hash = generateUUID().replaceAll('-', '');
operator.type = getOperatorTypeByValue('OPERATOR');
operator.operator = getOperationTypeByValue('SEMICOLON');
let operationTypeInput = htmlOperationTypeSelect(operation, operator);
operationTypeInput.replaceAll('', operator.hash);
operation.operators.push(operator);
if (afterOperator.type.value === 'VARIABLE') {
document.querySelector(`select[operator-id='${afterOperator.hash}']`).parentElement.insertAdjacentHTML('afterend', operationTypeInput);
} else if (afterOperator.type.value === 'VALUE') {
document.querySelector(`input[operator-id='${afterOperator.hash}']`).parentElement.insertAdjacentHTML('afterend', operationTypeInput);
}
document.getElementById(`operation${operation.hash}Operator${operator.hash}OperationTypeSelect`).addEventListener('change', ev => {
updateOperationOperator(ev.target.getAttribute('operation-id'), ev.target.getAttribute('operator-id'), ev.target.value)
});
}
// ***********************************************************************
// Listeners
// ***********************************************************************
export function updateOperationAssignValue (operationHash, newVariable) {
let operation = getOperationByHash(operationHash);
let variable = getVariableByHash(newVariable);
operation.assignedVariable = variable;
updateResume(operation.hash);
}
export function updateOperationOperator (operationHash, operatorHash, newValue) {
let operation = getOperationByHash(operationHash);
let operator = getOperatorByHash(operation, operatorHash);
switch (operator.type.value) {
case 'VARIABLE':
let variable = getVariableByHash(newValue);
operator.variable = variable;
break;
case 'VALUE':
operator.value = newValue;
break;
case 'OPERATOR':
operator.operator = getOperationTypeByValue(newValue);
const operationTypeSelect = document.getElementById(`operation${operation.hash}Operator${operator.hash}OperationTypeSelect`);
// If the operator isn't a semicolumn, it is the last item on the operator list and teh next elemtn is equal to null,
// we need to add a new operator select
if (operator.operator.name !== ';'
&& (operation.operators.indexOf(operator) === (operation.operators.length - 1))
&& operationTypeSelect.parentElement.nextElementSibling == null)
addOperatorKind(operation.hash);
else if (operator.operator.name === ';'
&& (operation.operators.indexOf(operator) === (operation.operators.length - 1))
&& operationTypeSelect.parentElement.nextElementSibling != null)
operationTypeSelect.parentElement.nextElementSibling.remove();
else if (operator.operator.name === ';'
&& (operation.operators.indexOf(operator) !== (operation.operators.length - 1))
&& operationTypeSelect.parentElement.nextElementSibling != null) {
let indexOfOperator = operation.operators.indexOf(operator) + 1;
operation.operators.splice(indexOfOperator);
let elementSibling = operationTypeSelect.parentElement.nextElementSibling;
let nextElementSibling = operationTypeSelect.parentElement.nextElementSibling;
while(nextElementSibling != null) {
nextElementSibling = elementSibling.nextElementSibling;
elementSibling.remove();
elementSibling = nextElementSibling;
}
}
break;
}
updateResume(operation.hash);
}
// Here we remove all operation that include the variable received as parameter
export function deleteOperationByVariable (variable) {
const operationsToRemove = [];
for (const i in operations) {
console.log(operations[i]);
if (operations[i].assignedVariable.hash === variable.hash) {
document.getElementById(`operation${operations[i].hash}Li`).remove();
operationsToRemove.push(operations[i]);
continue;
}
for (const j in operations[i].operators) {
console.log(j);
console.log(operations[i].operators[j]);
if (operations[i].operators[j].type.value === Operators.VARIABLE) {
if (operations[i].operators[j].variable.hash === variable.hash) {
document.getElementById(`operation${operations[i].hash}Li`).remove();
operationsToRemove.push(operations[i]);
// if (operation.operators.length > 2) {
//
// } else {
//
// }
}
}
}
}
for (const i in operationsToRemove) {
operations.splice(operations.indexOf(operationsToRemove[i]), 1);
}
}
// Here we remove all operation that include the variable received as parameter
export function deleteOperation (hash) {
const operation = getOperationByHash(hash);
document.getElementById(`operation${hash}Li`).remove();
operations.splice(operations.indexOf(operation), 1);
}
// Here we remove all operation
export function deleteAllOperation () {
for (let i = 0; i < operations.length; i++) {
document.getElementById(`operation${operations[i].hash}Li`).remove();
}
operations.length = 0;
}
// ***********************************************************************
// Updating variable resume
// ***********************************************************************
function updateResume (hash) {
document.getElementById(`operation${hash}Resume`).setAttribute('title', generateResume(hash));
}
function generateResume (hash) {
const operation = getOperationByHash(hash);
let resume;
switch (operation.type) {
case 'ASSIGN':
resume = `${operation.assignedVariable.name}, recebe: `;
for (const i in operation.operators) {
console.log(operation.operators[i]);
switch (operation.operators[i].type.value) {
case Operators.OPERATOR:
resume += `${operation.operators[i].operator.friendlyName} `;
break;
case Operators.VALUE:
resume += `${operation.operators[i].value} `;
break;
case Operators.VARIABLE:
resume += `${operation.operators[i].variable.name} `;
break;
}
}
break;
case 'PRINT':
resume = `Escreva a variável: ${operation.assignedVariable.name}`
}
return resume;
}
// ***********************************************************************
// Print
// ***********************************************************************
export function createPrintOperation () {
const operation = Object.assign({}, operationScheme);
operation.hash = generateUUID().replaceAll('-', '');
operation.assignedVariable = variables.length > 0 ? variables[0] : null;
operation.type = 'PRINT';
operations.push(operation);
const printOperation = printOperationScheme(operation);
htmlOlCommandsOperations.insertAdjacentHTML('beforeend', printOperation);
updateResume(operation.hash);
// Changing focus to the variable type after creation for screen readers
document.getElementById(`operation${operation.hash}VariableSelectLabel`).focus();
document.getElementById(`operation${operation.hash}VariableSelect`).addEventListener('change', ev => {
updatePrintOperation(ev.target.getAttribute('operation-id'), ev.target.value);
});
document.getElementById(`operation${operation.hash}Delete`).addEventListener('click', ev => {
deleteOperation(ev.target.getAttribute('operation-id'));
});
}
// TODO:
// terminal => basico
function updatePrintOperation (hash, newValue) {
const operation = getOperationByHash(hash);
const variable = getVariableByHash(newValue);
operation.assignedVariable = variable;
updateResume(operation.hash);
}
// ***********************************************************************
// Util
// ***********************************************************************
export function getOperationByHash (hash) {
for (let i = 0; i < operations.length; i++) {
if (operations[i].hash === hash)
return operations[i];
}
return null;
}
// ***********************************************************************