// SpeechBubble


class SpeechBubble extends Sprite {
  // Constants
  float roundRectRadius = 32;
  // References
  Sprite spriteSpeaking; // the dude I'm giving a VOICE to.
  // Properties
  boolean isVisible;
  float offsetX,offsetY; // multiplied by my spriteSpeaking's width and height (so, like, vaguely where the mouth would be)
  String displayString; // just what we're displaying
  String fullString; // the whole line of dialogue
  float myScale;
  float targetMyScale;
  float myTextSize;
  color fillColor;
  color textColor = color(32);
  float timeUntilAddNextChar;
  int numCharsPulledFromFullString;
  
  SpeechBubble(Sprite SpriteSpeaking) {
    spriteSpeaking = SpriteSpeaking;
  }
  
  boolean hasTextBeenRead() { return !isVisible || numCharsPulledFromFullString >= fullString.length(); }
  
  
  void update() {
    if (!isVisible) return;
    // Update scale
    myScale += (targetMyScale-myScale) / 4;
    // Update displayText
    if (!hasTextBeenRead()) { // Do I still have text to mumble through?
      timeUntilAddNextChar -= deltaTime;
      if (timeUntilAddNextChar <= 0) {
        displayString += fullString.charAt(numCharsPulledFromFullString++);
        timeUntilAddNextChar = spriteSpeaking.speechSpeed;
      }
    }
    // Go towards my sprite
    if (abs(x-spriteSpeaking.x) > 10) {
      x += (spriteSpeaking.x-x) / 64;
    }
  }
  void draw() {
    if (!isVisible) return;
    // Line!
    noStroke();
    fill(fillColor);
    float spriteTargetX = spriteSpeaking.x+spriteSpeaking.w*offsetX;
    float spriteTargetY = spriteSpeaking.y+spriteSpeaking.h*offsetY;
    pushMatrix();
    translate((x+spriteTargetX)*0.5,(y+spriteTargetY)*0.5);
    rotate(atan2(y-spriteTargetY, x-spriteTargetX));
    float distance = sqrt((x-spriteTargetX)*(x-spriteTargetX) + (y-spriteTargetY)*(y-spriteTargetY));
    rect(0,0, distance-20,10);
    popMatrix();
    // Bubble!
    pushMatrix();
    translate(x,y);
    scale(myScale);
    drawBody();
    drawText();
    popMatrix();
  }
  
  void drawBody() {
    fill(fillColor, 220);
    stroke(fillColor, 255);
    strokeWeight(1);
    rect(0,0, w*1.1,h*1.1, roundRectRadius);
  }
  void drawText() {
    fill(textColor);
    textAlign(LEFT, CENTER);
    textSize(myTextSize);
    textLeading(myTextSize * 0.95);
    text(displayString, 0,0, w,h);
    // Update width and stuff
    //w = textWidth(displayString);
  }
  
  
  void appear(float X,float Y, String TextString) {
    isVisible = true;
    x = X;
    y = Y;
    w = 300;
    h = 140;
    offsetX = 0;
    offsetY = -0.2;
    fullString = TextString;
    displayString = "";
    myTextSize = 28;
    fillColor = color(255);
    myScale = 0;
    targetMyScale = 1;
    timeUntilAddNextChar = 0;
    numCharsPulledFromFullString = 0;
  }
  void disappear() {
    //framesSinceDisappeared = 0;
    isVisible = false;
  }
  
  void fastForwardText() {
    if (!isVisible) return;
    displayString = fullString;
    numCharsPulledFromFullString = fullString.length();
  }
  
  
}
