#include "cache.h"
#include "scenes.h"
#include "mykeyboard.h"
#include "globals.h"
#include "fonts.h"
#include "screenfx.h"
#include "log.h"
#include "object.h"
#include <deque>
#include "frames.h"
#include "mystr.h"
#include "mymath.h"
#include "camera.h"
#include "map.h"
#include "person.h"
#include "projectile.h"
#include "gui.h"
#include "particle.h"
#include "drawfx.h"
#include "powers.h"
#include "hiscore.h"
#include "weather.h"



int ActualLayer=0;
int ActualTile=0;

int ActualRectX=-1;
int ActualRectY=-1;
int ActualRectFX=-1;
int ActualRectFY=-1;
bool RectangleSelection=false;

int EditorX, EditorY;
int EditorMode=0;
int EditorType=0;

int ActualSpawn=0;

float MissionCompletedOpacity=0;
int MissionCompleted=0;
int MissionFailed=0;
float MissionFailedOpacity=0;
float WaitToRestart=0;

float ActualTime=0;

std::deque<std::string> briefing_text;

CacheBitmap *editor_cursor=NULL;


bool HelpLeftOver=false;
bool HelpRightOver=false;

bool BucketMode=false;
bool CollisionEditing=false;

bool ShowScore=false;
float ScoreOpacity=0.0;

bool ShowBriefing=false;
float BriefingOpacity=0.0;

bool ShowHelp=false;
float HelpOpacity=0.0;

bool SelectingTile=false;

int ActualCommand=0;
int ActualPortrait=-1;

int ActualStoryboard=0;

float ScoresNextOpacity=0;
bool ScoresNextOver=0;

const int COMMAND_NONE   = 0;
const int COMMAND_ATTACK = 1;


const int EDITOR_MODE_TILES  = 0;
const int EDITOR_MODE_SPAWNS = 1;
const int EDITOR_MODE_LIGHTS = 2;
const int EDITOR_MODE_MAP_DATA = 3;


int ActualFormation=0;
int ActualOverPower = -1;
int ActualPower = -1;

int HelpIndex=0;

float HSOpacity[4] = {0,0,0,0};
int HSIndex = 0;

bool CanGuard=0;

float BlackFade=0.0;
float BlackFadeDir=0;



const int FORMATION_NONE=0;
const int FORMATION_RECTANGLE=1;
const int FORMATION_LINE=2;
const int FORMATION_SPREAD=3;

Vec2D FormationCenter(0, 0);
int FormationX=0; int FormationY=0;


std::deque<Person *> GroupControl[8];

GuiButton *command_buttons[9];
GuiButton *storyboard_add;
GuiButton *storyboard_delete;
GuiButton *camera_button;

GuiButton *storyboard_back;
GuiButton *storyboard_next;
GuiButton *storyboard_camera;


GuiTakeoverElement *exit_confirm;


int MissionCheckDelay=0;
int WaitToScore=0;

GuiTypeBox *editor_powers_box[4];

GuiTypeBox *map_file_name;
GuiTypeBox *map_internal_name;

GuiTypeBox *map_width;
GuiTypeBox *map_height;
GuiTypeBox *map_weather;
GuiButton  *apply_changes;

GuiTypeBox *storyboard_boxes[8];
GuiButton *save_map_button;


GuiButton *storyboard_buttons[12];
int StoryboardSize=1;


GuiButton *load_map_button;

ALLEGRO_BITMAP *LightMap=NULL;

int ActualKills=0;
int ActualGrinchKills=0;
int ActualDeaths=0;
int ActualScore=0;
float ActualBestTime=0;

void SaveMap();

int HSWaitForNext=0;

int ActualLight=0;

int ActualPowers[4];
int ActualPowersCooldown[4];

std::string tooltip_text;
float tooltip_opacity=0.0;

bool StoryboardShowing=0;
float StoryboardY=0;
const int StoryboardHandH=28;


EditorStoryboard EditorStoryboards[12];


void StoryboardCamera() {
  TargetCamera_X=EditorStoryboards[ActualStoryboard].cam_x;
  TargetCamera_Y=EditorStoryboards[ActualStoryboard].cam_y;
}

void StoryboardNext() {
  ActualStoryboard += 1;
  if (ActualStoryboard >= StoryboardSize) ActualStoryboard = StoryboardSize-1;
  StoryboardCamera();
}

void StoryboardBack() {
  ActualStoryboard -= 1;
  if (ActualStoryboard < 0) ActualStoryboard = 0;
  StoryboardCamera();
}



void CopyStatsFromMap() {
  map_file_name->set_text(actual_map->GetName());
  map_internal_name->set_text(actual_map->GetInternalName());

  for (int i=0; i!=8; i+=1) {
    storyboard_boxes[i]->set_text(EditorStoryboards[ActualStoryboard].paragraph[i]);
  }

  TargetCamera_X = EditorStoryboards[ActualStoryboard].cam_x;
  TargetCamera_Y = EditorStoryboards[ActualStoryboard].cam_y;

  map_width->set_text(ToString(actual_map->GetW()));
  map_height->set_text(ToString(actual_map->GetH()));
  map_weather->set_text(ToString(actual_map->GetWeather()));

  for (int i=0; i!=4; i+=1) editor_powers_box[i]->set_text(ToString(MapPowers[i]));
}


void ApplyChangesToMap() {
  actual_map->Resize(ToFloat(map_width->get_text()), ToFloat(map_height->get_text()));
}

void CopyMapFromStats() {
  actual_map->SetName(map_file_name->get_text());
  actual_map->SetInternalName(map_internal_name->get_text());

  actual_map->SetWeather(ToFloat(map_weather->get_text()));

  for (int i=0; i!=8; i+=1) {
    EditorStoryboards[ActualStoryboard].paragraph[i] = storyboard_boxes[i]->get_text();
  }

  for (int i=0; i!=4; i+=1) MapPowers[i]=ToFloat(editor_powers_box[i]->get_text());
}

void CopyMapStoryboardsToEditor() {
  for (int i=0; i!=12; i+=1) {
    for (int i2=0; i2!=8; i2+=1) {
      EditorStoryboards[i].paragraph[i2] = ToString(actual_map_storyboard[i].text[i2]);
    }
    EditorStoryboards[i].cam_x = actual_map_storyboard[i].cam_x;
    EditorStoryboards[i].cam_y = actual_map_storyboard[i].cam_y;
  }
}


void SetActualStoryboard_1()  {ActualStoryboard=0;  CopyStatsFromMap();}
void SetActualStoryboard_2()  {ActualStoryboard=1;  CopyStatsFromMap();}
void SetActualStoryboard_3()  {ActualStoryboard=2;  CopyStatsFromMap();}
void SetActualStoryboard_4()  {ActualStoryboard=3;  CopyStatsFromMap();}
void SetActualStoryboard_5()  {ActualStoryboard=4;  CopyStatsFromMap();}
void SetActualStoryboard_6()  {ActualStoryboard=5;  CopyStatsFromMap();}
void SetActualStoryboard_7()  {ActualStoryboard=6;  CopyStatsFromMap();}
void SetActualStoryboard_8()  {ActualStoryboard=7;  CopyStatsFromMap();}
void SetActualStoryboard_9()  {ActualStoryboard=8;  CopyStatsFromMap();}
void SetActualStoryboard_10() {ActualStoryboard=9;  CopyStatsFromMap();}
void SetActualStoryboard_11() {ActualStoryboard=10; CopyStatsFromMap();}
void SetActualStoryboard_12() {ActualStoryboard=11; CopyStatsFromMap();}

void SetStoryboardCamera() {
  EditorStoryboards[ActualStoryboard].cam_x = Camera_X;
  EditorStoryboards[ActualStoryboard].cam_y = Camera_Y;
}


void AddStoryboard() {
  StoryboardSize += 1;
  if (StoryboardSize > 12) StoryboardSize=12;
  EditorStoryboards[StoryboardSize-1].clear();
}


void DeleteStoryboard() {
  StoryboardSize -= 1;
}


void CheckObjectives() {
  std::deque<Person *>::iterator it;
  bool done, someone_alive;
  int count_alive;
  if (MissionCompleted) return;
  if (MissionFailed) return;
  done = true;
  someone_alive=false;
  count_alive =0;
  for (it=persons.begin(); it!=persons.end(); it+=1) {
    if ((!(*it)->IsMine()) && (!(*it)->IsUnconscious())) {
      done = false;
      count_alive += 1;
    }
    else if (((*it)->IsMine()) && (!(*it)->IsUnconscious())) {
      someone_alive=true;
    }
  }

  if (count_alive < 5) {
    MissionCompleted = 1;
    MissionCompletedOpacity=0;
    WaitToScore = 200;
  }
  if ((!someone_alive) && (!MissionCompleted)) {
    MissionFailed = 1;
    MissionFailedOpacity=0;
    WaitToRestart=200;
  }
}



void CheckHiscoreTable() {
  ActualGrinchKills=ActualKills=ActualDeaths=0;
  for (int i=0;i!=4;i+=1) HSOpacity[i]=0;
  HSIndex=0;
  HSWaitForNext=0;

  std::deque<Person *>::iterator it;
  for (it=persons.begin(); it!=persons.end(); it+=1) {
    if ((*it)->IsUnconscious()) {
      if (((*it)->IsMine()) && (!(*it)->IsRobot())) {
        ActualDeaths+=1;
      }
      else {
        if ((*it)->IsGrinch()) ActualGrinchKills+=1;
        else ActualKills+=1;
      }
    }
  }


  ActualScore = ActualKills + (ActualGrinchKills*20) - (ActualDeaths*4);

  hiscore_table.AddTime(actual_map->GetName(), HSTime(UserName, ActualTime));
  hiscore_table.AddScore(actual_map->GetName(), HSScore(UserName, ActualScore));

  ActualBestTime = hiscore_table.GetBestTime(actual_map->GetName());

  hiscore_table.Save();
}



void UpdateRiotSound() {
  std::deque<Person *>::iterator it;
  int count;
  count = 0;
  for (it=persons.begin(); it!=persons.end(); it+=1) {
    if ((!(*it)->IsMine()) && (!(*it)->IsUnconscious())) {
      if ((*it)->InsideScreen()) {
        count += 1;
      }
    }
  }

  float vol;
  vol = count/30.0;
  if (vol > 2.5) vol =2.5;

  al_set_audio_stream_gain(riot, vol);
  al_set_audio_stream_playmode(riot, ALLEGRO_PLAYMODE_LOOP);
  al_set_audio_stream_playing(riot, true);
}



