"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var HaikuBase_1 = require("./HaikuBase");
var cssMatchOne_1 = require("./helpers/cssMatchOne");
var HAIKU_ID_ATTRIBUTE = 'haiku-id';
var HAIKU_TITLE_ATTRIBUTE = 'haiku-title';
var HAIKU_SOURCE_ATTRIBUTE = 'source';
var DEFAULT_TAG_NAME = 'div';
var COMPONENT_PSEUDO_TAG_NAME = DEFAULT_TAG_NAME;
var TEXT_PSEUDO_TAG_NAME = '__text__';
var CSS_QUERY_MAPPING = {
    name: 'elementName',
    attributes: 'attributes',
    children: 'children',
};
var HaikuElement = (function (_super) {
    __extends(HaikuElement, _super);
    function HaikuElement() {
        return _super.call(this) || this;
    }
    Object.defineProperty(HaikuElement.prototype, "childNodes", {
        get: function () {
            return (this.node && this.node.children) || [];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "children", {
        get: function () {
            return this.childNodes.map(function (childNode) {
                return HaikuElement['findOrCreateByNode'](childNode);
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "attributes", {
        get: function () {
            return (this.node && this.node.attributes) || {};
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "type", {
        get: function () {
            return (this.node && this.node.elementName) || DEFAULT_TAG_NAME;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "title", {
        get: function () {
            return this.attributes[HAIKU_TITLE_ATTRIBUTE];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "source", {
        get: function () {
            return this.attributes[HAIKU_SOURCE_ATTRIBUTE];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "id", {
        get: function () {
            return this.attributes.id;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "className", {
        get: function () {
            return this.attributes.class;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "tagName", {
        get: function () {
            if (this.isTextNode()) {
                return TEXT_PSEUDO_TAG_NAME;
            }
            if (this.isComponent()) {
                return COMPONENT_PSEUDO_TAG_NAME;
            }
            return this.type || DEFAULT_TAG_NAME;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "nodeType", {
        get: function () {
            if (this.isTextNode()) {
                return 3;
            }
            return 1;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "instance", {
        get: function () {
            return this.node && this.node.__instance;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "context", {
        get: function () {
            return this.node && this.node.__context;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "parentNode", {
        get: function () {
            return this.node && this.node.__parent;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "parent", {
        get: function () {
            return this.parentNode && this.parentNode.__element;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "host", {
        get: function () {
            if (this.instance) {
                return this.instance;
            }
            return this.parent && this.parent.host;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "layout", {
        get: function () {
            return this.node && this.node.layout && this.node.layout.computed;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "translation", {
        get: function () {
            return this.layout && this.layout.translation;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "rotation", {
        get: function () {
            return this.layout && this.layout.rotation;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "scale", {
        get: function () {
            return this.layout && this.layout.scale;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "size", {
        get: function () {
            return this.layout && this.layout.size;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HaikuElement.prototype, "target", {
        get: function () {
            return this.node && this.node.__target;
        },
        enumerable: true,
        configurable: true
    });
    HaikuElement.prototype.getComponentId = function () {
        return this.attributes[HAIKU_ID_ATTRIBUTE];
    };
    HaikuElement.prototype.isSimpleNode = function () {
        return !this.isComponent();
    };
    HaikuElement.prototype.isTextNode = function () {
        return typeof this.node === 'string';
    };
    HaikuElement.prototype.isComponent = function () {
        return !!this.instance;
    };
    HaikuElement.prototype.componentMatches = function (selector) {
        if (!this.isComponent()) {
            return false;
        }
        var trimmed = selector.trim();
        var source = this.source;
        var title = this.title;
        var id = this.id;
        return (trimmed === COMPONENT_PSEUDO_TAG_NAME ||
            trimmed === source ||
            trimmed === title ||
            trimmed === id);
    };
    HaikuElement.prototype.matches = function (selector) {
        return (this.componentMatches(selector) ||
            cssMatchOne_1.default(this.node, selector, CSS_QUERY_MAPPING));
    };
    HaikuElement.prototype.visit = function (iteratee) {
        if (iteratee(this) !== false) {
            return this.visitDescendants(iteratee);
        }
    };
    HaikuElement.prototype.visitDescendants = function (iteratee) {
        var children = this.children;
        for (var i = 0; i < children.length; i++) {
            if (children[i].visit(iteratee) === false) {
                break;
            }
        }
    };
    HaikuElement.prototype.querySelector = function (selector) {
        var _this = this;
        return this.cacheFetch("querySelector:" + selector, function () {
            var out;
            _this.visitDescendants(function (element) {
                if (element.matches(selector)) {
                    out = element;
                    return false;
                }
            });
            return out;
        });
    };
    HaikuElement.prototype.querySelectorAll = function (selector) {
        var _this = this;
        return this.cacheFetch("querySelectorAll:" + selector, function () {
            var out = [];
            _this.visitDescendants(function (element) {
                if (element.matches(selector)) {
                    out.push(element);
                }
            });
            return out;
        });
    };
    HaikuElement.prototype.getRotationX = function () {
        return this.rotation && this.rotation.x;
    };
    HaikuElement.prototype.getRotationY = function () {
        return this.rotation && this.rotation.y;
    };
    HaikuElement.prototype.getRotationZ = function () {
        return this.rotation && this.rotation.z;
    };
    HaikuElement.prototype.getScaleX = function () {
        return this.scale && this.scale.x;
    };
    HaikuElement.prototype.getScaleY = function () {
        return this.scale && this.scale.y;
    };
    HaikuElement.prototype.getScaleZ = function () {
        return this.scale && this.scale.z;
    };
    HaikuElement.prototype.getPositionX = function () {
        return this.translation && this.translation.x;
    };
    HaikuElement.prototype.getPositionY = function () {
        return this.translation && this.translation.y;
    };
    HaikuElement.prototype.getPositionZ = function () {
        return this.translation && this.translation.z;
    };
    HaikuElement.prototype.getTranslationX = function () {
        return this.translation && this.translation.x;
    };
    HaikuElement.prototype.getTranslationY = function () {
        return this.translation && this.translation.y;
    };
    HaikuElement.prototype.getTranslationZ = function () {
        return this.translation && this.translation.z;
    };
    HaikuElement.prototype.getSizeX = function () {
        return this.size && this.size.x;
    };
    HaikuElement.prototype.getSizeY = function () {
        return this.size && this.size.y;
    };
    HaikuElement.prototype.getSizeZ = function () {
        return this.size && this.size.z;
    };
    return HaikuElement;
}(HaikuBase_1.default));
exports.default = HaikuElement;
HaikuElement['findByNode'] = function (node) {
    var registry = HaikuBase_1.default['getRegistryForClass'](HaikuElement);
    var matches = registry.filter(function (instance) {
        return instance.node === node;
    });
    if (matches.length > 0) {
        return matches[0];
    }
};
HaikuElement['connectNodeWithElement'] = function (node, element) {
    if (element) {
        element.node = node;
    }
    if (node && typeof node === 'object') {
        node.__element = element;
    }
};
HaikuElement['createByNode'] = function (node) {
    var element = new HaikuElement();
    HaikuElement['connectNodeWithElement'](node, element);
    return element;
};
HaikuElement['findOrCreateByNode'] = function (node) {
    var found = HaikuElement['findByNode'](node);
    if (found) {
        return found;
    }
    return HaikuElement['createByNode'](node);
};
//# sourceMappingURL=HaikuElement.js.map