class PowerBar {
   int index;
   int xPos;
   int yPos;
   int height = 20;
   int width = 40;
  
  PowerBar(int index, int xPos, int yPos) {
    this.index = index;
   this.xPos = xPos;
   this.yPos = yPos;
  } 
    
  void render(int powerLevel) {
    stroke(255,255,255,255);
      fill(0, 255, 0, 0);
      if(powerLevel > this.index) {
         fill(0, 255, 0, 255);
      }
      rect(this.xPos, this.yPos - (this.index * (this.height + 4)), this.width, this.height);
  }
}

class PowerButton {
  int xPos;
  int yPos;
  int width = 40;
  int height = 40;
  
  int buttonPressed = 0;
  boolean powerLevelReported = false;
  
  PowerButton(int xPos, int yPos) {
    this.xPos = xPos;
    this.yPos = yPos;
  }
  
  void listen() {
    if(mousePressed && this.buttonPressed == 0) {
      if(mouseX > this.xPos && mouseX < this.xPos + this.width) {
        if(mouseY > this.yPos && mouseY < this.yPos + this.height) {
          this.buttonPressed = mouseButton;
        }
      }
    }
  }
  
  void releaseListen() {
    this.buttonPressed = 0;
    this.powerLevelReported = false;
  }
  
  void render() {
    stroke(255,255,255,0);
      fill(255, 255, 255, 255);
      
      if(this.buttonPressed == LEFT || this.buttonPressed == RIGHT) {
         fill(96, 96, 255, 255);
      }
      
      ellipse(this.xPos + (this.width / 2), this.yPos + (this.height / 2), this.width, this.height);
  }
  
  int getPowerLevelChange() {
    if(!this.powerLevelReported) {
    if (this.buttonPressed == LEFT) {
      this.powerLevelReported = true; 
      return 1;
    } else if (this.buttonPressed == RIGHT) {
     this.powerLevelReported = true;
     return -1;
     }
    }
    return 0;
  }
}


class PowerMeter {
  
  int xPos;
  int yPos;
  
  int powerBarHeight;
  PowerButton powerButton;
  PowerBar[] powerBars;
  
  int powerLevel = 0;
  
 PowerMeter(int xPos, int yPos, int meterSize) {
   this.powerBarHeight = meterSize;
   this.powerBars = new PowerBar[this.powerBarHeight];
   this.xPos = xPos;
   this.yPos = yPos;
   for(int i = 0; i < this.powerBarHeight; i++) {
     this.powerBars[i] = new PowerBar(i, this.xPos, this.yPos);
   
   }
   this.powerButton = new PowerButton(this.xPos, this.yPos + 22);
 }
 
 void render() {
     for(int i = 0; i < this.powerBars.length; i++) {
       this.powerBars[i].render(this.powerLevel);
     }
      this.powerButton.render();
      

 }
 
 void listen() {
    this.powerButton.listen();
 }
 
 void releaseListen() {
   this.powerButton.releaseListen();
 }
 
 int update(int maxPowerRemaining) {
        int difference = this.powerButton.getPowerLevelChange();
       if(difference != 0) {
         if(maxPowerRemaining - difference >= 0) {
           if(this.powerLevel + difference <= this.powerBarHeight && this.powerLevel + difference >= 0) { 
             this.powerLevel += difference;
             maxPowerRemaining -= difference;
           }
         }
       }
     return maxPowerRemaining;
   }
}

class PowerReserve {
  int xPos;
  int yPos;
  
  int maxPowerReserve;
  int powerRemaining;
  
  
  PowerBar[] powerBars;

PowerReserve(int xPos, int yPos, int powerReserve) {
   powerBars = new PowerBar[powerReserve];
  this.xPos = xPos;
  this.yPos = yPos;
  this.maxPowerReserve = powerReserve;
  this.powerRemaining = this.maxPowerReserve;
  for(int i = 0; i < this.maxPowerReserve; i++) {
     this.powerBars[i] = new PowerBar(i, this.xPos, this.yPos);
   }
  
   
 } 
 
 void render() {
   for(int i = 0; i < this.powerBars.length; i++) {
       this.powerBars[i].render(this.powerRemaining);
     }
 }
}


class Star {
  int xPos;
  int yPos;
  int boundaryX;
  int boundaryY;
  int depth;
  int[] starColor = new int[3];
 Star(int boundaryX, int boundaryY, int maxDepth) {
   this.depth = (int) random(1, maxDepth);
   this.boundaryX = boundaryX;
   this.boundaryY = boundaryY;
   this.xPos = (int)random(0, boundaryX);
   this.yPos = (int)random(0, boundaryY);
   this.starColor[0] = (int)random(0, 255);
   this.starColor[1] = (int)random(0, 255);
   this.starColor[2] = (int)random(0, 255);
 }
 
 void render() {
   stroke(this.starColor[0], this.starColor[1], this.starColor[2]);
  point(this.xPos, this.yPos);
 }
 
 void update() {
    this.xPos += this.depth;
   this.yPos += this.depth;
  if(this.xPos > this.boundaryX) {
    this.xPos = 0;
 }
 if(this.yPos > this.boundaryY) {
    this.yPos = 0; 
 }
}
}

PowerMeter[] meters;
PowerReserve reserve;


Star[] stars = new Star[100];

void setup() {
  background(0, 0, 0);
  size(400, 600);
  
   for(int i = 0; i < stars.length; i++) {
    stars[i] = new Star(400, 600, 3);
  }
  
  meters = new PowerMeter[(int)random(0, 4) + 3];
  
  for(int i = 0; i < meters.length; i++) {
    meters[i] = new PowerMeter((i * 50) + 70, 500, (int)random(1, 12));
  }
  reserve = new PowerReserve(20, 500, (int)random(4, 20));
}

void draw() {
  background(0, 0, 0);
  
  for(int i = 0; i < stars.length; i++) {
   stars[i].update();
   stars[i].render(); 
  }
  
  for(int i = 0; i < meters.length; i++) {
    meters[i].listen();
    meters[i].render();
    reserve.powerRemaining = meters[i].update(reserve.powerRemaining);
  }
  
  reserve.render();
}

void mouseReleased() {
  for(int i = 0; i < meters.length; i++) {
    meters[i].releaseListen();
  }
}