void DrawEditor() {


  if (EditorType == EDITOR_MODE_TILES) {
  if (ActualRectX == -1) {
    DRAW_TRANSFORMED(editor_cursor->get_bit(), RSW((EditorX * SCREEN_TILE_W)+SCREEN_TILE_W/2-Camera_X), RSH((EditorY * SCREEN_TILE_H)+SCREEN_TILE_H/2-Camera_Y), RSW(SCREEN_TILE_W), RSH(SCREEN_TILE_H), 0, 0);
  }
  else {
    al_draw_scaled_bitmap(editor_cursor->get_bit(), 0, 0, al_get_bitmap_width(editor_cursor->get_bit()), al_get_bitmap_height(editor_cursor->get_bit()),
    RSW((EditorX * SCREEN_TILE_W)-Camera_X), RSH((EditorY * SCREEN_TILE_H)-Camera_Y), RSW(SCREEN_TILE_W)*(mabs(ActualRectFX-ActualRectX)+1), RSH(SCREEN_TILE_H)*(mabs(ActualRectFY-ActualRectY)+1), 0);
  }


  game_font->Print("Actual Layer: "+ToString(ActualLayer), 21, 41, al_map_rgb(0, 0, 0));
  game_font->Print("Actual Tile: "+ToString(ActualTile), 21, 61, al_map_rgb(0, 0, 0));

  game_font->Print("Actual Layer: "+ToString(ActualLayer), 20, 40);
  game_font->Print("Actual Tile: "+ToString(ActualTile), 20, 60);
  }

  if (EditorType == EDITOR_MODE_TILES) game_font->Print("Tiles Edition", 20, 80);
  if (EditorType == EDITOR_MODE_SPAWNS) game_font->Print("Spawns Edition", 20, 80);
  if (EditorType == EDITOR_MODE_LIGHTS) game_font->Print("Lights Edition", 20, 80);

  if (EditorType == EDITOR_MODE_TILES) {
  if (SelectingTile) {
    al_clear_to_color(al_map_rgb_f(120, 120, 120));
    game_font->Print("Select the tile you would like to paste:  " + ToString(ActualTile), 10, 20);

    CacheBitmap *cb = actual_map->GetTileset();

    int div, lh;
    div = SCREEN_W / (RSW((TILESET_WIDTH * SCREEN_TILE_W)) + RSW(6));

    lh = SCREEN_H - RSH(64);
    lh = lh / (RSH(SCREEN_TILE_W));

    float sh, fh;
    sh = 0;
    div += 1;

    for (int i=0; i != div; i+=1) {
      fh = sh + (lh*REAL_TILE_H);
      if (fh >= al_get_bitmap_height(cb->get_bit())) {
        fh = al_get_bitmap_height(cb->get_bit())-1;
      }

      float mx, my;
      mx = RSW((TILESET_WIDTH * SCREEN_TILE_W)+RSW(6)) * i + RSW(4);
      my = RSH(48);

      int dh;
      dh = (fh-sh)/REAL_TILE_H;

      al_draw_scaled_bitmap(cb->get_bit(), 0, sh, al_get_bitmap_width(cb->get_bit()), fh-sh, mx, my, RSW(SCREEN_TILE_W)*TILESET_WIDTH, RSH(SCREEN_TILE_H)*dh, 0);
      if (CollisionEditing) {
      for (int tx=0; tx!=TILESET_WIDTH; tx +=1) {
        for (int ty=0; ty!=dh; ty +=1) {
          int t;
          t = ((ty+(sh/REAL_TILE_H)) * TILESET_WIDTH) + tx;
          if (actual_map->GetTileCollision(t) == 1) DRAW_TRANSFORMED(collision_bit, mx+(tx*RSW(SCREEN_TILE_W))+SRW(SCREEN_TILE_W/2), my+(ty*RSH(SCREEN_TILE_H))+SRH(SCREEN_TILE_H/2), RSW(SCREEN_TILE_W), RSH(SCREEN_TILE_H), 0, 0);
          if (actual_map->GetTileCollision(t) == 2) DRAW_TRANSFORMED(collision2_bit, mx+(tx*RSW(SCREEN_TILE_W))+SRW(SCREEN_TILE_W/2), my+(ty*RSH(SCREEN_TILE_H))+SRH(SCREEN_TILE_H/2), RSW(SCREEN_TILE_W), RSH(SCREEN_TILE_H), 0, 0);
        }
      }
      }
      sh = fh;
    }

    if (ActualRectX == -1) {
      DRAW_TRANSFORMED(editor_cursor->get_bit(), EditorX, EditorY, RSW(SCREEN_TILE_W), RSH(SCREEN_TILE_H), 0, 0);
    }
    else {
      int sx, sy, fx, fy;
      sx = ActualRectX; sy = ActualRectY; fx = ActualRectFX; fy = ActualRectFY;
      if (fx < sx) {int t=fx; fx=sx; sx=t;}
      if (fy < sy) {int t=fy; fx=sy; sy=t;}


      int tx, ty;

      int i;
      i = ActualRectY / lh;

      int mx, my;

      mx = RSW((TILESET_WIDTH * SCREEN_TILE_W) + 6) * i + RSW(4);
      my = RSH(48);

      tx = RSW(ActualRectX * SCREEN_TILE_W) + mx;
      ty = my + RSH((ActualRectY - (i * lh)) * SCREEN_TILE_H);

      al_draw_scaled_bitmap(editor_cursor->get_bit(), 0, 0, al_get_bitmap_width(editor_cursor->get_bit()), al_get_bitmap_height(editor_cursor->get_bit()),
                            tx, ty, ((fx-sx)+1) * RSW(SCREEN_TILE_W), ((fy-sy)+1) * RSH(SCREEN_TILE_H), 0);
    }
  }
  }

  if (EditorType == EDITOR_MODE_SPAWNS) {
    al_draw_filled_rectangle(0, SCREEN_H-RSH(48), SCREEN_W, SCREEN_H,al_map_rgba_f(0.5, 0.5, 0.5, 0.7));
    for (int x=0; x!=SPAWNS_SIZE; x+=1) {
      if (ActualSpawn != x) OPACITY_BLEND(0.5);
      DRAW_TRANSFORMED(spawns[x], x*RSW(45)+RSW(20), SCREEN_H-RSH(22), RSW(40), RSH(40), 0, 0);
      NORMAL_BLEND;
    }

    if (mouse_y < SCREEN_H-RSH(48)) {
      DRAW_TRANSFORMED(spawns[ActualSpawn], mouse_x, mouse_y, RSW(32), RSH(32), 0, 0);
    }

    std::deque<SpawnPoint *>::iterator it;
    for (it=spawn_points.begin(); it!=spawn_points.end(); it+=1) {
      DRAW_TRANSFORMED(spawns[(*it)->type], RSW((*it)->x-Camera_X), RSW((*it)->y-Camera_Y), RSW(32), RSH(32), 0, 0);
    }
  }

  if (EditorType == EDITOR_MODE_LIGHTS) {
    al_draw_filled_rectangle(0, SCREEN_H-RSH(48), SCREEN_W, SCREEN_H,al_map_rgba_f(0.5, 0.5, 0.5, 0.7));
    for (int x=0; x!=LIGHTS_SIZE; x+=1) {
      if (ActualLight != x) OPACITY_BLEND(0.5);
      DRAW_TRANSFORMED(lights[x], x*RSW(45)+RSW(20), SCREEN_H-RSH(22), RSW(40), RSH(40), 0, 0);
      NORMAL_BLEND;
    }
  }


  if (EditorType == EDITOR_MODE_MAP_DATA) {
    al_draw_filled_rectangle(0, 0, SCREEN_W, SCREEN_H,al_map_rgba_f(0.5, 0.5, 0.5, 0.7));
    game_font->Print("Map Data Edition", 20, 80);
    for (int i=0; i!=4; i+=1) {
      editor_powers_box[i]->draw();
    }

    map_file_name->draw();
    map_internal_name->draw();

    save_map_button->draw();
    load_map_button->draw();

    storyboard_add->draw();
    storyboard_delete->draw();

    for (int i=0; i!=8; i+=1) {
      storyboard_boxes[i]->draw();
    }
    for (int i=0; i!=12; i+=1) {
      storyboard_buttons[i]->draw();
    }

    storyboard_add->draw();
    storyboard_delete->draw();

    map_width->draw();
    map_height->draw();
    map_weather->draw();
    apply_changes->draw();
  }

}


void FillBucket(int x, int y, int o_t, int tl) {
  if (o_t == tl) return;
  if (actual_map->GetTile(ActualLayer, x, y) != o_t) return;
  if (actual_map->SetTile(ActualLayer, x, y, tl)) {
    FillBucket(x+1, y, o_t, tl);
    FillBucket(x-1, y, o_t, tl);
    FillBucket(x, y+1, o_t, tl);
    FillBucket(x, y-1, o_t, tl);
  }
}

void SetAttackCommand() {
  ActualCommand = COMMAND_ATTACK;
  ActualPower = -1;
}

