//class_BackGround


class BackGround {
  float Hue = 132;
  float Saturation = 100;
  float Brightness = 255;
  float diagonalLineParallax = 1;// 1.4; /*1 is no parallax, greater is more. Don't make it less than 0, because we don't draw images out there.*/
  float marbleParallax = 1.3;
  float rectBounds = 600; //the Height of the bounding box in which rectangles are allowed
  float rectFadeDistance = 300; //how far away from rectBounds rectangles begin to fade
  float dLTWidth,dLTHeight; //the width and height of the thick diagonal line image (so we don't have to write out diagonalLineThick_img.width every time)
  int rectangleLifespan = 600; //expected rectangle life-span
  int type; //what type of background we are. 0 is outside.
  Rectangle[] rectangle;
  BackGround(int Type) {
    type = Type;
    reset();
  }
  void draw() {
    //Draw.
    //background
    background(Hue,Saturation,Brightness);
    if(type==0 || type==1) {
      pushMatrix();
      translate(camera.x-width*0.5,camera.y-height*0.5); // HACK! the -width*0.5 stuff. BECAUSE THIS GAME IS DIFFERENT FROM SCALE'S CAMERA I GUESS.
      //white gradient
      tint(255, Brightness);
      image(gradient_img, 0,300, width,500);
      noTint();
      //blue gradient
      rotate( PI); //pushMatrix
      tint(Hue+8,Saturation*2,Brightness*0.7, 255);
      //tint(140,240,179);
      image(gradient_img, -width,-height, width,height);
      noTint();
      rotate(-PI); //popMatrix
      popMatrix();

      //rectangles!
      for(int i=0; i<rectangle.length; i++)
        rectangle[i].draw();

      if(type==0) {
        //diagonal lines
        pushMatrix();
        translate(camera.x-(camera.x/diagonalLineParallax)%width,camera.y-(camera.y/diagonalLineParallax)%height);
        if(camera.x<0) translate(-width, 0); //ugh. Hate this hack thing. Why is it when camera.x is less than 0 stuff gets offset?
        if(camera.y<0) translate(0,-height); //ugh. Hate this hack thing. Why is it when camera.y is less than 0 stuff gets offset?
        tint(255, 32);
        image(diagonalLines_img, 0,0, width,height);
        image(diagonalLines_img, width,0, width,height);
        image(diagonalLines_img, 0,height, width,height);
        image(diagonalLines_img, width,height, width,height);
      }
      else if(type==1) {
        //diagonal lines
        pushMatrix();
        translate(camera.x-(camera.x/diagonalLineParallax)%dLTWidth,camera.y-(camera.y/diagonalLineParallax)%dLTHeight);
        if(camera.x<0) translate(-dLTWidth, 0); //ugh. Hate this hack thing. Why is it when camera.x is less than 0 stuff gets offset?
        if(camera.y<0) translate(0,-dLTHeight); //ugh. Hate this hack thing. Why is it when camera.y is less than 0 stuff gets offset?
        tint(255, 24);
        image(diagonalLinesThick_img, 0,0, dLTWidth,dLTHeight);
        image(diagonalLinesThick_img, dLTWidth,0, dLTWidth,dLTHeight);
        image(diagonalLinesThick_img, 0,dLTHeight, dLTWidth,dLTHeight);
        image(diagonalLinesThick_img, dLTWidth,dLTHeight, dLTWidth,dLTHeight);
      }
      noTint();
      popMatrix();
    }
    else if(type==2) {
      //transparent, black gradient
      tint(0, 100);
      image(gradient_img, camera.x,camera.y, width,height);
      noTint();
      //marble-like gradient
      pushMatrix();
      translate(camera.x-(camera.x/marbleParallax)%width,camera.y-(camera.y/marbleParallax)%height);
      if(camera.x<0) translate(-width, 0); //ugh. Hate this hack thing. Why is it when camera.x is less than 0 stuff gets offset?
      if(camera.y<0) translate(0,-height); //ugh. Hate this hack thing. Why is it when camera.y is less than 0 stuff gets offset?
      tint(0, 80);
      image(marble_img, 0,0, width,height);
      image(marble_img, width,0, width,height);
      image(marble_img, 0,height, width,height);
      image(marble_img, width,height, width,height);
      noTint();
      popMatrix();
    }
  }
  void reset() {
    rectangle = new Rectangle[20];
    for(int i=0; i<rectangle.length; i++) {
      rectangle[i] = new Rectangle(this, i);
      rectangle[i].framesAlive = int(rectangleLifespan*random(1));
    }
    dLTWidth  = diagonalLinesThick_img.width;
    dLTHeight = diagonalLinesThick_img.height;
    dLTWidth  = width;
    dLTHeight = height;
  }

