'use strict';
const utils = require('./util/utils');
// Attaches utility functions to a Rac instance that add functions to all
// drawable and style class prototypes.
//
// Intended to receive the Rac class as parameter.
module.exports = function attachProtoFunctions(Rac) {
function assertDrawer(drawable) {
if (drawable.rac == null || drawable.rac.drawer == null) {
throw Rac.Exception.drawerNotSetup(
`drawable-type:${utils.typeName(drawable)}`);
}
}
// Container of prototype functions for drawable classes.
Rac.drawableProtoFunctions = {};
/**
* Adds to `drawableClass.prototype` all the functions contained in
* `Rac.drawableProtoFunctions`. These are the functions shared by all
* drawable objects, for example `draw()` and `debug()`.
*
* @param {class} drawableClass - Class to setup with drawable functions
*/
Rac.setupDrawableProtoFunctions = function(drawableClass) {
Object.keys(Rac.drawableProtoFunctions).forEach(name => {
drawableClass.prototype[name] = Rac.drawableProtoFunctions[name];
});
}
Rac.drawableProtoFunctions.draw = function(style = null){
assertDrawer(this);
this.rac.drawer.drawObject(this, style);
return this;
};
Rac.drawableProtoFunctions.debug = function(drawsText = false){
assertDrawer(this);
this.rac.drawer.debugObject(this, drawsText);
return this;
};
Rac.drawableProtoFunctions.log = function(message = null){
let coalescedMessage = message ?? '%o';
console.log(coalescedMessage, this);
return this;
};
Rac.drawableProtoFunctions.push = function() {
this.rac.pushStack(this);
return this;
}
Rac.drawableProtoFunctions.pop = function() {
return this.rac.popStack();
}
Rac.drawableProtoFunctions.peek = function() {
return this.rac.peekStack();
}
Rac.drawableProtoFunctions.attachToShape = function() {
this.rac.peekShape().addOutline(this);
return this;
}
Rac.drawableProtoFunctions.popShape = function() {
return this.rac.popShape();
}
Rac.drawableProtoFunctions.popShapeToComposite = function() {
let shape = this.rac.popShape();
this.rac.peekComposite().add(shape);
return this;
}
Rac.drawableProtoFunctions.attachToComposite = function() {
this.rac.peekComposite().add(this);
return this;
}
Rac.drawableProtoFunctions.popComposite = function() {
return this.rac.popComposite();
}
Rac.drawableProtoFunctions.attachTo = function(someComposite) {
if (someComposite instanceof Rac.Composite) {
someComposite.add(this);
return this;
}
if (someComposite instanceof Rac.Shape) {
someComposite.addOutline(this);
return this;
}
throw Rac.Exception.invalidObjectType(
`Cannot attachTo composite - someComposite-type:${utils.typeName(someComposite)}`);
};
// Container of prototype functions for style classes.
Rac.styleProtoFunctions = {};
// Adds to the given class prototype all the functions contained in
// `Rac.styleProtoFunctions`. These are functions shared by all
// style objects (E.g. `apply()`).
Rac.setupStyleProtoFunctions = function(classObj) {
Object.keys(Rac.styleProtoFunctions).forEach(name => {
classObj.prototype[name] = Rac.styleProtoFunctions[name];
});
}
Rac.styleProtoFunctions.apply = function(){
assertDrawer(this);
this.rac.drawer.applyObject(this);
};
Rac.styleProtoFunctions.log = Rac.drawableProtoFunctions.log;
Rac.styleProtoFunctions.applyToClass = function(classObj) {
assertDrawer(this);
this.rac.drawer.setClassDrawStyle(classObj, this);
};
}; // attachProtoFunctions