void UpdateEditor() {
  static bool FromSelectingTile;

  Pause = 1;

  if (EditorType == EDITOR_MODE_TILES) {

  BucketMode=false;
  CollisionEditing=false;
  if (Keyboard_Active[ALLEGRO_KEY_B]) {
    BucketMode=true;
    cursor=cursor_bucket;
  }

  if (!SelectingTile) {
    EditorX = (int)(SRW(mouse_x) + Camera_X) / SCREEN_TILE_W;
    EditorY = (int)(SRH(mouse_y) + Camera_Y) / SCREEN_TILE_H;

    if ((Keyboard_Active[ALLEGRO_KEY_MOUSE_LCLICK]) && (!FromSelectingTile)) {
      if (ActualRectX == -1) {
        if (BucketMode) {
          FillBucket(EditorX, EditorY, actual_map->GetTile(ActualLayer, EditorX, EditorY), ActualTile);
        }
        else {
          actual_map->SetTile(ActualLayer, EditorX, EditorY, ActualTile);
        }
      }
      else {
        int sx, sy, fx, fy;
        sx = EditorX; sy = EditorY;
        fx = sx + mabs(ActualRectFX-ActualRectX)+1; fy = sy + mabs(ActualRectFY-ActualRectY)+1;

        if (sx < 0) sx = 0;
        if (sy < 0) sy = 0;
        if (fx > actual_map->GetW()) fx = actual_map->GetW();
        if (fy > actual_map->GetH()) fy = actual_map->GetH();

        for (int x=sx; x!=fx; x+=1) {
          for (int y=sy; y!=fy; y+=1) {
            int tl, tx, ty;
            tx = ActualRectX+(x-sx); ty = ActualRectY+(y-sy);
            tl = (ty * TILESET_WIDTH) + tx;
            actual_map->SetTile(ActualLayer, x, y, tl);
          }
        }
      }
    }
    else {
      if (!Keyboard_Active[ALLEGRO_KEY_MOUSE_LCLICK]) FromSelectingTile = false;
    }
    if ((Keyboard_Active[ALLEGRO_KEY_MOUSE_RCLICK])) {
      if (ActualRectX == -1) {
        actual_map->SetTile(ActualLayer, EditorX, EditorY, -1);
      }
      else {
        int sx, sy, fx, fy;
        sx = EditorX; sy = EditorY;
        fx = sx + mabs(ActualRectFX-ActualRectX)+1; fy = sy + mabs(ActualRectFY-ActualRectY)+1;

        if (sx < 0) sx = 0;
        if (sy < 0) sy = 0;
        if (fx > actual_map->GetW()) fx = actual_map->GetW();
        if (fy > actual_map->GetH()) fy = actual_map->GetH();

        for (int x=sx; x!=fx; x+=1) {
          for (int y=sy; y!=fy; y+=1) {
            actual_map->SetTile(ActualLayer, x, y, -1);
          }
        }
      }
    }
  }
  else {
    ActualTile = -1;

    EditorX = -500;
    EditorY = -500;

    if (Keyboard_Active[ALLEGRO_KEY_C]) CollisionEditing = true;


    CacheBitmap *cb = actual_map->GetTileset();
    int div, lh;
    div = SCREEN_W / (RSW((TILESET_WIDTH * SCREEN_TILE_W)) + RSW(6));
    lh = SCREEN_H - RSH(64);
    lh = lh / (RSH(SCREEN_TILE_W));
    float sh, fh;
    float last_dh;
    sh = 0;
    div += 1;
    for (int i=0; i != div; i+=1) {
      fh = sh + (lh*REAL_TILE_H);
      if (fh >= al_get_bitmap_height(cb->get_bit())) {
        fh = al_get_bitmap_height(cb->get_bit())-1;
      }

      float mx, my;
      mx = RSW((TILESET_WIDTH * SCREEN_TILE_W) + 6) * i + RSW(4);
      my = RSH(48);

      int dh;
      dh = (fh-sh)/REAL_TILE_H;

      if ((mouse_y > RSH(48)) && (mouse_y < RSH(48 + (SCREEN_TILE_H * dh))) && (mouse_x > mx) && (mouse_x < mx+(TILESET_WIDTH*SCREEN_TILE_W))) {
        int tx, ty;
        tx = (mouse_x - mx) / RSW(SCREEN_TILE_W);
        ty = ((mouse_y - my) / RSH(SCREEN_TILE_H)) + (i*last_dh);

        ActualTile = (ty * TILESET_WIDTH) + tx;

        EditorX = RSW(((tx * SCREEN_TILE_W) + SCREEN_TILE_W/2)) + mx;
        EditorY = my + RSH((ty- (i * last_dh)) * SCREEN_TILE_H + SCREEN_TILE_H/2);

        if (Keyboard_Time_Pressed[ALLEGRO_KEY_MOUSE_LCLICK] > 5) {
          if (ActualRectX == -1) {
            ActualRectX = tx; ActualRectY = ty;
            ActualRectFX = tx; ActualRectFY = ty;
          }
          else {
            ActualRectFX = tx; ActualRectFY = ty;
          }
        }

      }

      last_dh = dh;

      sh = fh;
    }

    if (CollisionEditing) {
      if (Keyboard_Recently_Released[ALLEGRO_KEY_MOUSE_RCLICK]) {
        if (ActualTile != -1) {
          actual_map->SetTileCollision(ActualTile, (actual_map->GetTileCollision(ActualTile) == 0 ? 1 : actual_map->GetTileCollision(ActualTile) == 1 ? 2 : 0));
        }
      }
    }

    if (Keyboard_Recently_Released[ALLEGRO_KEY_MOUSE_LCLICK]) {
      FromSelectingTile = true;
      SelectingTile = false;

      if (ActualRectFX < ActualRectX) {int t=ActualRectFX; ActualRectFX=ActualRectX; ActualRectX=t;}
      if (ActualRectFY < ActualRectY) {int t=ActualRectFY; ActualRectFY=ActualRectY; ActualRectY=t;}
    }
  }

  }

  if ((Keyboard_Recently_Input[ALLEGRO_KEY_S]) && (Keyboard_Active[ALLEGRO_KEY_LCTRL])) {
    SaveMap();
  }


  if (Keyboard_Recently_Input[ALLEGRO_KEY_F2]) EditorType = EDITOR_MODE_TILES;
  if (Keyboard_Recently_Input[ALLEGRO_KEY_F3]) EditorType = EDITOR_MODE_SPAWNS;
  if (Keyboard_Recently_Input[ALLEGRO_KEY_F4]) EditorType = EDITOR_MODE_LIGHTS;
  if (Keyboard_Recently_Input[ALLEGRO_KEY_F5]) EditorType = EDITOR_MODE_MAP_DATA;

  if (EditorType == EDITOR_MODE_SPAWNS) {
    if (mouse_y > SCREEN_H-RSH(48)) {
     if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
      for (int x=0; x!=SPAWNS_SIZE; x+=1) {
        if (mouse_x > RSW(x*45)) {
          ActualSpawn = x;
        }
      }
     }
    }
    else {
      if (Keyboard_Active[ALLEGRO_KEY_MOUSE_RCLICK]) {
        if (Keyboard_Active[ALLEGRO_KEY_E]) {
          std::deque<SpawnPoint *>::iterator it;
          for (it=spawn_points.begin(); it!=spawn_points.end(); it+=1) {
            if (distance_between_points((*it)->x, (*it)->y, SRW(mouse_x)+Camera_X, SRH(mouse_y)+Camera_Y) < 16) {
              spawn_points.erase(it);
              break;
            }
          }
        }
      }
      if ((Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_RCLICK]) && (!Keyboard_Active[ALLEGRO_KEY_E])) {
        SpawnPoint *sp;
        sp = new SpawnPoint(SRW(mouse_x)+Camera_X, SRH(mouse_y)+Camera_Y, ActualSpawn);
        spawn_points.push_back(sp);
      }
    }
  }

  if (EditorType == EDITOR_MODE_LIGHTS) {
    if (mouse_y > SCREEN_H-RSH(48)) {
     if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
      for (int x=0; x!=LIGHTS_SIZE; x+=1) {
        if (mouse_x > RSW(x*45)) {
          ActualLight = x;
        }
      }
     }
    }
    else {
    if (Keyboard_Active[ALLEGRO_KEY_MOUSE_RCLICK]) {
      if (Keyboard_Active[ALLEGRO_KEY_E]) {
        std::deque<LightPoint *>::iterator it;
        for (it=light_points.begin(); it!=light_points.end(); it+=1) {
          if (distance_between_points((*it)->x, (*it)->y, SRW(mouse_x)+Camera_X, SRH(mouse_y)+Camera_Y) < 64) {
            light_points.erase(it);
            break;
          }
        }
      }
    }
    if ((Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_RCLICK]) && (!Keyboard_Active[ALLEGRO_KEY_E])) {
      LightPoint *sp;
      sp = new LightPoint(SRW(mouse_x)+Camera_X, SRH(mouse_y)+Camera_Y, ActualLight);
      light_points.push_back(sp);
    }
    }
  }



  if (EditorType==EDITOR_MODE_MAP_DATA) {
    for (int i=0; i!=4; i+=1) {
      editor_powers_box[i]->show();
      editor_powers_box[i]->update();
      if (editor_powers_box[i]->changed()) CopyMapFromStats();
    }
    map_file_name->show();
    map_internal_name->show();
    save_map_button->show();
    load_map_button->show();

    for (int i=0; i!=12; i+=1) {
      storyboard_buttons[i]->hide();
    }
    for (int i=0; i!=StoryboardSize; i+=1) {
      storyboard_buttons[i]->show();
    }
    storyboard_add->show();
    storyboard_delete->show();

    for (int i=0; i!=8; i+=1) {
      storyboard_boxes[i]->show();
      storyboard_boxes[i]->update();
      if (storyboard_boxes[i]->changed()) CopyMapFromStats();
    }
    for (int i=0; i!=12; i+=1) {
      storyboard_buttons[i]->update();
    }


    map_file_name->update();
    map_internal_name->update();
    save_map_button->update();
    load_map_button->update();
    storyboard_add->update();
    storyboard_delete->update();
    map_width->update();
    map_height->update();
    apply_changes->update();
    map_weather->update();
    if (map_weather->changed()) CopyMapFromStats();


    if (map_file_name->changed()) CopyMapFromStats();
    if (map_internal_name->changed()) CopyMapFromStats();

  }
  else {
    for (int i=0; i!=4; i+=1) {
      editor_powers_box[i]->hide();
    }
    map_file_name->hide();
    map_internal_name->hide();
    save_map_button->hide();
  }


  if (EditorType == EDITOR_MODE_TILES) {

  if (Keyboard_Recently_Input[ALLEGRO_KEY_1]) ActualLayer = 0;
  if (Keyboard_Recently_Input[ALLEGRO_KEY_2]) ActualLayer = 1;
  if (Keyboard_Recently_Input[ALLEGRO_KEY_3]) ActualLayer = 2;



  if ((Keyboard_Recently_Input[ALLEGRO_KEY_D])) {
    SelectingTile = (SelectingTile ? 0 : 1);
    ActualRectX = -1;
  }


  if ((Keyboard_Active[ALLEGRO_KEY_Q]) && (Keyboard_Active[ALLEGRO_KEY_W]) && (Keyboard_Active[ALLEGRO_KEY_E])) {
    actual_map->Clear();
  }

  }


}





/*=================================================*/



void SelectByRect() {
  if (ActualRectFX < ActualRectX) {int t=ActualRectFX; ActualRectFX=ActualRectX; ActualRectX=t;}
  if (ActualRectFY < ActualRectY) {int t=ActualRectFY; ActualRectFY=ActualRectY; ActualRectY=t;}

  std::deque<Person *>::iterator it;

  DeselectAllPeople();

  int count=0;

  for (it=persons.begin(); it!=persons.end(); it+=1) {
    if ((*it)->IsMine() && (!(*it)->IsUnconscious())) {
      if (inside_rect((*it)->GetRX()+RSW(Camera_X), (*it)->GetRY()+RSW(Camera_Y), ActualRectX, ActualRectY, ActualRectFX, ActualRectFY)) {
        (*it)->Select();
      }
      else if (inside_rect((*it)->GetRX()+RSW(Camera_X)-RSW((*it)->GetW())/2, (*it)->GetRY()+RSW(Camera_Y)-RSH((*it)->GetH())/2, ActualRectX, ActualRectY, ActualRectFX, ActualRectFY)) {
       (*it)->Select();
      }
      else if (inside_rect((*it)->GetRX()+RSW(Camera_X)+RSW((*it)->GetW())/2, (*it)->GetRY()+RSW(Camera_Y)-RSH((*it)->GetH())/2, ActualRectX, ActualRectY, ActualRectFX, ActualRectFY)) {
        (*it)->Select();
      }
      else if (inside_rect((*it)->GetRX()+RSW(Camera_X)+RSW((*it)->GetW())/2, (*it)->GetRY()+RSW(Camera_Y)+RSH((*it)->GetH())/2, ActualRectX, ActualRectY, ActualRectFX, ActualRectFY)) {
        (*it)->Select();
      }
      else if (inside_rect((*it)->GetRX()+RSW(Camera_X)-RSW((*it)->GetW())/2, (*it)->GetRY()+RSW(Camera_Y)+RSH((*it)->GetH())/2, ActualRectX, ActualRectY, ActualRectFX, ActualRectFY)) {
        (*it)->Select();
      }
    }
  }
}

