import { FF_D_MasterSlave } from "./FF_D.js";
import { Gate } from "./Gate.js";
import { IC_type } from "./Enums.js";
import { Integrated } from "./Integrated.js";
import { Node } from "./Node.js";
/**
* FlipFlop JK class
* @classdesc FlipFlop JK class
* @extends Integrated
* @memberof module:IntegratedCiruits
*/
export class FF_JK extends Integrated {
/**
* @constructor
* @param {Number} isNegativeEdgeTrig Flag for Negative or Positive Edge Trigger
*/
constructor(isNegativeEdgeTrig) {
super(IC_type.FF_JK);
this.nodeJ = new Node(this.posX + 5, this.posY + 30);
this.nodeClock = new Node(this.posX + 5, this.posY + (this.height / 2));
this.nodeK = new Node(this.posX + 5, this.posY + this.height - 30);
this.nodeQ = new Node(this.posX + this.width - 5, this.posY + 30, true);
this.nodeNotQ = new Node(this.posX + this.width + 5, this.posY + this.height - 30, true);
this.ff_D = new FF_D_MasterSlave();
this.orGate = new Gate("OR");
this.andGate_Q = new Gate("AND");
this.andGate_NotQ = new Gate("AND");
this.isNegativeEdgeTrig = isNegativeEdgeTrig;
this.nodeStartID = nodeJ.id;
}
/**
* Destroy this FF_JK
*/
destroy() {
this.nodeK.destroy();
this.nodeClock.destroy();
this.nodeJ.destroy();
this.nodeQ.destroy();
this.nodeNotQ.destroy();
}
/**
* Draw this FF_JK
*/
draw() {
super.draw();
this.generateOutput();
this.nodeJ.updatePosition(this.posX + 5, this.posY + 30);
this.nodeClock.updatePosition(this.posX + 5, this.posY + (this.height / 2));
this.nodeK.updatePosition(this.posX + 5, this.posY + this.height - 30);
this.nodeQ.updatePosition(this.posX + this.width - 5, this.posY + 30);
this.nodeNotQ.updatePosition(this.posX + this.width - 5, this.posY + this.height - 30);
this.nodeJ.draw();
this.nodeClock.draw();
this.nodeK.draw();
this.nodeQ.draw();
this.nodeNotQ.draw();
if (this.isNegativeEdgeTrig) {
fill(0xFF); // white
stroke(0);
strokeWeight(2);
circle(this.posX + 17, this.posY + (this.height / 2), 8);
}
}
/**
* Refresh this FF_JK nodes ID
*/
refreshNodes()
{
let currentID = this.nodeStartID;
this.nodeJ.setID(currentID);
currentID++;
this.nodeClock.setID(currentID);
currentID++;
this.nodeK.setID(currentID);
currentID++;
this.nodeQ.setID(currentID);
currentID++;
this.nodeNotQ.setID(currentID);
}
/**
* Generate this FF_JK output
*/
generateOutput() {
let clockValue = this.isNegativeEdgeTrig ? this.nodeClock.value : !this.nodeClock.value;
this.andGate_NotQ.input[0].value = this.nodeJ.value;
this.andGate_NotQ.input[1].value = this.ff_D.nodeNotQ.value;
this.andGate_Q.input[0].value = !this.nodeK.value;
this.andGate_Q.input[1].value = this.ff_D.nodeQ.value;
this.andGate_Q.generateOutput();
this.andGate_NotQ.generateOutput();
this.orGate.input[0].value = this.andGate_Q.output.value;
this.orGate.input[1].value = this.andGate_NotQ.output.value;
this.orGate.generateOutput();
this.ff_D.nodeD.value = this.orGate.output.value;
this.ff_D.nodeClock.value = clockValue;
this.ff_D.generateOutput();
this.nodeQ.value = this.ff_D.nodeQ.value;
this.nodeNotQ.value = this.ff_D.nodeNotQ.value;
}
/**
* Called when mouse is clicked
* @returns {Boolean} Boolean, true if element is clicked
*/
mouseClicked() {
//Return true if at least one component is clicked
let result = this.isMouseOver();
result |= this.nodeJ.mouseClicked();
result |= this.nodeK.mouseClicked();
result |= this.nodeClock.mouseClicked();
result |= this.nodeQ.mouseClicked();
result |= this.nodeNotQ.mouseClicked();
return result;
}
}