/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/**
* @module baja/tag/entityDecoder
*/
define([ "bajaScript/sys",
"bajaScript/baja/tag/Id",
"bajaScript/baja/tag/Tag",
"bajaScript/baja/tag/TagSet",
"bajaScript/baja/tag/RelationSet",
"bajaScript/baja/tag/Relation",
"bajaScript/baja/tag/BasicEntity",
"bajaPromises" ], function (
baja,
Id,
Tag,
TagSet,
RelationSet,
Relation,
BasicEntity,
Promise) {
"use strict";
function decodeTag(val, name) {
var type = name[name.length - 1],
Float = baja.Float,
Double = baja.Double;
name = name.substring(0, name.length - 1);
switch (type) {
case "M": return new Tag(name);
case "B": return new Tag(name, baja.$("baja:Boolean", val));
case "D": return new Tag(name, baja.$("baja:Double", val));
case "I": return new Tag(name, baja.$("baja:Integer", val));
case "F": return new Tag(name, baja.$("baja:Float", val));
case "L": return new Tag(name, baja.$("baja:Long", val));
case "S":
case "J":
return new Tag(name, baja.$("baja:String").decodeFromString(val));
case "A": return new Tag(name, baja.$("baja:AbsTime").decodeFromString(val));
case "O": return new Tag(name, baja.$("baja:Ord").decodeFromString(val));
case "Y":
return baja.$("baja:DynamicEnum").decodeAsync(val)
.then(function (tagValue) {
return new Tag(name, tagValue);
});
case "G":
return baja.$("baja:EnumRange").decodeAsync(val)
.then(function (tagValue) {
return new Tag(name, tagValue);
});
case "R": return new Tag(name, baja.$("baja:RelTime").decodeFromString(val));
case "U": return new Tag(name, baja.$("baja:Unit").decodeFromString(val));
case "Z": return new Tag(name, baja.$("baja:TimeZone").decodeFromString(val));
case "N":
switch (val) {
case "fNaN": return new Tag(name, Float.NaN);
case "fpInf": return new Tag(name, Float.POSITIVE_INFINITY);
case "fnInf": return new Tag(name, Float.NEGATIVE_INFINITY);
case "dNaN": return new Tag(name, Double.make(Number.NaN));
case "dpInf": return new Tag(name, Double.POSITIVE_INFINITY);
case "dnInf": return new Tag(name, Double.NEGATIVE_INFINITY);
}
break;
default: throw new Error("Unknown value type: " + type);
}
}
/*
* @param {Array.<String>} tags an array of string encoded tags
* @returns {Promise.<baja.TagSet>}
*/
function decodeTags(tags) {
var promises = [];
baja.iterate(tags, function (val, name) {
promises.push(Promise.resolve(decodeTag(val, name)));
});
return Promise.all(promises)
.then(function (tagsArray) {
return new TagSet(tagsArray);
});
}
/*
* @param {Array.<Object>} relations an array of json encoded relations
* @returns {Promise.<baja.RelationSet>}
*/
function decodeRelations(relations) {
var relationPromises = [];
baja.iterate(relations, function (relationJson) {
var tagPromises = [];
if (relationJson.rtags) {
baja.iterate(relationJson.rtags, function (val, name) {
tagPromises.push(Promise.resolve(decodeTag(val, name)));
});
}
relationPromises.push(
Promise.all(tagPromises)
.then(function (rtags) {
return new Relation(relationJson.rId, relationJson.entityOrd, new TagSet(rtags), relationJson.inbound);
})
);
});
return Promise.all(relationPromises)
.then(function (relationsArray) {
return new RelationSet(relationsArray);
});
}
/*
* @param {Object} entityJson a json encoded entity
* @returns {Promise.<baja.tag.BasicEntity>}
*/
function decodeEntity(entityJson) {
return Promise.all([
entityJson.tags ? decodeTags(entityJson.tags) : new TagSet(),
entityJson.relations ? decodeRelations(entityJson.relations) : new RelationSet()
])
.then(function ([ tagSet, relationSet ]) {
return new BasicEntity(entityJson.ord, tagSet, relationSet);
});
}
return {
decodeEntity: decodeEntity,
decodeTags: decodeTags,
decodeRelations: decodeRelations
};
});