"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OjNavigationList = void 0;
const selenium_webdriver_1 = require("selenium-webdriver");
const __1 = require("../../");
const OjNavigationListBase_1 = require("./OjNavigationListBase");
/**
 * The component WebElement for [oj-navigation-list](../../jsdocs/oj.ojNavigationList.html).
 * Do not instantiate this class directly, instead, use
 * [ojNavigationList](../functions/elements.ojNavigationList-1.html).
 */
class OjNavigationList extends OjNavigationListBase_1.OjNavigationListBase {
    // Put overrides here
    /**
     * Sets the value of "expanded" property.
     * Specifies the key set containing the keys of the items that should be expanded.
  
  Use the ExpandedKeySet class to specify items to expand.
  Use the ExpandAllKeySet class to expand all items.
     * @param expanded The value to set for "expanded"
     * @override
     */
    async changeExpanded(expanded) {
        await this.whenReady();
        await this.getDriver().executeScript(`
        const ele = arguments[0];
        const expanded = arguments[1];
        const keySet = require('ojs/ojkeyset');
        const expandedKeySet = new keySet.ExpandedKeySet(expanded);
        ele.expanded = expandedKeySet;
        `, this, expanded);
        await this.whenBusyContextReady();
    }
    /*
     * Expands items specified by index path. Note: This expands all intermediate items too.
     * This also collapses all other nodes if any expanded already.
     * @param index array of index path to the element to be expanded
     */
    async changeExpandedByIndex(indexes) {
        this.whenReady();
        let expansionTree = this._getExpansionTree(indexes);
        await this.getDriver().executeScript([
            /* Reference to the current nav list */
            'var ele = arguments[0]',
            /* Expansiontree(type object) of given index array */
            'let expansionTree = arguments[1];',
            '_traverseListToExpand(null, expansionTree);',
            /* Check it has collapsed class */
            ' function _isCollapsed(item) {',
            '  return _hasClass(item,"oj-collapsed");',
            ' }',
            /* Check it has expanded class */
            ' function _isExpanded(item) {',
            '  return _hasClass(item,"oj-expanded");',
            ' }',
            /* Expand the item if it is not exapanded */
            ' function  expandItem(item) {',
            '  let isExpanded = _isExpanded(item);',
            '  if (!isExpanded) {',
            '   var collapsedIcon = item.querySelector(".oj-navigationlist-collapse-icon");',
            '   collapsedIcon.click();',
            '  }',
            ' }',
            /* Collapse the item if it is not collapsed */
            ' function collapseItem(item) {',
            '  let isCollapsed = _isCollapsed(item);',
            '  if (!isCollapsed) {',
            '   var expandedIcon = item.querySelector(".oj-navigationlist-expand-icon");',
            '   expandedIcon.click();',
            '  }',
            ' }',
            /* Check given class name in element */
            ' function _hasClass(element, className) {',
            ' let classes =  element.getAttribute("class");',
            ' let hasClass = false;',
            ' classes.split(" ").forEach(c => {',
            '  if (c === className) {',
            '   hasClass = true;',
            '  }',
            ' });',
            ' return hasClass;',
            ' }',
            /* Get the element by its index */
            ' function getItemByIndex(index, parent){',
            ' let item;',
            '  if (!parent)',
            '   item = ele.querySelector(".oj-navigationlist-element > .oj-navigationlist-item-element:nth-child(" + index + ")")',
            '  else {',
            '   item = parent.querySelector(".oj-navigationlist-group > .oj-navigationlist-item-element:nth-child(" + index + ")")',
            '  }',
            ' return item;',
            ' }',
            /* This will check should item be exapanded only if present in exapasion tree*/
            ' function  shouldBeExpanded(expansionTree, indexPath){',
            '  if (indexPath.length === 0) {',
            '   return false;',
            '  }',
            '  for (let i=0; i < indexPath.length; i++) {',
            '  expansionTree = expansionTree[indexPath[i]];',
            '   if (!expansionTree) {',
            '    return false;',
            '   }',
            '  }',
            ' return true;',
            ' }',
            /* Expands items specified by index path
             This also collapses all other nodes if any expanded already */
            ' function _traverseListToExpand(parent, expansionTree, parentIndexPath) {',
            '  let item, indexPath, index = 1;',
            '  item =  getItemByIndex(index, parent);',
            '  parentIndexPath = parentIndexPath && parentIndexPath.length > 0 ? parentIndexPath : []',
            '  while (item) {',
            '   let isExpanded =  _isExpanded(item);',
            '   let isCollapsed = _isCollapsed(item);',
            '     if (isCollapsed || isExpanded) {',
            '       indexPath = parentIndexPath.concat([index])',
            '       if (isCollapsed && shouldBeExpanded(expansionTree, indexPath)) {',
            '           expandItem(item);',
            '       }',
            '     _traverseListToExpand(item, expansionTree, indexPath);',
            '     if (isExpanded && !shouldBeExpanded(expansionTree, indexPath)) {',
            '         collapseItem(item);',
            '     }',
            '   }',
            '   index = index + 1;',
            '   item =  getItemByIndex(index, parent);',
            '  }',
            ' }'
        ].join('\n'), this, expansionTree);
    }
    /**
     * Create a object of given index array
     * @param pathsToBeExpanded array of index path to the element to be selected
     */
    _getExpansionTree(pathsToBeExpanded = []) {
        let children, expansionTree = {};
        for (let i = 0; i < pathsToBeExpanded.length; i++) {
            children = expansionTree;
            for (let j = 0; j < pathsToBeExpanded[i].length; j++) {
                let index = pathsToBeExpanded[i][j];
                if (!children[index]) {
                    children[index] = {};
                }
                children = children[index];
            }
        }
        return expansionTree;
    }
    /**
     * Selets item specified by index path. Note: This expands all intermediate items too.
     * @param index array of index path to the element to be selected
     */
    async changeSelectionByIndex(index) {
        await this.whenReady();
        let indexArray, parent;
        if (!Array.isArray(index)) {
            indexArray = [index];
        }
        else {
            indexArray = index;
        }
        for (let i = 0; i < indexArray.length; i++) {
            parent = await this._getItemByIndex(indexArray[i], parent);
            if (parent && i < indexArray.length - 1) {
                await this._expandItem(parent);
            }
            else {
                await parent?.click();
            }
        }
    }
    /**
     * Gets the value of "expanded" property.
     * Specifies the key set containing the keys of the items that should be expanded.
  
  Use the ExpandedKeySet class to specify items to expand.
  Use the ExpandAllKeySet class to expand all items.
     * @return The value of "expanded" property.
     * @override
     */
    async getExpanded() {
        await this.whenReady();
        let expanded = await this.getDriver().executeScript(['return Array.from(arguments[0].expanded.values());'].join('\n'), this);
        return expanded;
    }
    /**
     * Returns item node specified by index path.
     * @param index array of index path to the element to be returned
     */
    async getItemByIndex(indexPath) {
        let item;
        for (let i = 0; i < indexPath.length; i++) {
            item = item
                ? await this._getItemByIndex(indexPath[i], item)
                : await this._getItemByIndex(indexPath[i]);
        }
        return item;
    }
    async _hasClass(element, className) {
        let classes = await element.getAttribute('class');
        let hasClass = false;
        classes.split(' ').forEach((c) => {
            if (c === className) {
                hasClass = true;
            }
        });
        return hasClass;
    }
    async _getItemByIndex(index, parent) {
        let item;
        try {
            if (!parent)
                item = await this.findElement(selenium_webdriver_1.By.css('.oj-navigationlist-element > .oj-navigationlist-item-element:nth-child(' + index + ')'));
            else {
                item = await parent.findElement(selenium_webdriver_1.By.css('.oj-navigationlist-group > .oj-navigationlist-item-element:nth-child(' + index + ')'));
            }
        }
        catch (e) {
            item = undefined; //element not found
        }
        return item;
    }
    async _isExpanded(item) {
        return await this._hasClass(item, 'oj-expanded');
    }
    async _expandItem(item) {
        let isExpanded = await this._isExpanded(item);
        if (!isExpanded) {
            var collapsedIcon = await item.findElement(selenium_webdriver_1.By.css('.oj-navigationlist-collapse-icon'));
            await collapsedIcon.click();
            await this.whenBusyContextReady();
        }
    }
    /**
     * Retrieve a SlotProxy which represents a single navlist item.
     * @param key The key within the Collection's dataset associated with the item.
     */
    async findItem(itemLocator) {
        // rendere in DOM
        const el = await this.getDriver().executeScript(`
    return arguments[0].getNodeBySubId({ subId: 'oj-navigationlist-item', key: ${JSON.stringify(itemLocator.key)} })
    `, this);
        return (0, __1.slotProxy)(el, this);
    }
}
exports.OjNavigationList = OjNavigationList;
//# sourceMappingURL=OjNavigationList.js.map