function Control(el, { value = 0,
    min = 0,
    max = 100,
    minAngle = 0,
    maxAngle = 360,
    wheelSpeed = 0.1,
    step = 1 } = {}) {

    const img = document.createElement('img')
    img.src = '1@3x.png'
    img.style.width = '100%'
    img.style.height = 'auto'
    el.append(img)
    
    let forceChange = new Event('change')
    this.currentValue = document.createElement('input')
    this.currentValue.type = 'number'
    this.currentValue.value = value

    const ratio = (maxAngle - minAngle) / (max - min)
    const getAngle = () => (value - min) * ratio + minAngle

    this.getValue = () => {
        return value
    }

    this.setValue = newValue => {
        if (newValue > max) {
            newValue = max
        }
        if (newValue < min) {
            newValue = min
        }
        value = newValue
        this.currentValue.value = value
        this.currentValue.dispatchEvent(forceChange)
        img.style.transform = `rotate(${getAngle()}deg)`
    }

    img.onmousewheel = e => {
        const { deltaY } = e

        const newValue = value + deltaY * wheelSpeed
        this.setValue(newValue)

        e.preventDefault()
    }

    img.onclick = e => {
        const { layerX } = e
        const { width } = img
        
        layerX > width / 2? this.setValue(value + step) : this.setValue(value - step)
    }

    const toDeg = rad => ((rad * 180) / Math.PI + 360 + 90) % 360

    let prevMouseAngle = null

    img.onmousedown = e => {
        const y = e.layerY - img.height / 2
        const x = e.layerX - img.width / 2
        prevMouseAngle = toDeg(Math.atan2(y, x))
        e.preventDefault()
    }

    img.onmousemove = e => {
        if (prevMouseAngle === null) return
        const y = e.layerY - img.height / 2
        const x = e.layerX - img.width / 2
        let currentAngle = toDeg(Math.atan2(y, x))
        let moveAngleDiff = (currentAngle - prevMouseAngle)
        this.setValue(value + moveAngleDiff / ratio)
        prevMouseAngle = currentAngle
    }

    img.onmouseout = img.onmouseup = () => {
        prevMouseAngle = null
    }

    this.setValue(value)
}


let track = document.getElementById('track')
let audioSpin = document.getElementById('audio-spin')
const volumeControl = new Control(audioSpin, { value: 50, min: 0, max: 100, minAngle: 0, maxAngle: 360 })
track.volume = volumeControl.getValue() / 100
volumeControl.currentValue.onchange = () =>  track.volume = volumeControl.getValue() / 100


// RGB
const Red  = new Control(red, {min: 0, max: 255})
const Green  = new Control(green, {value: 200, min: 0, max: 255})
const Blue  = new Control(blue, {value: 125, min: 0, max: 255})

let setRGB = (element) => {
    element.style.backgroundColor = `rgb(${Red.getValue()||0}, ${Green.getValue()||0}, ${Blue.getValue()||0})`
}
setRGB(document.getElementById('color-window'))

Red.currentValue.onchange = () => setRGB(document.getElementById('color-window'))
Green.currentValue.onchange = () => setRGB(document.getElementById('color-window'))
Blue.currentValue.onchange = () => setRGB(document.getElementById('color-window'))
