import CircuitElement from '../circuitElement';
import Node, { findNode } from '../node';
import simulationArea from '../simulationArea';
import { correctWidth, lineTo, moveTo, fillText3 } from '../canvasApi';
import { colors } from '../themer/themer';
/**
* @class
* TTY
* TypeWriter - We can give 4 inputs:
* clock and input of 7 bits are main input required
* on the edge change the data is added onto the display
* screen of the typewriter
* @extends CircuitElement
* @param {number} x - x coord of element
* @param {number} y - y coord of element
* @param {Scope=} scope - the ciruit in which we want the Element
* @param {string=} dir - direcion in which element has to drawn
* @category sequential
*/
export default class TTY extends CircuitElement {
constructor(x, y, scope = globalScope, rows = 3, cols = 32) {
super(x, y, scope, 'RIGHT', 1);
/*
this.scope['TTY'].push(this);
*/
this.directionFixed = true;
this.fixedBitWidth = true;
this.cols = cols || parseInt(prompt('Enter cols:'));
this.rows = rows || parseInt(prompt('Enter rows:'));
this.elementWidth = Math.max(40, Math.ceil(this.cols / 2) * 20);
this.elementHeight = Math.max(40, Math.ceil(this.rows * 15 / 20) * 20);
this.setWidth(this.elementWidth / 2);
this.setHeight(this.elementHeight / 2);
// this.element = new Element(x, y, "TTY",this.elementWidth/2, this,this.elementHeight/2);
this.clockInp = new Node(-this.elementWidth / 2, this.elementHeight / 2 - 10, 0, this, 1, 'Clock');
this.asciiInp = new Node(-this.elementWidth / 2, this.elementHeight / 2 - 30, 0, this, 7, 'Ascii Input');
// this.qOutput = new Node(20, -10, 1, this);
this.reset = new Node(30 - this.elementWidth / 2, this.elementHeight / 2, 0, this, 1, 'Reset');
this.en = new Node(10 - this.elementWidth / 2, this.elementHeight / 2, 0, this, 1, 'Enable');
// this.masterState = 0;
// this.slaveState = 0;
this.prevClockState = 0;
this.data = '';
this.buffer = '';
}
/**
* @memberof TTY
* this function is used to change the size of the screen
*/
changeRowSize(size) {
if (size == undefined || size < 1 || size > 10) return;
if (this.rows == size) return;
var obj = new TTY(this.x, this.y, this.scope, size, this.cols);
this.delete();
simulationArea.lastSelected = obj;
return obj;
}
/**
* @memberof TTY
* this function is used to change the size of the screen
*/
changeColSize(size) {
if (size == undefined || size < 20 || size > 100) return;
if (this.cols == size) return;
var obj = new TTY(this.x, this.y, this.scope, this.rows, size);
this.delete();
simulationArea.lastSelected = obj;
return obj;
}
/**
* @memberof TTY
* if no input or enable key is set to 0 returns false
*/
isResolvable() {
if (this.reset.value == 1) return true;
if (this.en.value == 0 || (this.en.connections.length && this.en.value == undefined)) return false;
else if (this.clockInp.value == undefined) return false;
else if (this.asciiInp.value == undefined) return false;
return true;
}
/**
* @memberof TTY
* To resolve the Typewriter clock and input of 7 bits are
* used to get the ascii and then on the edge change the
* data is added onto the display screen of the typewriter.
*/
resolve() {
if (this.reset.value == 1) {
this.data = '';
return;
}
if (this.en.value == 0) {
this.buffer = '';
return;
}
if (this.clockInp.value == this.prevClockState) {
if (this.clockInp.value == 0) {
this.buffer = String.fromCharCode(this.asciiInp.value);
}
} else if (this.clockInp.value != undefined) {
if (this.clockInp.value == 1) {
this.data += this.buffer;
if (this.data.length > this.cols * this.rows) { this.data = this.data.slice(1); }
} else if (this.clockInp.value == 0) {
this.buffer = String.fromCharCode(this.asciiInp.value);
}
this.prevClockState = this.clockInp.value;
}
}
customSave() {
var data = {
nodes: {
clockInp: findNode(this.clockInp),
asciiInp: findNode(this.asciiInp),
reset: findNode(this.reset),
en: findNode(this.en),
},
constructorParamaters: [this.rows, this.cols],
};
return data;
}
customDraw() {
var ctx = simulationArea.context;
//
ctx.strokeStyle = (colors['stroke']);
ctx.fillStyle = (colors['fill']);
ctx.beginPath();
ctx.lineWidth = correctWidth(3);
var xx = this.x;
var yy = this.y;
// rect(ctx, xx - this.elementWidth/2, yy - this.elementHeight/2, this.elementWidth, this.elementHeight);
moveTo(ctx, -this.elementWidth / 2, this.elementHeight / 2 - 15, xx, yy, this.direction);
lineTo(ctx, 5 - this.elementWidth / 2, this.elementHeight / 2 - 10, xx, yy, this.direction);
lineTo(ctx, -this.elementWidth / 2, this.elementHeight / 2 - 5, xx, yy, this.direction);
// if ((this.b.hover&&!simulationArea.shiftDown)|| simulationArea.lastSelected == this || simulationArea.multipleObjectSelections.contains(this))
// ctx.fillStyle = "rgba(255, 255, 32,0.8)";
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = colors['input_text'];
ctx.textAlign = 'center';
var startY = -7.5 * this.rows + 3;
for (var i = 0; i < this.data.length; i += this.cols) {
var lineData = this.data.slice(i, i + this.cols);
lineData += ' '.repeat(this.cols - lineData.length);
fillText3(ctx, lineData, 0, startY + (i / this.cols) * 15 + 9, xx, yy, 15, 'Courier New', 'center');
}
ctx.fill();
}
}
TTY.prototype.tooltipText = 'TTY ToolTip : Tele typewriter selected.';
TTY.prototype.helplink = 'https://docs.circuitverse.org/#/chapter4/6sequentialelements?id=tty';
TTY.prototype.mutableProperties = {
'cols': {
name: 'Columns',
type: 'number',
max: '100',
min: '20',
func: 'changeColSize',
},
'rows': {
name: 'Rows',
type: 'number',
max: '10',
min: '1',
func: 'changeRowSize',
},
};
TTY.prototype.objectType = 'TTY';
Source