#include_function ".\bosslib\CommonDataHelpers.dnh"

let StbMovePositionX = 0;
let StbMovePositionY = 0;
let StbMovePositionSpeed = 0;
let StbMovePositionTime = 0;
let StbMovePositionWeight = 0;
let StbMoveType = 0;

// Customized Wait function that is meant to be used in place of the usual
// Wait function. This one will pause and slowdown the boss and object shot
// logic correctly. You should also use Wait(1) instead of yield; inside
// tasks.
function Wait(t){
  loop(t){
    while(GetGameSpeed < 0){ yield; }
    loop(GetGameSpeed+1){ yield; }
  }
}

// This is called by InitializeStbBoss and manages the pausing and slowing of
// boss movement.
task RunMovementManager {
  loop {
    if(Timer != 0){
      alternative(StbMoveType)
      case(1){
        let x = StbMovePositionX;
        let y = StbMovePositionY;
        let speed = StbMovePositionSpeed;
        let angle = AngleFrom(GetX, GetY, x, y);
        let distance = Distance(GetX, GetY, x, y);
        while(distance > speed && StbMoveType == 1 && StbMovePositionX == x && StbMovePositionY == y && StbMovePositionSpeed == speed){
          if(GetGameSpeed >= 0){
            SetX(GetX+cos(angle)*speed*(1/(GetGameSpeed+1)));
            SetY(GetY+sin(angle)*speed*(1/(GetGameSpeed+1)));
            distance -= speed*(1/(GetGameSpeed+1));
          }
          yield;
        }
        if(StbMoveType == 1 && StbMovePositionX == x && StbMovePositionY == y && StbMovePositionSpeed == speed){
          SetX(x);
          SetY(y);
          StbMoveType = 0;
          StbMovePositionX = 0;
          StbMovePositionY = 0;
          StbMovePositionSpeed = 0;
        }
      }
      case(2){
        let x = StbMovePositionX;
        let y = StbMovePositionY;
        let time = StbMovePositionTime;
        let distance = Distance(GetX, GetY, x, y);
        let angle = AngleFrom(GetX, GetY, x, y);
        let speed = distance/time;
        while(distance > speed && StbMoveType == 2 && StbMovePositionX == x && StbMovePositionY == y && StbMovePositionTime == time){
          if(GetGameSpeed >= 0){
            SetX(GetX+cos(angle)*speed*(1/(GetGameSpeed+1)));
            SetY(GetY+sin(angle)*speed*(1/(GetGameSpeed+1)));
            distance -= speed*(1/(GetGameSpeed+1));
          }
          yield;
        }
        if(StbMoveType == 2 && StbMovePositionX == x && StbMovePositionY == y && StbMovePositionTime == time){
          SetX(x);
          SetY(y);
          StbMoveType = 0;
          StbMovePositionX = 0;
          StbMovePositionY = 0;
          StbMovePositionTime = 0;
        }
      }
      case(3){
        let x = StbMovePositionX;
        let y = StbMovePositionY;
        let weight = StbMovePositionWeight;
        let maxspeed = StbMovePositionSpeed;
        let distance = Distance(GetX, GetY, x, y);
        let angle = AngleFrom(GetX, GetY, x, y);
        while(distance > 1 && StbMoveType == 3 && StbMovePositionX == x && StbMovePositionY == y && StbMovePositionWeight == weight && StbMovePositionSpeed == maxspeed){
          let speed = distance/weight;
          if(speed > maxspeed) { speed = maxspeed; }
          if(GetGameSpeed >= 0){
            SetX(GetX + cos(angle)*speed*(1/(GetGameSpeed+1)));
            SetY(GetY + sin(angle)*speed*(1/(GetGameSpeed+1)));
            distance = Distance(GetX, GetY, x, y);
          }
          yield;
        }
        if(StbMoveType == 3 && StbMovePositionX == x && StbMovePositionY == y && StbMovePositionWeight == weight && StbMovePositionSpeed == maxspeed){
          SetX(x);
          SetY(y);
          StbMoveType = 0;
          StbMovePositionX = 0;
          StbMovePositionY = 0;
          StbMovePositionSpeed = 0;
          StbMovePositionWeight = 0;
        }
      }
      others {
        yield;
      }
    }
    else {
      let x = GetCenterX;
      let y = 0;
      let speed = 5;
      let angle = AngleFrom(GetX, GetY, x, y);
      let distance = Distance(GetX, GetY, x, y);
      while(distance > speed){
        if(GetGameSpeed >= 0){
          SetX(GetX+cos(angle)*speed*(1/(GetGameSpeed+1)));
          SetY(GetY+sin(angle)*speed*(1/(GetGameSpeed+1)));
          distance -= speed*(1/(GetGameSpeed+1));
        }
        yield;
      }
    }
    yield;
  }
}

// Works like SetMovePosition01
function SetStbMovePosition01(x, y, speed){
  StbMovePositionX = x;
  StbMovePositionY = y;
  StbMovePositionSpeed = speed;
  StbMovePositionTime = 0;
  StbMovePositionWeight = 0;
  StbMoveType = 1;
}

// Works like SetMovePosition02
function SetStbMovePosition02(x, y, time){
  StbMovePositionX = x;
  StbMovePositionY = y;
  StbMovePositionSpeed = 0;
  StbMovePositionTime = time;
  StbMovePositionWeight = 0;
  StbMoveType = 2;
}

// Works like SetMovePosition03
function SetStbMovePosition03(x, y, weight, maxspeed){
  StbMovePositionX = x;
  StbMovePositionY = y;
  StbMovePositionSpeed = maxspeed;
  StbMovePositionTime = 0;
  StbMovePositionWeight = weight;
  StbMoveType = 3;
}