bool MapChange=false;

void ChangeToNextMap() {
  MapChange=true;
  BlackFadeDir = 0.01;
  BlackFade = 0;
}


void GScene_Game::draw() {
  al_clear_to_color(al_map_rgb_f(0, 0, 0));
  actual_map->DrawBack();
  actual_map->DrawLayer(0);
  actual_map->DrawLayer(1);

  if (EditorMode==0) DrawObjectsZOrder();
  DrawParticles();
  DrawProjectiles();

  actual_map->DrawLayer(2);
  actual_map->DrawFront();

  DrawPowers();

  if (DynamicLighting) {
    DRAWTO(LightMap);
    al_clear_to_color(al_map_rgba_f(0, 0, 0, 0.4));
    al_set_blender(ALLEGRO_ALPHA, ALLEGRO_ONE, al_map_rgba_f(1, 1, 1, 1.0));
    std::deque<Person *>::iterator it;
    for (it=persons.begin(); it!=persons.end(); it+=1) {
      (*it)->DrawLight();
    }
    std::deque<LightPoint *>::iterator itl;
    for (itl=light_points.begin(); itl!=light_points.end(); itl+=1) (*itl)->Draw();

    DRAWNORMAL;
    al_set_blender(ALLEGRO_INVERSE_ALPHA, ALLEGRO_ALPHA, al_map_rgba_f(1, 1, 1, 1.0));
    al_draw_bitmap(LightMap, 0, 0, 0);
    NORMAL_BLEND;
  }

  if (actual_map->GetWeather()) GameWeather->Draw();



  game_font->Print("FPS: "+ToString(FPS), 21, 21, al_map_rgb(0, 0, 0));
  game_font->Print("FPS: "+ToString(FPS), 20, 20);

  if (EditorMode) {
    DrawEditor();
  }
  else {
    if (!RectangleSelection) {
      ActualRectX=-1; ActualRectY=-1;
      ActualRectFX=-1; ActualRectFY=-1;
    }
  }

  if ((!ShowScore) && (!ShowBriefing)) {
    if (RectangleSelection) {
      float sx, sy, fx, fy;
      sx = ActualRectX-RSW(Camera_X);  sy = ActualRectY-RSH(Camera_Y);
      fx = ActualRectFX-RSW(Camera_X); fy = ActualRectFY-RSH(Camera_Y);
      if (fx < sx) {int t=fx; fx=sx; sx=t;}
      if (fy < sy) {int t=fy; fy=sy; sy=t;}

      al_draw_rectangle(sx, sy, fx, fy, al_map_rgb_f(0, 1, 0), RSW(1));
    }
  }


  if (!EditorMode) {

  int mx;
  mx = SCREEN_W-RSW(180);
  al_draw_scaled_bitmap(right_border, 0, 0, al_get_bitmap_width(right_border), al_get_bitmap_height(right_border),
                        SCREEN_W-RSW(al_get_bitmap_width(right_border)), 0,
                        RSW(al_get_bitmap_width(right_border)), SCREEN_H, 0);
  std::deque<Person *>::iterator it;
  int count=0;
  for (it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
    if ((*it)->GetPortrait() != NULL) {
      CacheBitmap *cb;
      cb = (*it)->GetPortrait();

      if (actual_selection.size() > 1) {
        int tx, ty;
        tx = count % 3;
        ty = count / 3;
        DRAW_TRANSFORMED(cb->get_bit(), mx+RSW(15)+tx*RSW(55)+RSW(20), RSH(122)+ty*RSH(53)+RSH(20), RSW(40), RSH(40), 0, 0);

        float p;
        p=(*it)->GetLifePercent();
        if (p < 1.0) {
          p *= cb->Height();
          al_draw_scaled_bitmap(cb->get_red_bit(), 0, p, cb->Width(), cb->Height() - p, mx+RSW(15)+tx*RSW(55), RSH(122)+ty*RSH(53)+p/2, SRW(40), SRH(40 - (p/2)), 0);
        }

        if (count == ActualPortrait) {
          DRAW_TRANSFORMED(remark_portrait, mx+RSW(15)+tx*RSW(55)+RSW(20), RSH(122)+ty*RSH(53)+RSH(20), RSW(40), RSH(40), 0, 0);
        }
      }

      if (count == 0) {
        DRAW_TRANSFORMED(cb->get_bit(), mx+RSW(12)+RSW(40), RSH(16)+RSH(40), RSW(80), RSH(80), 0, 0);
        float p;
        p=(*it)->GetLifePercent();
        if (p < 1.0) {
          p *= RSH(cb->Height());
          al_draw_scaled_bitmap(cb->get_red_bit(), 0, p, cb->Width(), cb->Height() - p, mx+RSW(12), SRH(16)+p, RSW(80), RSH(cb->Height() - p), 0);
        }
        game_font->Print((*it)->GetName(), mx+RSW(10)+2, RSH(20)+2, al_map_rgb(0, 0, 0));
        game_font->Print((*it)->GetName(), mx+RSW(10), RSH(20));
      }
    }
    count+=1;
    if (count > 17) break;
  }

  for (int i=0; i!=9; i+=1) {
    command_buttons[i]->draw();
    if ((i > 4) && (command_buttons[i]->is_visible())) {
      if (ActualFormation == (i-5)) {
        DRAW_TRANSFORMED(remark_button, command_buttons[i]->get_x()+command_buttons[i]->get_w()/2, command_buttons[i]->get_y()+command_buttons[i]->get_h()/2,
        command_buttons[i]->get_w(),command_buttons[i]->get_h(), 0, 0);
      }
    }
  }


    for (int i=0; i!=4; i+=1) {
      float tx, ty;
      ALLEGRO_BITMAP *bit;
      if (i == 0) {tx = mx + RSW(48); ty = RSH(670);}
      if (i == 1) {tx = mx + RSW(130); ty = RSH(670);}
      if (i == 2) {tx = mx + RSW(48); ty = RSH(727);}
      if (i == 3) {tx = mx + RSW(130); ty = RSH(727);}

      if ((ActualPower == i)||(ActualOverPower==i)) bit = powers[(i*3)+1];
      else if (ActualPowers[i] > 0) bit = powers[(i*3)];
      else bit = powers[(i*3)+2];

      if (ActualPowersCooldown[i] > 0) bit=powers[(i*3)+2];

      DRAW_TRANSFORMED(bit, tx, ty, RSW(al_get_bitmap_width(bit)), RSH(al_get_bitmap_height(bit)), 0, 0);

      game_font->Print(ToString(ActualPowers[i]), tx+RSW(30), ty+RSH(22));
    }


    if ((tooltip_text != "") || (tooltip_opacity > 0)) {
      float rw, rh;

      OPACITY_BLEND(tooltip_opacity);

      rw = RSW(al_get_bitmap_width(low_border));
      rh = RSH(24);
      DRAW_TRANSFORMED(low_border, rw/2, SCREEN_H-rh/2, rw, rh, 0, 0);

      game_font->Print(tooltip_text, RSW(4), SCREEN_H-RSH(8));

      NORMAL_BLEND;
    }

  }

/*

  float rw, rh;
  OPACITY_BLEND(0.8);
  rw = RSW(al_get_bitmap_width(storyboard_bit));
  rh = RSH(al_get_bitmap_height(storyboard_bit));
  DRAW_TRANSFORMED(storyboard_bit, RSW(20) + rw/2, StoryboardY+rh/2, rw, rh, 0, 0);
  NORMAL_BLEND;

  storyboard_back->draw();
  storyboard_next->draw();
  storyboard_camera->draw();

  if (StoryboardShowing) {
    for (int i=0; i!=8; i+=1) {
      game_font->Print(EditorStoryboards[ActualStoryboard].paragraph[i], RSW(40)+1, RSH(30)+(game_font->Height()+1)*i+StoryboardY+1, al_map_rgba_f(0, 0, 0, 1));
      game_font->Print(EditorStoryboards[ActualStoryboard].paragraph[i], RSW(40), RSH(30)+(game_font->Height()+1)*i+StoryboardY);
    }
  }
*/

  if (!EditorMode) {

    al_draw_scaled_bitmap(right_border_top, 0, 0, al_get_bitmap_width(right_border_top), al_get_bitmap_height(right_border_top),
                        SCREEN_W-RSW(al_get_bitmap_width(right_border_top)), 0,
                        RSW(al_get_bitmap_width(right_border_top)), SCREEN_H, 0);
  }



  if (MissionFailed) {
    OPACITY_BLEND(MissionFailedOpacity);
    float rw, rh;
    rw = RSW(al_get_bitmap_width(mission_failed_bit));
    rh = RSH(al_get_bitmap_height(mission_failed_bit));
    DRAW_TRANSFORMED(mission_failed_bit, SCREEN_W/2, SCREEN_H/3, rw, rh, 0, 0);
    NORMAL_BLEND;
  }

  if (MissionCompleted) {
    OPACITY_BLEND(MissionCompletedOpacity-ScoreOpacity);
    float rw, rh;
    rw = RSW(al_get_bitmap_width(mission_complete_bit));
    rh = RSH(al_get_bitmap_height(mission_complete_bit));
    DRAW_TRANSFORMED(mission_complete_bit, SCREEN_W/2, SCREEN_H/3, rw, rh, 0, 0);
    OPACITY_BLEND(ScoreOpacity);
    if (ShowScore) {
      rw = RSW(al_get_bitmap_width(score_table_bit));
      rh = RSH(al_get_bitmap_height(score_table_bit));
      DRAW_TRANSFORMED(score_table_bit, SCREEN_W/2, SCREEN_H/2, rw, rh, 0, 0);

      rw = RSW(900);
      rh = RSH(613);

      float tx, ty;

      OPACITY_BLEND(HSOpacity[0]);
      tx = SCREEN_W/2-rw/2+RSW(600); ty = SCREEN_H/2-rh/2+RSH(170);
      score_font->Print(ToString(ActualKills), tx, ty);

      OPACITY_BLEND(HSOpacity[1]);
      tx = SCREEN_W/2-rw/2+RSW(600); ty = SCREEN_H/2-rh/2+RSH(226);
      score_font->Print(ToString(ActualGrinchKills) + " X (20)", tx, ty);

      OPACITY_BLEND(HSOpacity[2]);
      tx = SCREEN_W/2-rw/2+RSW(600); ty = SCREEN_H/2-rh/2+RSH(310);
      score_font->Print(ToString(ActualDeaths) + " X (4)", tx, ty);

      OPACITY_BLEND(HSOpacity[3]);
      tx = SCREEN_W/2-rw/2+RSW(640); ty = SCREEN_H/2-rh/2+RSH(422);
      score_font->Print(ToString(ActualScore), tx, ty);

      OPACITY_BLEND(ScoreOpacity);

      tx = SCREEN_W/2-rw/2+RSW(320); ty = SCREEN_H/2-rh/2+RSH(552);
      int min;
      min = (int)ActualTime/60;
      score_font->Print(ToString(min) + ":" + ToString(ActualTime - (min*60)), tx, ty);

      tx = SCREEN_W/2-rw/2+RSW(320); ty = SCREEN_H/2-rh/2+RSH(600);
      min = (int)ActualBestTime/60;
      score_font->Print(ToString(min) + ":" + ToString(ActualBestTime - (min*60)), tx, ty);

      OPACITY_BLEND(ScoresNextOpacity);
      tx = SCREEN_W/2-rw/2+RSW(795); ty = SCREEN_H/2-rh/2+RSH(555);
      ALLEGRO_BITMAP *bit;
      if (ScoresNextOver) bit = results_next_on;
      else bit = results_next;
      rw = RSW(al_get_bitmap_width(bit)); rh = RSH(al_get_bitmap_height(bit));
      DRAW_TRANSFORMED(bit, tx, ty, rw, rh, 0, 0);
    }
    NORMAL_BLEND;
  }

  if (BriefingOpacity > 0) {
    float rw, rh;
    rw = RSW(al_get_bitmap_width(briefing_bit));
    rh = RSH(al_get_bitmap_height(briefing_bit));
    OPACITY_BLEND(BriefingOpacity);
    DRAW_TRANSFORMED(briefing_bit, SCREEN_W/2, SCREEN_H/2, rw, rh, 0, 0);

    float tx, ty;
    tx = SCREEN_W/2-rw/2+RSW(850); ty = SCREEN_H/2-rh/2+RSH(600);
    ALLEGRO_BITMAP *bit;
    if (ScoresNextOver) bit = results_next_on;
    else bit = results_next;
    rw = RSW(al_get_bitmap_width(bit)); rh = RSH(al_get_bitmap_height(bit));
    DRAW_TRANSFORMED(bit, tx, ty, rw, rh, 0, 0);

    std::deque<std::string>::iterator it;
    int i;
    i=0;
    for (it=briefing_text.begin(); it!=briefing_text.end(); it+=1) {
      hiscore_font->Print((*it), SCREEN_W/2-RSW(432)+2, RSH(240)+(hiscore_font->Height()+1)*i+2, al_map_rgba_f(0, 0, 0, BriefingOpacity));
      OPACITY_BLEND(BriefingOpacity);
      hiscore_font->Print((*it), SCREEN_W/2-RSW(432), RSH(240)+(hiscore_font->Height()+1)*i);
      i+=1;
    }

    NORMAL_BLEND;
  }


  if (HelpOpacity > 0) {
    float rw, rh;
    rw = RSW(al_get_bitmap_width(help_bit));
    rh = RSH(al_get_bitmap_height(help_bit));
    OPACITY_BLEND(HelpOpacity);
    DRAW_TRANSFORMED(help_bit, SCREEN_W/2, SCREEN_H/2, rw, rh, 0, 0);

    rw = RSW(al_get_bitmap_width(help_pages[HelpIndex]));
    rh = RSH(al_get_bitmap_height(help_pages[HelpIndex]));
    DRAW_TRANSFORMED(help_pages[HelpIndex], SCREEN_W/2, SCREEN_H/2, rw, rh, 0, 0);
    NORMAL_BLEND;

    float tx, ty;
    if (HelpIndex < HELP_SCREENS-1) {
      tx = SCREEN_W/2-rw/2+RSW(910); ty = SCREEN_H/2-rh/2+RSH(660);
      rw = RSW(90); rh = RSH(56);
      ALLEGRO_BITMAP *bit;
      if (HelpRightOver) bit = results_next_on;
      else bit = results_next;
      DRAW_TRANSFORMED(bit, tx, ty, rw, rh, 0, 0);
    }
    if (HelpIndex > 0) {
      tx = SCREEN_W/2-rw/2+RSW(90); ty = SCREEN_H/2-rh/2+RSH(660);
      rw = RSW(90); rh = RSH(56);
      ALLEGRO_BITMAP *bit;
      if (HelpLeftOver) bit = results_next_on;
      else bit = results_next;
      DRAW_TRANSFORMED(bit, tx, ty, rw, rh, 0, ALLEGRO_FLIP_HORIZONTAL);
    }
  }


  if (BlackFade != 0) {
    al_draw_filled_rectangle(0, 0, SCREEN_W, SCREEN_H, al_map_rgba_f(0, 0, 0, BlackFade));
  }

  float rw, rh;

  rw = RSW(al_get_bitmap_width(cursor));
  rh = RSH(al_get_bitmap_height(cursor));

  Vec2D last_pos;
  last_pos = Vec2D(mick_x, mick_y);
  DrawTransformedMotionBlur(cursor, mouse_x+rw/2, mouse_y+rh/2, rw, rh, 0, 0, last_pos);
  DRAW_TRANSFORMED(cursor, mouse_x+rw/2, mouse_y+rh/2, rw, rh, 0, 0);

  al_flip_display();
}



