// Preloads
let publicPixel;
let uniWide;
let tenderness;
let impact;
let comicSans;
let witchwoode;

// objecten
let mic;

// Enums
const allShapes = {
  Rect: "Rect",
  Circle: "Circle",
  Typography: "Typography",
  Triangle: "Triangle",
  Quad: "Quad",
  Torus: "Torus",
  Line: "Line",
}

// Arrays
let objects = [];
let possibleTexts = ["xD", ":)", ":P", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
   "67", "41", "69", "pwn", "PWNED", "sou", "wtf", "WTF?!", "WTH", "tf?", "uhm", "tuff",
  "alpha", "cat", "dog", "snake", "otter", "seal", "raccoon", "thief", "sybau", "ohio",
  "volume", "massive", "ginger", "blonde", "Netherlands", "USA", "UK", "Greece", "Spain",
  "Germany", "France", "ai", "art", "generative", "DDOS", "insert cool message here",
  "let art = cool", "AHHHH", "steam", "ubisoft", "activision", "gravity", "window", "discord",
  "TRASH!", "bongo", "bro", "yo", "YOLO", "!", "@", "#", "$", "%", "^", "&", "*", "()",
  "-", "=", "+", "[]", "{}", "|", "<>", ".", ",", "alt", "roblos", "meinkraft", "cool", "chest",
  "1K", "Nike", "gremlin", "zombie", "skeleton", "spider", "witch", "mimic", "dragon", "Pat", "Jen", "Cloud",
  "OverPNess", "sink", "shipping", "captain", "cookie", "pickle", "tomato", "patty", "meat", "sweet", "14:28",
  "BLAST!", "PublicPixel.ttf", "UniWide.otf", "FTW", "GG", "O_O", "crow", "coc", "hats","modification",
  "DIAMONDS!", "Emeralds", "coal...", "iron", "doge", "chocolate rain", "wireless", "wired", "mouse",
  "I", "have", "too", "much", "text!!!", "dear", "god", "send", "help", "why", "can't I", "stop?!", "clock",
  "AK-47", "Fox", "Laser", "gun", "AHH!!!", "DAMNN", "ZAMNN", "🦍", "tenderness.otf", "IT'S OVER 9000!!!", "wha-",
  "Toaster", "fridge", "sans", "abovetale", "monkey", "BANANA", "je mange un orange", "tYpOgRaPhY", "punk", "table",
  "array", "variable", "ENUM", "plant", "godly", "gnarly", "feline", "U-turn", "B-line", "furby", "tamagotchi",
  "metal detector", "58%", "battery saving", "consts", "seeds", "CAPITALIZED", "WEEK 4", "TV", "Wee Woo", "switch",
  "PBJ TIME!", "Illuminati", "confirmed", "H4x0r", "guest", "666", "love", "kindness", "determination", "fish",
  "1 pound", "settings", "possibleTexts", "Did you know...", "Does he know?", "Hold up!", "His writing is fire?!",
  "NANI??", "Legoshi", "Haru", "Louis", "Riz", "Cherryton", "Crain", "Excavator", "Train", "automobile", "bike", "skate 4", "the dead dog from marley and me",
  "Douglas Douglas", "Parkzer", "Paul Blart: Mall Cop", "The cat returns", "YOU EAT BABIES!", "How does he write \n like he's running out of time?", 
  "Overseer", "Trevor", "Micheal", "Franklin", "Javascript", "Long List of Possibilities", "THE SINK\nIS SHIPPING!", 
  "Alexander Hamilton", "Julius Ceasar", "Mark Rutte", "Geert Wilders", "Meer of Minder?", "protests", "deportations???",
  "Standby for titanfall!", "BT-7274", "Pilot Jack Cooper", "Bjorn the Unicorn", "EXTREME FEVER!", "Ode to Joy", "Tubular",
  "The frontier is worth\nevery part of\n this fight!", "brb", "press ENTER to\n generate new art!", "Cities:Skylines",
  "among us", "frontier defense", "the LEGEND", "Prince of darkness", "relsay", "tic tac toe", "Hello world!", "the company",
  "flowerman", "great asset", "employee", "4546B", "aurora", "Subnautical", "BELOW ZERO", "comical", "perseverance", "OBJECTION!",
  "HOLD IT!", "Lawyers Law", "Judge Judy Hopps", "Ancient builders", "order of the stone", "Jesse", "Olivia", "Axel", "Romeo", "Gauntlet",
  "Admin", "noob vs pro vs hacker", "Sean Combs", "MCSM", "Wither Storm", "Lee Everett", "Clementine", "400 days", "DLC", "Whimsical",
  "Gordon Freeman", "The right man in\nthe wrong place", "Strider", "Combine", "combination", "NOT throwing away\nmy shot", "demogorgan",
  "cats > dogs", "mitochondria", "red blood cells", "brain stem", "github", "Michealsoft Store", "sketch.js", "index.html", "jsconfig.json",
  "everybody do the\n FLOP!", "I like trains", "You only have OneShot", "Who's your daddy?", "the liberty behind our liberation", "independence", 
  "witness", "John Cena", "Dwayne 'the rock' Johnson", "He will never be satisfied", "bongo cat", "History has its sides", "Option C", "Doubt",
  "Attitude", "Doom", "Lafayette", "Lance", "Oh, guardian!", "Pancakes!", "GTX 1660 TI", "Duel", "blue bird", "martlet", "Deltatale", "Furocious",
  "furiousdestroyer", "ImADumbDumb", "Dr. Trayorrous\nor however you\nspell it", "diamond minecart", "mod showcase", "epic proportions", "Integrity",
  "Park in the south", "Kenny is dead?!", "Humble folk\nwithout tempation", "Paranoid", "SOS", "can you...\nhear me?", "I'm stuck!", "ARG",
  "GLaDOS", "Wheatley", "The cake is a lie!", "Hot topic", "cow tipper", "time to strike!", "Water bucket challenge!", "Idiocracy", "Futuristic", "Chemical",
  "H2O2", "Waterperoxide", "Gluten", "Lust", "Sin", "Greed", "Rings", "Hell", "Godly", "Oh my...", "goodness!", "bloody hell m8", "oi bruv", "spooderman",
  "Uranium", "Street racer parking only", "Pokeball", "Controller", "Virtual Reality", "REAL LIFE!!", "bowser", "wowsers", "meow", "woof", "*chirp*", "animal",
  "I like your pants a lot", "GOLDEN KNIGHTTTT!!", "plant-shaped plant", "Vaporeon", "Sylveon", "A platypus?", "PERRY THE PLATYPUS?", "Fortnite lamnmower", 
  "Nerf shotgun", "are you having fun yet?", "I will find you.", "grades", "cash money", "fancy", "Particularly", "Cooking", "Tomodachi", "the dark lord",
  "Mee News", "Kevin Macleod", "Copyright-full", "Copied", "Togore-tastic!", "DUI", "Death", "Inevitabiltiy", "Destiny still arrives", "Cops & Robbers",
  "Rover", "Satellite", "Jebediah Kerman", "Still alive", "Want you gone", "You wouldn't know", "Science to be done", "People are still alive", "Run.",
  "ESCAPE WHILE YOU CAN", "CLOSE THIS SOFTWARE!", "Virus", "The chosen one", "Animator", "VS", "Animation", "Powerhouse of the cell", "hey I just met you",
  "And this is crazy", "Here's my number", "so call me, maybe", "It's going down", "we're yelling", "TIMBER!!", "You better move", "You better dance.",
  "Al is weird", "Polka face", "Joe Rogan", "Fox News", "NOS", "Bol.com", "Advertisement", "free roux", "omni man", "Where is he?!", "Solid Snake", "Metal gear",
  "Christmas", "Halloween", "Beautiful", "Burning", "Frontspace", "Fanboys", "my time", "to go", "soon.", "Macrohards Teams", "Deliciously", "Deleiate", "flower", 
  "Killer bunny", "Friday the 13th", "Nonstop", "Skyradio", "Steeds verassend", "altijd voordeelig", "ooga booga", "The sims 2.7", "MMORPG", "Super Small", "Epstein list", 
  "why are there 2 godlies", "THE HEAVY IS DEAD?!", "Nostalgia", "1csd4", "sin", "cos", "tan", "a^2 + b^2 = c^2", "musical", "pacifist", "genocide", "skibidi", "crafting",
  "death", "Beatle", "ladybug", "gamer", "Robots","Toodles", "m8", "spotify", "spoof", "teacher", "damn", "zamn", "zed", "btd6", "bow", "turret", "tank",
  "female", "1337 B.C.", "Appie broodjes", "Tikkie", "betalingen", "taxes", "boni", "yarr", " my name\njeff", "guthib", "Mozilla Firefox", "TDS",
  "style.css", "industry plant", "*SWEAR WORD*", "tictak", "it's in the name", "Forza Sunset 7", "Pitch", "with a B", "bliss", "ignorance", "response",
  "the class of '87", "Freddy's Fazballs", "Chica the kitchen", "Bunny the Bonnie", "Failure", "weird", "angle", "complex", "mathamatics", "like a bird",
  "freeeennnnchhh\nfriesssss", "Staircase", "I fell from the light\nTalk or should I fight?\nMonster genocide\nThis my undertale", "wordle",
  "Dilly Dally", "Pork Valley", "Zeus", "Kratos", "the third", "LEGENDARY!!!", "NOOO", "anime", "manga", "ghost stories\nenglish dub", "bloatware",
  "Shovel? where??", "White & Nerdy", "Close,\n but no cigar ):", "Been spending all my life", "living in the", "Amish paradise", "pain & suffering",
  "sue", "lawsuit", "Egyptians", "cat jesus", "idk what to write", "Whats up, gun?", "singularity", "invitation", "vampirism", "electronic mailing",
  "muck", "Squiddo Games", "Truman has a show", "Programming", "Coding", "Loathing", "Littering", "Beautiful", "Protocol 3", "Protect the pilot", "Kamikaze",
  "titanic", "iceberg", "fresh meat", "Juicy Juice", "Polluting Parks", "Climate Change", "ln 73\ncoll103\nspaces:2\nUTF-8\nCRLF", "cool reference",
  "Corruption", "PocketPal", "Tamagotchi < Tomodachi", "I want a new", "hat", "clothes", "room", "1000 degrees knife", "I'm hungry", "arrow",
  "x = (-b+√b^2-4ac) / 2a", "√", "ENEMIES", "BLOOD", "TORTURE", "el gato", "italiano", "black coffee", "white coffee??", "Steve", "I, am", "get rotated",
  "baby shark", "kinderen voor kinderen", "Hello darkness", "my old friend", "I've come to talk to you", "again", "nonsense", "electrity", "#OWNED",
  "einsteinium", "sussy amongus", "Montgomery Gator\nfrom hit game\n FNAF:SB", "Aarron Burr, sir", "I disagree", "That's why we need it", "abrasive",
  "electricity but\nspelled correctly", "Jesse Pinkman VS Jesse MCSM", "synced", "geeked", "obligatory", "typoe", "movie film", "impact.ttf",
  "comicsanslight.ttf", "witchwoode-Regular.ttf", "wingdings didnt work", "Hamilton, sit down", "pro-council", "democratic", "conservative", "smartest",
  "annoying", "6x = 12, x =2", "history", "breaking grounds", "scientific", "Persian", "Anubis", "Financial Report", "scrap", "SAUSE-age", "leetcode",
  "c#", "c++", "gdscript", "blueprints", "UE5", "Unreal Engine", "Godot", "Unity", "Gamemaker", "RPGMaker", "RPG in a box", "car engine", "transformator",
  "dess knight theory", "yoo hoo its a labubu", "LVL 25.5 asteroid", "Barbie", "Warschau", "Redbull", "wings", "longshot", "trickshot", "backflip", "sick AF",
  "Nothing built can last forever.\nAnd every legend, no matter how great, fades with time.\nWith each passing year, more and more details are lost...\nuntil all that remains are myths.\n Half truths. To put it simply, lies.\nAnd yet in all the known universe, between here and the Far Lands,\nthe legend of the Order of the Stone endures, unabridged, as self-evident fact.\nIndeed, it is only a troubled land that has need for heroes - and ours was fortunate to have, so long ago, four heroes such as these:\nGabriel the Warrior, before whose sword all combatants would tremble.\nEllegaard the Redstone Engineer, whose machines would spark an era of invention.\nMagnus the Rogue, who would channel his destructive creativity for the benefit of all.\nAnd Soren the Architect, Builder of Worlds and leader of the Order of the Stone.\nThese FOUR friends together, would give so much to gain their rightful place as FOUR heroes.\nTheir greatest quest would take them on a dangerous journey to fight a mysterious creature known as the Ender Dragon.\nIn the end, the Order of the Stone emerged victorious and the dragon was defeated.\nTheir story complete, they slipped away into the pages of legends.",
  "The FitnessGram Pacer Test is a multistage aerobic capacity test that progressively gets more difficult as it continues.\nThe 20 meter pacer test will begin in 30 seconds.\nLine up at the start.\nThe running speed starts slowly but gets faster each minute after you hear this signal bodeboop.\nA sing lap should be completed every time you hear this sound.\nding. Remember to run in a straight line and run as long as possible. The second time you fail to complete a lap before the sound, your test is over.\nThe test will begin on the word start.\nOn your mark. Get ready!… Start. ding! "];
