import { AttributeCellValue } from "./AttributeCellValue";
import { LabelCellValue } from "./LabelCellValue";
import { View } from './View';
/**
 * A abstract definition for small visual area populated with labels and values. Labels are typically presented as simple text phrases.
 * Values are usually presented inside a UI component, such as a TextField or ComboBox.
 */
export class Details extends View {
    findCellValue(matcher) {
        return this.findCellValueForRow((row) => {
            let cellValue = null;
            row.some((cell) => {
                return cell.values.some((value) => {
                    cellValue = matcher(value);
                    return !!cellValue;
                });
            });
            return cellValue;
        });
    }
    /**
     * @param matcher - a function that given a row of cells, returns a matching CellValue (or null)
     */
    findCellValueForRow(matcher) {
        let cellValue = null;
        this.rows.some(row => {
            cellValue = matcher(row);
            return !!cellValue;
        });
        return cellValue;
    }
    getAttributeCellValue(propertyName) {
        return this.attributeCellsByPropName[propertyName];
    }
    /**
     * 1-based index
     * @param number
     */
    getConstantByIndex(index) {
        return this.constants.length >= index ? this.constants[index - 1] : null;
    }
    getLabelForProperty(propertyName) {
        return this.labelsByPropName[propertyName];
    }
    get constants() {
        if (!this.constantsArray) {
            this.initIndexes();
        }
        return this.constantsArray;
    }
    get propertyNames() {
        if (!this.propertyNamesArray) {
            this.initIndexes();
        }
        return this.propertyNamesArray;
    }
    get attributeCells() {
        return Object.keys(this.attributeCellsByPropName).map(key => this.attributeCellsByPropName[key]);
    }
    get attributeCellsByPropName() {
        if (!this.attributeCellMap) {
            this.initIndexes();
        }
        return this.attributeCellMap;
    }
    get labelsByPropName() {
        if (!this.propertyLabelMap) {
            this.initIndexes();
        }
        return this.propertyLabelMap;
    }
    initIndexes() {
        this.attributeCellMap = {};
        this.propertyLabelMap = {};
        this.constantsArray = [];
        this.propertyNamesArray = [];
        this.rows.forEach((row) => {
            const [firstCell, secondCell] = row;
            if (firstCell && firstCell.values) {
                const [labelCellValue] = firstCell.values;
                if (labelCellValue instanceof LabelCellValue) {
                    if (secondCell && secondCell.values) {
                        const [cellValue] = secondCell.values;
                        if (cellValue instanceof AttributeCellValue) {
                            this.propertyNamesArray.push(cellValue.propertyName);
                            this.propertyLabelMap[cellValue.propertyName] = labelCellValue;
                        }
                        else if (cellValue instanceof LabelCellValue) {
                            if (!cellValue.value) {
                                this.constantsArray.push(labelCellValue.value);
                            }
                        }
                    }
                    else {
                        this.constantsArray.push(labelCellValue.value);
                    }
                }
            }
            row.forEach((cell) => {
                cell.values.forEach((cellValue) => {
                    if (cellValue instanceof AttributeCellValue) {
                        this.attributeCellMap[cellValue.propertyName] = cellValue;
                    }
                });
            });
        });
    }
}