void SelectGroup(int i) {
  DeselectAllPeople();
  for (std::deque<Person *>::iterator it=GroupControl[i].begin(); it!=GroupControl[i].end(); it+=1) {
    actual_selection.push_back(*it);
    if (!(*it)->IsUnconscious()) (*it)->Select();
  }
}


void SetGroup(int i) {
  GroupControl[i].clear();
  GetCurrentSelection();
  for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
    GroupControl[i].push_back(*it);
  }
}

void OrderGuard() {
  for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
    (*it)->OrderGuard();
  }
}

void OrderStop() {
  for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
    if ((*it)->IsMine()) (*it)->OrderStop();
  }
}

void UpdateOrdering() {
  if ((mouse_x < GUI_LIMIT) && (actual_selection.size() > 0)) {
    if (!actual_selection[0]->IsMine()) return;
    cursor = cursor_walk;
    if (ActualCommand == COMMAND_ATTACK) {
      cursor = cursor_attack;
    }
    if (ActualOver != NULL) {
      if (!ActualOver->IsMine()) {
        cursor = cursor_attack;
      }
    }
    if (Keyboard_Recently_Released[ALLEGRO_KEY_MOUSE_RCLICK]) {
      if (ActualOver != NULL) {
        if ((!ActualOver->IsMine()) || (ActualCommand == COMMAND_ATTACK)) {
          for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
            (*it)->TargetAttack(ActualOver);
          }
          ActualCommand = COMMAND_NONE;
        }
      }
      else {
        float tx, ty;
        tx = SRW(mouse_x)+Camera_X;
        ty = SRH(mouse_y)+Camera_Y;
        Vec2D angle, or_angle, center;

        FormationX=0; FormationY=0;

        center = Vec2D(0, 0);
        for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
          center += Vec2D((*it)->GetX(), (*it)->GetY());
        }

        center = center/actual_selection.size();
        angle = Vec2D(tx, ty) - center;
        angle = angle.Normalized();
        or_angle = angle;
        float t;
        t=angle.x;
        angle.x = angle.y;
        angle.y = -t;

        if (ActualFormation==FORMATION_NONE) {
          for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
            if (ActualCommand == COMMAND_ATTACK) (*it)->TargetSweep(tx, ty);
            else (*it)->TargetWalk(tx, ty);
          }
        }
        if (ActualFormation==FORMATION_RECTANGLE) {
          float t_w, p_w;
          p_w = (actual_selection[0]->GetW()/2)+2;
          t_w = p_w * (actual_selection.size() > 10 ? 10 : actual_selection.size());
          for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
            float mx, my;
            mx = angle.x * ((p_w*FormationX)-t_w/2);
            my = angle.y * ((p_w*FormationX)-t_w/2);

            mx -= or_angle.x * ((p_w*2) * FormationY);
            my -= or_angle.y * ((p_w*2) * FormationY);

            if (actual_map->IsFree(tx+mx, ty+my)) {
              if (ActualCommand == COMMAND_ATTACK) (*it)->TargetSweep(tx+mx, ty+my);
              else (*it)->TargetWalk(tx+mx, ty+my);
            }
            else {
              if (ActualCommand == COMMAND_ATTACK) (*it)->TargetSweep(tx, ty);
              else (*it)->TargetWalk(tx, ty);
            }
            FormationX+=1;

            if (FormationX > 10) {
              FormationX=0;
              FormationY+=1;
            }
          }
        }
        if (ActualFormation==FORMATION_LINE) {
          float t_w, p_w;
          p_w = (actual_selection[0]->GetW()/2)+2;
          t_w = p_w * actual_selection.size();
          for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
            float mx, my;
            mx = angle.x * ((p_w*FormationX)-t_w/2);
            my = angle.y * ((p_w*FormationX)-t_w/2);
            if (actual_map->IsFree(tx+mx, ty+my)) {
              if (ActualCommand == COMMAND_ATTACK) (*it)->TargetSweep(tx+mx, ty+my);
              else (*it)->TargetWalk(tx+mx, ty+my);
            }
            else {
              if (ActualCommand == COMMAND_ATTACK) (*it)->TargetSweep(tx, ty);
              else (*it)->TargetWalk(tx, ty);
            }
            FormationX+=1;
          }
        }
        if (ActualFormation==FORMATION_SPREAD) {
          float t_w, p_w;
          p_w = (actual_selection[0]->GetW()/2)+2;
          t_w = p_w * (actual_selection.size() > 10 ? 10 : actual_selection.size());
          for (std::deque<Person *>::iterator it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
            float mx, my;
            mx = angle.x * ((p_w*3*FormationX)-t_w/2);
            my = angle.y * ((p_w*3*FormationX)-t_w/2);

            mx -= or_angle.x * ((p_w*3) * FormationY);
            my -= or_angle.y * ((p_w*3) * FormationY);

            if (actual_map->IsFree(tx+mx, ty+my)) {
              if (ActualCommand == COMMAND_ATTACK) (*it)->TargetSweep(tx+mx, ty+my);
              else (*it)->TargetWalk(tx+mx, ty+my);
            }
            else {
              if (ActualCommand == COMMAND_ATTACK) (*it)->TargetSweep(tx, ty);
              else (*it)->TargetWalk(tx, ty);
            }
            FormationX+=1;

            if (FormationX > 10) {
              FormationX=0;
              FormationY+=1;
            }
          }
        }
      }
      ActualCommand=0;
    }
  }
}



