#include_function ".\configMenus.dnh"
#include_function ".\configResources.dnh"
#include_function ".\lib\CommonDataHelpers.dnh"
#include_function ".\lib\DrawTextNew\text.dnh"

let MaxLevelChoice = length(LevelsStringArray)-1;
let MaxSceneChoice = length(LevelsStringArray[0])-1;
let MaxMusicRoomChoice = length(BgmArray)-1;

let ControlsEnabled = false;

let CurrentMenu = "main";

let MainMenuChoice = 0;

let LevelChoice = 0;
let SceneChoice = 0;

let MusicRoomChoice = 0;
let MusicRoomCurrent = 0;

let HelpChoice = 0;

task CreateMenus {
  PlayMusic(BgmArray[0][0]);
  yield;
  MenuControl;
  StageSelectBG;
  MainMenuBG;
  MainMenuGrains;
  MainMenuHeading;
  MainMenuChoices;
  MenuHeadings;
  BossTitle;
  ShotsRequired;
  DisplayLevel;
  DisplayLevelArrows;
  MusicRoomSongList;
}

task MenuControl {
  SetPlayerX(GetCenterX);
  SetPlayerY(GetClipMaxY);
  SetPlayerEnabled(false);
  DisableMenuControls(45);
  ForbidShot(true);
  ForbidBomb(true);
  loop {
    if(ControlsEnabled){
      while(CurrentMenu == "main" && ControlsEnabled){
        if(GetKeyState(VK_DOWN)==KEY_PUSH){
          MainMenuChoice++;
          if(MainMenuChoice>5){MainMenuChoice -= 6;}
        }
        if(GetKeyState(VK_UP)==KEY_PUSH){
          MainMenuChoice--;
          if(MainMenuChoice<0){MainMenuChoice += 6;}
        }
        if(GetKeyState(VK_SHOT)==KEY_PUSH){
          DisableMenuControls(30);
          alternative(MainMenuChoice)
            case(0){CurrentMenu = "stage select"; DisplayScenes(LevelChoice, 0);}
            case(1){CurrentMenu = "replay";}
            case(2){CurrentMenu = "music room";}
            case(3){CurrentMenu = "option";}
            case(4){CurrentMenu = "help";}
            case(5){Clear;}
        }
        if(GetKeyState(VK_BOMB)==KEY_PUSH){
          MainMenuChoice = 5;
        }
        yield;
      }

      while(CurrentMenu == "stage select" && ControlsEnabled){
        if(GetKeyState(VK_DOWN)==KEY_PUSH){
          SceneChoice++;
          if(SceneChoice > MaxSceneChoice){SceneChoice = 0;}
        }
        if(GetKeyState(VK_UP)==KEY_PUSH){
          SceneChoice--;
          if(SceneChoice < 0){SceneChoice = MaxSceneChoice;}
        }
        if(GetKeyState(VK_RIGHT)==KEY_PUSH){
          DisableMenuControls(20);
          LevelChoice++;
          if(LevelChoice > MaxLevelChoice){LevelChoice = 0;}
          SceneChoice = 0;
          MaxSceneChoice = length(LevelsStringArray[LevelChoice])-1;
          DisplayScenes(LevelChoice, 1);
        }
        if(GetKeyState(VK_LEFT)==KEY_PUSH){
          DisableMenuControls(20);
          LevelChoice--;
          if(LevelChoice < 0){LevelChoice = MaxLevelChoice;}
          SceneChoice = 0;
          MaxSceneChoice = length(LevelsStringArray[LevelChoice])-1;
          DisplayScenes(LevelChoice, -1);
        }
        if(GetKeyState(VK_SHOT)==KEY_PUSH){
          CurrentMenu = "none";
          CreateEnemyAndWait(LevelsStringArray[LevelChoice][SceneChoice][0]);
        }
        if(GetKeyState(VK_BOMB)==KEY_PUSH){
          DisableMenuControls(30);
          CurrentMenu = "main";
        }
        yield;
      }
      
      while(CurrentMenu == "replay" && ControlsEnabled){
        if(GetKeyState(VK_BOMB)==KEY_PUSH){
          DisableMenuControls(30);
          CurrentMenu = "main";
        }
        yield;
      }
      
      while(CurrentMenu == "music room" && ControlsEnabled){
        if(GetKeyState(VK_DOWN)==KEY_PUSH){
          MusicRoomChoice++;
          if(MusicRoomChoice > MaxMusicRoomChoice){MusicRoomChoice = 0;}
        }
        if(GetKeyState(VK_UP)==KEY_PUSH){
          MusicRoomChoice--;
          if(MusicRoomChoice < 0){MusicRoomChoice = MaxMusicRoomChoice;}
        }
        if(GetKeyState(VK_SHOT)==KEY_PUSH){
          if(MusicRoomCurrent != MusicRoomChoice){
            DeleteMusic(BgmArray[MusicRoomCurrent][0]);
            LoadMusic(BgmArray[MusicRoomCurrent][0]);
            MusicRoomCurrent = MusicRoomChoice;
            PlayMusic(BgmArray[MusicRoomCurrent][0]);
          }
        }
        if(GetKeyState(VK_BOMB)==KEY_PUSH){
          DisableMenuControls(30);
          CurrentMenu = "main";
          if(MusicRoomCurrent != 0){
            DeleteMusic(BgmArray[MusicRoomCurrent][0]);
            LoadMusic(BgmArray[MusicRoomCurrent][0]);
            MusicRoomCurrent = 0;
          }
          MusicRoomChoice = 0;
          PlayMusic(BgmArray[0][0]);
        }
        yield;
      }
      
      while(CurrentMenu == "option" && ControlsEnabled){
        if(GetKeyState(VK_BOMB)==KEY_PUSH){
          DisableMenuControls(30);
          CurrentMenu = "main";
        }
        yield;
      }
      
      while(CurrentMenu == "help" && ControlsEnabled){
        if(GetKeyState(VK_DOWN)==KEY_PUSH){}
        if(GetKeyState(VK_UP)==KEY_PUSH){}
        if(GetKeyState(VK_SHOT)==KEY_PUSH){}
        if(GetKeyState(VK_BOMB)==KEY_PUSH){
          DisableMenuControls(30);
          CurrentMenu = "main";
        }
        yield;
      }
    }
    yield;
  }
}

