import { DataAnnotation } from './DataAnnotation';
import { TypeNames } from './types';
/**
 * The implementation of {@link Record}.
 * Represents a 'Record' or set of {@link Property} (names and values).
 * An Record may also have {@link Annotation}s (style annotations) that apply to the whole 'record'
 */
export class RecordImpl {
    constructor(id, properties = [], annotations = [], type) {
        this.id = id;
        this.properties = properties;
        this.annotations = annotations;
        this.type = type;
    }
    annotationsAtName(propName) {
        const p = this.propAtName(propName);
        return p ? p.annotations : [];
    }
    afterEffects(after) {
        const effects = [];
        after.properties.forEach(afterProp => {
            const beforeProp = this.propAtName(afterProp.name);
            if (!afterProp.equals(beforeProp)) {
                effects.push(afterProp);
            }
        });
        return new RecordImpl(after.id, effects, after.annotations, after.type);
    }
    get backgroundColor() {
        return DataAnnotation.backgroundColor(this.annotations);
    }
    backgroundColorFor(propName) {
        const p = this.propAtName(propName);
        return p && p.backgroundColor ? p.backgroundColor : this.backgroundColor;
    }
    get foregroundColor() {
        return DataAnnotation.foregroundColor(this.annotations);
    }
    foregroundColorFor(propName) {
        const p = this.propAtName(propName);
        return p && p.foregroundColor ? p.foregroundColor : this.foregroundColor;
    }
    get imageName() {
        return DataAnnotation.imageName(this.annotations);
    }
    imageNameFor(propName) {
        const p = this.propAtName(propName);
        return p && p.imageName ? p.imageName : this.imageName;
    }
    get imagePlacement() {
        return DataAnnotation.imagePlacement(this.annotations);
    }
    imagePlacementFor(propName) {
        const p = this.propAtName(propName);
        return p && p.imagePlacement ? p.imagePlacement : this.imagePlacement;
    }
    get isBoldText() {
        return DataAnnotation.isBoldText(this.annotations);
    }
    isBoldTextFor(propName) {
        const p = this.propAtName(propName);
        return p && p.isBoldText ? p.isBoldText : this.isBoldText;
    }
    get isItalicText() {
        return DataAnnotation.isItalicText(this.annotations);
    }
    isItalicTextFor(propName) {
        const p = this.propAtName(propName);
        return p && p.isItalicText ? p.isItalicText : this.isItalicText;
    }
    get isPlacementCenter() {
        return DataAnnotation.isPlacementCenter(this.annotations);
    }
    isPlacementCenterFor(propName) {
        const p = this.propAtName(propName);
        return p && p.isPlacementCenter ? p.isPlacementCenter : this.isPlacementCenter;
    }
    get isPlacementLeft() {
        return DataAnnotation.isPlacementLeft(this.annotations);
    }
    isPlacementLeftFor(propName) {
        const p = this.propAtName(propName);
        return p && p.isPlacementLeft ? p.isPlacementLeft : this.isPlacementLeft;
    }
    get isPlacementRight() {
        return DataAnnotation.isPlacementRight(this.annotations);
    }
    isPlacementRightFor(propName) {
        const p = this.propAtName(propName);
        return p && p.isPlacementRight ? p.isPlacementRight : this.isPlacementRight;
    }
    get isPlacementStretchUnder() {
        return DataAnnotation.isPlacementStretchUnder(this.annotations);
    }
    isPlacementStretchUnderFor(propName) {
        const p = this.propAtName(propName);
        return p && p.isPlacementStretchUnder ? p.isPlacementStretchUnder : this.isPlacementStretchUnder;
    }
    get isPlacementUnder() {
        return DataAnnotation.isPlacementUnder(this.annotations);
    }
    isPlacementUnderFor(propName) {
        const p = this.propAtName(propName);
        return p && p.isPlacementUnder ? p.isPlacementUnder : this.isPlacementUnder;
    }
    get isUnderline() {
        return DataAnnotation.isUnderlineText(this.annotations);
    }
    isUnderlineFor(propName) {
        const p = this.propAtName(propName);
        return p && p.isUnderline ? p.isUnderline : this.isUnderline;
    }
    get overrideText() {
        return DataAnnotation.overrideText(this.annotations);
    }
    overrideTextFor(propName) {
        const p = this.propAtName(propName);
        return p && p.overrideText ? p.overrideText : this.overrideText;
    }
    propAtIndex(index) {
        return this.properties[index];
    }
    propAtName(propName) {
        let prop = null;
        this.properties.some(p => {
            if (p.name === propName) {
                prop = p;
                return true;
            }
            return false;
        });
        return prop;
    }
    get propCount() {
        return this.properties.length;
    }
    get propNames() {
        return this.properties.map(p => {
            return p.name;
        });
    }
    get propValues() {
        return this.properties.map(p => {
            return p.value;
        });
    }
    get tipText() {
        return DataAnnotation.tipText(this.annotations);
    }
    tipTextFor(propName) {
        const p = this.propAtName(propName);
        return p && p.tipText ? p.tipText : this.tipText;
    }
    toJSON() {
        return {
            id: this.id,
            properties: this.properties,
            type: TypeNames.RecordTypeName
        };
    }
    toRecord() {
        return this;
    }
    valueAtName(propName) {
        let value = null;
        this.properties.some(p => {
            if (p.name === propName) {
                value = p.value;
                return true;
            }
            return false;
        });
        return value;
    }
}