void SelectDoubleClick() {
  DeselectAllPeople();
  std::deque<Person *>::iterator it;
  int tp;
  tp = ActualOver->GetType();
  for (it=persons.begin(); it!=persons.end(); it+=1) {
    if (((*it)->IsMine()) && (!(*it)->IsUnconscious()) && ((*it)->GetType() == tp) && ((*it)->InsideScreen())) {
      (*it)->Select();
    }
  }
}



bool ComplentaryScreens() {
  if (ShowScore) return false;
  if (ShowHelp) return false;
  if (ShowBriefing) return false;
  return true;
}


void GScene_Game::update() {
  cursor = cursor_normal;
  Pause = 0;
  ActualOver = NULL;

  tooltip_text="";

  UpdateGlobalZoomFactor();
  poll_my_keyboard();
  UpdateDelta();
  if ((ComplentaryScreens())) {
    update_key_camera();
    update_camera();
  }

  if (EditorMode) {
    UpdateEditor();
  }


  if (DebugMode) {
    if (Keyboard_Recently_Input[ALLEGRO_KEY_F1]) {
      EditorMode = (EditorMode == 0 ? 1 : 0);
    }
    if (Keyboard_Recently_Input[ALLEGRO_KEY_F7]) {
      MissionCompleted = 1;
      MissionCompletedOpacity=0;
      WaitToScore = 200;
    }
  }

  if ((!EditorMode) && (ComplentaryScreens())) {
  if ((mouse_x < GUI_LIMIT) && (ActualPower==-1)) {
    if ((Keyboard_Active[ALLEGRO_KEY_MOUSE_LCLICK]) && (ActualRectX==-1)) {
      ActualRectX = mouse_x+RSW(Camera_X);
      ActualRectY = mouse_y+RSH(Camera_Y);
    }
    if (Keyboard_Time_Pressed[ALLEGRO_KEY_MOUSE_LCLICK] > 6) {
      ActualRectFX = mouse_x+RSW(Camera_X);
      ActualRectFY = mouse_y+RSH(Camera_Y);
      RectangleSelection=true;
    }
    if ((Keyboard_Recently_Released[ALLEGRO_KEY_MOUSE_LCLICK]) && (RectangleSelection)) {
      DeselectAllPeople();
      SelectByRect();
    }
  }
  else  {
    RectangleSelection = false;
  }
  }

  if (ComplentaryScreens()) {

  ActualTime += DeltaTime;

  std::deque<Object *>::iterator ito;
  for (ito = GameObjects.begin(); ito!=GameObjects.end(); ito+=1) {
    (*ito)->Update();
  }
  UpdateProjectiles();
  UpdateParticles();
  UpdateRiotSound();

  UpdatePowers();

  }

  if (!Keyboard_Active[ALLEGRO_KEY_MOUSE_LCLICK]) RectangleSelection=false;


  UpdateObjectZSorting();

  if (Keyboard_Recently_Input[ALLEGRO_KEY_1]) if (Keyboard_Active[ALLEGRO_KEY_LCTRL]) SetGroup(0); else SelectGroup(0);
  if (Keyboard_Recently_Input[ALLEGRO_KEY_2]) if (Keyboard_Active[ALLEGRO_KEY_LCTRL]) SetGroup(1); else SelectGroup(1);
  if (Keyboard_Recently_Input[ALLEGRO_KEY_3]) if (Keyboard_Active[ALLEGRO_KEY_LCTRL]) SetGroup(2); else SelectGroup(2);
  if (Keyboard_Recently_Input[ALLEGRO_KEY_4]) if (Keyboard_Active[ALLEGRO_KEY_LCTRL]) SetGroup(3); else SelectGroup(3);
  if (Keyboard_Recently_Input[ALLEGRO_KEY_5]) if (Keyboard_Active[ALLEGRO_KEY_LCTRL]) SetGroup(4); else SelectGroup(4);
  if (Keyboard_Recently_Input[ALLEGRO_KEY_6]) if (Keyboard_Active[ALLEGRO_KEY_LCTRL]) SetGroup(5); else SelectGroup(5);
  if (Keyboard_Recently_Input[ALLEGRO_KEY_7]) if (Keyboard_Active[ALLEGRO_KEY_LCTRL]) SetGroup(6); else SelectGroup(6);
  if (Keyboard_Recently_Input[ALLEGRO_KEY_8]) if (Keyboard_Active[ALLEGRO_KEY_LCTRL]) SetGroup(7); else SelectGroup(7);



  GetCurrentSelection();
  if (ComplentaryScreens()) {
    UpdateOrdering();


  std::deque<Person *>::iterator it;
  int count;
  count = 0;
  ActualPortrait=-1;
  int mx;
  mx = SCREEN_W-RSW(180);
  for (it=actual_selection.begin(); it!=actual_selection.end(); it+=1) {
    if ((*it)->GetPortrait() != NULL) {
      CacheBitmap *cb;
      cb = (*it)->GetPortrait();

      if (actual_selection.size() > 1) {
        int tx, ty;
        tx = count % 3;
        ty = count / 3;
        float x, y, fx, fy;
        x = mx+RSW(15)+tx*RSW(55);
        y = RSH(122)+ty*RSH(53);
        fx = x+RSW(40);
        fy = y+RSH(40);

        if (inside_rect(mouse_x, mouse_y, x, y, fx, fy)) {
          ActualPortrait = count;
          if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
            DeselectAllPeople();
            (*it)->Select();
            GetCurrentSelection();
            break;
          }
        }
      }
    }
    count+=1;
    if (count > 17) break;
  }


  for (int i=0; i!=9; i+=1) {
    command_buttons[i]->hide();
    if (actual_selection.size() > 0) {
      if (actual_selection[0]->IsMine()) {
        if (i==0) command_buttons[i]->show();
        if ((i==1) && (CanGuard)) command_buttons[i]->show();
        if (i==2) command_buttons[i]->show();
      }
    }
    if (actual_selection.size() > 1) {
      if (i==5) command_buttons[i]->show();
      if (i==6) command_buttons[i]->show();
      if (i==7) command_buttons[i]->show();
      if (i==8) command_buttons[i]->show();
    }
    command_buttons[i]->update();

    if ((command_buttons[i]->is_active()) && (command_buttons[i]->is_visible())) {
      if (i==0) tooltip_text="(A)ttack - Attack a particular unit or attack everyone in the way.";
      if (i==1) tooltip_text="Guar(D) - Switch to Guard Mode. The Unit can't be pushed, but it can't move. Damage is reduced.";
      if (i==2) tooltip_text="(S)top - Stop the Units from whatever they're doing.";

      if (i==5) tooltip_text="No Formation - The units will just move to the target.";
      if (i==6) tooltip_text="Rectangle Formation - The units will form a Rectangle.";
      if (i==7) tooltip_text="Line Formation - The units will form a Line.";
      if (i==8) tooltip_text="Spread Formation - The units will form a wide rectangle.";
    }
  }

  ActualOverPower=-1;

  for (int i=0; i!=4; i+=1) {
    float tx, ty;
    ALLEGRO_BITMAP *bit;
    if (i == 0) {tx = mx + RSW(48); ty = RSH(675);}
    if (i == 1) {tx = mx + RSW(130); ty = RSH(675);}
    if (i == 2) {tx = mx + RSW(48); ty = RSH(732);}
    if (i == 3) {tx = mx + RSW(130); ty = RSH(732);}

    bit = powers[(i*3)];
    int rw,rh;
    rw=RSW(al_get_bitmap_width(bit));
    rh=RSH(al_get_bitmap_height(bit));
    if (ActualPowers[i] > 0) {
      if (inside_rect(mouse_x, mouse_y, tx-rw/2, ty-rh/2, tx+rw/2,ty+rh/2)) {
        ActualOverPower = i;
        if (i==0) tooltip_text="Flash Grenade - Unleash this brilliant Christmas decoration to doom your enemies into blindness.";
        if (i==1) tooltip_text="Smoke Grenade - Surround the insurgents with the annoying smoke these artifacts possess.";
        if (i==2) tooltip_text="Suprise! - Leave a gift packed with a nice surprise of peace-keeping automated guards.";
        if (i==3) tooltip_text="Merry Christmas - Summon the red-hatted lord to wreak havoc between the insurgents.";
        if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
          ActualPower = i;
          ActualCommand = 0;
        }
      }
    }
  }


  if (Keyboard_Recently_Input[ALLEGRO_KEY_ESCAPE]) {
    ActualCommand = 0;
    ActualPower = -1;
  }

  MissionCheckDelay -= DeltaTime;
  if (MissionCheckDelay < 0) {
    MissionCheckDelay = 180;
    CheckObjectives();
  }

  if (actual_map->GetWeather()) GameWeather->Update();

  }

  if (ActualPower != -1) cursor = cursor_power[ActualPower];

  if (al_key_down(&keyb, ALLEGRO_KEY_F12)) {
    exit_confirm->main();
  }

  if (Keyboard_Recently_Input[ALLEGRO_KEY_F11]) change_map(GameLevels[ActualLevel], true);


  if (MissionFailed) {
    MissionFailedOpacity += 0.02 * DeltaTime;
    if (MissionFailedOpacity < 0) MissionFailedOpacity = 0;
    if (MissionFailedOpacity > 1.0) MissionFailedOpacity=1.0;

    WaitToRestart -= DeltaTime;
    if (WaitToRestart <= 0) {
      change_map(GameLevels[ActualLevel], true);
    }
  }


  if (MissionCompleted) {
    MissionCompletedOpacity += 0.02 * DeltaTime;
    if (MissionCompletedOpacity < 0) MissionCompletedOpacity = 0;
    if (MissionCompletedOpacity > 1.0) MissionCompletedOpacity=1.0;

    WaitToScore -= DeltaTime;
    if ((WaitToScore < 0) && (ComplentaryScreens())) {
      WaitToScore=0;
      ScoreOpacity=0.0;
      ActualTime = ActualTime / 60.0;
      ShowScore=1;
      CheckHiscoreTable();
    }
    if (ShowScore) {
      cursor = cursor_normal;
      ScoreOpacity += 0.01*DeltaTime;
      if (ScoreOpacity > 1.0) {
        ScoreOpacity=1.0;
        if (HSIndex < 4) {
          if (HSWaitForNext == 0) {
            if (HSOpacity[HSIndex] == 0) al_play_sample(chalk[(randn(2)-1)], 1.3, 0.5, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL);
            HSOpacity[HSIndex] += 0.07*DeltaTime;
          }
          else {
            HSWaitForNext-=DeltaTime;
            if (HSWaitForNext < 0) HSWaitForNext = 0;
          }
          if (HSOpacity[HSIndex] > 1.0) {
            HSOpacity[HSIndex]=1.0;
            HSIndex+=1;
            if (HSIndex == 4) HSWaitForNext=120;
            else HSWaitForNext=50;
          }
        }
        else {
          if (HSWaitForNext == 0) {
            if (ScoresNextOpacity == 0) al_play_sample(next_appear, 1.2, 0.5, 1.0, ALLEGRO_PLAYMODE_ONCE, NULL);
            ScoresNextOpacity += 0.07*DeltaTime;
            if (ScoresNextOpacity > 1.0) ScoresNextOpacity = 1.0;
            ScoresNextOver = false;
            float tx, ty, rw, rh;
            rw = RSW(900);
            rh = RSH(613);
            tx = SCREEN_W/2-rw/2+RSW(795); ty = SCREEN_H/2-rh/2+RSH(555);
            rw = RSW(al_get_bitmap_width(results_next)); rh = RSH(al_get_bitmap_height(results_next));
            if (!MapChange) {
              if (inside_rect(mouse_x, mouse_y, tx-rw/2, ty-rh/2, tx+rw/2, ty+rh/2)) {
                ScoresNextOver = true;
                tooltip_text = "Continue to the next Level!";
                if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
                  ChangeToNextMap();
                }
              }
            }
          }
          else {
            HSWaitForNext-=DeltaTime;
            if (HSWaitForNext < 0) HSWaitForNext = 0;
          }
        }
      }
    }
  }