task CreateEnemyAndWait(path) {
  MovePlayerUp;
  FadeOutMusic(BgmArray[0][0], 30);
  SetTargetShotCount(LevelsNumberArray[LevelChoice][SceneChoice][1]);
  loop(30){yield;}
  DeleteMusic(BgmArray[0][0]);
  LoadMusic(BgmArray[0][0]);
  PlayMusic(BgmArray[LevelsNumberArray[LevelChoice][SceneChoice][2]][0]);
  loop(15){yield;}
  SetPlayerEnabled(true);
  loop(15){yield;}
  CreateEnemyFromFile(path, GetCenterX, 0, 0, 0, 0);
  yield;
  while(GetEnemyNum != 0 && !OnPlayerMissed){ yield; }
  loop(30){yield;}
  FadeOutMusic(BgmArray[LevelsNumberArray[LevelChoice][SceneChoice][2]][0], 30);
  loop(30){yield;}
  DeleteMusic(BgmArray[LevelsNumberArray[LevelChoice][SceneChoice][2]][0]);
  LoadMusic(BgmArray[LevelsNumberArray[LevelChoice][SceneChoice][2]][0]);
  PlayMusic(BgmArray[0][0]);
  CurrentMenu = "stage select";
  DisableMenuControls(45);
  loop(30){yield;}
  SetPlayerEnabled(false);
  SetPlayerX(GetCenterX);
  SetPlayerY(GetClipMaxY);
  SetTargetShotCount(0);
  
  task MovePlayerUp {
    loop(60){
      SetPlayerY(GetPlayerY-1);
      yield;
    }
  }
}

task MusicRoomSongList {
  let CurrentSong = 0;
  let alpha1 = [];
  loop(length(BgmArray)){
    alpha1 = alpha1 ~ [0];
  }
  
  DrawSongList;
  DrawSongDescription;
  
  loop {
    while(CurrentMenu != "music room"){
      yield;
    }
    loop(10){yield;}
    ascent(i in 0..length(alpha1)){
      if(i == 0){alpha1[i]=255;}
      else {alpha1[i]=128;}
      loop(2){yield;}
    }
    while(CurrentMenu == "music room"){
      ascent(i in 0..length(alpha1)){
        if(i == MusicRoomChoice){alpha1[i] = 255;}
        else {alpha1[i] = 128;}
      }
      yield;
    }
    descent(i in 0..15){
      ascent(j in 0..length(alpha1)){
        if(j == MusicRoomChoice){alpha1[j] = i*255/15}
        else {alpha1[j] = i*128/15;}
      }
      yield;
    }
    ascent(i in 0..length(alpha1)){
      alpha1[i] = 0;
    }
  }
  
  task DrawSongList {
    let Songs = [];
    loop {
      while(CurrentMenu != "music room"){
        yield;
      }
      ascent(i in 0..length(BgmArray)){
        Songs = Songs ~ [DrawTextNew(BgmArray[i][1], 50, 150+i*20, 0, 0.85, 1, 8, alpha1[i])];
      }
      while(CurrentMenu == "music room"){
        ascent(i in 0..length(BgmArray)){
          ascent(j in 0..length(BgmArray[i][1])){
            ObjEffect_SetVertexColor(Songs[i], j*6, alpha1[i], 255, 192, 192);
            ObjEffect_SetVertexColor(Songs[i], j*6+1, alpha1[i], 255, 192, 192);
            ObjEffect_SetVertexColor(Songs[i], j*6+2, alpha1[i], 255, 192, 192);
            ObjEffect_SetVertexColor(Songs[i], j*6+3, alpha1[i], 255, 192, 192);
            ObjEffect_SetVertexColor(Songs[i], j*6+4, alpha1[i], 255, 192, 192);
            ObjEffect_SetVertexColor(Songs[i], j*6+5, alpha1[i], 255, 192, 192);
          }
        }
        yield;
      }
      ascent(i in 0..length(BgmArray)){
        Obj_Delete(Songs[i]);
      }
      Songs = [];
    }
  }
  
  task DrawSongDescription {
    let alpha2 = [0, 0, 0, 0, 0, 0, 0];
    let Descriptions = [];
    loop {
      alpha2 = [0, 0, 0, 0, 0, 0, 0];
      ascent(i in 0..length(Descriptions)){
        Obj_Delete(Descriptions[i]);
      }
      Descriptions = [];
      CurrentSong = 0;
      while(CurrentMenu != "music room"){
        yield;
      }
      
      ascent(i in 0..7){
        let x = 40;
        let y = 340+i*16;
        if(i==0){x = 30;}
        Descriptions = Descriptions ~ [DrawTextNew(BgmArray[CurrentSong][i+1], x, y, 0, 0.85, 1, 8, alpha2[i])];
      }
      RefreshAlpha;
      while(CurrentMenu == "music room"){
        loop(60){
          ascent(i in 0..7){
            ascent(j in 0..length(BgmArray[CurrentSong][i+1])){
              ObjEffect_SetVertexColor(Descriptions[i], j*6, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+1, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+2, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+3, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+4, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+5, alpha2[i], 255, 192, 192);
            }
          }
          yield;
          if(CurrentMenu != "music room"){ break; }
        }
        while(CurrentSong == MusicRoomCurrent && CurrentMenu == "music room"){
          yield;
        }
        if(CurrentMenu != "music room"){ break; }
        RefreshAlpha;
        loop(10){
          ascent(i in 0..7){
            ascent(j in 0..length(BgmArray[CurrentSong][i+1])){
              ObjEffect_SetVertexColor(Descriptions[i], j*6, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+1, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+2, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+3, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+4, alpha2[i], 255, 192, 192);
              ObjEffect_SetVertexColor(Descriptions[i], j*6+5, alpha2[i], 255, 192, 192);
            }
          }
          yield;
        }
        ascent(i in 0..length(Descriptions)){
          Obj_Delete(Descriptions[i]);
        }
        CurrentSong = MusicRoomCurrent;
        Descriptions = [];
        ascent(i in 0..7){
          let x = 40;
          let y = 340+i*16;
          if(i==0){x = 30;}
          Descriptions = Descriptions ~ [DrawTextNew(BgmArray[CurrentSong][i+1], x, y, 0, 0.85, 1, 8, alpha2[i])];
        }
      }
    }
    
    
    task RefreshAlpha {
      let oldalpha = alpha2;
      descent(i in 0..10){
        ascent(j in 0..length(alpha2)){
          alpha2[j] = i*oldalpha[j]/10;
        }
        yield;
      }
      ascent(i in 0..7){
        FadeInLine(i);
        loop(2){yield;}
      }
      task FadeInLine(indx) {
        ascent(i in 0..15){
          alpha2[indx] = i*15;
          yield;
        }
        alpha2[indx] = 255;
      }
    }
  }
}