let possibleFonts = [];
let possibleShapes = [allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect, allShapes.Rect,
    allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle, allShapes.Circle,
    allShapes.Typography, allShapes.Typography, allShapes.Typography, allShapes.Typography, allShapes.Typography, allShapes.Typography,
    allShapes.Triangle, allShapes.Triangle,
    allShapes.Quad, allShapes.Quad,
    allShapes.Line,
    allShapes.Torus]; // Dingen meerdere keren herhalen maakt het meer common, dit zorgt ervoor dat er niet te veel is van een specifiek ding, zou dit met een for loop in setup doen, maar mag geen setup func gebruiken
let placableShapes = [allShapes.Rect, allShapes.Circle];

// Seeds
let objectsSeed = 0;
let colorSeed = 0;

// vars
let sizeMultiplier = 1;
let neededSize = 1;
let totalStartObjects = 100;

// consts
const canvasXSize = 800;
const canvasYSize = 600;

function preload() {
  impact = loadFont("/../assets_week_4/Fonts/impact.ttf");
  comicSans = loadFont("/../assets_week_4/Fonts/Ldfcomicsanslight-6dZo.ttf");
  publicPixel = loadFont("/../assets_week_4/Fonts/PublicPixel.ttf");
  uniWide = loadFont("/../assets_week_4/Fonts/UniWide.otf");
  tenderness = loadFont("/../assets_week_4/Fonts/tenderness.otf");
  witchwoode = loadFont("/../assets_week_4/Fonts/Witchwoode-Regular.ttf")
  possibleFonts = [impact, comicSans, publicPixel, uniWide, tenderness, witchwoode];
}

