unit g_Camera;

interface
uses
  g_Types, g_Data,
  {$INCLUDE uses.inc};

procedure Camera_Create(self : zCamera);
procedure Camera_Update(self : zCamera; time : float); overload;
procedure Camera_Update(self : zCamera; pos : izPosition_f; time : float); overload;
implementation

procedure Camera_Create(self : zCamera);
begin
  self^.PastTime := 0;
  self^.SpeedX    := 0;
  self^.SpeedY    := 0;
  self^.Pos[0]   := 0;
  self^.Pos[1]   := 0;
  self^.left[0]  := 0;
  self^.left[1]  := 0;
  self^.right[0] := 0;
  self^.right[1] := 0;
  self^.target   := 0;
  self^.CurPos := Cur.pos;
end;

procedure Camera_Update(self : zCamera; time : float);
var
 speedX,SpeedY : float;
begin
  case self^.Typ of
    ctCharView : begin
      if World.Characters[self^.target].Pos[0] < ScrCenterX then self^.pos[0] := 0 else
      if World.Characters[self^.target].Pos[0] < World.MapSize[0]-ScrCenterX then
       self^.pos[0] := -trunc(World.Characters[self^.target].Pos[0]-ScrCenterX);

      if World.Characters[self^.target].Pos[1] < ScrCenterY then self^.pos[1] := 0 else
      if World.Characters[self^.target].Pos[1] < World.MapSize[1]-ScrCenterY then
       self^.pos[1] := -trunc(World.Characters[self^.target].Pos[1]-ScrCenterY);
      end;
    ctFree : begin
        SpeedX := self^.SpeedX;
        SpeedY := self^.SpeedY;
        if Cur.Pos[0] < 30 then self^.speedX := self^.speedX + 1800*time else
        if Cur.Pos[0] > Options.ScreenWidth-30 then self^.speedX := self^.speedX - 1800*time;

        if Cur.Pos[1] < 30 then self^.speedY := self^.speedY + 1800*time else
        if Cur.Pos[1] > Options.ScreenHeight-30 then self^.speedY := self^.speedY - 1800*time;

       self^.Pos[0] := self^.Pos[0] + self^.speedX*time;
       self^.Pos[1] := self^.Pos[1] + self^.speedY*time;

      if (self^.SpeedX = SpeedX) then
      if (self^.SpeedX < 2) and (self^.SpeedX > -2) then self^.SpeedX := 0 else
      if self^.SpeedX > 0 then self.SpeedX := self^.SpeedX-1800*time else self.SpeedX := self^.SpeedX+1800*time;
      if (self^.SpeedY = SpeedY) then
      if (self^.SpeedY < 2) and (self^.SpeedY > -2) then self^.SpeedY := 0 else
      if self^.SpeedY > 0 then self.SpeedY := self^.SpeedY-1800*time else self.SpeedY := self^.SpeedY+1800*time;

       if self^.Pos[0] > 0 then begin
         self^.Pos[0] := 0;
         self^.SpeedX := 0;
       end else if self^.Pos[0] < -World.MapSize[0]+Options.ScreenWidth then
       begin
         self^.Pos[0] := -World.MapSize[0]+Options.ScreenWidth;
         self^.SpeedX := 0;
       end;
       if self^.Pos[1] > 0 then begin
         self^.Pos[1] := 0;
         self^.SpeedY := 0;
       end else if self^.Pos[1] < -World.MapSize[1]+Options.ScreenHeight then
       begin
         self^.Pos[1] := -World.MapSize[1]+Options.ScreenHeight;
         self^.SpeedY := 0;
       end;
    end;
  end;
  self^.Pos_2[0] := self^.Pos[0] - options.ScreenWidth;
  self^.Pos_2[1] := self^.Pos[1] - options.ScreenHeight;
  self^.left[0] := -trunc((self^.pos[0])/64);
  self^.left[1] := -trunc((self^.pos[1])/64);
  self^.right[0]:= -trunc((self^.pos[0]-Options.ScreenWidth)/64);
  self^.right[1]:= -trunc((self^.pos[1]-Options.ScreenHeight)/64);
  if self^.right[0] > World.MapSize_num[0]-1 then self^.right[0] := World.MapSize_num[0]-1;
  if self^.right[1] > World.MapSize_num[1]-1 then self^.right[1] := World.MapSize_num[1]-1;
end;

procedure Camera_Update(self : zCamera; pos : izPosition_f; time : float); overload;
begin
  self^.Pos[0] := self^.Pos[0] + 100*pos[0]*time;
  self^.Pos[1] := self^.Pos[1] + 100*pos[1]*time;
end;

end.