  class Rectangle {
    BackGround myBackground;
    float x,y;
    float xVel,yVel;
    float Width,Height;
    float WidthVel,HeightVel;
    float Hue,Saturation,Brightness;
    float BrightnessVel;
    float parallax;
    float transparency;
    int framesAlive;
    int id;
    Rectangle(BackGround MyBackground, int Id) {
      myBackground = MyBackground;
      id = Id;
      reset();
    }
    void draw() {
      if(framesAlive>=0) { //if we're not "still in the womb" (for a mild offset)
        //Math.
        x += xVel;
        Brightness += BrightnessVel;
        Saturation -= BrightnessVel/2; //Uhh....
        if(framesAlive>rectangleLifespan) {
          reset();
          return;
        }
//        x += camera.xVel * parallax;
//        y += camera.yVel * parallax;
        Width += WidthVel;
        Height += HeightVel;
        //make sure the camera can see you
        if(x+Width/2<camera.x-width*0.5) {
          //x = (((camera.x*parallax+x) - x) + width);
          //x = (((camera.x*parallax+x) - x) + width);
          //x += camera.x*parallax;
          //println((((camera.x*parallax+x) - x) * 2 + width)  /  (camera.x*parallax+x));
          ///x -= width*(0+parallax);
          //println(x);
          //println(camera.x + (width+Width)*(1+parallax));
          //reset();
          //return;
          x += width+Width;
        }
        //*
        else if(x-Width/2>camera.x+width*0.5) {
          //x = (camera.x)*parallax;
          //x -= (Width + width) * (1+parallax);
          //reset();
          //return;
          x -= width+Width;
        }
        if(y+Height/2<camera.y-height*0.5) {
          //yOnScreen += (Height + rectBounds) * (1+parallax);
          //reset();
          //return;
          y += rectBounds+Height;
        }
        else if(y-Height/2>camera.y+rectBounds+height*0.5) {
          //yOnScreen -= (Height + rectBounds) * (1+parallax);
          //reset();
          //return;
          y -= rectBounds+Height;
        }
        //println(x);
        //*/
        //transparency!
        transparency = sin(float(framesAlive)/float(rectangleLifespan)*PI) * 128;
        if(y-camera.y>rectBounds-rectFadeDistance) {
          transparency *= (rectFadeDistance + (rectBounds - (y-camera.y+rectFadeDistance))) /rectFadeDistance;
        }

        //Draw.
        fill(Hue,Saturation,Brightness, transparency);
        noStroke();
        //rect(x,y, Width,Height);
        tint(Hue,Saturation,Brightness, transparency);
        image(blurredRectangle_img, x-Width/2,y-Height/2, Width,Height);
        noTint();
        fill(0, 200);
        textAlign(CENTER, CENTER);
        textSize(32);
        //text(parallax, xOnScreen+Width/2,yOnScreen+Height/2);
      }

      //framesAlive!
      framesAlive ++;
    }
    void reset() {
      Width = random(140,180);
      Height = random(100,120);
      parallax = float(id)/float(rectangle.length)*0.7-0.2;
      //parallax = 0.5;
      Width *= 1.5 - parallax;
      Height *= 1.5 - parallax;
      WidthVel = random(-0.1,0.2);
      HeightVel = random(-0.1,0.2);
      x = camera.x+random(-Width,width);
      y = camera.y+random(-Height,height);
      xVel = random(-1,1) * 0.2;
      yVel = 0;
      transparency = 255;
      Hue = myBackground.Hue + random(0,8);
      float randomBright = random(-80,20);
      Saturation = myBackground.Saturation - randomBright*4;
      BrightnessVel = random(-40,40)/rectangleLifespan;
      Brightness = myBackground.Brightness + randomBright - BrightnessVel*rectangleLifespan;
      framesAlive = (int)random(-10,0);
      //framesAlive = 0;
    }
  }
}