function setup() {
    createCanvas(canvasXSize, canvasYSize, WEBGL);
    angleMode(DEGREES);
    mic = new p5.AudioIn();
    mic.start();
    normalMaterial();
}

function draw() { // In godot is dit de process function

  let vol = (constrain(mic.getLevel(), 0, 3)) * 5;
  console.log("MIC VOLUME: " + vol);

  neededSize = (1 + vol);

  print("SIZE: " + neededSize)

  sizeMultiplier = lerp(sizeMultiplier, neededSize, 0.05);

  _show_art();
}

function _show_art() {
  let totalObjects = objects.length; // Krijg lengte

  sizeMultiplier = lerp(sizeMultiplier, neededSize, 0.02);

  randomSeed(colorSeed);

  background(random(0, 255), random(0, 255), random(0, 255), random(0, 255));

  for (let objectGettingPlaced = 0; objectGettingPlaced < totalObjects; objectGettingPlaced++) {

    let object = objects[objectGettingPlaced];

    let color = [random(255), random(255), random(255), random(255)]
    fill(color[0], color[1], color[2], color[3]);

    switch(object.type) {
      case allShapes.Rect:
        push();
        rotate(object.rotX);
        rect(object.posX, object.posY, object.rectWidth * sizeMultiplier, object.rectLength * sizeMultiplier);
        pop();
        break;
      
      case allShapes.Circle:
        circle(object.posX, object.posY, object.diameter * sizeMultiplier);
        break;
      
      case allShapes.Typography:
        push();
        rotate(object.rotX);
        textSize(round(object.size * sizeMultiplier));
        textFont(object.font);
        text(object.contents, object.posX, object.posY);
        pop();
        break;
      
      case allShapes.Triangle:
        triangle(object.posX1 * sizeMultiplier, object.posY1, object.posX2, object.posY2 * sizeMultiplier,
        object.posX3 * sizeMultiplier, object.posY3);
        break;

      case allShapes.Quad:
        quad(object.posX1, object.posY1 * sizeMultiplier, object.posX2 * sizeMultiplier, object.posY2, 
        object.posX3, object.posY3 * sizeMultiplier, object.posX4 * sizeMultiplier, object.posY4);
        break;
      
      case allShapes.Torus:
        push();
        translate(object.posX, object.posY, 0);
        rotateX(object.rotX)
        rotateY(object.rotY)
        rotateZ(object.rotZ)
        torus(object.radius * sizeMultiplier, object.tubeRadius * sizeMultiplier, object.detailX, object.detailY);
        for (let i = 0; i < object.radius; i++) {
          let stop = round(random(0,10));
          if (stop <= 1) {
            break;
          }
          else {
            randomSeed(objectsSeed);
            for (let changedColor = 0; changedColor < color.length; changedColor++) {
              let change = random(-10,10);
              color[changedColor] += change;
            }
            torus((object.radius - i) * sizeMultiplier, object.tubeRadius * sizeMultiplier, object.detailX - (i * 2), object.detailY - (i * 2));
          }
        }
        pop();
        break;
      
      case allShapes.Line:
        push();
        stroke(color[0], color[1], color[2], color[3]);
        strokeWeight(object.lineSize * sizeMultiplier);
        line(object.posX1, object.posY1, object.posX2, object.posY2);
        pop();
    }
  }

}