/*

  if ((!ShowScore) && (!ShowBriefing)) {
    if ((inside_rect(mouse_x, mouse_y, RSW(214), 0, RSW(540), RSH(28))) && (!StoryboardShowing)) {
      StoryboardShowing = true;
    }
    else if (StoryboardShowing) {
      if (inside_rect(mouse_x, mouse_y, RSW(20), 0, RSW(700), RSH(266))) {
        StoryboardShowing=true;
      }
      else {
        StoryboardShowing=false;
      }
    }
  }
*/

  if (tooltip_text != "") {
    tooltip_opacity += 0.07*DeltaTime;
    if (tooltip_opacity > 1.0) tooltip_opacity = 1.0;
  }
  if (tooltip_text == "") {
    tooltip_opacity -= 0.07*DeltaTime;
    if (tooltip_opacity < 0.0) tooltip_opacity = 0.0;
  }

  BlackFade += BlackFadeDir*DeltaTime;
  if (BlackFade < 0) BlackFade=0;
  if (BlackFade > 1) BlackFade=1;

  if ((MapChange) && (BlackFade == 1.0)) {
    ActualLevel+=1;
    MapChange=false;
    change_map();
  }

  if (ShowBriefing) {
    BriefingOpacity += 0.03*DeltaTime;
    float tx, ty, rw, rh;
    rw = RSW(al_get_bitmap_width(briefing_bit));
    rh = RSH(al_get_bitmap_height(briefing_bit));

    tx = SCREEN_W/2-rw/2+RSW(850); ty = SCREEN_H/2-rh/2+RSH(600);
    rw = RSW(al_get_bitmap_width(results_next)); rh = RSH(al_get_bitmap_height(results_next));
    ScoresNextOver=false;
    if (inside_rect(mouse_x, mouse_y, tx-rw/2, ty-rh/2, tx+rw/2, ty+rh/2)) {
      ScoresNextOver = true;
      tooltip_text = "Proceed";
      if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
        ShowBriefing=false;
      }
    }
  }

  else {
    BriefingOpacity -= 0.03*DeltaTime;
  }


  if (ShowHelp) {
    HelpOpacity += 0.03*DeltaTime;
    float tx, ty, rw, rh;
    rw = RSW(al_get_bitmap_width(help_bit)); rh = RSH(al_get_bitmap_height(help_bit));
    tx = SCREEN_W/2-rw/2+RSW(910); ty = SCREEN_H/2-rh/2+RSH(660);
    rw = RSW(90); rh = RSH(56);
    HelpRightOver=false;
    HelpLeftOver=false;
    if (inside_rect(mouse_x, mouse_y, tx-rw/2, ty-rh/2, tx+rw/2, ty+rh/2)) {
      HelpRightOver = true;
      if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
        HelpIndex+=1;
        if (HelpIndex >= HELP_SCREENS) HelpIndex=HELP_SCREENS-1;
      }
    }

    rw = RSW(al_get_bitmap_width(help_bit)); rh = RSH(al_get_bitmap_height(help_bit));
    tx = SCREEN_W/2-rw/2+RSW(90); ty = SCREEN_H/2-rh/2+RSH(660);
    rw = RSW(90); rh = RSH(56);
    if (inside_rect(mouse_x, mouse_y, tx-rw/2, ty-rh/2, tx+rw/2, ty+rh/2)) {
      HelpLeftOver = true;
      if (Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) {
        HelpIndex-=1;
        if (HelpIndex < 0) HelpIndex=0;
      }
    }
  }
  else {
    HelpOpacity -= 0.03*DeltaTime;
  }

  if (HelpOpacity < 0.0) HelpOpacity = 0.0;
  if (HelpOpacity > 1.0) HelpOpacity = 1.0;


  if ((!ShowHelp) && (!ShowScore) && (!EditorMode)) {
    if (Keyboard_Recently_Input[ALLEGRO_KEY_F8]) ShowBriefing=(ShowBriefing ? 0 : 1);
  }

  if ((!ShowScore) && (!EditorMode) && (!ShowBriefing)) {
    if (Keyboard_Recently_Input[ALLEGRO_KEY_F9]) ShowHelp=(ShowHelp ? 0 : 1);
  }

  if (BriefingOpacity < 0.0) BriefingOpacity = 0.0;
  if (BriefingOpacity > 1.0) BriefingOpacity = 1.0;

  DelayAfterDoubleClick -= 1;
  if (DelayAfterDoubleClick < 0) DelayAfterDoubleClick = 0;

  if (mouse_x < GUI_LIMIT) {
    if ((ActualOver != NULL) && (Keyboard_Double_Pressed[ALLEGRO_KEY_MOUSE_LCLICK])) {
      SelectDoubleClick();
      DelayAfterDoubleClick=10;
    }
    if ((Keyboard_Recently_Input[ALLEGRO_KEY_MOUSE_LCLICK]) && (ActualOver==NULL) && (ActualPower==-1)) DeselectAllPeople();
  }


/*
  if ((StoryboardShowing) && (!ShowScore)) {
    float ty;
    StoryboardY += ((-StoryboardY) / 10.0)*DeltaTime;
    if (StoryboardY > 0) StoryboardY=0;
  }
  else {
    float ty;
    ty = -RSH(al_get_bitmap_height(storyboard_bit))+RSH(StoryboardHandH);
    StoryboardY -= (mabs(ty-StoryboardY) / 10.0)*DeltaTime;
    if (StoryboardY < ty) StoryboardY=ty;
  }

  storyboard_back->set_position(RSW(45), StoryboardY + RSH(200));
  storyboard_next->set_position(RSW(330), StoryboardY + RSH(200));
  storyboard_camera->set_position(RSW(630), StoryboardY + RSH(200));

  storyboard_back->update();
  storyboard_next->update();
  storyboard_camera->update();
*/
  FramesUpdated+=1;
}

void SetFormationNone() {ActualFormation=FORMATION_NONE;}
void SetFormationRectangle() {ActualFormation=FORMATION_RECTANGLE;}
void SetFormationLine() {ActualFormation=FORMATION_LINE;}
void SetFormationSpread() {ActualFormation=FORMATION_SPREAD;}


bool CreatedMap=0;



void change_map(std::string filename, bool SameLevel) {

  SameLevel=false;
  if (ActualLevel >= GAME_LEVELS) {
    BlackFadeDir=-0.1;
    Scene=SCENE_END;
    return;
  }

  if (MaximumAchievedLevel < ActualLevel+1) MaximumAchievedLevel=ActualLevel+1;
  Savegame();

  filename = GameLevels[ActualLevel];


  if (CreatedMap) {
    for(std::deque<Person *>::iterator it=persons.begin(); it != persons.end(); it++) {
      delete *it;
    }
    GameObjects.clear();
    projectiles.clear();
    persons.clear();
    actual_selection.clear();


    delete actual_map;
    std::deque<SpawnPoint *>::iterator it;
    for (it=spawn_points.begin(); it!=spawn_points.end(); it+=1) {
      delete (*it);
    }
    spawn_points.clear();

    std::deque<LightPoint *>::iterator itl;
    for (itl=light_points.begin(); itl!=light_points.end(); itl+=1) {
      delete (*itl);
    }
    light_points.clear();
    DeleteParticleList();
  }

  actual_map = new Map();
  actual_map->Load(filename);

  CopyMapStoryboardsToEditor();


  ObjectZOrder_list=NULL;

  for (int i=0; i!=8; i+=1) {GroupControl[i].clear();}

  CreatedMap=1;
  ShowScore=0;
  MissionCompleted=0;
  MissionFailed=0;
  MissionCompletedOpacity=0;
  ScoreOpacity=0.0;
  ScoresNextOpacity=0.0;

  HSWaitForNext=0;

  ResetPowers();

  BlackFade=1.0;
  BlackFadeDir=-0.01;

  for (int i=0; i!=4; i+=1) ActualPowers[i] = MapPowers[i];

  ActualStoryboard=0;
  CopyStatsFromMap();

  SpawnPeople();

  StoryboardY = -RSH(al_get_bitmap_height(storyboard_bit))+RSH(StoryboardHandH);

  BriefingOpacity=0;
  if (!SameLevel) ShowBriefing = true;

  briefing_text.clear();
  std::string full_text;
  for (int i=0; i!=8; i+=1) {
    full_text += EditorStoryboards[0].paragraph[i]+" ";
  }

  briefing_text = turn_to_paragraph(hiscore_font, full_text, RSW(815));


  ActualTime=0;
}


bool GameCreated=0;


void AcceptQuit() {
  exit_confirm->Quit();
  Scene=-1;
}

void CancelQuit() {
  exit_confirm->Quit();
}


void SaveMap() {
  for (int i=0; i!=StoryboardSize; i+=1) actual_map_storyboard[i].CopyFromEditor(&(EditorStoryboards[i]));

  actual_map->Save(map_file_name->get_text());

  AL_MESSAGE("Map was succesfully saved!");
}

void LoadMap() {
  change_map(map_file_name->get_text());
}


