{$COMMAND Copy:MCP_CopyAreaToBuffer}
{$COMMAND Paste:MCP_WritePasteFunctionToLog}

type MCP_Unit =
record
  UnitType: TKMUnitType;
  Position: TKMPoint;
  Count: integer;
end;

var
  MCP_Tiles: array of TKMTerrainTileBrief;
  MCP_Units: array of MCP_Unit;

procedure MCP_T(x, y, terrain, rotation, height, obj: integer);
begin
  setLength(MCP_Tiles, Length(MCP_Tiles) + 1);

  MCP_Tiles[High(MCP_Tiles)].X := x;
  MCP_Tiles[High(MCP_Tiles)].Y := y;
  MCP_Tiles[High(MCP_Tiles)].Terrain := terrain;
  MCP_Tiles[High(MCP_Tiles)].Rotation := rotation;
  MCP_Tiles[High(MCP_Tiles)].Height := height;
  MCP_Tiles[High(MCP_Tiles)].Obj := obj;

  MCP_Tiles[High(MCP_Tiles)].UpdateTerrain := true;
  MCP_Tiles[High(MCP_Tiles)].UpdateRotation := true;
  MCP_Tiles[High(MCP_Tiles)].UpdateHeight := true;
  MCP_Tiles[High(MCP_Tiles)].UpdateObject := true;
end;

procedure MCP_A(x,y: integer; unitType: TKMUnitType);
begin
  setLength(MCP_Units, Length(MCP_Units) + 1);

  MCP_Units[High(MCP_Units)].Position.X := x;
  MCP_Units[High(MCP_Units)].Position.Y := y;
  MCP_Units[High(MCP_Units)].UnitType := unitType;
  MCP_Units[High(MCP_Units)].Count := 0;
end;

procedure MCP_F(x,y,count: integer);
begin
  setLength(MCP_Units, Length(MCP_Units) + 1);

  MCP_Units[High(MCP_Units)].Position.X := x;
  MCP_Units[High(MCP_Units)].Position.Y := y;
  MCP_Units[High(MCP_Units)].UnitType := utFish;
  MCP_Units[High(MCP_Units)].Count := 0;
end;

//Minimum version to make script shorter.
procedure T(x, y, terrain, rotation, height, obj: integer);
begin
  MCP_T(x,y,terrain,rotation,height,obj);
end;

procedure F(x,y,count: integer);
begin
  MCP_F(x,y,count);
end;

procedure AN(x,y: integer; unitType: TKMUnitType);
begin
  MCP_A(x,y,unitType);
end;

procedure MCP_CopyAreaToBuffer(aHandID: Integer; xCopyFrom, yCopyFrom, xCopyTo, yCopyTo: integer);
var
  x: integer;
  y: integer;
  unitId: integer;
  unitType: TKMUnitType;
begin

  setLength(MCP_Tiles, 0);

  for x:= xCopyFrom to xCopyTo do
  begin

    for y:= yCopyFrom to yCopyTo do
    begin
      MCP_T(x,y,S.MapTileType(x,y),S.MapTileRotation(x,y),S.MapTileHeight(x,y),S.MapTileObject(x,y));

      unitId := S.UnitAt(x,y);
      if (unitId <> -1) then
      begin
        unitType := S.UnitTypeEx(unitId);
        if ((unitType = utWolf) or (unitType = utWatersnake) or (unitType = utSeastar) or (unitType = utCrab) or
            (unitType = utWaterflower) or (unitType = utWaterleaf) or (unitType = utDuck)) then
        begin
          MCP_A(x,y,unitType);
        end else
        if (unitType = utFish) then
        begin
          MCP_F(x,y,S.UnitFishCount(unitId));
        end;
      end;
    end;
  end;

end;

procedure MCP_WritePasteFunctionToLog(aHandID: Integer; xPaste, yPaste: integer);
var
  i: integer;
  str: string;
  xFirst: integer;
  yFirst: integer;
begin

  if (Length(MCP_Tiles) = 0) then
  begin
    A.Log('Buffer is empty');
    exit;
  end;

  xFirst := MCP_Tiles[0].X;
  yFirst := MCP_Tiles[0].Y;

  for i:= 0 to High(MCP_Tiles) do
  begin

    str := str + 'T(' + IntToStr(xPaste + MCP_Tiles[i].X - xFirst) + ','
                          + IntToStr(yPaste + MCP_Tiles[i].Y - yFirst) + ','
                          + IntToStr(MCP_Tiles[i].Terrain) + ','
                          + IntToStr(MCP_Tiles[i].Rotation) + ','
                          + IntToStr(MCP_Tiles[i].Height) + ','
                          + IntToStr(MCP_Tiles[i].Obj) + ');';
  end;

  for i:= 0 to High(MCP_Units) do
  begin

    if (MCP_Units[i].UnitType = utFish) then
    begin
      str := str + 'F(' + IntToStr(xPaste + MCP_Units[i].Position.X - xFirst) + ','
                          + IntToStr(yPaste + MCP_Units[i].Position.Y - yFirst) + ','
                          + IntToStr(MCP_Units[i].Count) + ');';
    end else
    begin
      str := str + 'AN(' + IntToStr(xPaste + MCP_Units[i].Position.X - xFirst) + ','
                          + IntToStr(yPaste + MCP_Units[i].Position.Y - yFirst) + ','
                          + IntToStr(MCP_Units[i].UnitType) + ');';
    end;

  end;

  A.Log(str);
end;

procedure MCP_PasteFromBuffer();
var
  i: integer;
  unitId: integer;
begin

  for i:= 0 to High(MCP_Tiles) do
  begin
    unitId := S.UnitAt(MCP_Tiles[i].X, MCP_Tiles[i].Y);
    if (unitId <> -1) then
    begin
      A.UnitKill(unitId, true);
    end;
  end;

  A.MapTilesArraySet(MCP_Tiles, false, true);

  for i:= 0 to High(MCP_Units) do
  begin
    unitId := A.GiveAnimalEx(MCP_Units[i].UnitType, MCP_Units[i].Position.X, MCP_Units[i].Position.Y);

    if ((MCP_Units[i].UnitType = utFish) and (MCP_Units[i].Count > 0)) then
    begin
      A.UnitFishCountSet(unitId, MCP_Units[i].Count);
    end;

  end;

end;

procedure MCP_ClearBuffer();
begin
  setLength(MCP_Tiles, 0);
  setLength(MCP_Units, 0);
end;

