export default class Loop {
    constructor(id, name, start, end, acids, length, pdb, chain, protein, source, geometry) {
        this.id = id;
        this.name = name;
        this.start = start;
        this.end = end;
        this.acids = acids;
        this.length = length;
        this.pdb = pdb;
        this.chain = chain;
        this.protein = protein;
        this.source = source;

        this.flexibility = null;

        if (geometry != null) {
            this.distance = geometry.distance;
            this.rho = geometry.rho;
            this.delta = geometry.delta;
            this.theta = geometry.theta
        }

        this.color = null;
        this.replacement = null;
    }

    get hasGeometry() {
        return this.distance != null && !isNaN(this.distance);
    }


    get position() {
        return `${this.start}-${this.end}`
    }

    get coilStart() {

        for (let index = 1; index < this.acids.length; index++) {
            let acid = this.acids[index];
            if (acid.simple_secondary_structure != this.acids[index - 1].simple_secondary_structure) {
                return acid.pdb_number - 1
            }
        }
        return null;

    }

    get coilEnd() {

        for (let index = this.acids.length - 2; index >= 0; index--) {
            let acid = this.acids[index];
            if (acid.simple_secondary_structure != this.acids[index + 1].simple_secondary_structure) {
                return acid.pdb_number + 1
            }
        }
        return null;
    }

    invalidateGeometry() {
        this.distance = NaN;
        this.rho = NaN;
        this.delta = NaN;
        this.theta = NaN;
        this.source = "Custom";
    }



    setPosition(from, to, protein) {
        let { min, max } = protein.minMaxPdbNumber;
        if (from < to) {
            if (from >= min) {
                this.start = from;
            }
            if (to <= max) {
                this.end = to;
            }
            this.invalidateGeometry();
        }
    }

    loopCorrelationWith(interesting_loop_id) {
        return this.crosscorelation.anm[interesting_loop_id].value
    }

    maximumSubCorrelationWith(interesting_loop_id) {
        let loop1_segment = this.protein.segmentation.getSegmentByName(this.id);
        let loop2_segment = this.protein.segmentation.getSegmentByName(interesting_loop_id);

        let loop1_secses = loop1_segment.ss_segment_list.map((name) =>
            this.protein.segmentation.getSegmentByName(name)
        );
        let loop2_secses = loop2_segment.ss_segment_list.map((name) =>
            this.protein.segmentation.getSegmentByName(name)
        );

        let maximum = 0.0;
        for (let loop1_secs of loop1_secses) {
            for (let loop2_secs of loop2_secses) {
                try {
                    let value = this.protein.secs_crosscol["anm"][loop1_secs.name][
                        loop2_secs.name
                    ].value;
                    if (
                        loop1_secs.name.startsWith("C") &&
                        Math.abs(value) >= Math.abs(maximum)
                    ) {
                        maximum = value;
                    }
                }
                catch(err) {
                    console.warn(`Something went wrong with ${loop1_secs?.name} x ${loop2_secs?.name} when computing maxSubCorrelation for ${this.id} and ${interesting_loop_id}`)
                    console.warn(err);
                }
            }
        }
        return maximum;
    }

    nukeFlexibility() {
        this.flexibility = null;
    }
}