/*
This code is free software.
It comes without any warranty, to the extent permitted by applicable law.
You can redistribute it and/or modify it under the terms of the
Do What The Fuck You Want To Public License, Version 2,
as published by Sam Hocevar
(see <https://wtfpl.net> for more details)
or (at your option) under the terms of the
GNU Affero General Public License
as published by the Free Software Foundation,
either version 3 of the License,
or (at your option) any later version.
(See <https://gnu.org/licenses/agpl>.)

Note that the associated assets are licenced differently.
*/

let time = 0;
let r = 200;
let r2 = r * 2
let axisOffset = r * 0.5;
let makeSense = true;
let drawBackground = true;
let isPhaseEnd;
let nebulaSound;
let scenestreamSound;
let sunflowerSound;
let font;
let creditZ;
let creditText;
let background2opacity = 0.001;
let canvas;
let button;

function preload() {
  nebulaSound = loadSound('assets/Doctor Gekil - 1 - Nebula - long version - 100 BPM.mp3');
  font = loadFont('assets/Inconsolata.otf');
}

function setup() {
  // Begin (asynchronously) loading stuff that we'll only need later.
  scenestreamSound = loadSound('assets/ALPA - 3 - Scenestream Daydreams +2.mp3');
  sunflowerSound = loadSound('assets/vulpivia_See the World in an Ocean of Undying Sunflowers.ogg');
  
  // actual setup
  canvas = createCanvas(r * 3, r * 3, WEBGL);
  ortho();
  colorMode(HSB);
  textFont(font);

  // Create a button and place it beneath the canvas.
  button = createButton('▶');
  button.position(0, 3 * r);

  // Call start() when the button is pressed.
  button.mousePressed(start);

  nebulaSound.addCue(1 * 60 + 26 - 10, endPhase);
  nebulaSound.addCue(1 * 60 + 26, beginPhase2);
  nebulaSound.addCue(2 * 60 +  4.5 - 10, endPhase);
  nebulaSound.addCue(2 * 60 +  4.5, beginPhase3);
  nebulaSound.addCue(2 * 60 + 41 - 5, endPhase);
  nebulaSound.addCue(2 * 60 + 41, beginPhase4);

  scenestreamSound.addCue(1 * 60 +  8 - 10, endPhase);
  scenestreamSound.addCue(1 * 60 +  8, beginPhase5);
  scenestreamSound.addCue(1 * 60 + 22 - 10, endPhase);
  scenestreamSound.addCue(1 * 60 + 22, beginPhase2);
  scenestreamSound.addCue(1 * 60 + 49 - 10, endPhase);
  scenestreamSound.addCue(1 * 60 + 49, beginPhase7);

  sunflowerSound.addCue(1 * 60 +  8, beginPhase8);
  sunflowerSound.addCue(1 * 60 + 20, beginCredits, {content: "das-g", size: r*0.8});
  sunflowerSound.addCue(1 * 60 + 30, beginFadeToBlack);
  sunflowerSound.addCue(1 * 60 + 40, beginCredits, {content: "mandaloopsie", size: r*0.4});
  sunflowerSound.addCue(2 * 60 +  6, beginCredits, {content: "music:\n\n\"Nebula\" (long version)\nby Doctor Gekil\n\n\"Scenestream Daydreams +2\"\nby ALPA\nCC BY-NC-SA 4.0\n\n\"See the World in an Ocean\nof Undying Sunflowers\"\nby vulpivia\nCC0 1.0\n\nfont: \"Inconsolata\" by Raph Levien\nSIL Open Font License v1.10", size: r*0.14});
}

function start() {
  button.remove();
  canvas.elt.requestFullscreen();
  setTimeout(() => {
    beginPhase1();
    nebulaSound.play();
    draw = realDraw;
  }, 5000);
}

function draw() {
  background(0);
  text('click the button below to start animation', 0, 0)
}

function realDraw() {
  time += deltaTime;
  if (drawBackground) {
    background(220);
  }
  drawX();
}

function endPhase() {
  isPhaseEnd = true;
}

function beginPhase() {
  isPhaseEnd = false;
  time = 0;
  axisOffset = r * 0.5
}

function beginPhase1(){
  beginPhase();
  makeSense = true;
  drawX = draw1;
}

function beginPhase2() {
  beginPhase();
  drawX = draw2; 
}

function beginPhase3() {
  beginPhase();
  drawX = draw1;
  makeSense = false;
}

function beginPhase4() {
  beginPhase();
  drawX = draw2;
  scenestreamSound.play();
  nebulaSound.stop();
}

function beginPhase5() {
  drawBackground = false;
  beginPhase1();
}

function beginPhase7() {
  beginPhase3();
  sunflowerSound.play();
  scenestreamSound.stop();
}

function beginPhase8() {
  beginPhase();
  drawX = draw2;
}

function beginCredits(arg) {
  drawX = drawCredits;
  creditZ = 0;
  creditText = arg.content;
  textSize(arg.size);
}

function beginFadeToBlack() {
  background2opacity = 1;
}

function draw1() {
  for (let i = 0; i < 5; i++) {
    foo(475+12*i);
  }
  if (isPhaseEnd){
    axisOffset += deltaTime/20;
  }
}

function draw2(){  
  for (let i = 0; i < (time / 500 % 1000); i++) {
    foo(475+12*i);
  }
  if (isPhaseEnd){
    axisOffset += deltaTime/20;
  }
}

function drawCredits() {
  makeSense = false;
  drawBackground = false;
  draw2();
  resetMatrix();
  translate(0,0,creditZ);
  fill(0,0,0,background2opacity);
  rectMode(CENTER);
  square(0, 0, 5*r);
  if(background2opacity > 0) {
    background2opacity += deltaTime * 0.00001;
  }
  if(creditZ <= 3*r) {
    creditZ += deltaTime * r * 0.00005;
  }
  textAlign(CENTER, CENTER);
  fill(255);
  stroke(1);
  strokeWeight(4);
  text(creditText, 0, 0);
  strokeWeight(1);
}

function foo(bar) {
  angle = (time/bar) % TAU ;
  fill(degrees((angle)) % 360, 50, 100);
  if(makeSense){
    resetMatrix();
  };
  rotateZ(angle);
  rotateX(PI/3);
  ellipse(axisOffset,0,r,2*r)
}