function _generate_random_seeds() {
  objectsSeed = random(0,99999999999);
  colorSeed = random(0,99999999999);
}

function _generate_new_objects() {
  sizeMultiplier = 0;  

  objects = [];

  for (let stuff = 0; stuff < totalStartObjects; stuff++) {
    let shape = pickRandom(possibleShapes); // Krijg een random shape

    switch (shape) {
      case allShapes.Rect:
        objects.push({
          type: allShapes.Rect,
          rotX: random(0,360),
          posX: random(-canvasXSize / 2, canvasXSize / 2),
          posY: random(-canvasYSize / 2, canvasYSize / 2),
          rectWidth: random(50,150),
          rectLength: random(50,150),
        });
        break;

      case allShapes.Circle:
        objects.push({
          type: allShapes.Circle,
          posX: random(-canvasXSize / 2, canvasXSize / 2),
          posY: random(-canvasYSize / 2, canvasYSize / 2),
          diameter: random(50, 150),
        });
        break;
      
      case allShapes.Typography:
        objects.push({
          type: allShapes.Typography,
          contents: pickRandom(possibleTexts),
          size: random(8, 96),
          font: pickRandom(possibleFonts),
          rotX: random(0, 360),
          posX: random(-canvasXSize / 2, canvasXSize / 2),
          posY: random(-canvasYSize / 2, canvasYSize / 2),
        })
        break;
      
        case allShapes.Triangle:
          objects.push({
            type: allShapes.Triangle,
            posX1: random(-canvasXSize / 2, canvasXSize / 2),
            posY1: random(-canvasYSize / 2, canvasYSize / 2),
            posX2: random(-canvasXSize / 2, canvasXSize / 2),
            posY2: random(-canvasYSize / 2, canvasYSize / 2),
            posX3: random(-canvasXSize / 2, canvasXSize / 2),
            posY3: random(-canvasYSize / 2, canvasYSize / 2),
          })
          break;

        case allShapes.Quad:
          objects.push({
            type: allShapes.Quad,
            posX1: random(-canvasXSize / 2, canvasXSize / 2),
            posY1: random(-canvasYSize / 2, canvasYSize / 2),
            posX2: random(-canvasXSize / 2, canvasXSize / 2),
            posY2: random(-canvasYSize / 2, canvasYSize / 2),
            posX3: random(-canvasXSize / 2, canvasXSize / 2),
            posY3: random(-canvasYSize / 2, canvasYSize / 2),
            posX4: random(-canvasXSize / 2, canvasXSize / 2),
            posY4: random(-canvasYSize / 2, canvasYSize / 2),
          })
          break;

        case allShapes.Torus:
          objects.push({
            type: allShapes.Torus,
            radius: random(10, 50),
            tubeRadius: random(5, 25),
            detailX: round(random(4, 16)),
            detailY: round(random(4, 12)),
            posX: random(-canvasXSize / 2, canvasXSize / 2),
            posY: random(-canvasYSize / 2, canvasYSize / 2),
            rotX: random(0,360),
            rotY: random(0,360),
            rotZ: random(0,360),
        })
        break;
      
        case allShapes.Line:
          objects.push({
            type: allShapes.Line,
            lineSize: random(2, 24),
            posX1: random(-canvasXSize / 2, canvasXSize / 2),
            posY1: random(-canvasYSize / 2, canvasYSize / 2),
            posX2: random(-canvasXSize / 2, canvasXSize / 2),
            posY2: random(-canvasYSize / 2, canvasYSize / 2),
          })

    }

    print(objects);

  }
}

