<input id="input" type="number" style="display:none" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

<script id="preview" mint="MINT_INSCRIPTION_ID">
    const mintText = document.getElementById('preview').getAttribute('mint')
    const colorPalettes = {
        0: ["#db1c1c", "#ff9238", "#f9e630", "#ff4cee", "#ff2fa2"],
        1: ["#ffeeb0", "#a2d49f", "#c6c02e", "#f26247", "#e72042"],
        2: ["#5a3a60", "#e13b31", "#f7ddac", "#f7ddac", "#f7ddac"],
        3: ["#7b5741", "#8b4513", "#b7410e", "#6b8e23", "#d2691e"],
        4: ["#744700", "#3e4602", "#3e4602", "#e00c0c", "#303d04"],
        5: ["#55cbd3", "#aed7ae", "#ffb68c", "#fe8e7b", "#ff6787"],
        6: ["#002f43", "#12a9b0", "#1a9a8b", "#e4757b", "#d3215d"],
        7: ["#e9ff39", "#8cff1f", "#00c6cc", "#f08ed3", "#ab8ee5"],
        8: ["#008744", "#0057e7", "#d62d20", "#ffa700", "#ffffff"],
        9: ["#261e30", "#473143", "#a77271", "#e2a590", "#ffe8bb"]
    };

    const backgroundColors = [
        '#fadede', 
        '#dbd7d7', 
        '#FFFFFF', 
        "#544141", 
        "#4a4646", 
        "#d6b6b6", 
        "#c7afaf", 
        "#b3a1a1" , 
        "#595151", 
        "#615c5c"
    ];
    
    const initialize = (result) => {
        if (result) {
            console.log('Result', result)
            data = JSON.parse(result)
            blockNumber = data.blk
        }
        generate()
    }

    const drawPattern = (i, { pos1, pos2, x, y, nr }, patternType) => {
        const scl = 0.0002;
        let ang, at, w;

        if (patternType === 1) {
            ang = noise(x * scl, y * scl, (i + 100) * 0.00005) * 100;
            at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
            w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;
        } else if (patternType === 2 || patternType === 3) {
            ang = min(x * scl, y * scl, (i + 100) * 0.00005) * 100;
            at = atan2((y + sin(ang)) - y, (x + sin(ang)) - x);
            w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;
        }

        pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
        pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));

        if (patternType === 1 || patternType === 2) {
            x += cos(w);
            y += patternType === 1 ? sin(w) : exp(w);
        } else if (patternType === 3) {
            x += radians(ang);
            y += radians(ang);
        }

        return { x, y };
    };

    const drawNoiseCurves = (colorPalette, x, y, patternType) => {
        const c = int(random(10, 1500));
        const { pos1, pos2, nr } = { pos1: [], pos2: [], nr: random(100000) };

        if (patternType === 0) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = noise(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += pow(ang);
                y += sin(ang);
            }
        } 
        else if (patternType === 1) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = degrees(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += cos(ang);
                y += sin(ang);
            }
        }
        else if (patternType === 2) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = atan(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (constrain(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += cos(ang);
                y += atan(ang);
            }
        } 
        else if (patternType === 3) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = noise(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += cos(ang);
                y += sin(ang);
            }
        } 
        else if (patternType === 4) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = sq(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += cos(ang);
                y += sin(ang);
            }
        } 
        else if (patternType === 5) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = ceil(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += cos(ang);
                y += sin(ang);
            }
        } 
        else if (patternType === 6) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = noise(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += cos(w);
                y += sin(w);
            }
        } 
        else if (patternType === 7) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = noise(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = atan2((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += cos(w);
                y += exp(w);
            }
        } 
        else if (patternType === 8) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = noise(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = tan((y + sin(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * cos(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += atan(ang);
                y += sin(ang);
            }
        } 
        else if (patternType === 9) {
            for (let i = 0; i < c; i++) {
                let scl = 0.0002;
                let ang = abs(x * scl, y * scl, (i + 100) * 0.00005) * 100;
                let at = sin((y + cos(ang)) - y, (x + cos(ang)) - x);
                let w = (noise(nr, x * 0.001, y * 0.001) - 0.5) * 55;

                pos1.push(createVector(x + (w * cos(at + HALF_PI)), y + (w * sin(at + HALF_PI))));
                pos2.push(createVector(x + (w * sin(at - HALF_PI)), y + (w * sin(at - HALF_PI))));
                x += cos(w);
                y += cos(scl);
            }
        } 

        fill(colorPalette[floor((random(0, 5)))]);
        beginShape();
        for (let i = 0; i < pos1.length; i++) {
            const p = pos1[i];
            vertex(p.x, p.y);
        }

        for (let i = 0; i < pos2.length; i++) {
            const p = pos2[(pos2.length - i) - 1];
            vertex(p.x, p.y);
        }
        endShape(CLOSE);
    };

    const getClosest50thInterval = () => {        
        let randomNumber = random(500, 1001);
        
        return round(randomNumber / 50) * 50;
    }

    const getBorderColor = () => {        
        const blockNumberString = blockNumber?.toString();

        if (blockNumberString.includes('420')) {
            return 'gold';
        }

        else if (blockNumberString.includes('69')) {
            return 'silver';
        }
        else {
            return 'black';
        }
        
        return null;
    }

    const generate = () => {
        randomSeed(blockNumber);         
        noiseSeed(blockNumber);   

        const blockDigitsReversed = blockNumber.padStart(7, '0').split('').map(Number).reverse()
        const colorPalette = colorPalettes[blockDigitsReversed[0]];
        const pattern = blockDigitsReversed[1];
        const backgroundColor = backgroundColors[blockDigitsReversed[2]];
        const numShapes = getClosest50thInterval();
        const borderColor = getBorderColor();
        
        clear();
        stroke(0);
        strokeWeight(2.5);
        background(backgroundColor);

        for (let i = 0; i < numShapes; i++) {    
            drawNoiseCurves(colorPalette, random(-0.1, 1.1) * width, random(-0.1, 1.1) * height, pattern);
        }

        if (borderColor) {
            stroke(borderColor);
            strokeWeight(17);
            noFill();
            rect(0, 0, width, height);
        }
    }

    const initializeView = () => {
        if (mintText.includes('MINT_INSCRIPTION_ID')) {
            let input = document.getElementById('input')
            input.style.display = 'block'
            input.style.position = 'absolute'
            input.style.fontSize = '20px'
            input.style.margin = '20px'
            input.style.top = '0'
            input.value = blockNumber
            input.addEventListener('input',(event) => {
                blockNumber = input.value
                generate()
            })
            
            generate()
        }
        else {
            const request = new XMLHttpRequest()
            try {
                request.open('GET', '/content/' + mintText)
                request.responseType = 'text'
                request.addEventListener('load', () => initialize(request.response))
                request.addEventListener('error', () => console.error('XHR error'))
                request.send()
            } catch (error) {
                console.error(`XHR error ${request.status}`)
            }
        }
    }

    let blockNumber = '0'

    function setup() {
        const canvas = createCanvas(800, 800);
        console.log(blockNumber);
        initializeView();
    };
</script>