package game.locations.celestialLockBasement;

import openfl.events.Event;
import openfl.events.MouseEvent;
import openfl.geom.Rectangle;

import base.GameSprite;

import game.locations.Location;
import game.locations.Interactive;

import aseprite.Aseprite;

/**
 *  Crate
 */
class Crate extends Interactive {
  var basement: CelestialLockBasement;

  var mode: String = 'pull_out';

  var outPosition: Rectangle;

  public function new(basement: CelestialLockBasement) {
    super();

    this.basement = basement;

    initBitmap('assets/locations/celestialLockBasement/crate.png');

    addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
    addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
    addEventListener(MouseEvent.MOUSE_OUT, onMouseUp);
  }

  override function onMouseDown(e: MouseEvent) {
    if(mode == 'pull_out') {
      outPosition = getBounds(basement);
      x = outPosition.x;
      y = outPosition.y;
      basement.addChild(this);

      startDrag(false, new Rectangle(x, y, 0, 20));
    }

    if(mode == 'pull_sides') {
      startDrag(false, new Rectangle(outPosition.x, outPosition.y + 20, 180, 0));
    }
  }

  function onMouseUp(e: MouseEvent) {
    if(mode == 'pull_out') {
      stopDrag();
      mode = 'pull_sides';

      x = outPosition.x;
      y = outPosition.y + 20;
    }

    if(mode == 'pull_sides') {
      stopDrag();
    }
  }
}

/**
 *  Elevator Button
 */
class CargoElevatorButton extends Interactive {
  var anim: Aseprite;

  public function new() {
    super(null);

    anim = new Aseprite('assets/locations/celestialLockBasement/elevator_button');
    addChild(anim);
  }

  override function action() {
    Game.currentGame.playSound('sound/elevator/button.ogg');

    var distBoard:DistributionBoard = cast Game.currentGame.getLocation(DistributionBoard);

    if(distBoard.on) {
      actionable = false;
      anim.play('on');
      dispatchEvent(new Event('call'));
      var sound = Game.currentGame.playSound('sound/elevator/move_shorter.ogg');
      sound.addEventListener(Event.SOUND_COMPLETE, function(e: Event) {
        anim.play('off');
        dispatchEvent(new Event('arrived'));
      });
    } else {
      Game.currentGame.sayRandom(['Не работает', 'Похоже лифт отклюен']);
      super.action();
    }
  }
}

/**
 *  Elevator
 */
class CargoElevator extends GameSprite {
  var doorLeft: GameSprite;
  var doorRight: GameSprite;
  var platform: GameSprite;

  public function new(crate: Crate) {
    super();

    platform = new GameSprite();

    var inside: Interactive = new Interactive();
    inside.initBitmap('assets/locations/celestialLockBasement/elevator_inside.png');
    platform.addChild(inside);

    crate.x = 7;
    crate.y = 10;
    platform.addChild(crate);

    platform.y = -200;

    addChild(platform);

    doorLeft = new GameSprite('assets/locations/celestialLockBasement/elevator_door_left.png');
    doorLeft.mouseEnabled = false;
    doorLeft.x = 3;
    doorLeft.y = 3;
    addChild(doorLeft);

    doorRight = new GameSprite('assets/locations/celestialLockBasement/elevator_door_right.png', false, -22, 0);
    doorRight.mouseEnabled = false;
    doorRight.x = 46;
    doorRight.y = 3;
    addChild(doorRight);

    var frame = new Interactive(['Хозяйственный лифт\nДаже если я помещусь в нем, все равно он управляется только снаружи']);
    frame.initBitmap('assets/locations/celestialLockBasement/elevator_frame.png');
    addChild(frame);

    var button = new CargoElevatorButton();
    button.x = 55;
    button.y = 14;
    button.addEventListener('call', function(e: Event) {
      platform.tween({ y: 0 }, 9);
      dispatchEvent(new Event('busy'));
    });
    button.addEventListener('arrived', function(e: Event) {
      open(function() {
        frame.actionable = false;
      dispatchEvent(new Event('not_busy'));
      });
    });
    addChild(button);

    var elevatorMask = new GameSprite('assets/locations/celestialLockBasement/elevator_mask.png');
    mask = elevatorMask;
    addChild(elevatorMask);
  }

  function open(callback: Void -> Void) {
    var sound = Game.currentGame.playSound('sound/elevator/doors_open.ogg');
    doorLeft.tween({ scaleX: 0 }, 1.7);
    doorRight.tween({ scaleX: 0 }, 1.7).then(callback);
  }
}

/**
 *  Window
 */
class Window extends Interactive {
  var crate: Crate;
  public function new(crate: Crate) {
    super();

    this.crate = crate;
    initBitmap('assets/locations/celestialLockBasement/windows.png');
  }

  override function action() {
    if((crate.x >= 170)&&(crate.x <= 215)) {
      Game.currentGame.setLocation(game.locations.celestialLockBasementWindow.CelestialLockBasementWindow);
    } else {
      Game.currentGame.sayRandom([
        'Слишком высоко',
        'Возможно я смогу позвать кого-то через окно, но мне не дотянуться',
        'Мне нужно встать на что-то чтобы достать до окна'
      ]);
    }
    super.action();
  }
}

/**
 *  Location
 */
class CelestialLockBasement extends Location {
  var crate: Crate;

  public function new() {
    super();

    id = 'celestialLockBasement';

    addBmpLayer('bg');

    crate = new Crate(this);

    var elevator = new CargoElevator(crate);
    elevator.x = 52;
    elevator.y = 88;
    addChild(elevator);

    var door = new Interactive(game.locations.celestialLock.CelestialLockDoor);
    door.initBitmap(bmpPath('door'));
    door.x = 286;
    door.y = 71;
    addChild(door);

    var windows = new Window(crate);
    windows.x = 175;
    windows.y = 40;
    addChild(windows);

    elevator.addEventListener('busy', function(e: Event) {
      navigation = false;
      door.actionable = false;
    });

    elevator.addEventListener('not_busy', function(e: Event) {
      navigation = true;
      door.actionable = true;
    });

    downLocation = BlankWall;
    leftLocation = DistributionBoard;
  }
}
