unit uZepelin;

interface
uses
  zglHeader, uMaterials, uList, LexUtils,
  uMap, uBomb;

type
  TZepelinList = class(TList)
    Map : TMap;
    Bombs : TBombList;
    constructor Create(const pMap : TMap; const pBombs : TBombList); overload;
    function  Add(E : TZepelinList) : TList; overload;
    procedure InBoom(bX, bY, X0, Y0, X1, Y1 : Single); virtual;
  end;

  TZepelin = class(TZepelinList)
    pX, pY, mX, mY, bW, bH, Live : Single;
    W, H : Integer;
      
    fiTimer : Integer;

    blinkA : byte;
    blink, blinkP : Integer;
    constructor Create;
    procedure Init; override;
    procedure Draw; override;
    procedure Update; override;
    procedure InBoom(bX, bY, X0, Y0, X1, Y1 : Single); override;
  end;
implementation

{ TZepelinList }

function TZepelinList.Add(E: TZepelinList): TList;
begin
  E.Map := (Root as TZepelinList).Map;
  E.Bombs := (Root as TZepelinList).Bombs;
  Result := inherited Add(E);
end;

constructor TZepelinList.Create(const pMap: TMap; const pBombs: TBombList);
begin
  inherited Create;
  Map := pMap;
  Bombs := pBombs;
end;

procedure TZepelinList.InBoom(bX, bY, X0, Y0, X1, Y1: Single);
begin

end;

{ TZepelin }

constructor TZepelin.Create;
begin
  W := 128;
  H := 64;
  bW := W * 0.65;
  bH := H * 0.65;

end;

procedure TZepelin.Init;
begin
  if random(2) > 0 then
  begin
    pX := - W * (1 + random(15));
    mX := + 1;
  end
  else
  begin
    pX := Map.WinW + W * (1 + random(15));
    mX := - 1;
  end;
  pY := 15 + random(8) * 15;
  Live := 100;
end;

procedure TZepelin.Draw;
begin
  ssprite2d_Draw(m_zepelin, pX - W div 2, pY - H div 2, W, H, 0);

  if blink > 0 then
  begin
    fx_SetColorMode( FX_COLOR_SET );
    fx2d_SetColor( $FFFFFF );
    ssprite2d_Draw(m_zepelin, pX - W div 2, pY - H div 2, W, H, 0,  blinkA, FX_BLEND or FX_COLOR);
    fx_SetColorMode( FX_COLOR_MIX );
  end;

  pr2d_Rect(pX - 32, pY - H div 2, 64, 8, $FF0000, 250, PR2D_FILL);
  if Live > 0 then
    pr2d_Rect(pX - 32, pY - H div 2, 64 * Live/100, 8, $10FF10, 240, PR2D_FILL);

  Next.Draw;
end;

procedure TZepelin.Update;
begin
  Next.Update;

  pX := pX + mX;
  pY := pY + mY;

  if Live > 0 then
  begin
    if (mX < 0) and (pX < -W) then
      mX := 1
    else
    if (mX > 0) and (pX > Map.WinW + W) then
      mX := -1;

    if fiTimer > 0 then
      fiTimer := fiTimer - 1
    else
      begin
      Bombs.Add(TBomb.Create(pX, pY));
      fiTimer := 100 + random(10) * 25;
    end;
  end;

  if blink > 0 then
  begin
    blinkA := blinkA + blinkP;
    if ((blinkP > 0) and (blinkA > 100))
    or ((blinkP < 0) and (blinkA < 030)) then
    begin
      BlinkP := -BlinkP;
      blink := blink - 1;
    end;
  end;

  if Live < 0 then
    mY := mY + 0.001;
end;

procedure TZepelin.InBoom(bX, bY, X0, Y0, X1, Y1: Single);
var
  Dem : Single;
begin
  (Next as TZepelinList).InBoom(bX, bY, X0, Y0, X1, Y1);

  if (blink <= 0) and (pX + bW >= X0) and (pY + bH >= Y0) and (pX - bW <= X1) and (pY - bH <= Y1) then
  begin
    Dem := W - PointDistanceXY(pX - bX, pY - bY);
    if Dem > 0 then
    begin
      Live := Live - Dem;
      if Live > 0 then
      begin
        blink  := 11;
        blinkA := 20;
        blinkP := +20;
       // GSound.PlaySound(8);
      end
    end;
  end;
end;

end.