task BossTitle {
  let obj = InitializeEffectObject(LevelsStringArray[LevelChoice][SceneChoice][1], 0, 0, 256, 32, -128, -16, 128, 16);
  Obj_SetPosition(obj, 320, 80);
  FadeOutEffectObject(obj, 0, 1, 0, 255, 255, 255);
  loop {
    while(CurrentMenu != "stage select"){
      yield;
    }
    loop(30){yield;}
    FadeInEffectObject(obj, 20, 0, 255, 255, 255, 255);
    while(CurrentMenu == "stage select"){
      let LastScene = SceneChoice;
      let LastLevel = LevelChoice;
      yield;
      if(LastScene != SceneChoice || LastLevel != LevelChoice){
        FadeOutEffectObject(obj, 3, 255, 0, 255, 255, 255);
        loop(3){yield;}
        FadeInEffectObject(obj, 15, 0, 255, 255, 255, 255);
      }
      ObjEffect_SetTexture(obj, LevelsStringArray[LevelChoice][SceneChoice][1]);
    }
    FadeOutEffectObject(obj, 30, 255, 0, 255, 255, 255);
  }
}

task ShotsRequired {
  let shots = LevelsNumberArray[LevelChoice][SceneChoice][1]-1;
  let obj = InitializeEffectObject(imgRequiredShots[shots], 0, 0, 256, 32, -128, -16, 128, 16);
  Obj_SetPosition(obj, 320, 112);
  FadeOutEffectObject(obj, 0, 1, 0, 255, 255, 255);
  loop {
    while(CurrentMenu != "stage select"){
      yield;
    }
    loop(30){yield;}
    FadeInEffectObject(obj, 20, 0, 255, 255, 255, 255);
    while(CurrentMenu == "stage select"){
      let LastScene = SceneChoice;
      let LastLevel = LevelChoice;
      yield;
      if(LastScene != SceneChoice || LastLevel != LevelChoice){
        FadeOutEffectObject(obj, 3, 255, 0, 255, 255, 255);
        loop(3){yield;}
        FadeInEffectObject(obj, 15, 0, 255, 255, 255, 255);
      }
      shots = LevelsNumberArray[LevelChoice][SceneChoice][1]-1;
      ObjEffect_SetTexture(obj, imgRequiredShots[shots]);
    }
    FadeOutEffectObject(obj, 30, 255, 0, 255, 255, 255);
  }
}

