/**
* @module montage/core/gate
* @requires montage/core/core
* @requires montage/core/logger
*/
var Montage = require("./core").Montage,
logger = require("./logger").logger("gate"),
Map = require("collections/map");
/**
* @class Gate
* @extends Montage
*/
var Gate = exports.Gate = Montage.specialize(/** @lends Gate.prototype # */ {
/**
* @function
* @returns {Gate} A new Gate instance.
*/
init: {
enumerable: false,
value: function () {
this.reset();
return this;
}
},
/**
* @function
* @param {string} delegate The delegate to be initialized.
* @returns itself
*/
initWithDelegate: {
enumerable: false,
value: function (delegate) {
this.reset();
this.delegate = delegate;
return this;
}
},
/**
* @function
* @param {string} propertyDescriptor The propertyDescriptor to be initialized.
* @returns itself
*/
initWithDescriptor: {
enumerable: false,
value: function (propertyDescriptor) {
var fieldName;
this.reset();
for (fieldName in propertyDescriptor) {
if (propertyDescriptor.hasOwnProperty(fieldName)) {
this.setField(fieldName, propertyDescriptor[fieldName].value);
}
}
return this;
}
},
/**
* @type {Property}
* @default {number} 0
*/
count: {
value: 0
},
/**
* @type {Property}
* @default {string} null
*/
table: {
value: null
},
/**
* @function
* @param {Array} aFieldName The aFieldName array.
* @returns !table or table[aFieldName]
*/
getField: {
enumerable: false,
value: function (aFieldName) {
var table = this.table;
return !table || table[aFieldName];
}
},
/**
* @function
* @param {Array} aFieldName The aFieldName array.
* @param {number} value The count on the array.
*/
setField: {
enumerable: false,
value: function (aFieldName, value) {
var table = this.table || (this.table = new Map()),
fieldValue,
oldCount = this.count;
fieldValue = table[aFieldName];
if (typeof fieldValue === "undefined" && !value) {
// new field
this.count++;
} else if (typeof fieldValue !== "undefined" && fieldValue !== value) {
if (value) {
this.count--;
} else {
this.count++;
}
} else if (value && logger.isDebug) {
logger.debug(this, aFieldName + " was not set before.");
}
table[aFieldName] = !!value;
if (this.count === 0 && oldCount > 0) {
this.callDelegateMethod(true);
} else if (oldCount === 0 && this.count > 0) {
this.callDelegateMethod(false);
}
}
},
/**
* @function
* @param {Array} aFieldName The aFieldName array to be removed.
*/
removeField: {
enumerable: false,
value: function (aFieldName) {
var table = this.table, fieldValue = table[aFieldName];
if (typeof fieldValue !== "undefined" && !fieldValue) {
// if the value was false decrement the count
this.count--;
}
delete table[aFieldName];
}
},
/**
* @type {Property}
* @default {string} null
*/
delegate: {
enumerable: false,
value: null
},
/**
* @function
* @param {number} value The value to be called.
*/
callDelegateMethod: {
value: function (value) {
var delegateMethod;
if (this.delegate && typeof (delegateMethod = this.delegate["gateDidBecome" + (value ? "True" : "False")]) === "function") {
delegateMethod.call(this.delegate, this);
}
},
enumerable: false
},
/**
* @type {Function}
* @returns this.count === 0
*/
value: {
enumerable: false,
get: function () {
return this.count === 0;
}
},
/**
* @function
*/
reset: {
enumerable: false,
value: function () {
this.table = {};
this.count = 0;
}
},
/**
* @function
* @returns {string} result
*/
toString: {
value: function () {
var fieldNames = this._fields,
i,
iField,
result = "";
for (i = 0; (iField = fieldNames[i]); i++) {
result += iField + "[" + (this._value & fieldNames[iField]) + "], ";
}
return result;
}
}
});