summaryrefslogtreecommitdiffstats
path: root/genome.mjs
blob: bb5c09ad9066d5aaa9bc20efd019f2f88941ed4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import Codon from './codon.mjs'
import Die from './die.mjs'
import { randomItem } from './utils.mjs'

class Genome {
    constructor(nucleotides) {
        const codonList = document.createElement('ol')

        this.codons = []
        let tmpCodon = []
        nucleotides.forEach(base => {
            tmpCodon.push(base)
            if (tmpCodon.length == 3) {
                const c = new Codon(...tmpCodon)
                codonList.appendChild(c.elt)
                this.codons.push(c)
                tmpCodon = []
            }
        })
        this.elt.appendChild(codonList)

        this.lock()
        this._boundNucleotideClickedHandler =
            this.nucleotideClickedHandler.bind(this)
        this.codons.forEach(c => {
            c.bases.forEach(b => {
                b.onClick = this._boundNucleotideClickedHandler
            })
        })
    }

    get elt() {
        if (this._elt === undefined) {
            this._elt = document.createElement('li')
            this._elt.classList.add('genome')
        }
        return this._elt
    }

    get nucleotides() {
        return this.codons.reduce((acc, c) => {
            return acc.concat(c.bases)
        }, [])
    }

    get length() {
        return this.codons.reduce((acc, c) => {
            return acc + c.bases.length
        }, 0)
    }

    get onNucleotideSelectionChanged() {
        if (this._onNucleotideSelectionChanged !== undefined) {
            return this._onNucleotideSelectionChanged
        }
        return () => {}
    }

    set onNucleotideSelectionChanged(fn) {
        this._onNucleotideSelectionChanged = fn
    }

    lock() {
        this.elt.classList.add('locked')
        this.codons.forEach(n => n.lock())
    }

    unlock() {
        this.elt.classList.remove('locked')
        this.codons.forEach(n => n.unlock())
    }

    clone() {
        return new Genome(this.nucleotides.map(n => n.value))
    }

    get selectedNucleotide() {
	return this._selectedNucleotide
    }

    set selectedNucleotide(nucleotide) {
	if (this.selectedNucleotide !== undefined) {
	    this.selectedNucleotide.deselect()
	}
	this._selectedNucleotide = nucleotide
	this._selectedNucleotide.select()

        let i = 0
        for (const c of this.codons) {
            for (const b of c.bases) {
                if (b === this._selectedNucleotide) {
                    this.selectedCodon = c
	            this.onNucleotideSelectionChanged(this._selectedNucleotide, i)
                    return
                }
                i++
            }
        }
    }

    nucleotideClickedHandler(nucleotide) {
	this.selectedNucleotide = nucleotide
    }
}

export default Genome