task DisplayLevelArrows {
  let LeftArrow = InitializeEffectObject(imgHeading2, 386, 64, 408, 92, -11, -16, 11, 16);
  let RightArrow = InitializeEffectObject(imgHeading2, 422, 64, 444, 92, -11, -16, 11, 16);
  let offset = 70;
  Obj_SetPosition(LeftArrow, 320-offset, 40);
  Obj_SetPosition(RightArrow, 320+offset, 40);
  FadeOutEffectObject(LeftArrow, 0, 1, 0, 255, 255, 255);
  FadeOutEffectObject(RightArrow, 0, 1, 0, 255, 255, 255);
  if(LevelChoice == 0){
    ObjEffect_SetTexture(LeftArrow, "");
  }
  else {
    ObjEffect_SetTexture(LeftArrow, imgHeading2);
  }
  if(LevelChoice == MaxLevelChoice){
    ObjEffect_SetTexture(RightArrow, "");
  }
  else {
    ObjEffect_SetTexture(RightArrow, imgHeading2);
  }
  
  let counter = 0;
  loop {
    while(CurrentMenu != "stage select"){
      yield;
    }
    FadeInEffectObject(LeftArrow, 30, 0, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
    FadeInEffectObject(RightArrow, 30, 0, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
    loop(30){yield;}
    while(CurrentMenu == "stage select"){
      ascent(i in 0..4){
        ObjEffect_SetVertexColor(LeftArrow, i, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
        ObjEffect_SetVertexColor(RightArrow, i, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
      }
      if(LevelChoice == 0){
        ObjEffect_SetTexture(LeftArrow, "");
      }
      else {
        ObjEffect_SetTexture(LeftArrow, imgHeading2);
      }
      if(LevelChoice == MaxLevelChoice){
        ObjEffect_SetTexture(RightArrow, "");
      }
      else {
        ObjEffect_SetTexture(RightArrow, imgHeading2);
      }
      counter += 9;
      yield;
    }
    FadeOutEffectObject(LeftArrow, 30, 255, 0, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
    FadeOutEffectObject(RightArrow, 30, 255, 0, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
  }
  
}

task DisplayLevel {
  let Level = InitializeEffectObject(imgHeading2, 210, 0, 280, 32, -35, -16, 35, 16);
  let Number = InitializeEffectObject(imgHeading2, 32, 60, 64, 94, -16, -16, 16, 16);
  Obj_SetPosition(Level, 305, 40);
  Obj_SetPosition(Number, 360, 40);
  FadeOutEffectObject(Level, 0, 1, 0, 255, 255, 255);
  FadeOutEffectObject(Number, 0, 1, 0, 255, 255, 255);
  
  let counter = 0;
  loop {
    while(CurrentMenu != "stage select"){
      yield;
    }
    FadeInEffectObject(Level, 30, 0, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
    FadeInEffectObject(Number, 30, 0, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
    loop(30){yield;}
    while(CurrentMenu == "stage select"){
      ascent(i in 0..4){
        ObjEffect_SetVertexColor(Level, i, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
        ObjEffect_SetVertexColor(Number, i, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
      }
      counter += 4;
      ObjEffect_SetVertexUV(Number, 0, 32+LevelChoice*32, 60);
      ObjEffect_SetVertexUV(Number, 1, 64+LevelChoice*32, 60);
      ObjEffect_SetVertexUV(Number, 2, 64+LevelChoice*32, 94);
      ObjEffect_SetVertexUV(Number, 3, 32+LevelChoice*32, 94);
      yield;
    }
    FadeOutEffectObject(Level, 30, 255, 0, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
    FadeOutEffectObject(Number, 30, 255, 0, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
  }
}

task DisplayScenes(level, dir) {
  let Scene = [];
  let Number = [];
  ascent(i in 0..MaxSceneChoice+1){
    let obj = InitializeEffectObject(imgHeading2, 296, 6, 344, 28, 0, -11, 48, 11);
    Obj_SetPosition(obj, 60+dir*100, 113+i*27);
    Scene = Scene ~ [obj];
    obj = InitializeEffectObject(imgHeading2, 368+i*16, 6, 384+i*16, 28, 0, -11, 16, 11);
    Obj_SetPosition(obj, 120+dir*100, 113+i*27);
    Number = Number ~ [obj];
  }
  
  ascent(i in 0..length(Scene)){
    FadeInEffectObject(Scene[i], 10, 0, 255, 100, 100, 100);
    FadeInEffectObject(Number[i], 10, 0, 255, 100, 100, 100);
  }
  descent(j in 0..10){
    ascent(i in 0..length(Scene)){
      Obj_SetPosition(Scene[i], Obj_GetX(Scene[i])-dir*j*2.2, Obj_GetY(Scene[i]));
      Obj_SetPosition(Number[i], Obj_GetX(Number[i])-dir*j*2.2, Obj_GetY(Number[i]));
    }
    yield;
  }
  ascent(i in 0..length(Scene)){
    Obj_SetPosition(Scene[i], 60, Obj_GetY(Scene[i]));
    Obj_SetPosition(Number[i], 120, Obj_GetY(Scene[i]));
  }
  
  let counter = 0;
  while(LevelChoice == level && CurrentMenu != "main"){
    while(CurrentMenu != "none" && CurrentMenu != "main" && LevelChoice == level){
      ascent(i in 0..length(Scene)){
        if(i == SceneChoice){
          ascent(j in 0..4){
            ObjEffect_SetVertexColor(Scene[i], j, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
            ObjEffect_SetVertexColor(Number[i], j, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
          }
        }
        else {
          ascent(j in 0..4){
            ObjEffect_SetVertexColor(Scene[i], j, 255, 100, 100, 100);
            ObjEffect_SetVertexColor(Number[i], j, 255, 100, 100, 100);
          }
        }
      }
      counter += 9;
      if(GetKeyState(VK_UP)==KEY_PUSH || GetKeyState(VK_DOWN)==KEY_PUSH){counter = 0;}
      yield;
    }
    if(CurrentMenu == "main" || LevelChoice != level){break;}
    ascent(i in 0..length(Scene)){
      if(i == SceneChoice){
        FadeOutEffectObject(Scene[i], 30, 255, 0, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
        FadeOutEffectObject(Number[i], 30, 255, 0, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
      }
      else {
        FadeOutEffectObject(Scene[i], 30, 255, 0, 100, 100, 100);
        FadeOutEffectObject(Number[i], 30, 255, 0, 100, 100, 100);
      }
    }
    while(CurrentMenu == "none"){
      yield;
    }
    ascent(i in 0..length(Scene)){
      if(i == SceneChoice){
        FadeInEffectObject(Scene[i], 30, 0, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
        FadeInEffectObject(Number[i], 30, 0, 255, 192+sin(counter)*63, 192+sin(counter)*63, 192+sin(counter)*63);
      }
      else {
        FadeInEffectObject(Scene[i], 30, 0, 255, 100, 100, 100);
        FadeInEffectObject(Number[i], 30, 0, 255, 100, 100, 100);
      }
    }
    loop(30){yield;}
  }
  
  let dir2 = 0;
  if(LevelChoice > level && absolute(LevelChoice-level) == 1){
    dir2 = -1;
  }
  else if(LevelChoice < level && absolute(LevelChoice-level) == 1){
    dir2 = 1;
  }
  else if(LevelChoice > level && absolute(LevelChoice-level) >= 1){
    dir2 = 1;
  }
  else if(LevelChoice < level && absolute(LevelChoice-level) >= 1){
    dir2 = -1;
  }
  
  let fadetime = 10;
  if(CurrentMenu == "main"){fadetime = 30;}
  
  ascent(i in 0..length(Scene)){
    FadeOutEffectObject(Scene[i], fadetime, 255, 0, 100, 100, 100);
    FadeOutEffectObject(Number[i], fadetime, 255, 0, 100, 100, 100);
  }
  descent(j in 0..10){
    ascent(i in 0..length(Scene)){
      Obj_SetPosition(Scene[i], Obj_GetX(Scene[i])+dir2*j*2.2, Obj_GetY(Scene[i]));
      Obj_SetPosition(Number[i], Obj_GetX(Number[i])+dir2*j*2.2, Obj_GetY(Number[i]));
    }
    yield;
  }
  
  ascent(i in 0..length(Scene)){
    Obj_Delete(Scene[i]);
    Obj_Delete(Number[i]);
  }
}

task MenuHeadings {
  let Heading = InitializeEffectObject("", 0, 0, 0, 0, -128, -32, 128, 32);
  Obj_SetPosition(Heading, -256, 40);
  loop {
    while(CurrentMenu == "main"){
      yield;
    }
    alternative(CurrentMenu)
      case("stage select"){
        ObjEffect_SetTexture(Heading, imgHeading2);
        ObjEffect_SetVertexUV(Heading, 0, 0, 0);
        ObjEffect_SetVertexUV(Heading, 1, 208, 0);
        ObjEffect_SetVertexUV(Heading, 2, 208, 60);
        ObjEffect_SetVertexUV(Heading, 3, 0, 60);
        ObjEffect_SetVertexXY(Heading, 0, 0, -30);
        ObjEffect_SetVertexXY(Heading, 1, 208, -30);
        ObjEffect_SetVertexXY(Heading, 2, 208, 30);
        ObjEffect_SetVertexXY(Heading, 3, 0, 30);
      }
      case("replay"){
        ObjEffect_SetTexture(Heading, imgHeading2);
        ObjEffect_SetVertexUV(Heading, 0, 0, 196);
        ObjEffect_SetVertexUV(Heading, 1, 208, 196);
        ObjEffect_SetVertexUV(Heading, 2, 208, 256);
        ObjEffect_SetVertexUV(Heading, 3, 0, 256);
        ObjEffect_SetVertexXY(Heading, 0, 0, -30);
        ObjEffect_SetVertexXY(Heading, 1, 208, -30);
        ObjEffect_SetVertexXY(Heading, 2, 208, 30);
        ObjEffect_SetVertexXY(Heading, 3, 0, 30);
      }
      case("music room"){
        ObjEffect_SetTexture(Heading, imgHeading1);
        ObjEffect_SetVertexUV(Heading, 0, 0, 128);
        ObjEffect_SetVertexUV(Heading, 1, 256, 128);
        ObjEffect_SetVertexUV(Heading, 2, 256, 192);
        ObjEffect_SetVertexUV(Heading, 3, 0, 192);
        ObjEffect_SetVertexXY(Heading, 0, 0, -32);
        ObjEffect_SetVertexXY(Heading, 1, 256, -32);
        ObjEffect_SetVertexXY(Heading, 2, 256, 32);
        ObjEffect_SetVertexXY(Heading, 3, 0, 32);
      }
      case("option"){
        ObjEffect_SetTexture(Heading, imgOptions);
        ObjEffect_SetVertexUV(Heading, 0, 0, 0);
        ObjEffect_SetVertexUV(Heading, 1, 256, 0);
        ObjEffect_SetVertexUV(Heading, 2, 256, 64);
        ObjEffect_SetVertexUV(Heading, 3, 0, 64);
        ObjEffect_SetVertexXY(Heading, 0, 0, -32);
        ObjEffect_SetVertexXY(Heading, 1, 256, -32);
        ObjEffect_SetVertexXY(Heading, 2, 256, 32);
        ObjEffect_SetVertexXY(Heading, 3, 0, 32);
      }
      case("help"){
        ObjEffect_SetTexture(Heading, imgHeading1);
        ObjEffect_SetVertexUV(Heading, 0, 0, 192);
        ObjEffect_SetVertexUV(Heading, 1, 256, 192);
        ObjEffect_SetVertexUV(Heading, 2, 256, 256);
        ObjEffect_SetVertexUV(Heading, 3, 0, 256);
        ObjEffect_SetVertexXY(Heading, 0, 0, -32);
        ObjEffect_SetVertexXY(Heading, 1, 256, -32);
        ObjEffect_SetVertexXY(Heading, 2, 256, 32);
        ObjEffect_SetVertexXY(Heading, 3, 0, 32);
      }
    descent(i in 0..15){
      Obj_SetPosition(Heading, Obj_GetX(Heading)+i*2.6, 40);
      yield;
    }
    while(CurrentMenu != "main"){
      if(CurrentMenu == "none"){
        FadeOutEffectObject(Heading, 30, 255, 0, 255, 255, 255);
        while(CurrentMenu == "none"){yield;}
        FadeInEffectObject(Heading, 30, 0, 255, 255, 255, 255);
      }
      yield;
    }
    descent(i in 0..15){
      Obj_SetPosition(Heading, Obj_GetX(Heading)-i*2.6, 40);
      yield;
    }
  }
}

task MainMenuGrains {
  let lines1 = InitializeEffectObject(imgLines1, 0, 0, 640, 480, 0, 0, 640, 480);
  let lines2 = InitializeEffectObject(imgLines2, 0, 0, 640, 480, 0, 0, 640, 480);
  let lines3 = [
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2),
    InitializeEffectObject(imgHeading1, 0, 102, 480, 106, -240, -2, 240, 2)
  ];
  ascent(i in 0..16){
    ObjEffect_SetAngle(lines3[i], 0, 0, 90);
    Obj_SetPosition(lines3[i], -1000, -1000);
  }
  
  let xMove1 = 0;
  let yMove1 = 0;
  let xMove2 = 0;
  let yMove2 = 0;
  let counter = 0;
  
  ManageLines3;
  
  loop {
    while(CurrentMenu != "none"){
      xMove1 += 1;
      yMove1 = rand(0, 256);
      xMove2 -= 0.5;
      yMove2 = rand(0, 256);
      ObjEffect_SetVertexUV(lines1, 0, 0+xMove1, 0+yMove1);
      ObjEffect_SetVertexUV(lines1, 1, 640+xMove1, 0+yMove1);
      ObjEffect_SetVertexUV(lines1, 2, 640+xMove1, 480+yMove1);
      ObjEffect_SetVertexUV(lines1, 3, 0+xMove1, 480+yMove1);
      ObjEffect_SetVertexUV(lines2, 0, 0+xMove2, 0+yMove2);
      ObjEffect_SetVertexUV(lines2, 1, 640+xMove2, 0+yMove2);
      ObjEffect_SetVertexUV(lines2, 2, 640+xMove2, 480+yMove2);
      ObjEffect_SetVertexUV(lines2, 3, 0+xMove2, 480+yMove2);
      ascent(i in 0..4){
        ObjEffect_SetVertexColor(lines1, i, 89-sin(counter)*50, 255, 255, 255);
        ObjEffect_SetVertexColor(lines2, i, 178+sin(counter)*50, 255, 255, 255);
      }
      counter++;
      
      yield;
    }
    FadeOutEffectObject(lines1, 30, 89-sin(counter)*50, 0, 255, 255, 255);
    FadeOutEffectObject(lines2, 30, 178+sin(counter)*50, 0, 255, 255, 255);
    xMove1 = 0;
    xMove2 = 0;
    counter = 0;
    while(CurrentMenu == "none"){
      yield;
    }
    FadeInEffectObject(lines1, 30, 0, 89-sin(counter)*50, 255, 255, 255);
    FadeInEffectObject(lines2, 30, 0, 178+sin(counter)*50, 255, 255, 255);
    loop(30){yield;}
  }
  
  task ManageLines3 {
    let counter2 = 0;
    let indx = 0;
    loop {
      while(CurrentMenu != "none"){
        if(counter2%10==0){
          MakeDarkLine(rand(32, 608), rand(-2.5, 2.5), indx);
          indx++;
          if(indx==16){indx=0;}
        }
        counter2++;
        yield;
      }
      counter2 = 0;
      while(CurrentMenu == "none"){
        yield;
      }
    }
    
    task MakeDarkLine(x, speed, i){
      let random = rand(0, 256);
      ascent(j in 0..90){
        if(j<=10){
          ascent(k in 0..4){
            ObjEffect_SetVertexColor(lines3[i], k, j*25, 255, 255, 255);
          }
        }
        if(j>=80){
          ascent(k in 0..4){
            ObjEffect_SetVertexColor(lines3[i], k, (90-j)*25, 255, 255, 255);
          }
        }
        ObjEffect_SetVertexUV(lines3[i], 0, j*-8+random, 102);
        ObjEffect_SetVertexUV(lines3[i], 1, 480+j*-8+random, 102);
        ObjEffect_SetVertexUV(lines3[i], 2, 480+j*-8+random, 106);
        ObjEffect_SetVertexUV(lines3[i], 3, j*-8+random, 106);
        Obj_SetPosition(lines3[i], x+speed*j, 240);
        yield;
        if(CurrentMenu == "none"){
          break;
        }
      }
      Obj_SetPosition(lines3[i], -1000, -1000);
    }
  }
}

task MainMenuHeading {
  let bunkachou = InitializeEffectObject(imgHeading1, 0, 0, 256, 48, -128, -24, 128, 24);
  let stb = InitializeEffectObject(imgHeading1, 0, 48, 256, 72, -128, -12, 128, 12);
  let copyright = InitializeEffectObject(imgHeading1, 0, 72, 256, 96, -128, -12, 128, 12);
  Obj_SetPosition(bunkachou, 420, 410);
  Obj_SetPosition(stb, 538, 431);
  Obj_SetPosition(copyright, 550, 465);
  
  FadeInEffectObject(bunkachou, 30, 0, 255, 255, 255, 255);
  FadeInEffectObject(stb, 30, 0, 255, 255, 255, 255);
  FadeInEffectObject(copyright, 75, 0, 255, 255, 255, 255);
  
  loop {
    while(CurrentMenu == "main"){
      yield;
    }
    FadeOutEffectObject(bunkachou, 30, 255, 128, 255, 255, 255);
    FadeOutEffectObject(stb, 30, 255, 128, 255, 255, 255);
    FadeOutEffectObject(copyright, 30, 255, 0, 255, 255, 255);
    while(CurrentMenu != "main"){
      if(CurrentMenu == "none"){
        FadeOutEffectObject(bunkachou, 30, 128, 0, 255, 255, 255);
        FadeOutEffectObject(stb, 30, 128, 0, 255, 255, 255);
        while(CurrentMenu == "none"){
          yield;
        }
        FadeInEffectObject(bunkachou, 30, 0, 128, 255, 255, 255);
        FadeInEffectObject(stb, 30, 0, 128, 255, 255, 255);
      }
      yield;
    }
    FadeInEffectObject(bunkachou, 30, 128, 255, 255, 255, 255);
    FadeInEffectObject(stb, 30, 128, 255, 255, 255, 255);
    FadeInEffectObject(copyright, 60, 0, 255, 255, 255, 255);
    yield;
  }
}

task MainMenuChoices {
  let ChoiceBGs = [
    InitializeEffectObject(imgMenu1, 0, 192, 160, 256, 0, -32, 160, 32),
    InitializeEffectObject(imgMenu1, 0, 192, 160, 256, 0, -32, 160, 32),
    InitializeEffectObject(imgMenu1, 0, 192, 160, 256, 0, -32, 160, 32),
    InitializeEffectObject(imgMenu1, 0, 192, 160, 256, 0, -32, 160, 32),
    InitializeEffectObject(imgMenu1, 0, 192, 160, 256, 0, -32, 160, 32),
    InitializeEffectObject(imgMenu1, 0, 192, 160, 256, 0, -32, 160, 32)
  ];
  ascent(i in 0..6){
    ascent(j in 0..4){
      ObjEffect_SetVertexColor(ChoiceBGs[i], j, 255, 100, 100, 100);
    }
  }
  let GameStart = InitializeEffectObject(imgMenu1, 0,   96,  160, 128, 0, -16, 160, 16);
  let Replay = InitializeEffectObject(   imgMenu1, 160, 96,  256, 128, 0, -16, 96,  16);
  let MusicRoom = InitializeEffectObject(imgMenu1, 0,   128, 160, 160, 0, -16, 160, 16);
  let Option = InitializeEffectObject(   imgMenu1, 160, 128, 256, 160, 0, -16, 96,  16);
  let Help = InitializeEffectObject(     imgMenu1, 0,   160, 80,  192, 0, -16, 80,  16);
  let Quit = InitializeEffectObject(     imgMenu1, 80,  160, 160, 192, 0, -16, 80,  16);
  
  ManageChoice(GameStart, 144, 0,   96,  160, 128, 0,  0);
  ManageChoice(Replay,    182, 160, 96,  256, 128, 3,  1);
  ManageChoice(MusicRoom, 220, 0,   128, 160, 160, 6,  2);
  ManageChoice(Option,    258, 160, 128, 256, 160, 9,  3);
  ManageChoice(Help,      296, 0,   160, 80,  192, 12, 4);
  ManageChoice(Quit,      334, 80,  160, 160, 192, 15, 5);
  
  task ManageChoice(id, y, left, top, right, bottom, delay, bg){
    Obj_SetPosition(id, -180, y);
    Obj_SetPosition(ChoiceBGs[bg], -180, y+20);
    loop {
      loop(delay){yield;}
      descent(i in 0..20){
        Obj_SetPosition(id, Obj_GetX(id)+i*1.25, y);
        Obj_SetPosition(ChoiceBGs[bg], Obj_GetX(id)+i*1.25, y+20);
        yield;
      }
      Obj_SetPosition(id, 60, y);
      Obj_SetPosition(ChoiceBGs[bg], 60, y+20);
      ManageHighlight;
      
      while(CurrentMenu == "main"){
        yield;
      }
      
      descent(i in 0..15){
        Obj_SetPosition(id, -180+i*16, y);
        Obj_SetPosition(ChoiceBGs[bg], -180+i*16, y+20);
        yield;
      }
      Obj_SetPosition(id, -180, y);
      Obj_SetPosition(ChoiceBGs[bg], -180, y+20);
      
      while(CurrentMenu != "main"){
        yield;
      }
    }
    
    task ManageHighlight {
      let MenuID;
      let counter = 90;
      alternative(id)
        case(GameStart){MenuID = 0;}
        case(Replay){MenuID = 1;}
        case(MusicRoom){MenuID = 2;}
        case(Option){MenuID = 3;}
        case(Help){MenuID = 4;}
        case(Quit){MenuID = 5;}

      while(CurrentMenu == "main"){
        if(MenuID == MainMenuChoice){
          ObjEffect_SetVertexUV(id, 0, left, top-96);
          ObjEffect_SetVertexUV(id, 1, right, top-96);
          ObjEffect_SetVertexUV(id, 2, right, bottom-96);
          ObjEffect_SetVertexUV(id, 3, left, bottom-96);
          if(Obj_GetX(id)>56){
            Obj_SetPosition(id, Obj_GetX(id)-1, y);
            Obj_SetPosition(ChoiceBGs[bg], Obj_GetX(ChoiceBGs[bg])+1, y+20);
          }
          
          ascent(i in 0..4){
            ObjEffect_SetVertexColor(id, i, 255, 205+sin(counter)*50, 205+sin(counter)*50, 205+sin(counter)*50);
            ObjEffect_SetVertexColor(ChoiceBGs[bg], i, 255, 150-sin(counter)*50, 50+sin(counter)*50, 50+sin(counter)*50);
          }
        }
        else {
          counter = 90;
          ObjEffect_SetVertexUV(id, 0, left, top);
          ObjEffect_SetVertexUV(id, 1, right, top);
          ObjEffect_SetVertexUV(id, 2, right, bottom);
          ObjEffect_SetVertexUV(id, 3, left, bottom);
          if(Obj_GetX(id)<60){
            Obj_SetPosition(id, Obj_GetX(id)+1, y);
            Obj_SetPosition(ChoiceBGs[bg], Obj_GetX(ChoiceBGs[bg])-1, y+20);
          }
          else {
            Obj_SetPosition(id, 60, y);
          }
          
          ascent(i in 0..4){
            ObjEffect_SetVertexColor(id, i, 255, 255, 255, 255);
            ObjEffect_SetVertexColor(ChoiceBGs[bg], i, 255, 100, 100, 100);
          }
        }
        counter+=9;
        yield;
      }
    }
  }
}

task StageSelectBG {
  let obj = InitializeEffectObject(imgTitleBG2, 0, 0, 640, 480, 0, 0, 640, 480);
  loop {
    while(CurrentMenu != "none"){
      yield;
    }
    FadeOutEffectObject(obj, 30, 255, 0, 255, 255, 255);
    while(CurrentMenu == "none"){
      yield;
    }
    FadeInEffectObject(obj, 30, 0, 255, 255, 255, 255);
  }
}

task MainMenuBG {
  let obj = InitializeEffectObject(imgTitleBG1, 0, 0, 640, 480, 0, 0, 640, 480);
  
  loop {
    while(CurrentMenu == "main"){
      loop(rand_int(60, 1200)){
        yield;
        if(CurrentMenu != "main"){ break; }
      }
      if(CurrentMenu == "main"){FlickerEffect;}
    }
    FadeOutEffectObject(obj, 30, 255, 0, 255, 255, 255);
    while(CurrentMenu != "main"){
      yield;
    }
    FadeInEffectObject(obj, 30, 0, 255, 255, 255, 255);
  }
  
  task FlickerEffect {
    let yOffset = rand(-75, 75);
    ascent(i in 0..4){
      Obj_SetPosition(obj, 0, Obj_GetY(obj)+i*(yOffset/4));
      yield;
    }
    descent(i in 0..2){
      Obj_SetPosition(obj, 0, yOffset*-0.5+i*(yOffset/4));
      yield;
    }
    Obj_SetPosition(obj, 0, 0);
    ascent(i in 0..6){
      ascent(j in 0..4){
        ObjEffect_SetVertexColor(obj, j, 255, 255-i*30, 255-i*30, 255-i*30);
      }
      yield;
    }
    descent(i in 0..6){
      ascent(j in 0..4){
        ObjEffect_SetVertexColor(obj, j, 255, 255-i*30, 255-i*30, 255-i*30);
      }
      yield;
    }
    ascent(j in 0..4){
      ObjEffect_SetVertexColor(obj, j, 255, 255, 255, 255);
    }
  }
}

function InitializeEffectObject(path, left1, top1, right1, bottom1, left2, top2, right2, bottom2){
  let obj = Obj_Create(OBJ_EFFECT);
  ObjEffect_SetTexture(obj, path);
  ObjEffect_SetLayer(obj, 8);
  ObjEffect_SetPrimitiveType(obj, PRIMITIVE_TRIANGLEFAN);
  ObjEffect_CreateVertex(obj, 4);
  ObjEffect_SetVertexUV(obj, 0, left1, top1);
  ObjEffect_SetVertexUV(obj, 1, right1, top1);
  ObjEffect_SetVertexUV(obj, 2, right1, bottom1);
  ObjEffect_SetVertexUV(obj, 3, left1, bottom1);
  ObjEffect_SetVertexXY(obj, 0, left2, top2);
  ObjEffect_SetVertexXY(obj, 1, right2, top2);
  ObjEffect_SetVertexXY(obj, 2, right2, bottom2);
  ObjEffect_SetVertexXY(obj, 3, left2, bottom2);
  return obj;
}

task FadeOutEffectObject(id, time, max, min, r, g, b) {
  descent(i in 0..time){
    ascent(j in 0..4){
      ObjEffect_SetVertexColor(id, j, min+i*((max-min)/time), r, g, b);
    }
    yield;
  }
  ascent(j in 0..4){
    ObjEffect_SetVertexColor(id, j, min, r, g, b);
  }
}

task FadeInEffectObject(id, time, min, max, r, g, b) {
  ascent(i in 0..time){
    ascent(j in 0..4){
      ObjEffect_SetVertexColor(id, j, min+i*((max-min)/time), r, g, b);
    }
    yield;
  }
  ascent(j in 0..4){
    ObjEffect_SetVertexColor(id, j, max, r, g, b);
  }
}

task DisableMenuControls(time){
  ControlsEnabled = false;
  loop(time){yield;}
  ControlsEnabled = true;
}