function pickRandom(object) { // p5.js heeft deze mooie godot functie niet ):<
  let result;

  thing = floor(random(object.length)); // random nummer
  result = object[thing]; // krijg vorig nummer van array

  return result;
}

function mousePressed() {
  if (mouseButton === LEFT) {

    let shape = pickRandom(placableShapes);

    switch (shape) {
      case allShapes.Circle:
        objects.push({
        type: allShapes.Circle,
        posX: mouseX - (canvasXSize / 2),
        posY: mouseY - (canvasYSize / 2),
        diameter: random(50,150),
        })
        break;
      case allShapes.Rect:
        objects.push({
          type: allShapes.Rect,
          rotX: 0,
          posX: mouseX - (canvasXSize / 2),
          posY: mouseY - (canvasYSize / 2),
          rectWidth: random(50,150),
          rectLength: random(50,150),
        })
    }
  }
}


function keyPressed() {
  if (keyCode === 13) { // Enter
    _generate_random_seeds();
    randomSeed(objectsSeed);
    totalStartObjects = random(100, 250);
    _generate_new_objects();
  }

  else if (keyCode === 83) { // S
    saveCanvas("Mijn zieke kunsttalent", "webp"); // webp D: (slaat screenshot op)
  }

  else if (keyCode === 8) { // backspace
    _generate_random_seeds();
  }
}