/// <reference path="../lib-definitions/jquery.d.ts" />
var econda;
(function (econda) {
    var util;
    (function (util) {
        /**
         * Dom helper functions.
         *
         * <h3>JQuery Support</h3>
         * If jQuery is loaded, most functions will use jQuery dom manipulation functions. This allows the use of css selectors.
         *
         * Example without jQuery
         *     // only element ids are allowed
         *     var w = new econda.recengine.Widget({element: '#HTMLElementId' });
         *
         * Example when jQuery is loaded
         *     // jQuery css selectors are supported
         *     var w = new econda.recengine.Widget({element: '.myWidgetContainer .inner' });
         *
         * Do not allow econda sdk functions to use jQuery:
         *     econda.util.DomHelper.useJQueryIfLoaded = false;
         *
         * @class econda.util.DomHelper
         * @static
         */
        var DomHelper = (function () {
            function DomHelper() {
            }
            /**
             * Returns true if econda.util.DomHelper.useJQueryIfLoaded is true and jQuery is available
             * @private
             * @return {Boolean}
             */
            DomHelper._useJQuery = function () {
                return (this.useJQueryIfLoaded && (typeof jQuery != 'undefined'));
            };
            DomHelper.update = function (element, html) {
                if (this._useJQuery()) {
                    return jQuery(element).html(html);
                }
                else {
                    return this._update(element, html);
                }
            };
            /**
             * Creates a document fragment from given html string
             * @param {String} html
             * @returns {Object} DocumentFragment object
             */
            DomHelper.createFragmentFromHtml = function (html) {
                var frag = document.createDocumentFragment(), temp = document.createElement('div');
                temp.innerHTML = html;
                while (temp.firstChild) {
                    frag.appendChild(temp.firstChild);
                }
                return frag;
            };
            /**
             * Appends html to given parent node. Executes javascript nodes in html.
             */
            DomHelper.appendFromHtml = function (parentNode, html) {
                var temp = document.createElement('div');
                temp.innerHTML = html;
                while (temp.firstChild) {
                    if (String(temp.firstChild.nodeName).toLowerCase() === 'script') {
                        // browsers will not execute javascript that was set using innerHTML, so we
                        // have to recreate those nodes here
                        var scriptText = temp.firstChild.textContent || temp.firstChild.innerHTML;
                        var scriptNode = document.createElement('script');
                        scriptNode.type = 'text/javascript';
                        if (temp.children[0].getAttribute('src')) {
                            scriptNode.src = temp.children[0].getAttribute('src');
                        }
                        else {
                            try {
                                scriptNode.appendChild(document.createTextNode(scriptText));
                            }
                            catch (e) {
                                scriptNode.text = scriptText;
                            }
                        }
                        parentNode.appendChild(scriptNode);
                        temp.removeChild(temp.firstChild);
                    }
                    else {
                        // move node to new parent element
                        parentNode.appendChild(temp.firstChild);
                    }
                }
            };
            DomHelper.empty = function (element) {
                var node = DomHelper.element(element);
                while (node.firstChild) {
                    node.removeChild(node.firstChild);
                }
            };
            /**
             * Fallback function if jquery is not loaded or useJQueryIfLoaded was set to false
             * @param {String|HTMLElement} element Element id as string or JavaScript element object
             * @param {String} html
             * @returns {String} inner html of element
             * @private
             */
            DomHelper._update = function (element, html) {
                var el = this.element(element);
                var ret = null;
                if (el) {
                    el.innerHTML = html;
                    this._handleJavascript(el);
                    ret = el.innerHTML;
                }
                return ret;
            };
            /**
             * Fallback function javascript handler if jquery is not loaded or useJQueryIfLoaded was set to false
             * @param {HTMLElement} element parent element object
             * @private
             */
            DomHelper._handleJavascript = function (element) {
                var i, ii, scripts = element.getElementsByTagName("script");
                if (scripts.length > 0) {
                    for (i = 0, ii = scripts.length; i < ii; i += 1) {
                        var scriptNode = this._generateScriptNode(scripts[i].text || scripts[i].textContent || scripts[i].innerHTML || "");
                        element.appendChild(scriptNode);
                    }
                }
            };
            /**
             * Create and return JavaScript node with given source code
             * @param {String} code JavaScript code
             * @private
             */
            DomHelper._generateScriptNode = function (code) {
                var script = document.createElement("script");
                script.type = "text/javascript";
                script.appendChild(document.createTextNode(code));
                return script;
            };
            /**
             * True if document is ready
             * @returns {Boolean}
             */
            DomHelper.isDocumentReady = function () {
                return document.readyState === 'complete' || document.readyState === 'interactive';
            };
            /**
             * Register callback function to be called on document ready. If a function is registered while document is already ready
             * the function will be executed immediately.
             * @param {Function} callback Callback handler
             */
            DomHelper.documentReady = function (callback) {
                // execute if document is already ready
                if (DomHelper.isDocumentReady()) {
                    callback();
                    return;
                }
                // add callback if not already executed
                var called = false, isFrame = false;
                // cast to <any> to disable typescript checks
                var doc = document, win = window;
                function ready() {
                    if (called) {
                        return;
                    }
                    called = true;
                    callback();
                }
                if (doc.addEventListener) {
                    doc.addEventListener("DOMContentLoaded", ready, false);
                }
                else if (doc.attachEvent) {
                    try {
                        isFrame = window.frameElement != null;
                    }
                    catch (e) {
                    }
                    if (doc.documentElement && doc.documentElement.doScroll && !isFrame) {
                        var tryScroll = function () {
                            if (called) {
                                return;
                            }
                            try {
                                doc.documentElement.doScroll("left");
                                ready();
                            }
                            catch (e) {
                                setTimeout(tryScroll, 10);
                            }
                        };
                        tryScroll();
                    }
                    doc.attachEvent("onreadystatechange", function () {
                        if (doc.readyState === "complete" || doc.readyState === 'interactive') {
                            ready();
                        }
                    });
                }
                if (win.addEventListener) {
                    win.addEventListener('load', ready, false);
                }
                else if (win.attachEvent) {
                    win.attachEvent('onload', ready);
                }
                else {
                    var fn = win.onload;
                    win.onload = function () {
                        fn && fn(null);
                        ready();
                    };
                }
            };
            DomHelper.remove = function (element) {
                var el = this.element(element);
                if (el) {
                    el.parentNode.removeChild(el);
                }
            };
            /**
             * Converts element identification (id or element reference) to element reference
             * @param {HTMLElement/String} selector element object or id
             * @returns {HTMLElement[]}
             */
            DomHelper.elements = function (selector) {
                var el = null;
                // try to use jquery
                if (this._useJQuery()) {
                    return jQuery(selector);
                }
                // no jquery, so we support only a by id query (that must result in a single element)
                if (typeof selector == 'string') {
                    if (selector.substr(0, 1) == '#') {
                        el = document.getElementById(selector.substr(1));
                    }
                    else {
                        el = document.getElementById(selector);
                    }
                }
                else {
                    el = selector;
                }
                if (el) {
                    return [el];
                }
                return { length: 0 };
            };
            /**
             * Converts element identification (id or element reference) to element reference
             * @param {HTMLElement/String} element object or id
             * @returns {HTMLElement}
             */
            DomHelper.element = function (element) {
                var el = this.elements(element);
                if (el.length > 0) {
                    return el[0];
                }
                else {
                    return null;
                }
            };
            /**
             * Set to true if we should use jQuery functions if available.
             * If set to false, CSS selectors and any other jquery related features
             * are not availabe.
             * @property {Boolean} [useJQueryIfLoaded=true]
             */
            DomHelper.useJQueryIfLoaded = true;
            return DomHelper;
        }());
        util.DomHelper = DomHelper; // end of class
    })(util = econda.util || (econda.util = {}));
})(econda || (econda = {})); // end of module