void create_game() {
  if (GameCreated) return;
  GameCreated=1;

  editor_cursor=load_cache_bitmap("Graphics/Editor/Cursor.png");
  GuiButton *gb;
  GuiTypeBox *gtb;
  GuiTextElement *gt;
  GuiElement *ge;

  for (int i=0; i!=9; i+=1) {

    void (*func) ();
    gb = new GuiButton();
    int tx, ty;
    tx = i % 3;
    ty = i / 3;
    func = NULL;
    if (i == 0) func = &SetAttackCommand;
    if (i == 1) func = &OrderGuard;
    if (i == 2) func = &OrderStop;
    if (i == 5) func = &SetFormationNone;
    if (i == 6) func = &SetFormationRectangle;
    if (i == 7) func = &SetFormationLine;
    if (i == 8) func = &SetFormationSpread;


    gb->init(SCREEN_W-RSW(180)+RSW(8)+tx*RSW(55), RSH(452)+ty*RSH(55), RSW(54), RSH(54), func, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
    gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
    gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
    GuiElement *gt;
    ge = new GuiElement();
    ge->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h());
    if (i==0) ge->set_base_bit(load_cache_bitmap("Graphics/GUI/OrderAttack.png"));
    if (i==1) ge->set_base_bit(load_cache_bitmap("Graphics/GUI/OrderShield.png"));
    if (i==2) ge->set_base_bit(load_cache_bitmap("Graphics/GUI/OrderStop.png"));
    if (i==5) ge->set_base_bit(load_cache_bitmap("Graphics/GUI/OrderNone.png"));
    if (i==6) ge->set_base_bit(load_cache_bitmap("Graphics/GUI/OrderRectangle.png"));
    if (i==7) ge->set_base_bit(load_cache_bitmap("Graphics/GUI/OrderLine.png"));
    if (i==8) ge->set_base_bit(load_cache_bitmap("Graphics/GUI/OrderSpread.png"));
    gb->set_element(ge);
    command_buttons[i] = gb;
  }



  gb = new GuiButton();
  gb->init(400, 100, 99, 32, &SaveMap, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
  gt = new GuiTextElement();
  gt->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h(), game_font, "Save Map", GUI_TEXT_ALIGN_CENTER);
  gb->set_element(gt);
  save_map_button = gb;

  gb = new GuiButton();
  gb->init(510, 100, 99, 32, &LoadMap, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
  gt = new GuiTextElement();
  gt->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h(), game_font, "Load Map", GUI_TEXT_ALIGN_CENTER);
  gb->set_element(gt);
  load_map_button = gb;


  gb = new GuiButton();
  gb->init(0, 0, 50, 50, &StoryboardBack, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
  ge = new GuiElement();
  ge->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h());
  //ge->set_base_bit(load_cache_bitmap("Graphics/GUI/Camera.png"));
  gb->set_element(ge);
  storyboard_back = gb;

  gb = new GuiButton();
  gb->init(0, 0, 50, 50, &StoryboardNext, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
  ge = new GuiElement();
  ge->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h());
  //ge->set_base_bit(load_cache_bitmap("Graphics/GUI/Camera.png"));
  gb->set_element(ge);
  storyboard_camera = gb;

  gb = new GuiButton();
  gb->init(0, 0, 50, 50, &StoryboardCamera, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
  ge = new GuiElement();
  ge->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h());
  //ge->set_base_bit(load_cache_bitmap("Graphics/GUI/Camera.png"));
  gb->set_element(ge);
  storyboard_next = gb;


  gtb = new GuiTypeBox();
  gtb->init(150, 100, 150, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_FILE_NAME);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Map File Name", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  map_file_name = gtb;

  gtb = new GuiTypeBox();
  gtb->init(150, 140, 250, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_ALL);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Map Internal Name", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  map_internal_name = gtb;


  gtb = new GuiTypeBox();
  gtb->init(150, 200, 50, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_NUMBERS);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Flash Grenades", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  editor_powers_box[0] = gtb;

  gtb = new GuiTypeBox();
  gtb->init(150, 240, 50, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_NUMBERS);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Smoke Grenades", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  editor_powers_box[1] = gtb;

  gtb = new GuiTypeBox();
  gtb->init(150, 280, 50, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_NUMBERS);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Special Gift", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  editor_powers_box[2] = gtb;

  gtb = new GuiTypeBox();
  gtb->init(150, 320, 50, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_NUMBERS);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Merry Christmas", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  editor_powers_box[3] = gtb;


  gtb = new GuiTypeBox();
  gtb->init(150, 370, 50, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_NUMBERS);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Map Width", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  map_width = gtb;


  gtb = new GuiTypeBox();
  gtb->init(150, 400, 50, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_NUMBERS);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Map Height", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  map_height = gtb;

  gtb = new GuiTypeBox();
  gtb->init(150, 500, 50, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, -1, KEY_TO_CHAR_MODE_NUMBERS);
  gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorTypeBox.png"));
  gt = new GuiTextElement();
  gt->init(20, gtb->get_y(), 175, gtb->get_h(), game_font, "Map Weather", GUI_TEXT_ALIGN_LEFT, al_map_rgb(255, 255, 255));
  gtb->attach_element(gt);
  map_weather = gtb;



  gb = new GuiButton();
  gb->init(150, 430, 99, 32, &ApplyChangesToMap, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
  gt = new GuiTextElement();
  gt->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h(), game_font, "Apply Changes", GUI_TEXT_ALIGN_CENTER);
  gb->set_element(gt);
  apply_changes = gb;


  for (int i=0; i!=8; i+=1) {
    gtb = new GuiTypeBox();
    gtb->init(250, 200+i*25, 700, 25, load_cache_bitmap("Graphics/GUI/EditorMarker.png"), game_font, 255, KEY_TO_CHAR_MODE_ALL);
    gtb->set_base_bit(load_cache_bitmap("Graphics/GUI/EditorSheet.png"));
    storyboard_boxes[i] = gtb;
  }

  for (int i=0; i!=12; i+=1) {
    void (*func) ();
    func = NULL;
    if (i == 0) func = &SetActualStoryboard_1;
    if (i == 1) func = &SetActualStoryboard_2;
    if (i == 2) func = &SetActualStoryboard_3;
    if (i == 3) func = &SetActualStoryboard_4;
    if (i == 4) func = &SetActualStoryboard_5;
    if (i == 5) func = &SetActualStoryboard_6;
    if (i == 6) func = &SetActualStoryboard_7;
    if (i == 7) func = &SetActualStoryboard_8;
    if (i == 8) func = &SetActualStoryboard_9;
    if (i == 9) func = &SetActualStoryboard_10;
    if (i == 10) func = &SetActualStoryboard_11;
    if (i == 11) func = &SetActualStoryboard_12;

    gb = new GuiButton();
    gb->init(252+58*i, 406, 58, 32, func, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
    gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
    gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
    gt = new GuiTextElement();
    gt->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h(), game_font, ToString(i), GUI_TEXT_ALIGN_CENTER);
    gb->set_element(gt);
    storyboard_buttons[i] = gb;
  }

  gb = new GuiButton();
  gb->init(252, 440, 150, 32, &AddStoryboard, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
  gt = new GuiTextElement();
  gt->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h(), game_font, "Add Storyboard", GUI_TEXT_ALIGN_CENTER);
  gb->set_element(gt);
  storyboard_add = gb;

  gb = new GuiButton();
  gb->init(420, 440, 150, 32, &DeleteStoryboard, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));
  gt = new GuiTextElement();
  gt->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h(), game_font, "Delete Storyboard", GUI_TEXT_ALIGN_CENTER);
  gb->set_element(gt);
  storyboard_delete = gb;

  gb= new GuiButton();
  gb->init(420, 500, 50, 50, &SetStoryboardCamera, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));

  ge = new GuiElement();
  ge->init(gb->get_x(), gb->get_y(), gb->get_w(), gb->get_h());
  ge->set_base_bit(load_cache_bitmap("Graphics/GUI/Camera.png"));
  gb->set_element(ge);
  camera_button = gb;


  exit_confirm = new GuiTakeoverElement();
  exit_confirm->init(0, 0, SCREEN_W, SCREEN_H);

  ge = new GuiElement();
  CacheBitmap *cb;
  cb=load_cache_bitmap("Graphics/GUI/QuitConfirm.png");
  float rw, rh;
  rw=RSW(cb->Width());
  rh=RSH(cb->Height());
  ge->init(SCREEN_W/2-rw/2, SCREEN_H/2-rh/2, rw, rh);
  ge->set_base_bit(cb);
  exit_confirm->attach_element(ge);

  gb= new GuiButton();
  gb->init(SCREEN_W/2-RSW(126), SCREEN_H/2-RSH(10), RSW(100), RSH(100), &AcceptQuit, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));

  ge = new GuiElement();
  cb = load_cache_bitmap("Graphics/GUI/Y.png");
  rw=RSW(cb->Width());
  rh=RSH(cb->Height());
  ge->init(gb->get_x()+RSW(50)-rw/2, gb->get_y()+RSH(50)-rh/2, rw, rh);
  ge->set_base_bit(cb);
  gb->set_element(ge);
  gb->set_shortcut(ALLEGRO_KEY_ENTER);
  exit_confirm->attach_element(gb);


  gb= new GuiButton();
  gb->init(SCREEN_W/2+RSW(26), SCREEN_H/2-RSH(10), RSW(100), RSH(100), &CancelQuit, load_cache_bitmap("Graphics/GUI/ButtonOn.png"));
  gb->set_base_bit(load_cache_bitmap("Graphics/GUI/Button.png"));
  gb->set_sound(load_cache_sample("Sounds/Click.ogg"));

  ge = new GuiElement();
  cb = load_cache_bitmap("Graphics/GUI/N.png");
  rw=RSW(cb->Width());
  rh=RSH(cb->Height());
  ge->init(gb->get_x()+RSW(50)-rw/2, gb->get_y()+RSH(50)-rh/2, rw, rh);
  ge->set_base_bit(cb);
  gb->set_element(ge);
  gb->set_shortcut(ALLEGRO_KEY_ESCAPE);
  exit_confirm->attach_element(gb);


  command_buttons[0]->set_shortcut(ALLEGRO_KEY_A);
  command_buttons[1]->set_shortcut(ALLEGRO_KEY_D);
  command_buttons[2]->set_shortcut(ALLEGRO_KEY_S);
  ActualFormation=FORMATION_NONE;
  al_set_new_bitmap_flags(ALLEGRO_NO_PRESERVE_TEXTURE);
  LightMap = al_create_bitmap(SCREEN_W, SCREEN_H);
  al_set_new_bitmap_flags(0);

  GameWeather = new GameWeatherClass();
  GameWeather->CreateParticles(200);
  GameWeather->SetType(WEATHER_TYPE_SNOWY);
}


void GScene_Game::main() {
  create_game();
  change_map();
  ChangeGlobalMusic(music_game);
  ShowHelp=false;
  al_start_timer(timer);
  global_log->LogMessage("Game Set Up succesfull.");
  ResetDelta();
  update();
  global_log->LogMessage("First Update was succesfull.");
  while (Scene == SCENE_GAME) {
    ALLEGRO_EVENT event;
    al_wait_for_event(queue, &event);
    if (event.type == ALLEGRO_EVENT_TIMER) {
      draw();
      update();
    }
  }

  al_set_audio_stream_gain(riot, 0);
}
