<commit_before>unit KM_InterfaceMapEditor;
{$I KaM_Remake.inc}
interface
uses
     {$IFDEF MSWindows} Windows, {$ENDIF}
     {$IFDEF Unix} LCLIntf, LCLType, {$ENDIF}
     Classes, Controls, KromUtils, Math, StrUtils, SysUtils, KromOGLUtils, TypInfo,
     KM_Controls, KM_Defaults, KM_Pics, KM_Maps, KM_Houses, KM_Units,
     KM_Points, KM_InterfaceDefaults, KM_Terrain;

type
  TKMapEdInterface = class (TKMUserInterface)
  private
    fShowPassability:byte;
    PrevHint:TObject;
    StorehouseItem:byte; //Selected ware in storehouse
    BarracksItem:byte; //Selected ware in barracks
    TileDirection: byte;
    fMaps: TKMapsCollection;
    fMapsMP: TKMapsCollection;

    procedure Create_Terrain_Page;
    procedure Create_Village_Page;
    procedure Create_Player_Page;
    procedure Create_Mission_Page;
    procedure Create_Menu_Page;
    procedure Create_MenuSave_Page;
    procedure Create_MenuLoad_Page;
    procedure Create_MenuQuit_Page;
    procedure Create_Unit_Page;
    procedure Create_House_Page;
    procedure Create_Store_Page;
    procedure Create_Barracks_Page;

    procedure SwitchPage(Sender: TObject);
    procedure DisplayHint(Sender: TObject);
    procedure Minimap_Update(Sender: TObject; const X,Y: Integer);

    procedure Menu_Save(Sender:TObject);
    procedure Menu_Load(Sender:TObject);
    procedure Menu_QuitMission(Sender:TObject);
    procedure Load_MapTypeChange(Sender:TObject);
    procedure Load_MapListUpdate;
    procedure Load_MapListUpdateDone(Sender: TObject);
    procedure Terrain_HeightChange(Sender: TObject);
    procedure Terrain_TilesChange(Sender: TObject);
    procedure Terrain_ObjectsChange(Sender: TObject);
    procedure Build_ButtonClick(Sender: TObject);
    procedure House_HealthChange(Sender:TObject; AButton:TMouseButton);
    procedure Unit_ButtonClick(Sender: TObject);
    procedure Unit_ArmyChange1(Sender:TObject); overload;
    procedure Unit_ArmyChange2(Sender:TObject; AButton:TMouseButton); overload;
    procedure Barracks_Fill(Sender:TObject);
    procedure Barracks_SelectWare(Sender:TObject);
    procedure Barracks_EditWareCount(Sender:TObject; AButton:TMouseButton);
    procedure Store_Fill(Sender:TObject);
    procedure Store_SelectWare(Sender:TObject);
    procedure Store_EditWareCount(Sender:TObject; AButton:TMouseButton);
    procedure Player_ChangeActive(Sender: TObject);
    procedure SetActivePlayer(aIndex: TPlayerIndex);
    procedure SetTileDirection(aTileDirection: byte);
    procedure Player_ColorClick(Sender:TObject);
    procedure Player_BlockRefresh;
    procedure Player_BlockClick(Sender:TObject);
    procedure Mission_AlliancesChange(Sender:TObject);
    procedure Mission_PlayerTypesChange(Sender:TObject);
    procedure View_Passability(Sender:TObject);

    function GetSelectedTile: TObject;
    function GetSelectedObject: TObject;
    function GetSelectedUnit: TObject;
  protected
    Panel_Main:TKMPanel;
      MinimapView: TKMMinimapView;
      Label_Coordinates:TKMLabel;
      TrackBar_Passability:TKMTrackBar;
      Label_Passability:TKMLabel;
      Button_PlayerSelect:array[0..MAX_PLAYERS-1]of TKMFlatButtonShape; //Animals are common for all
      Label_Stat,Label_Hint:TKMLabel;
    Panel_Common:TKMPanel;
      Button_Main:array[1..5]of TKMButton; //5 buttons
      Label_MenuTitle: TKMLabel; //Displays the title of the current menu below
      Label_MissionName: TKMLabel;

    Panel_Terrain:TKMPanel;
      Button_Terrain:array[1..4]of TKMButton;
      Panel_Brushes:TKMPanel;
        BrushSize:TKMTrackBar;
        BrushCircle,BrushSquare:TKMButtonFlat;
        //BrushesTable:array[1..27] of TKMButtonFlat; // todo
      Panel_Heights:TKMPanel;
        HeightSize,HeightShape:TKMTrackBar;
        HeightCircle,HeightSquare:TKMButtonFlat;
        HeightElevate, HeightUnequalize: TKMButtonFlat;
      Panel_Tiles:TKMPanel;
        TilesTable:array[1..MAPED_TILES_COLS*MAPED_TILES_ROWS] of TKMButtonFlat; //how many are visible?
        TilesScroll:TKMScrollBar;
        TilesRandom:TKMCheckBox;
      Panel_Objects:TKMPanel;
        ObjectErase:TKMButtonFlat;
        ObjectsTable:array[0..8] of TKMButtonFlat;
        ObjectsScroll:TKMScrollBar;

    Panel_Village:TKMPanel;
      Button_Village:array[1..3]of TKMButton;
      Panel_Build:TKMPanel;
        Button_BuildRoad,Button_BuildField,Button_BuildWine,Button_BuildCancel:TKMButtonFlat;
        Button_Build:array[1..GUI_HOUSE_COUNT]of TKMButtonFlat;
      Panel_Units:TKMPanel;
        Button_UnitCancel:TKMButtonFlat;
        Button_Citizen:array[0..13]of TKMButtonFlat;
        Button_Warriors:array[0..13]of TKMButtonFlat;
        Button_Animals:array[0..7]of TKMButtonFlat;
      Panel_Script:TKMPanel;

    Panel_Player:TKMPanel;
      Button_Player:array[1..3]of TKMButton;
      Panel_Goals:TKMPanel;
      Panel_Color:TKMPanel;
        ColorSwatch_Color:TKMColorSwatch;
      Panel_Block: TKMPanel;
        Button_BlockHouse: array [1 .. GUI_HOUSE_COUNT] of TKMButtonFlat;
        Image_BlockHouse: array [1 .. GUI_HOUSE_COUNT] of TKMImage;

    Panel_Mission:TKMPanel;
      Button_Mission:array[1..2]of TKMButton;
      Panel_Alliances:TKMPanel;
        CheckBox_Alliances: array[0..MAX_PLAYERS-1,0..MAX_PLAYERS-1] of TKMCheckBox;
        CheckBox_AlliancesSym:TKMCheckBox;
      Panel_PlayerTypes:TKMPanel;
        CheckBox_PlayerTypes: array[0..MAX_PLAYERS-1,0..1] of TKMCheckBox;

    Panel_Menu:TKMPanel;
      Button_Menu_Save,Button_Menu_Load,Button_Menu_Settings,Button_Menu_Quit:TKMButton;

      Panel_Save:TKMPanel;
        Radio_Save_MapType:TKMRadioGroup;
        Edit_SaveName:TKMEdit;
        Label_SaveExists:TKMLabel;
        CheckBox_SaveExists:TKMCheckBox;
        Button_SaveSave:TKMButton;
        Button_SaveCancel:TKMButton;

      Panel_Load:TKMPanel;
        Radio_Load_MapType:TKMRadioGroup;
        ListBox_Load:TKMListBox;
        Button_LoadLoad:TKMButton;
        Button_LoadCancel:TKMButton;

      Panel_Quit:TKMPanel;
        Button_Quit_Yes,Button_Quit_No:TKMButton;

    Panel_Unit:TKMPanel;
      Label_UnitName:TKMLabel;
      Label_UnitCondition:TKMLabel;
      Label_UnitDescription:TKMLabel;
      KMConditionBar_Unit:TKMPercentBar;
      Image_UnitPic:TKMImage;

      Panel_Army:TKMPanel;
        Button_Army_RotCW,Button_Army_RotCCW: TKMButton;
        Button_Army_ForUp,Button_Army_ForDown: TKMButton;
        ImageStack_Army: TKMImageStack;
        Label_ArmyCount: TKMLabel;
        Button_ArmyDec,Button_ArmyFood,Button_ArmyInc: TKMButton;

    Panel_House:TKMPanel;
      Label_House:TKMLabel;
      Image_House_Logo,Image_House_Worker:TKMImage;
      Label_HouseHealth:TKMLabel;
      KMHealthBar_House:TKMPercentBar;
      Button_HouseHealthDec,Button_HouseHealthInc:TKMButton;

    Panel_HouseStore:TKMPanel;
      Button_Store:array[1..STORE_RES_COUNT]of TKMButtonFlat;
      Label_Store_WareCount:TKMLabel;
      Button_StoreDec100,Button_StoreDec:TKMButton;
      Button_StoreInc100,Button_StoreInc:TKMButton;
    Panel_HouseBarracks:TKMPanel;
      Button_Barracks:array[1..BARRACKS_RES_COUNT]of TKMButtonFlat;
      Label_Barracks_WareCount:TKMLabel;
      Button_BarracksDec100,Button_BarracksDec:TKMButton;
      Button_BarracksInc100,Button_BarracksInc:TKMButton;
  public
    constructor Create(aScreenX, aScreenY: word);
    destructor Destroy; override;
    procedure Player_UpdateColors;
    procedure ShowHouseInfo(Sender:TKMHouse);
    procedure ShowUnitInfo(Sender:TKMUnit);
    property ShowPassability:byte read fShowPassability;
    procedure SetMinimap;
    procedure SetMapName(const aName:string);
    procedure RightClick_Cancel;
    function GetShownPage: TKMMapEdShownPage;
    procedure SetLoadMode(aMultiplayer:boolean);

    procedure KeyDown(Key:Word; Shift: TShiftState); override;
    procedure KeyUp(Key:Word; Shift: TShiftState); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X,Y: Integer); override;

    procedure Resize(X,Y: Word); override;
    procedure UpdateState(aTickCount: Cardinal); override;
  end;


implementation
uses KM_Units_Warrior, KM_PlayersCollection, KM_Player, KM_TextLibrary,
     KM_Utils, KM_Game, KM_GameApp, KM_Resource, KM_ResourceUnit, KM_ResourceCursors, KM_ResourceMapElements;


{Switch between pages}
procedure TKMapEdInterface.SwitchPage(Sender: TObject);
var
  i, k:Integer;
begin

  //Reset cursor mode
  GameCursor.Mode := cm_None;
  GameCursor.Tag1 := 0;

  //If the user clicks on the tab that is open, it closes it (main buttons only)
  if ((Sender = Button_Main[1]) and Panel_Terrain.Visible) or
     ((Sender = Button_Main[2]) and Panel_Village.Visible) or
     ((Sender = Button_Main[3]) and Panel_Player.Visible) or
     ((Sender = Button_Main[4]) and Panel_Mission.Visible) or
     ((Sender = Button_Main[5]) and Panel_Menu.Visible) then
     Sender := nil;

  //Reset shown item if user clicked on any of the main buttons
  if (Sender=Button_Main[1])or(Sender=Button_Main[2])or
     (Sender=Button_Main[3])or(Sender=Button_Main[4])or
     (Sender=Button_Main[5])or
     (Sender=Button_Menu_Settings)or(Sender=Button_Menu_Quit) then
  begin
    fPlayers.Selected:=nil;
  end;

  Label_MenuTitle.Caption := '';
  //Now hide all existing pages
    for i:=1 to Panel_Common.ChildCount do
      if Panel_Common.Childs[i] is TKMPanel then
      begin
        for k:=1 to TKMPanel(Panel_Common.Childs[i]).ChildCount do
          if TKMPanel(Panel_Common.Childs[i]).Childs[k] is TKMPanel then
            TKMPanel(Panel_Common.Childs[i]).Childs[k].Hide;
        Panel_Common.Childs[i].Hide;
      end;

  if (Sender = Button_Main[1])or(Sender = Button_Terrain[1]) then begin
    Panel_Terrain.Show;
    Panel_Brushes.Show;
    Label_MenuTitle.Caption:='Terrain - Brushes';
  end else

  if (Sender = Button_Main[1])or(Sender = Button_Terrain[2]) then begin
    Panel_Terrain.Show;
    Panel_Heights.Show;
    Label_MenuTitle.Caption:='Terrain - Heights';
    Terrain_HeightChange(HeightCircle); //Select the default mode
  end else

  if (Sender = Button_Main[1])or(Sender = Button_Terrain[3]) then begin
    Panel_Terrain.Show;
    Panel_Tiles.Show;
    Label_MenuTitle.Caption:='Terrain - Tiles';
    SetTileDirection(TileDirection); //ensures tags are in allowed ranges
    Terrain_TilesChange(GetSelectedTile);
  end else

  if (Sender = Button_Main[1])or(Sender = Button_Terrain[4]) then begin
    Panel_Terrain.Show;
    Panel_Objects.Show;
    Label_MenuTitle.Caption:='Terrain - Objects';
    Terrain_ObjectsChange(GetSelectedObject);
  end else

  if (Sender = Button_Main[2])or(Sender = Button_Village[1]) then begin
    Panel_Village.Show;
    Panel_Build.Show;
    Label_MenuTitle.Caption:='Village - Buildings';
    Build_ButtonClick(Button_BuildRoad);
  end else

  if (Sender = Button_Main[2])or(Sender = Button_Village[2]) then begin
    Panel_Village.Show;
    Panel_Units.Show;
    Label_MenuTitle.Caption:='Village - Units';
    Unit_ButtonClick(GetSelectedUnit);
  end else

  if (Sender = Button_Main[2])or(Sender = Button_Village[3]) then begin
    Panel_Village.Show;
    Panel_Script.Show;
    Label_MenuTitle.Caption:='Village - Script';
  end else

  if (Sender = Button_Main[3])or(Sender = Button_Player[1]) then begin
    Panel_Player.Show;
    Panel_Goals.Show;
    Label_MenuTitle.Caption:='Player - Goals';
  end else

  if (Sender = Button_Main[3])or(Sender = Button_Player[2]) then begin
    Panel_Player.Show;
    Panel_Color.Show;
    Label_MenuTitle.Caption:='Player - Color';
  end else

  if (Sender = Button_Main[3])or(Sender = Button_Player[3]) then begin
    Player_BlockRefresh;
    Panel_Player.Show;
    Panel_Block.Show;
    Label_MenuTitle.Caption:='Player - Block houses';
  end else

  if (Sender = Button_Main[4])or(Sender = Button_Mission[1]) then begin
    Panel_Mission.Show;
    Panel_Alliances.Show;
    Label_MenuTitle.Caption:='Mission - Alliances';
    Mission_AlliancesChange(nil);
  end else

  if (Sender = Button_Main[4])or(Sender = Button_Mission[2]) then begin
    Panel_Mission.Show;
    Panel_PlayerTypes.Show;
    Label_MenuTitle.Caption:='Mission - Player Types';
    Mission_PlayerTypesChange(nil);
  end else

  if (Sender=Button_Main[5]) or
     (Sender=Button_Quit_No) or
     (Sender = Button_LoadCancel) or
     (Sender = Button_SaveCancel) then begin
    Panel_Menu.Show;
    Label_MenuTitle.Caption := fTextLibrary[TX_MENU_TAB_OPTIONS];
  end else

  if Sender=Button_Menu_Quit then begin
    Panel_Quit.Show;
  end;

  if Sender = Button_Menu_Save then begin
    Edit_SaveName.Text := fGame.GameName;
    Menu_Save(Edit_SaveName);
    Panel_Save.Show;
  end;

  if Sender = Button_Menu_Load then begin
    Load_MapListUpdate;
    Panel_Load.Show;
  end;

  //Now process all other kinds of pages
  if Sender=Panel_Unit then begin
    TKMPanel(Sender).Show;
  end else

  if Sender=Panel_House then begin
    TKMPanel(Sender).Show;
  end;

  if Sender=Panel_HouseBarracks then begin
    TKMPanel(Sender).Parent.Show;
    TKMPanel(Sender).Show;
  end else

  if Sender=Panel_HouseStore then begin
    TKMPanel(Sender).Parent.Show;
    TKMPanel(Sender).Show;
  end;

end;


procedure TKMapEdInterface.DisplayHint(Sender: TObject);
begin
  if (PrevHint = Sender) then exit; //Hint didn't changed

  if Sender=nil then Label_Hint.Caption:=''
                else Label_Hint.Caption:=TKMControl(Sender).Hint;

  PrevHint := Sender;
end;


//Update viewport position when user interacts with minimap
procedure TKMapEdInterface.Minimap_Update(Sender: TObject; const X,Y: Integer);
begin
  fGame.Viewport.Position := KMPointF(X,Y);
end;


constructor TKMapEdInterface.Create(aScreenX, aScreenY: word);
var
  i: Integer;
begin
  inherited;

  BarracksItem   := 1; //First ware selected by default
  StorehouseItem := 1; //First ware selected by default
  TileDirection := 0;
  fMaps := TKMapsCollection.Create(False);
  fMapsMP := TKMapsCollection.Create(True);

  //Parent Page for whole toolbar in-game
  Panel_Main := TKMPanel.Create(fMyControls, 0, 0, aScreenX, aScreenY);

    TKMImage.Create(Panel_Main,0,   0,224,200,407); //Minimap place
    TKMImage.Create(Panel_Main,0, 200,224,400,404);
    TKMImage.Create(Panel_Main,0, 600,224,400,404);
    TKMImage.Create(Panel_Main,0,1000,224,400,404); //For 1600x1200 this is needed

    MinimapView := TKMMinimapView.Create(Panel_Main, 10, 10, 176, 176);
    MinimapView.OnChange := Minimap_Update;

    Label_Coordinates := TKMLabel.Create(Panel_Main,8,192,184,0,'X: Y:',fnt_Outline,taLeft);
    TrackBar_Passability := TKMTrackBar.Create(Panel_Main, 8, 210, 184, 0, Byte(High(TPassability)));
    TrackBar_Passability.Caption := 'View passability';
    TrackBar_Passability.Position := 0; //Disabled by default
    TrackBar_Passability.OnChange := View_Passability;
    Label_Passability := TKMLabel.Create(Panel_Main,8,248,184,0,'Off',fnt_Metal,taLeft);

    TKMLabel.Create(Panel_Main,8,270,184,0,'Player',fnt_Metal,taLeft);
    for i:=0 to MAX_PLAYERS-1 do begin
      Button_PlayerSelect[i]         := TKMFlatButtonShape.Create(Panel_Main, 8 + i*23, 290, 21, 32, inttostr(i+1), fnt_Grey, $FF0000FF);
      Button_PlayerSelect[i].CapOffsetY := -3;
      Button_PlayerSelect[i].Tag     := i;
      Button_PlayerSelect[i].OnClick := Player_ChangeActive;
    end;

    Label_MissionName := TKMLabel.Create(Panel_Main, 8, 340, 184, 10, '<<<LEER>>>', fnt_Metal, taLeft);

    Label_Stat:=TKMLabel.Create(Panel_Main,224+8,16,0,0,'',fnt_Outline,taLeft);
    Label_Hint:=TKMLabel.Create(Panel_Main,224+8,Panel_Main.Height-16,0,0,'',fnt_Outline,taLeft);
    Label_Hint.Anchors := [akLeft, akBottom];

  Panel_Common := TKMPanel.Create(Panel_Main,0,300,224,768);

    {5 big tabs}
    Button_Main[1] := TKMButton.Create(Panel_Common,   8, 72, 36, 36, 381);
    Button_Main[2] := TKMButton.Create(Panel_Common,  46, 72, 36, 36, 368);
    Button_Main[3] := TKMButton.Create(Panel_Common,  84, 72, 36, 36,  41);
    Button_Main[4] := TKMButton.Create(Panel_Common, 122, 72, 36, 36, 441);
    Button_Main[5] := TKMButton.Create(Panel_Common, 160, 72, 36, 36, 389);
    Button_Main[1].Hint := fTextLibrary[TX_MAPEDITOR_TERRAIN];
    Button_Main[2].Hint := fTextLibrary[TX_MAPEDITOR_VILLAGE];
    Button_Main[3].Hint := fTextLibrary[TX_MAPEDITOR_SCRIPTS_VISUAL];
    Button_Main[4].Hint := fTextLibrary[TX_MAPEDITOR_SCRIPTS_GLOBAL];
    Button_Main[5].Hint := fTextLibrary[TX_MAPEDITOR_MENU];
    for i:=1 to 5 do Button_Main[i].OnClick := SwitchPage;

    Label_MenuTitle:=TKMLabel.Create(Panel_Common,8,112,184,36,'',fnt_Metal,taLeft); //Should be one-line


{I plan to store all possible layouts on different pages which gets displayed one at a time}
{==========================================================================================}
  Create_Terrain_Page;
  Create_Village_Page;
  Create_Player_Page;
  Create_Mission_Page;

  Create_Menu_Page;
    Create_MenuSave_Page;
    Create_MenuLoad_Page;
    Create_MenuQuit_Page;

  Create_Unit_Page;
  Create_House_Page;
    Create_Store_Page;
    Create_Barracks_Page;
    //Create_TownHall_Page;

  fMyControls.OnHint := DisplayHint;

  SwitchPage(nil); //Update
end;


destructor TKMapEdInterface.Destroy;
begin
  fMaps.Free;
  fMapsMP.Free;
  SHOW_TERRAIN_WIRES := false; //Don't show it in-game if they left it on in MapEd
  inherited;
end;


//Update Hint position and etc..
procedure TKMapEdInterface.Resize(X,Y: Word);
begin
  Panel_Main.Width := X;
  Panel_Main.Height := Y;
end;


{Terrain page}
procedure TKMapEdInterface.Create_Terrain_Page;
var i,k:Integer;
begin
  Panel_Terrain := TKMPanel.Create(Panel_Common,0,128,196,28);
    Button_Terrain[1] := TKMButton.Create(Panel_Terrain,   8, 4, 36, 24, 383);
    Button_Terrain[2] := TKMButton.Create(Panel_Terrain,  48, 4, 36, 24, 388);
    Button_Terrain[3] := TKMButton.Create(Panel_Terrain,  88, 4, 36, 24, 382);
    Button_Terrain[4] := TKMButton.Create(Panel_Terrain, 128, 4, 36, 24, 385);
    for i:=1 to 4 do Button_Terrain[i].OnClick := SwitchPage;

    Panel_Brushes := TKMPanel.Create(Panel_Terrain,0,28,196,400);
      BrushSize   := TKMTrackBar.Create(Panel_Brushes, 8, 10, 100, 1, 12);
      BrushCircle := TKMButtonFlat.Create(Panel_Brushes, 114, 8, 24, 24, 359);
      BrushSquare := TKMButtonFlat.Create(Panel_Brushes, 142, 8, 24, 24, 352);

      TKMButtonFlat.Create(Panel_Brushes, 8, 30, 32, 32, 1, rxTiles);   // grass

      {TKMButtonFlat.Create(Panel_Brushes, 40, 30, 32, 32, 9, rxTiles);  // grass 2
      TKMButtonFlat.Create(Panel_Brushes, 8, 62, 32, 32, 35, rxTiles);  // dirt

      {BrushSize.OnChange   := TerrainBrush_Change;
      BrushCircle.OnChange := TerrainBrush_Change;
      BrushSquare.OnChange := TerrainBrush_Change;}

    Panel_Heights := TKMPanel.Create(Panel_Terrain,0,28,196,400);
      HeightSize   := TKMTrackBar.Create(Panel_Heights, 8, 10, 100, 1, 15); //1..15(4bit) for size
      HeightCircle := TKMButtonFlat.Create(Panel_Heights, 114, 8, 24, 24, 359);
      HeightSquare := TKMButtonFlat.Create(Panel_Heights, 142, 8, 24, 24, 352);
      HeightShape  := TKMTrackBar.Create(Panel_Heights, 8, 30, 100, 1, 15); //1..15(4bit) for slope shape

      HeightElevate             := TKMButtonFlat.Create(Panel_Heights,8,70,180,20,0);
      HeightElevate.OnClick     := Terrain_HeightChange;
      HeightElevate.Down        := True;
      HeightElevate.Caption     := 'Elevate';
      HeightElevate.CapOffsetY  := -12;
      HeightUnequalize          := TKMButtonFlat.Create(Panel_Heights,8,100,180,20,0);
      HeightUnequalize.OnClick  := Terrain_HeightChange;
      HeightUnequalize.Caption  := 'Uniqualize/flat';
      HeightUnequalize.CapOffsetY  := -12;

      HeightSize.OnChange   := Terrain_HeightChange;
      HeightShape.OnChange  := Terrain_HeightChange;
      HeightCircle.OnClick  := Terrain_HeightChange;
      HeightSquare.OnClick  := Terrain_HeightChange;

    Panel_Tiles := TKMPanel.Create(Panel_Terrain,0,28,196,400);
      TilesRandom := TKMCheckBox.Create(Panel_Tiles, 8, 4, 188, 20, 'Random Direction', fnt_Metal);
      TilesRandom.Checked := true;
      TilesRandom.OnClick := Terrain_TilesChange;
      TilesScroll := TKMScrollBar.Create(Panel_Tiles, 2, 30 + 4 + MAPED_TILES_ROWS * 32, 194, 20, sa_Horizontal, bsGame);
      TilesScroll.MaxValue := 256 div MAPED_TILES_ROWS - MAPED_TILES_COLS; // 16 - 6
      TilesScroll.Position := 0;
      TilesScroll.OnChange := Terrain_TilesChange;
      for i:=1 to MAPED_TILES_COLS do for k:=1 to MAPED_TILES_ROWS do begin
        TilesTable[(i-1)*MAPED_TILES_ROWS+k] := TKMButtonFlat.Create(Panel_Tiles,2+(i-1)*32,30+(k-1)*32,32,32,1,rxTiles); //2..9
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Tag := (k-1)*MAPED_TILES_COLS+i; //Store ID
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].OnClick := Terrain_TilesChange;
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].OnMouseWheel := TilesScroll.MouseWheel;
      end;
      Terrain_TilesChange(TilesScroll); //This ensures that the displayed images get updated the first time
      Terrain_TilesChange(TilesTable[1]);

    Panel_Objects := TKMPanel.Create(Panel_Terrain,0,28,196,400);
      ObjectsScroll := TKMScrollBar.Create(Panel_Objects, 8, 295, 180, 20, sa_Horizontal, bsGame);
      ObjectsScroll.MinValue := 0;
      ObjectsScroll.MaxValue := fResource.MapElements.ValidCount div 3 - 2;
      ObjectsScroll.Position := 0;
      ObjectsScroll.OnChange := Terrain_ObjectsChange;
      ObjectErase := TKMButtonFlat.Create(Panel_Objects, 8, 8,32,32,340);
      for I := 0 to 2 do for K := 0 to 2 do
      begin
        ObjectsTable[I*3+K] := TKMButtonFlat.Create(Panel_Objects, 8+I*65, 40+K*85,64,84,1,rxTrees); //RXid=1  // 1 2
        ObjectsTable[I*3+K].Tag := I*3+K; //Store ID
        ObjectsTable[I*3+K].OnClick := Terrain_ObjectsChange;
        ObjectsTable[I*3+K].OnMouseWheel := ObjectsScroll.MouseWheel;
      end;
      ObjectErase.Tag := 255; //no object
      ObjectErase.OnClick := Terrain_ObjectsChange;
    Terrain_ObjectsChange(ObjectsScroll); //This ensures that the displayed images get updated the first time
    Terrain_ObjectsChange(ObjectsTable[0]);
end;


{Build page}
procedure TKMapEdInterface.Create_Village_Page;
var i:Integer;
begin
  Panel_Village := TKMPanel.Create(Panel_Common,0,128,196,28);
    Button_Village[1] := TKMButton.Create(Panel_Village,   8, 4, 36, 24, 454);
    Button_Village[2] := TKMButton.Create(Panel_Village,  48, 4, 36, 24, 141);
    Button_Village[3] := TKMButton.Create(Panel_Village,  88, 4, 36, 24, 327);
    for i:=1 to 3 do Button_Village[i].OnClick := SwitchPage;

    Panel_Build := TKMPanel.Create(Panel_Village,0,28,196,400);
      TKMLabel.Create(Panel_Build,100,10,184,0,'Roadworks',fnt_Outline,taCenter);
      Button_BuildRoad   := TKMButtonFlat.Create(Panel_Build,  8,28,33,33,335);
      Button_BuildField  := TKMButtonFlat.Create(Panel_Build, 45,28,33,33,337);
      Button_BuildWine   := TKMButtonFlat.Create(Panel_Build, 82,28,33,33,336);
      Button_BuildCancel := TKMButtonFlat.Create(Panel_Build,156,28,33,33,340);
      Button_BuildRoad.OnClick  := Build_ButtonClick;
      Button_BuildField.OnClick := Build_ButtonClick;
      Button_BuildWine.OnClick  := Build_ButtonClick;
      Button_BuildCancel.OnClick:= Build_ButtonClick;
      Button_BuildRoad.Hint     := fTextLibrary[TX_BUILD_ROAD_HINT];
      Button_BuildField.Hint    := fTextLibrary[TX_BUILD_FIELD_HINT];
      Button_BuildWine.Hint     := fTextLibrary[TX_BUILD_WINE_HINT];
      Button_BuildCancel.Hint   := fTextLibrary[TX_BUILD_CANCEL_HINT];

      TKMLabel.Create(Panel_Build,100,65,184,0,'Houses',fnt_Outline,taCenter);
      for i:=1 to GUI_HOUSE_COUNT do
        if GUIHouseOrder[i] <> ht_None then begin
          Button_Build[i]:=TKMButtonFlat.Create(Panel_Build, 8+((i-1) mod 5)*37,83+((i-1) div 5)*37,33,33,fResource.HouseDat[GUIHouseOrder[i]].GUIIcon);
          Button_Build[i].OnClick:=Build_ButtonClick;
          Button_Build[i].Hint := fResource.HouseDat[GUIHouseOrder[i]].HouseName;
        end;

    Panel_Units := TKMPanel.Create(Panel_Village,0,28,196,400);

      //TKMLabel.Create(Panel_Units,100,10,0,0,'Citizens',fnt_Outline,taCenter);
      for i:=0 to High(Button_Citizen) do
      begin
        Button_Citizen[i] := TKMButtonFlat.Create(Panel_Units,8+(i mod 5)*37,8+(i div 5)*37,33,33,fResource.UnitDat[School_Order[i]].GUIIcon); //List of tiles 5x5
        Button_Citizen[i].Hint := fResource.UnitDat[School_Order[i]].UnitName;
        Button_Citizen[i].Tag := byte(School_Order[i]); //Returns unit ID
        Button_Citizen[i].OnClick := Unit_ButtonClick;
      end;
      Button_UnitCancel := TKMButtonFlat.Create(Panel_Units,8+((High(Button_Citizen)+1) mod 5)*37,8+(length(Button_Citizen) div 5)*37,33,33,340);
      Button_UnitCancel.Hint := fTextLibrary[TX_BUILD_CANCEL_HINT];
      Button_UnitCancel.OnClick := Unit_ButtonClick;

      //TKMLabel.Create(Panel_Units,100,140,0,0,'Warriors',fnt_Outline,taCenter);
      for i:=0 to High(Button_Warriors) do
      begin
        Button_Warriors[i] := TKMButtonFlat.Create(Panel_Units,8+(i mod 5)*37,124+(i div 5)*37,33,33, MapEd_Icon[i], rxGui);
        Button_Warriors[i].Hint := fResource.UnitDat[MapEd_Order[i]].UnitName;
        Button_Warriors[i].Tag := byte(MapEd_Order[i]); //Returns unit ID
        Button_Warriors[i].OnClick := Unit_ButtonClick;
      end;

      //TKMLabel.Create(Panel_Units,100,230,0,0,'Animals',fnt_Outline,taCenter);
      for i:=0 to High(Button_Animals) do
      begin
        Button_Animals[i] := TKMButtonFlat.Create(Panel_Units,8+(i mod 5)*37,240+(i div 5)*37,33,33, Animal_Icon[i], rxGui);
        Button_Animals[i].Hint := fResource.UnitDat[Animal_Order[i]].UnitName;
        Button_Animals[i].Tag := byte(Animal_Order[i]); //Returns animal ID
        Button_Animals[i].OnClick := Unit_ButtonClick;
      end;
      Unit_ButtonClick(Button_Citizen[0]); //Select serf as default

    Panel_Script := TKMPanel.Create(Panel_Village,0,28,196,400);
      TKMLabel.Create(Panel_Script,100,10,184,0,'Scripts',fnt_Outline,taCenter);
      {Button_ScriptReveal         := TKMButtonFlat.Create(Panel_Script,  8,28,33,33,335);
      Button_ScriptReveal.OnClick := Script_ButtonClick;
      Button_ScriptReveal.Hint    := 'Reveal a portion of map';}
end;


procedure TKMapEdInterface.Create_Player_Page;
var I: Integer; Col: array [0..255] of TColor4;
begin
  Panel_Player := TKMPanel.Create(Panel_Common,0,128,196,28);
    Button_Player[1] := TKMButton.Create(Panel_Player,   8, 4, 36, 24,  41);
    Button_Player[2] := TKMButton.Create(Panel_Player,  48, 4, 36, 24, 382);
    Button_Player[3] := TKMButton.Create(Panel_Player,  88, 4, 36, 24,  38);
    for I := 1 to 3 do Button_Player[I].OnClick := SwitchPage;

    Panel_Goals := TKMPanel.Create(Panel_Player,0,28,196,400);
      TKMLabel.Create(Panel_Goals,100,10,184,0,'Goals',fnt_Outline,taCenter);

    Panel_Color := TKMPanel.Create(Panel_Player,0,28,196,400);
      TKMLabel.Create(Panel_Color,100,10,184,0,'Colors',fnt_Outline,taCenter);
      TKMBevel.Create(Panel_Color,8,30,180,210);
      ColorSwatch_Color := TKMColorSwatch.Create(Panel_Color, 10, 32, 16, 16, 11);
      for I:=0 to 255 do Col[I] := fResource.Palettes.DefDal.Color32(I);
      ColorSwatch_Color.SetColors(Col);
      ColorSwatch_Color.OnClick := Player_ColorClick;

    Panel_Block := TKMPanel.Create(Panel_Player,0,28,196,400);
      TKMLabel.Create(Panel_Block, 100, 10, 184, 0, 'Block houses', fnt_Outline, taCenter);

      for I := 1 to GUI_HOUSE_COUNT do
      if GUIHouseOrder[I] <> ht_None then begin
        Button_BlockHouse[I] := TKMButtonFlat.Create(Panel_Block, 8+((I-1) mod 5)*37, 30 + ((I-1) div 5)*37,33,33,fResource.HouseDat[GUIHouseOrder[I]].GUIIcon);
        Button_BlockHouse[I].Hint := fResource.HouseDat[GUIHouseOrder[I]].HouseName;
        Button_BlockHouse[I].OnClick := Player_BlockClick;
        Button_BlockHouse[I].Tag := I;
        Image_BlockHouse[I] := TKMImage.Create(Panel_Block, 8+((I-1) mod 5)*37 + 13, 30 + ((I-1) div 5)*37 + 13, 16, 16, 0, rxGuiMain);
        Image_BlockHouse[I].Hitable := False;
        Image_BlockHouse[I].ImageCenter;
      end;
end;


procedure TKMapEdInterface.Create_Mission_Page;
var i,k:Integer;
begin
  Panel_Mission := TKMPanel.Create(Panel_Common,0,128,196,28);
    Button_Mission[1] := TKMButton.Create(Panel_Mission,  8, 4, 36, 24, 41);
    Button_Mission[2] := TKMButton.Create(Panel_Mission, 48, 4, 36, 24, 41);
    for i:=1 to 2 do Button_Mission[i].OnClick := SwitchPage;

    Panel_Alliances := TKMPanel.Create(Panel_Mission,0,28,196,400);
      TKMLabel.Create(Panel_Alliances,100,10,184,0,'Alliances',fnt_Outline,taCenter);
      for i:=0 to MAX_PLAYERS-1 do begin
        TKMLabel.Create(Panel_Alliances,32+i*20+2,30,20,20,inttostr(i+1),fnt_Outline,taLeft);
        TKMLabel.Create(Panel_Alliances,12,50+i*25,20,20,inttostr(i+1),fnt_Outline,taLeft);
        for k:=0 to MAX_PLAYERS-1 do begin
          CheckBox_Alliances[i,k] := TKMCheckBox.Create(Panel_Alliances, 28+k*20, 46+i*25, 20, 20, '', fnt_Metal);
          CheckBox_Alliances[i,k].Tag       := i * MAX_PLAYERS + k;
          CheckBox_Alliances[i,k].FlatStyle := true;
          CheckBox_Alliances[i,k].OnClick   := Mission_AlliancesChange;
        end;
      end;

      //It does not have OnClick event for a reason:
      // - we don't have a rule to make alliances symmetrical yet
      CheckBox_AlliancesSym := TKMCheckBox.Create(Panel_Alliances, 12, 50+MAX_PLAYERS*25, 176, 20, 'Symmetrical', fnt_Metal);
      CheckBox_AlliancesSym.Checked := true;
      CheckBox_AlliancesSym.Disable;

    Panel_PlayerTypes := TKMPanel.Create(Panel_Mission,0,28,196,400);
      TKMLabel.Create(Panel_PlayerTypes,100,10,184,0,'Player types',fnt_Outline,taCenter);
      for i:=0 to MAX_PLAYERS-1 do begin
        TKMLabel.Create(Panel_PlayerTypes,12,30,20,20,'#',fnt_Grey,taLeft);
        TKMLabel.Create(Panel_PlayerTypes,32,30,100,20,'Human',fnt_Grey,taLeft);
        TKMLabel.Create(Panel_PlayerTypes,102,30,100,20,'Computer',fnt_Grey,taLeft);
        TKMLabel.Create(Panel_PlayerTypes,12,50+i*25,20,20,inttostr(i+1),fnt_Outline,taLeft);
        for k:=0 to 1 do
        begin
          CheckBox_PlayerTypes[i,k] := TKMCheckBox.Create(Panel_PlayerTypes, 52+k*70, 48+i*25, 20, 20, '', fnt_Metal);
          CheckBox_PlayerTypes[i,k].Tag       := i;
          CheckBox_PlayerTypes[i,k].FlatStyle := true;
          CheckBox_PlayerTypes[i,k].OnClick   := Mission_PlayerTypesChange;
        end;
      end;
end;


{Menu page}
procedure TKMapEdInterface.Create_Menu_Page;
begin
  Panel_Menu:=TKMPanel.Create(Panel_Common,0,128,196,400);
    Button_Menu_Save:=TKMButton.Create(Panel_Menu,8,20,180,30,fTextLibrary[TX_MENU_SAVE_GAME],fnt_Metal);
    Button_Menu_Save.OnClick:=SwitchPage;
    Button_Menu_Save.Hint:=fTextLibrary[TX_MENU_SAVE_GAME];
    Button_Menu_Load:=TKMButton.Create(Panel_Menu,8,60,180,30,fTextLibrary[TX_MENU_LOAD_GAME],fnt_Metal);
    Button_Menu_Load.OnClick:=SwitchPage;
    Button_Menu_Load.Hint:=fTextLibrary[TX_MENU_LOAD_GAME];
    Button_Menu_Settings:=TKMButton.Create(Panel_Menu,8,100,180,30,fTextLibrary[TX_MENU_SETTINGS],fnt_Metal);
    Button_Menu_Settings.Hint:=fTextLibrary[TX_MENU_SETTINGS];
    Button_Menu_Settings.Disable;
    Button_Menu_Quit:=TKMButton.Create(Panel_Menu,8,180,180,30,fTextLibrary[TX_MENU_QUIT_MAPED],fnt_Metal);
    Button_Menu_Quit.Hint:=fTextLibrary[TX_MENU_QUIT_MAPED];
    Button_Menu_Quit.OnClick:=SwitchPage;
end;


{Save page}
procedure TKMapEdInterface.Create_MenuSave_Page;
begin
  Panel_Save := TKMPanel.Create(Panel_Common,0,128,196,400);
    TKMBevel.Create(Panel_Save, 8, 30, 180, 37);
    Radio_Save_MapType  := TKMRadioGroup.Create(Panel_Save,12,32,176,35,fnt_Grey);
    Radio_Save_MapType.ItemIndex := 0;
    Radio_Save_MapType.Items.Add(fTextLibrary[TX_MENU_MAPED_SPMAPS]);
    Radio_Save_MapType.Items.Add(fTextLibrary[TX_MENU_MAPED_MPMAPS]);
    Radio_Save_MapType.OnChange := Menu_Save;
    TKMLabel.Create(Panel_Save,100,90,184,20,'Save map',fnt_Outline,taCenter);
    Edit_SaveName       := TKMEdit.Create(Panel_Save,8,110,180,20, fnt_Grey);
    Edit_SaveName.AllowedChars := acFileName;
    Label_SaveExists    := TKMLabel.Create(Panel_Save,100,140,184,0,'Map already exists',fnt_Outline,taCenter);
    CheckBox_SaveExists := TKMCheckBox.Create(Panel_Save,8,160,180,20,'Overwrite', fnt_Metal);
    Button_SaveSave     := TKMButton.Create(Panel_Save,8,180,180,30,'Save',fnt_Metal);
    Button_SaveCancel   := TKMButton.Create(Panel_Save,8,220,180,30,'Cancel',fnt_Metal);
    Edit_SaveName.OnChange      := Menu_Save;
    CheckBox_SaveExists.OnClick := Menu_Save;
    Button_SaveSave.OnClick     := Menu_Save;
    Button_SaveCancel.OnClick   := SwitchPage;
end;


{Load page}
procedure TKMapEdInterface.Create_MenuLoad_Page;
begin
  Panel_Load := TKMPanel.Create(Panel_Common,0,108,196,400);
    TKMLabel.Create(Panel_Load, 8, 2, 184, 30, 'Available maps', fnt_Outline, taLeft);
    TKMBevel.Create(Panel_Load, 8, 20, 184, 38);
    Radio_Load_MapType := TKMRadioGroup.Create(Panel_Load,12,22,176,35,fnt_Grey);
    Radio_Load_MapType.ItemIndex := 0;
    Radio_Load_MapType.Items.Add(fTextLibrary[TX_MENU_MAPED_SPMAPS]);
    Radio_Load_MapType.Items.Add(fTextLibrary[TX_MENU_MAPED_MPMAPS]);
    Radio_Load_MapType.OnChange := Load_MapTypeChange;
    ListBox_Load := TKMListBox.Create(Panel_Load, 8, 75, 184, 205, fnt_Grey);
    Button_LoadLoad     := TKMButton.Create(Panel_Load,8,290,184,30,'Load',fnt_Metal);
    Button_LoadCancel   := TKMButton.Create(Panel_Load,8,325,184,30,'Cancel',fnt_Metal);
    Button_LoadLoad.OnClick     := Menu_Load;
    Button_LoadCancel.OnClick   := SwitchPage;
end;


{Quit page}
procedure TKMapEdInterface.Create_MenuQuit_Page;
begin
  Panel_Quit:=TKMPanel.Create(Panel_Common,0,128,200,400);
    TKMLabel.Create(Panel_Quit,100,40,184,60,'Any unsaved|changes will be lost',fnt_Outline,taCenter);
    Button_Quit_Yes   := TKMButton.Create(Panel_Quit,8,100,180,30,fTextLibrary[TX_MENU_QUIT_MISSION],fnt_Metal);
    Button_Quit_No    := TKMButton.Create(Panel_Quit,8,140,180,30,fTextLibrary[TX_MENU_DONT_QUIT_MISSION],fnt_Metal);
    Button_Quit_Yes.Hint      := fTextLibrary[TX_MENU_QUIT_MISSION];
    Button_Quit_No.Hint       := fTextLibrary[TX_MENU_DONT_QUIT_MISSION];
    Button_Quit_Yes.OnClick   := Menu_QuitMission;
    Button_Quit_No.OnClick    := SwitchPage;
end;


{Unit page}
procedure TKMapEdInterface.Create_Unit_Page;
begin
  Panel_Unit:=TKMPanel.Create(Panel_Common,0,112,200,400);
    Label_UnitName        := TKMLabel.Create(Panel_Unit,100,16,184,0,'',fnt_Outline,taCenter);
    Image_UnitPic         := TKMImage.Create(Panel_Unit,8,38,54,100,521);
    Label_UnitCondition   := TKMLabel.Create(Panel_Unit,132,40,116,0,fTextLibrary[TX_UNIT_CONDITION],fnt_Grey,taCenter);
    KMConditionBar_Unit   := TKMPercentBar.Create(Panel_Unit,73,55,116,15);
    Label_UnitDescription := TKMLabel.Create(Panel_Unit,8,152,184,200,'',fnt_Grey,taLeft); //Taken from LIB resource

  Panel_Army:=TKMPanel.Create(Panel_Unit,0,160,200,400);
    Button_Army_RotCCW   := TKMButton.Create(Panel_Army,  8, 0, 56, 40, 23);
    Button_Army_RotCW  := TKMButton.Create(Panel_Army,132, 0, 56, 40, 24);
    Button_Army_ForUp   := TKMButton.Create(Panel_Army,  8, 46, 56, 40, 33);
    ImageStack_Army     := TKMImageStack.Create(Panel_Army, 70, 46, 56, 40, 43, 50);
    Label_ArmyCount     := TKMLabel.Create(Panel_Army, 98, 60, 0, 0, '-', fnt_Outline, taCenter);
    Button_Army_ForDown := TKMButton.Create(Panel_Army,132, 46, 56, 40, 32);
    Button_Army_RotCW.OnClick   := Unit_ArmyChange1;
    Button_Army_RotCCW.OnClick  := Unit_ArmyChange1;
    Button_Army_ForUp.OnClick   := Unit_ArmyChange1;
    Button_Army_ForDown.OnClick := Unit_ArmyChange1;

    Button_ArmyDec      := TKMButton.Create(Panel_Army,  8,92,56,40,'-', fnt_Metal);
    Button_ArmyFood     := TKMButton.Create(Panel_Army, 70,92,56,40,29);
    Button_ArmyInc      := TKMButton.Create(Panel_Army,132,92,56,40,'+', fnt_Metal);
    Button_ArmyDec.OnClickEither := Unit_ArmyChange2;
    Button_ArmyFood.OnClick := Unit_ArmyChange1;
    Button_ArmyInc.OnClickEither := Unit_ArmyChange2;
end;


{House description page}
procedure TKMapEdInterface.Create_House_Page;
begin
  Panel_House:=TKMPanel.Create(Panel_Common,0,112,200,400);
    //Thats common things
    Label_House:=TKMLabel.Create(Panel_House,100,14,184,0,'',fnt_Outline,taCenter);
    Image_House_Logo:=TKMImage.Create(Panel_House,8,41,32,32,338);
    Image_House_Logo.ImageCenter;
    Image_House_Worker:=TKMImage.Create(Panel_House,38,41,32,32,141);
    Image_House_Worker.ImageCenter;
    Label_HouseHealth := TKMLabel.Create(Panel_House,130,41,60,20,fTextLibrary[TX_HOUSE_CONDITION],fnt_Mini,taCenter);
    Label_HouseHealth.FontColor := $FFE0E0E0;
    KMHealthBar_House := TKMPercentBar.Create(Panel_House,100,53,60,20);
    Button_HouseHealthDec := TKMButton.Create(Panel_House,80,53,20,20,'-', fnt_Metal);
    Button_HouseHealthInc := TKMButton.Create(Panel_House,160,53,20,20,'+', fnt_Metal);
    Button_HouseHealthDec.OnClickEither := House_HealthChange;
    Button_HouseHealthInc.OnClickEither := House_HealthChange;
end;


{Store page}
procedure TKMapEdInterface.Create_Store_Page;
var I: Integer;
begin
  Panel_HouseStore := TKMPanel.Create(Panel_House,0,76,200,400);
    for I := 1 to STORE_RES_COUNT do
    begin
      Button_Store[I] := TKMButtonFlat.Create(Panel_HouseStore, 8+((I-1)mod 5)*36,8+((I-1)div 5)*42,32,36,0);
      Button_Store[I].TexID := fResource.Resources[StoreResType[I]].GUIIcon;
      Button_Store[I].Tag := I;
      Button_Store[I].Hint := fResource.Resources[StoreResType[I]].Title;
      Button_Store[I].OnClick := Store_SelectWare;
    end;

    Button_StoreDec100      := TKMButton.Create(Panel_HouseStore,116,218,20,20,'<', fnt_Metal);
    Button_StoreDec100.Tag  := 100;
    Button_StoreDec       := TKMButton.Create(Panel_HouseStore,116,238,20,20,'-', fnt_Metal);
    Button_StoreDec.Tag   := 1;
    Label_Store_WareCount:= TKMLabel.Create (Panel_HouseStore,156,230,40,20,'',fnt_Metal,taCenter);
    Button_StoreInc100      := TKMButton.Create(Panel_HouseStore,176,218,20,20,'>', fnt_Metal);
    Button_StoreInc100.Tag  := 100;
    Button_StoreInc       := TKMButton.Create(Panel_HouseStore,176,238,20,20,'+', fnt_Metal);
    Button_StoreInc.Tag   := 1;
    Button_StoreDec100.OnClickEither := Store_EditWareCount;
    Button_StoreDec.OnClickEither    := Store_EditWareCount;
    Button_StoreInc100.OnClickEither := Store_EditWareCount;
    Button_StoreInc.OnClickEither    := Store_EditWareCount;
end;


{Barracks page}
procedure TKMapEdInterface.Create_Barracks_Page;
var i:Integer;
begin
  Panel_HouseBarracks:=TKMPanel.Create(Panel_House,0,76,200,400);
    for i:=1 to BARRACKS_RES_COUNT do
    begin
      Button_Barracks[i]:=TKMButtonFlat.Create(Panel_HouseBarracks, 8+((i-1)mod 6)*31,8+((i-1)div 6)*42,28,38,0);
      Button_Barracks[i].Tag := i;
      Button_Barracks[i].TexID := fResource.Resources[BarracksResType[i]].GUIIcon;
      Button_Barracks[i].TexOffsetX := 1;
      Button_Barracks[i].TexOffsetY := 1;
      Button_Barracks[i].CapOffsetY := 2;
      Button_Barracks[i].Hint := fResource.Resources[BarracksResType[i]].Title;
      Button_Barracks[i].OnClick := Barracks_SelectWare;
    end;
    Button_BarracksDec100     := TKMButton.Create(Panel_HouseBarracks,116,218,20,20,'<', fnt_Metal);
    Button_BarracksDec100.Tag := 100;
    Button_BarracksDec      := TKMButton.Create(Panel_HouseBarracks,116,238,20,20,'-', fnt_Metal);
    Button_BarracksDec.Tag  := 1;
    Label_Barracks_WareCount:= TKMLabel.Create (Panel_HouseBarracks,156,230,40,20,'',fnt_Metal,taCenter);
    Button_BarracksInc100     := TKMButton.Create(Panel_HouseBarracks,176,218,20,20,'>', fnt_Metal);
    Button_BarracksInc100.Tag := 100;
    Button_BarracksInc      := TKMButton.Create(Panel_HouseBarracks,176,238,20,20,'+', fnt_Metal);
    Button_BarracksInc.Tag  := 1;
    Button_BarracksDec100.OnClickEither := Barracks_EditWareCount;
    Button_BarracksDec.OnClickEither    := Barracks_EditWareCount;
    Button_BarracksInc100.OnClickEither := Barracks_EditWareCount;
    Button_BarracksInc.OnClickEither    := Barracks_EditWareCount;
end;


//Should update any items changed by game (resource counts, hp, etc..)
procedure TKMapEdInterface.UpdateState(aTickCount: Cardinal);
begin
  //
end;


procedure TKMapEdInterface.SetMinimap;
begin
  MinimapView.SetMinimap(fGame.Minimap);
  MinimapView.SetViewport(fGame.Viewport);
end;


procedure TKMapEdInterface.SetMapName(const aName: string);
begin
  Label_MissionName.Caption := aName;
end;


procedure TKMapEdInterface.Player_UpdateColors;
var i:Integer;
begin
  //Set player colors
  for i:=0 to MAX_PLAYERS-1 do
    Button_PlayerSelect[i].ShapeColor := fPlayers.Player[i].FlagColor;

  Button_Village[2].FlagColor := MyPlayer.FlagColor;
  for i:=Low(Button_Citizen) to High(Button_Citizen) do
    Button_Citizen[i].FlagColor := MyPlayer.FlagColor;
  for i:=Low(Button_Warriors) to High(Button_Warriors) do
    Button_Warriors[i].FlagColor := MyPlayer.FlagColor;
end;


procedure TKMapEdInterface.Player_ChangeActive(Sender: TObject);
begin
  if Panel_House.Visible or Panel_Unit.Visible then
    SwitchPage(nil);

  fPlayers.Selected := nil;

  if Sender <> nil then
    SetActivePlayer(TKMControl(Sender).Tag)
  else
    SetActivePlayer(-1);

  Player_BlockRefresh;
end;


procedure TKMapEdInterface.SetActivePlayer(aIndex: TPlayerIndex);
var I: Integer;
begin
  if aIndex <> -1 then
    MyPlayer := fPlayers.Player[aIndex]
  else
    MyPlayer := fPlayers.Player[0];

  for I := 0 to MAX_PLAYERS - 1 do
    Button_PlayerSelect[I].Down := (I = MyPlayer.PlayerIndex);

  Player_UpdateColors;
end;


procedure TKMapEdInterface.Terrain_HeightChange(Sender: TObject);
begin
  GameCursor.MapEdSize := HeightSize.Position;
  GameCursor.MapEdSlope := HeightShape.Position;

  if Sender = HeightCircle then
  begin
    HeightCircle.Down := true;
    HeightSquare.Down := false;
    GameCursor.MapEdShape := hsCircle;
  end else
  if Sender = HeightSquare then
  begin
    HeightSquare.Down := true;
    HeightCircle.Down := false;
    GameCursor.MapEdShape := hsSquare;
  end else
  if Sender = HeightElevate then
  begin
    HeightElevate.Down := True;
    HeightUnequalize.Down:=false;
    GameCursor.Mode := cm_Elevate;
  end;
  if Sender = HeightUnequalize then
  begin
    HeightElevate.Down  := false;
    HeightUnequalize.Down := true;
    GameCursor.Mode := cm_Equalize;
  end;
end;


procedure TKMapEdInterface.Terrain_TilesChange(Sender: TObject);

  function GetTileIDFromTag(aTag: byte):byte;
  var Tile:byte;
  begin
    Tile := 32*((aTag-1) div MAPED_TILES_COLS) + (aTag-1) mod MAPED_TILES_COLS + TilesScroll.Position;
    Result := MapEdTileRemap[EnsureRange(Tile+1,1,256)];
  end;

var i,k,TileID:Integer;
begin
  if Sender = TilesRandom then
    GameCursor.MapEdDir := 4 * byte(TilesRandom.Checked); //Defined=0..3 or Random=4

  if Sender = TilesScroll then //Shift tiles
    for i:=1 to MAPED_TILES_COLS do
    for k:=1 to MAPED_TILES_ROWS do
    begin
      if GetTileIDFromTag((k-1)*MAPED_TILES_COLS+i) <> 0 then
      begin
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].TexID := GetTileIDFromTag((k-1)*MAPED_TILES_COLS+i); //icons are in 2..9
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Enable;
      end
      else
      begin
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].TexID := 0;
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Disable;
      end;
      if GameCursor.Mode = cm_Tiles then
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Down := (GameCursor.Tag1+1 = GetTileIDFromTag((k-1)*MAPED_TILES_COLS+i));
    end;
  if Sender is TKMButtonFlat then
  begin
    TileID := GetTileIDFromTag(TKMButtonFlat(Sender).Tag);
    if TileID <> 0 then
    begin
      GameCursor.Mode := cm_Tiles;
      GameCursor.Tag1 := TileID-1; //MapEdTileRemap is 1 based, tag is 0 based
      if TilesRandom.Checked then
        GameCursor.MapEdDir := 4;
      for i:=1 to MAPED_TILES_COLS do
      for k:=1 to MAPED_TILES_ROWS do
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Down := (Sender = TilesTable[(i-1)*MAPED_TILES_ROWS+k]);
    end;
  end;
end;


procedure TKMapEdInterface.Terrain_ObjectsChange(Sender: TObject);
var I, ObjID: Integer;
begin
  for I := 0 to 8 do
    ObjectsTable[i].Down := False;

  ObjectErase.Down := False;

  if Sender = ObjectsScroll then
  begin
    for I := 0 to 8 do
    begin
      ObjID := ObjectsScroll.Position * 3 + I;
      if ObjID < fResource.MapElements.ValidCount then
      begin
        ObjectsTable[I].TexID := MapElem[fResource.MapElements.ValidToObject[ObjID]].Anim.Step[1] + 1;
        ObjectsTable[I].Caption := IntToStr(ObjID);
        ObjectsTable[I].Enable;
      end
      else
      begin
        ObjectsTable[I].TexID := 0;
        ObjectsTable[I].Caption := '';
        ObjectsTable[I].Disable;
      end;
      ObjectsTable[I].Down := ObjID = fResource.MapElements.ObjectToValid[GameCursor.Tag1]; //Mark the selected one using reverse lookup
    end;
    ObjectErase.Down := (GameCursor.Tag1 = 255); //or delete button
  end;

  if Sender is TKMButtonFlat then
  begin
    ObjID := ObjectsScroll.Position * 3 + TKMButtonFlat(Sender).Tag; //0..n-1

    if (not InRange(ObjID, 0, fResource.MapElements.ValidCount - 1))
    and not (TKMButtonFlat(Sender).Tag = 255) then
      Exit; //Don't let them click if it is out of range

    GameCursor.Mode := cm_Objects;
    if TKMButtonFlat(Sender).Tag = 255 then
      GameCursor.Tag1 := 255 //erase object
    else
      GameCursor.Tag1 := fResource.MapElements.ValidToObject[ObjID]; //0..n-1
    for I := 0 to 8 do
      ObjectsTable[I].Down := (Sender = ObjectsTable[I]); //Mark the selected one
    ObjectErase.Down := (Sender = ObjectErase); //or delete button
  end;
end;


procedure TKMapEdInterface.Build_ButtonClick(Sender: TObject);
var i:Integer;
begin
  //Release all buttons
  for i:=1 to Panel_Build.ChildCount do
    if Panel_Build.Childs[i] is TKMButtonFlat then
      TKMButtonFlat(Panel_Build.Childs[i]).Down:=false;

  //Press the button
  TKMButtonFlat(Sender).Down := true;

  //Reset cursor and see if it needs to be changed
  GameCursor.Mode:=cm_None;
  GameCursor.Tag1:=0;

  if Button_BuildCancel.Down then begin
    GameCursor.Mode:=cm_Erase;
  end;
  if Button_BuildRoad.Down then begin
    GameCursor.Mode:=cm_Road;
  end;
  if Button_BuildField.Down then begin
    GameCursor.Mode:=cm_Field;
  end;
  if Button_BuildWine.Down then begin
    GameCursor.Mode:=cm_Wine;
  end;
{  if Button_BuildWall.Down then begin
    GameCursor.Mode:=cm_Wall;
  end;}

  for i:=1 to GUI_HOUSE_COUNT do
  if GUIHouseOrder[i] <> ht_None then
  if Button_Build[i].Down then begin
     GameCursor.Mode := cm_Houses;
     GameCursor.Tag1 := byte(GUIHouseOrder[i]);
  end;
end;


procedure TKMapEdInterface.Unit_ButtonClick(Sender: TObject);
var i:Integer;
begin
  if Sender=nil then begin GameCursor.Mode:=cm_None; exit; end;

  //Release all buttons
  for i:=1 to Panel_Units.ChildCount do
    if Panel_Units.Childs[i] is TKMButtonFlat then
      TKMButtonFlat(Panel_Units.Childs[i]).Down := false;

  //Press the button
  TKMButtonFlat(Sender).Down:=true;

  //Reset cursor and see if it needs to be changed
  GameCursor.Mode:=cm_None;
  GameCursor.Tag1:=0;
  //Label_Build.Caption := '';

  if Button_UnitCancel.Down then begin
    GameCursor.Mode:=cm_Erase;
  end;

  if (TKMButtonFlat(Sender).Tag in [byte(UNIT_MIN)..byte(UNIT_MAX)]) then
  begin
    GameCursor.Mode := cm_Units;
    GameCursor.Tag1 := byte(TKMButtonFlat(Sender).Tag);
  end;

end;


procedure TKMapEdInterface.View_Passability(Sender: TObject);
begin
  SHOW_TERRAIN_WIRES := (TKMTrackBar(Sender).Position <> 0);
  fShowPassability := TKMTrackBar(Sender).Position;
  if TKMTrackBar(Sender).Position <> 0 then
    Label_Passability.Caption := GetEnumName(TypeInfo(TPassability), TKMTrackBar(Sender).Position)
  else
    Label_Passability.Caption := 'Off';
end;


procedure TKMapEdInterface.ShowHouseInfo(Sender: TKMHouse);
begin
  if Sender = nil then<commit_msg>Restored passability display in MapEd<commit_after>unit KM_InterfaceMapEditor;
{$I KaM_Remake.inc}
interface
uses
     {$IFDEF MSWindows} Windows, {$ENDIF}
     {$IFDEF Unix} LCLIntf, LCLType, {$ENDIF}
     Classes, Controls, KromUtils, Math, StrUtils, SysUtils, KromOGLUtils, TypInfo,
     KM_Controls, KM_Defaults, KM_Pics, KM_Maps, KM_Houses, KM_Units,
     KM_Points, KM_InterfaceDefaults, KM_Terrain;

type
  TKMapEdInterface = class (TKMUserInterface)
  private
    PrevHint:TObject;
    StorehouseItem:byte; //Selected ware in storehouse
    BarracksItem:byte; //Selected ware in barracks
    TileDirection: byte;
    fMaps: TKMapsCollection;
    fMapsMP: TKMapsCollection;

    procedure Create_Terrain_Page;
    procedure Create_Village_Page;
    procedure Create_Player_Page;
    procedure Create_Mission_Page;
    procedure Create_Menu_Page;
    procedure Create_MenuSave_Page;
    procedure Create_MenuLoad_Page;
    procedure Create_MenuQuit_Page;
    procedure Create_Unit_Page;
    procedure Create_House_Page;
    procedure Create_Store_Page;
    procedure Create_Barracks_Page;

    procedure SwitchPage(Sender: TObject);
    procedure DisplayHint(Sender: TObject);
    procedure Minimap_Update(Sender: TObject; const X,Y: Integer);

    procedure Menu_Save(Sender:TObject);
    procedure Menu_Load(Sender:TObject);
    procedure Menu_QuitMission(Sender:TObject);
    procedure Load_MapTypeChange(Sender:TObject);
    procedure Load_MapListUpdate;
    procedure Load_MapListUpdateDone(Sender: TObject);
    procedure Terrain_HeightChange(Sender: TObject);
    procedure Terrain_TilesChange(Sender: TObject);
    procedure Terrain_ObjectsChange(Sender: TObject);
    procedure Build_ButtonClick(Sender: TObject);
    procedure House_HealthChange(Sender:TObject; AButton:TMouseButton);
    procedure Unit_ButtonClick(Sender: TObject);
    procedure Unit_ArmyChange1(Sender:TObject); overload;
    procedure Unit_ArmyChange2(Sender:TObject; AButton:TMouseButton); overload;
    procedure Barracks_Fill(Sender:TObject);
    procedure Barracks_SelectWare(Sender:TObject);
    procedure Barracks_EditWareCount(Sender:TObject; AButton:TMouseButton);
    procedure Store_Fill(Sender:TObject);
    procedure Store_SelectWare(Sender:TObject);
    procedure Store_EditWareCount(Sender:TObject; AButton:TMouseButton);
    procedure Player_ChangeActive(Sender: TObject);
    procedure SetActivePlayer(aIndex: TPlayerIndex);
    procedure SetTileDirection(aTileDirection: byte);
    procedure Player_ColorClick(Sender:TObject);
    procedure Player_BlockRefresh;
    procedure Player_BlockClick(Sender:TObject);
    procedure Mission_AlliancesChange(Sender:TObject);
    procedure Mission_PlayerTypesChange(Sender:TObject);
    procedure View_Passability(Sender:TObject);

    function GetSelectedTile: TObject;
    function GetSelectedObject: TObject;
    function GetSelectedUnit: TObject;
  protected
    Panel_Main:TKMPanel;
      MinimapView: TKMMinimapView;
      Label_Coordinates:TKMLabel;
      TrackBar_Passability:TKMTrackBar;
      Label_Passability:TKMLabel;
      Button_PlayerSelect:array[0..MAX_PLAYERS-1]of TKMFlatButtonShape; //Animals are common for all
      Label_Stat,Label_Hint:TKMLabel;
    Panel_Common:TKMPanel;
      Button_Main:array[1..5]of TKMButton; //5 buttons
      Label_MenuTitle: TKMLabel; //Displays the title of the current menu below
      Label_MissionName: TKMLabel;

    Panel_Terrain:TKMPanel;
      Button_Terrain:array[1..4]of TKMButton;
      Panel_Brushes:TKMPanel;
        BrushSize:TKMTrackBar;
        BrushCircle,BrushSquare:TKMButtonFlat;
        //BrushesTable:array[1..27] of TKMButtonFlat; // todo
      Panel_Heights:TKMPanel;
        HeightSize,HeightShape:TKMTrackBar;
        HeightCircle,HeightSquare:TKMButtonFlat;
        HeightElevate, HeightUnequalize: TKMButtonFlat;
      Panel_Tiles:TKMPanel;
        TilesTable:array[1..MAPED_TILES_COLS*MAPED_TILES_ROWS] of TKMButtonFlat; //how many are visible?
        TilesScroll:TKMScrollBar;
        TilesRandom:TKMCheckBox;
      Panel_Objects:TKMPanel;
        ObjectErase:TKMButtonFlat;
        ObjectsTable:array[0..8] of TKMButtonFlat;
        ObjectsScroll:TKMScrollBar;

    Panel_Village:TKMPanel;
      Button_Village:array[1..3]of TKMButton;
      Panel_Build:TKMPanel;
        Button_BuildRoad,Button_BuildField,Button_BuildWine,Button_BuildCancel:TKMButtonFlat;
        Button_Build:array[1..GUI_HOUSE_COUNT]of TKMButtonFlat;
      Panel_Units:TKMPanel;
        Button_UnitCancel:TKMButtonFlat;
        Button_Citizen:array[0..13]of TKMButtonFlat;
        Button_Warriors:array[0..13]of TKMButtonFlat;
        Button_Animals:array[0..7]of TKMButtonFlat;
      Panel_Script:TKMPanel;

    Panel_Player:TKMPanel;
      Button_Player:array[1..3]of TKMButton;
      Panel_Goals:TKMPanel;
      Panel_Color:TKMPanel;
        ColorSwatch_Color:TKMColorSwatch;
      Panel_Block: TKMPanel;
        Button_BlockHouse: array [1 .. GUI_HOUSE_COUNT] of TKMButtonFlat;
        Image_BlockHouse: array [1 .. GUI_HOUSE_COUNT] of TKMImage;

    Panel_Mission:TKMPanel;
      Button_Mission:array[1..2]of TKMButton;
      Panel_Alliances:TKMPanel;
        CheckBox_Alliances: array[0..MAX_PLAYERS-1,0..MAX_PLAYERS-1] of TKMCheckBox;
        CheckBox_AlliancesSym:TKMCheckBox;
      Panel_PlayerTypes:TKMPanel;
        CheckBox_PlayerTypes: array[0..MAX_PLAYERS-1,0..1] of TKMCheckBox;

    Panel_Menu:TKMPanel;
      Button_Menu_Save,Button_Menu_Load,Button_Menu_Settings,Button_Menu_Quit:TKMButton;

      Panel_Save:TKMPanel;
        Radio_Save_MapType:TKMRadioGroup;
        Edit_SaveName:TKMEdit;
        Label_SaveExists:TKMLabel;
        CheckBox_SaveExists:TKMCheckBox;
        Button_SaveSave:TKMButton;
        Button_SaveCancel:TKMButton;

      Panel_Load:TKMPanel;
        Radio_Load_MapType:TKMRadioGroup;
        ListBox_Load:TKMListBox;
        Button_LoadLoad:TKMButton;
        Button_LoadCancel:TKMButton;

      Panel_Quit:TKMPanel;
        Button_Quit_Yes,Button_Quit_No:TKMButton;

    Panel_Unit:TKMPanel;
      Label_UnitName:TKMLabel;
      Label_UnitCondition:TKMLabel;
      Label_UnitDescription:TKMLabel;
      KMConditionBar_Unit:TKMPercentBar;
      Image_UnitPic:TKMImage;

      Panel_Army:TKMPanel;
        Button_Army_RotCW,Button_Army_RotCCW: TKMButton;
        Button_Army_ForUp,Button_Army_ForDown: TKMButton;
        ImageStack_Army: TKMImageStack;
        Label_ArmyCount: TKMLabel;
        Button_ArmyDec,Button_ArmyFood,Button_ArmyInc: TKMButton;

    Panel_House:TKMPanel;
      Label_House:TKMLabel;
      Image_House_Logo,Image_House_Worker:TKMImage;
      Label_HouseHealth:TKMLabel;
      KMHealthBar_House:TKMPercentBar;
      Button_HouseHealthDec,Button_HouseHealthInc:TKMButton;

    Panel_HouseStore:TKMPanel;
      Button_Store:array[1..STORE_RES_COUNT]of TKMButtonFlat;
      Label_Store_WareCount:TKMLabel;
      Button_StoreDec100,Button_StoreDec:TKMButton;
      Button_StoreInc100,Button_StoreInc:TKMButton;
    Panel_HouseBarracks:TKMPanel;
      Button_Barracks:array[1..BARRACKS_RES_COUNT]of TKMButtonFlat;
      Label_Barracks_WareCount:TKMLabel;
      Button_BarracksDec100,Button_BarracksDec:TKMButton;
      Button_BarracksInc100,Button_BarracksInc:TKMButton;
  public
    constructor Create(aScreenX, aScreenY: word);
    destructor Destroy; override;
    procedure Player_UpdateColors;
    procedure ShowHouseInfo(Sender:TKMHouse);
    procedure ShowUnitInfo(Sender:TKMUnit);
    procedure SetMinimap;
    procedure SetMapName(const aName:string);
    procedure RightClick_Cancel;
    function GetShownPage: TKMMapEdShownPage;
    procedure SetLoadMode(aMultiplayer:boolean);

    procedure KeyDown(Key:Word; Shift: TShiftState); override;
    procedure KeyUp(Key:Word; Shift: TShiftState); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X,Y: Integer); override;

    procedure Resize(X,Y: Word); override;
    procedure UpdateState(aTickCount: Cardinal); override;
  end;


implementation
uses KM_Units_Warrior, KM_PlayersCollection, KM_Player, KM_TextLibrary,
     KM_Utils, KM_Game, KM_GameApp, KM_Resource, KM_ResourceUnit, KM_ResourceCursors, KM_ResourceMapElements;


{Switch between pages}
procedure TKMapEdInterface.SwitchPage(Sender: TObject);
var
  i, k:Integer;
begin

  //Reset cursor mode
  GameCursor.Mode := cm_None;
  GameCursor.Tag1 := 0;

  //If the user clicks on the tab that is open, it closes it (main buttons only)
  if ((Sender = Button_Main[1]) and Panel_Terrain.Visible) or
     ((Sender = Button_Main[2]) and Panel_Village.Visible) or
     ((Sender = Button_Main[3]) and Panel_Player.Visible) or
     ((Sender = Button_Main[4]) and Panel_Mission.Visible) or
     ((Sender = Button_Main[5]) and Panel_Menu.Visible) then
     Sender := nil;

  //Reset shown item if user clicked on any of the main buttons
  if (Sender=Button_Main[1])or(Sender=Button_Main[2])or
     (Sender=Button_Main[3])or(Sender=Button_Main[4])or
     (Sender=Button_Main[5])or
     (Sender=Button_Menu_Settings)or(Sender=Button_Menu_Quit) then
  begin
    fPlayers.Selected:=nil;
  end;

  Label_MenuTitle.Caption := '';
  //Now hide all existing pages
    for i:=1 to Panel_Common.ChildCount do
      if Panel_Common.Childs[i] is TKMPanel then
      begin
        for k:=1 to TKMPanel(Panel_Common.Childs[i]).ChildCount do
          if TKMPanel(Panel_Common.Childs[i]).Childs[k] is TKMPanel then
            TKMPanel(Panel_Common.Childs[i]).Childs[k].Hide;
        Panel_Common.Childs[i].Hide;
      end;

  if (Sender = Button_Main[1])or(Sender = Button_Terrain[1]) then begin
    Panel_Terrain.Show;
    Panel_Brushes.Show;
    Label_MenuTitle.Caption:='Terrain - Brushes';
  end else

  if (Sender = Button_Main[1])or(Sender = Button_Terrain[2]) then begin
    Panel_Terrain.Show;
    Panel_Heights.Show;
    Label_MenuTitle.Caption:='Terrain - Heights';
    Terrain_HeightChange(HeightCircle); //Select the default mode
  end else

  if (Sender = Button_Main[1])or(Sender = Button_Terrain[3]) then begin
    Panel_Terrain.Show;
    Panel_Tiles.Show;
    Label_MenuTitle.Caption:='Terrain - Tiles';
    SetTileDirection(TileDirection); //ensures tags are in allowed ranges
    Terrain_TilesChange(GetSelectedTile);
  end else

  if (Sender = Button_Main[1])or(Sender = Button_Terrain[4]) then begin
    Panel_Terrain.Show;
    Panel_Objects.Show;
    Label_MenuTitle.Caption:='Terrain - Objects';
    Terrain_ObjectsChange(GetSelectedObject);
  end else

  if (Sender = Button_Main[2])or(Sender = Button_Village[1]) then begin
    Panel_Village.Show;
    Panel_Build.Show;
    Label_MenuTitle.Caption:='Village - Buildings';
    Build_ButtonClick(Button_BuildRoad);
  end else

  if (Sender = Button_Main[2])or(Sender = Button_Village[2]) then begin
    Panel_Village.Show;
    Panel_Units.Show;
    Label_MenuTitle.Caption:='Village - Units';
    Unit_ButtonClick(GetSelectedUnit);
  end else

  if (Sender = Button_Main[2])or(Sender = Button_Village[3]) then begin
    Panel_Village.Show;
    Panel_Script.Show;
    Label_MenuTitle.Caption:='Village - Script';
  end else

  if (Sender = Button_Main[3])or(Sender = Button_Player[1]) then begin
    Panel_Player.Show;
    Panel_Goals.Show;
    Label_MenuTitle.Caption:='Player - Goals';
  end else

  if (Sender = Button_Main[3])or(Sender = Button_Player[2]) then begin
    Panel_Player.Show;
    Panel_Color.Show;
    Label_MenuTitle.Caption:='Player - Color';
  end else

  if (Sender = Button_Main[3])or(Sender = Button_Player[3]) then begin
    Player_BlockRefresh;
    Panel_Player.Show;
    Panel_Block.Show;
    Label_MenuTitle.Caption:='Player - Block houses';
  end else

  if (Sender = Button_Main[4])or(Sender = Button_Mission[1]) then begin
    Panel_Mission.Show;
    Panel_Alliances.Show;
    Label_MenuTitle.Caption:='Mission - Alliances';
    Mission_AlliancesChange(nil);
  end else

  if (Sender = Button_Main[4])or(Sender = Button_Mission[2]) then begin
    Panel_Mission.Show;
    Panel_PlayerTypes.Show;
    Label_MenuTitle.Caption:='Mission - Player Types';
    Mission_PlayerTypesChange(nil);
  end else

  if (Sender=Button_Main[5]) or
     (Sender=Button_Quit_No) or
     (Sender = Button_LoadCancel) or
     (Sender = Button_SaveCancel) then begin
    Panel_Menu.Show;
    Label_MenuTitle.Caption := fTextLibrary[TX_MENU_TAB_OPTIONS];
  end else

  if Sender=Button_Menu_Quit then begin
    Panel_Quit.Show;
  end;

  if Sender = Button_Menu_Save then begin
    Edit_SaveName.Text := fGame.GameName;
    Menu_Save(Edit_SaveName);
    Panel_Save.Show;
  end;

  if Sender = Button_Menu_Load then begin
    Load_MapListUpdate;
    Panel_Load.Show;
  end;

  //Now process all other kinds of pages
  if Sender=Panel_Unit then begin
    TKMPanel(Sender).Show;
  end else

  if Sender=Panel_House then begin
    TKMPanel(Sender).Show;
  end;

  if Sender=Panel_HouseBarracks then begin
    TKMPanel(Sender).Parent.Show;
    TKMPanel(Sender).Show;
  end else

  if Sender=Panel_HouseStore then begin
    TKMPanel(Sender).Parent.Show;
    TKMPanel(Sender).Show;
  end;

end;


procedure TKMapEdInterface.DisplayHint(Sender: TObject);
begin
  if (PrevHint = Sender) then exit; //Hint didn't changed

  if Sender=nil then Label_Hint.Caption:=''
                else Label_Hint.Caption:=TKMControl(Sender).Hint;

  PrevHint := Sender;
end;


//Update viewport position when user interacts with minimap
procedure TKMapEdInterface.Minimap_Update(Sender: TObject; const X,Y: Integer);
begin
  fGame.Viewport.Position := KMPointF(X,Y);
end;


constructor TKMapEdInterface.Create(aScreenX, aScreenY: word);
var
  i: Integer;
begin
  inherited;

  BarracksItem   := 1; //First ware selected by default
  StorehouseItem := 1; //First ware selected by default
  TileDirection := 0;
  fMaps := TKMapsCollection.Create(False);
  fMapsMP := TKMapsCollection.Create(True);

  //Parent Page for whole toolbar in-game
  Panel_Main := TKMPanel.Create(fMyControls, 0, 0, aScreenX, aScreenY);

    TKMImage.Create(Panel_Main,0,   0,224,200,407); //Minimap place
    TKMImage.Create(Panel_Main,0, 200,224,400,404);
    TKMImage.Create(Panel_Main,0, 600,224,400,404);
    TKMImage.Create(Panel_Main,0,1000,224,400,404); //For 1600x1200 this is needed

    MinimapView := TKMMinimapView.Create(Panel_Main, 10, 10, 176, 176);
    MinimapView.OnChange := Minimap_Update;

    Label_Coordinates := TKMLabel.Create(Panel_Main,8,192,184,0,'X: Y:',fnt_Outline,taLeft);
    TrackBar_Passability := TKMTrackBar.Create(Panel_Main, 8, 210, 184, 0, Byte(High(TPassability)));
    TrackBar_Passability.Caption := 'View passability';
    TrackBar_Passability.Position := 0; //Disabled by default
    TrackBar_Passability.OnChange := View_Passability;
    Label_Passability := TKMLabel.Create(Panel_Main,8,248,184,0,'Off',fnt_Metal,taLeft);

    TKMLabel.Create(Panel_Main,8,270,184,0,'Player',fnt_Metal,taLeft);
    for i:=0 to MAX_PLAYERS-1 do begin
      Button_PlayerSelect[i]         := TKMFlatButtonShape.Create(Panel_Main, 8 + i*23, 290, 21, 32, inttostr(i+1), fnt_Grey, $FF0000FF);
      Button_PlayerSelect[i].CapOffsetY := -3;
      Button_PlayerSelect[i].Tag     := i;
      Button_PlayerSelect[i].OnClick := Player_ChangeActive;
    end;

    Label_MissionName := TKMLabel.Create(Panel_Main, 8, 340, 184, 10, '<<<LEER>>>', fnt_Metal, taLeft);

    Label_Stat:=TKMLabel.Create(Panel_Main,224+8,16,0,0,'',fnt_Outline,taLeft);
    Label_Hint:=TKMLabel.Create(Panel_Main,224+8,Panel_Main.Height-16,0,0,'',fnt_Outline,taLeft);
    Label_Hint.Anchors := [akLeft, akBottom];

  Panel_Common := TKMPanel.Create(Panel_Main,0,300,224,768);

    {5 big tabs}
    Button_Main[1] := TKMButton.Create(Panel_Common,   8, 72, 36, 36, 381);
    Button_Main[2] := TKMButton.Create(Panel_Common,  46, 72, 36, 36, 368);
    Button_Main[3] := TKMButton.Create(Panel_Common,  84, 72, 36, 36,  41);
    Button_Main[4] := TKMButton.Create(Panel_Common, 122, 72, 36, 36, 441);
    Button_Main[5] := TKMButton.Create(Panel_Common, 160, 72, 36, 36, 389);
    Button_Main[1].Hint := fTextLibrary[TX_MAPEDITOR_TERRAIN];
    Button_Main[2].Hint := fTextLibrary[TX_MAPEDITOR_VILLAGE];
    Button_Main[3].Hint := fTextLibrary[TX_MAPEDITOR_SCRIPTS_VISUAL];
    Button_Main[4].Hint := fTextLibrary[TX_MAPEDITOR_SCRIPTS_GLOBAL];
    Button_Main[5].Hint := fTextLibrary[TX_MAPEDITOR_MENU];
    for i:=1 to 5 do Button_Main[i].OnClick := SwitchPage;

    Label_MenuTitle:=TKMLabel.Create(Panel_Common,8,112,184,36,'',fnt_Metal,taLeft); //Should be one-line


{I plan to store all possible layouts on different pages which gets displayed one at a time}
{==========================================================================================}
  Create_Terrain_Page;
  Create_Village_Page;
  Create_Player_Page;
  Create_Mission_Page;

  Create_Menu_Page;
    Create_MenuSave_Page;
    Create_MenuLoad_Page;
    Create_MenuQuit_Page;

  Create_Unit_Page;
  Create_House_Page;
    Create_Store_Page;
    Create_Barracks_Page;
    //Create_TownHall_Page;

  fMyControls.OnHint := DisplayHint;

  SwitchPage(nil); //Update
end;


destructor TKMapEdInterface.Destroy;
begin
  fMaps.Free;
  fMapsMP.Free;
  SHOW_TERRAIN_WIRES := false; //Don't show it in-game if they left it on in MapEd
  inherited;
end;


//Update Hint position and etc..
procedure TKMapEdInterface.Resize(X,Y: Word);
begin
  Panel_Main.Width := X;
  Panel_Main.Height := Y;
end;


{Terrain page}
procedure TKMapEdInterface.Create_Terrain_Page;
var i,k:Integer;
begin
  Panel_Terrain := TKMPanel.Create(Panel_Common,0,128,196,28);
    Button_Terrain[1] := TKMButton.Create(Panel_Terrain,   8, 4, 36, 24, 383);
    Button_Terrain[2] := TKMButton.Create(Panel_Terrain,  48, 4, 36, 24, 388);
    Button_Terrain[3] := TKMButton.Create(Panel_Terrain,  88, 4, 36, 24, 382);
    Button_Terrain[4] := TKMButton.Create(Panel_Terrain, 128, 4, 36, 24, 385);
    for i:=1 to 4 do Button_Terrain[i].OnClick := SwitchPage;

    Panel_Brushes := TKMPanel.Create(Panel_Terrain,0,28,196,400);
      BrushSize   := TKMTrackBar.Create(Panel_Brushes, 8, 10, 100, 1, 12);
      BrushCircle := TKMButtonFlat.Create(Panel_Brushes, 114, 8, 24, 24, 359);
      BrushSquare := TKMButtonFlat.Create(Panel_Brushes, 142, 8, 24, 24, 352);

      TKMButtonFlat.Create(Panel_Brushes, 8, 30, 32, 32, 1, rxTiles);   // grass

      {TKMButtonFlat.Create(Panel_Brushes, 40, 30, 32, 32, 9, rxTiles);  // grass 2
      TKMButtonFlat.Create(Panel_Brushes, 8, 62, 32, 32, 35, rxTiles);  // dirt

      {BrushSize.OnChange   := TerrainBrush_Change;
      BrushCircle.OnChange := TerrainBrush_Change;
      BrushSquare.OnChange := TerrainBrush_Change;}

    Panel_Heights := TKMPanel.Create(Panel_Terrain,0,28,196,400);
      HeightSize   := TKMTrackBar.Create(Panel_Heights, 8, 10, 100, 1, 15); //1..15(4bit) for size
      HeightCircle := TKMButtonFlat.Create(Panel_Heights, 114, 8, 24, 24, 359);
      HeightSquare := TKMButtonFlat.Create(Panel_Heights, 142, 8, 24, 24, 352);
      HeightShape  := TKMTrackBar.Create(Panel_Heights, 8, 30, 100, 1, 15); //1..15(4bit) for slope shape

      HeightElevate             := TKMButtonFlat.Create(Panel_Heights,8,70,180,20,0);
      HeightElevate.OnClick     := Terrain_HeightChange;
      HeightElevate.Down        := True;
      HeightElevate.Caption     := 'Elevate';
      HeightElevate.CapOffsetY  := -12;
      HeightUnequalize          := TKMButtonFlat.Create(Panel_Heights,8,100,180,20,0);
      HeightUnequalize.OnClick  := Terrain_HeightChange;
      HeightUnequalize.Caption  := 'Uniqualize/flat';
      HeightUnequalize.CapOffsetY  := -12;

      HeightSize.OnChange   := Terrain_HeightChange;
      HeightShape.OnChange  := Terrain_HeightChange;
      HeightCircle.OnClick  := Terrain_HeightChange;
      HeightSquare.OnClick  := Terrain_HeightChange;

    Panel_Tiles := TKMPanel.Create(Panel_Terrain,0,28,196,400);
      TilesRandom := TKMCheckBox.Create(Panel_Tiles, 8, 4, 188, 20, 'Random Direction', fnt_Metal);
      TilesRandom.Checked := true;
      TilesRandom.OnClick := Terrain_TilesChange;
      TilesScroll := TKMScrollBar.Create(Panel_Tiles, 2, 30 + 4 + MAPED_TILES_ROWS * 32, 194, 20, sa_Horizontal, bsGame);
      TilesScroll.MaxValue := 256 div MAPED_TILES_ROWS - MAPED_TILES_COLS; // 16 - 6
      TilesScroll.Position := 0;
      TilesScroll.OnChange := Terrain_TilesChange;
      for i:=1 to MAPED_TILES_COLS do for k:=1 to MAPED_TILES_ROWS do begin
        TilesTable[(i-1)*MAPED_TILES_ROWS+k] := TKMButtonFlat.Create(Panel_Tiles,2+(i-1)*32,30+(k-1)*32,32,32,1,rxTiles); //2..9
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Tag := (k-1)*MAPED_TILES_COLS+i; //Store ID
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].OnClick := Terrain_TilesChange;
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].OnMouseWheel := TilesScroll.MouseWheel;
      end;
      Terrain_TilesChange(TilesScroll); //This ensures that the displayed images get updated the first time
      Terrain_TilesChange(TilesTable[1]);

    Panel_Objects := TKMPanel.Create(Panel_Terrain,0,28,196,400);
      ObjectsScroll := TKMScrollBar.Create(Panel_Objects, 8, 295, 180, 20, sa_Horizontal, bsGame);
      ObjectsScroll.MinValue := 0;
      ObjectsScroll.MaxValue := fResource.MapElements.ValidCount div 3 - 2;
      ObjectsScroll.Position := 0;
      ObjectsScroll.OnChange := Terrain_ObjectsChange;
      ObjectErase := TKMButtonFlat.Create(Panel_Objects, 8, 8,32,32,340);
      for I := 0 to 2 do for K := 0 to 2 do
      begin
        ObjectsTable[I*3+K] := TKMButtonFlat.Create(Panel_Objects, 8+I*65, 40+K*85,64,84,1,rxTrees); //RXid=1  // 1 2
        ObjectsTable[I*3+K].Tag := I*3+K; //Store ID
        ObjectsTable[I*3+K].OnClick := Terrain_ObjectsChange;
        ObjectsTable[I*3+K].OnMouseWheel := ObjectsScroll.MouseWheel;
      end;
      ObjectErase.Tag := 255; //no object
      ObjectErase.OnClick := Terrain_ObjectsChange;
    Terrain_ObjectsChange(ObjectsScroll); //This ensures that the displayed images get updated the first time
    Terrain_ObjectsChange(ObjectsTable[0]);
end;


{Build page}
procedure TKMapEdInterface.Create_Village_Page;
var i:Integer;
begin
  Panel_Village := TKMPanel.Create(Panel_Common,0,128,196,28);
    Button_Village[1] := TKMButton.Create(Panel_Village,   8, 4, 36, 24, 454);
    Button_Village[2] := TKMButton.Create(Panel_Village,  48, 4, 36, 24, 141);
    Button_Village[3] := TKMButton.Create(Panel_Village,  88, 4, 36, 24, 327);
    for i:=1 to 3 do Button_Village[i].OnClick := SwitchPage;

    Panel_Build := TKMPanel.Create(Panel_Village,0,28,196,400);
      TKMLabel.Create(Panel_Build,100,10,184,0,'Roadworks',fnt_Outline,taCenter);
      Button_BuildRoad   := TKMButtonFlat.Create(Panel_Build,  8,28,33,33,335);
      Button_BuildField  := TKMButtonFlat.Create(Panel_Build, 45,28,33,33,337);
      Button_BuildWine   := TKMButtonFlat.Create(Panel_Build, 82,28,33,33,336);
      Button_BuildCancel := TKMButtonFlat.Create(Panel_Build,156,28,33,33,340);
      Button_BuildRoad.OnClick  := Build_ButtonClick;
      Button_BuildField.OnClick := Build_ButtonClick;
      Button_BuildWine.OnClick  := Build_ButtonClick;
      Button_BuildCancel.OnClick:= Build_ButtonClick;
      Button_BuildRoad.Hint     := fTextLibrary[TX_BUILD_ROAD_HINT];
      Button_BuildField.Hint    := fTextLibrary[TX_BUILD_FIELD_HINT];
      Button_BuildWine.Hint     := fTextLibrary[TX_BUILD_WINE_HINT];
      Button_BuildCancel.Hint   := fTextLibrary[TX_BUILD_CANCEL_HINT];

      TKMLabel.Create(Panel_Build,100,65,184,0,'Houses',fnt_Outline,taCenter);
      for i:=1 to GUI_HOUSE_COUNT do
        if GUIHouseOrder[i] <> ht_None then begin
          Button_Build[i]:=TKMButtonFlat.Create(Panel_Build, 8+((i-1) mod 5)*37,83+((i-1) div 5)*37,33,33,fResource.HouseDat[GUIHouseOrder[i]].GUIIcon);
          Button_Build[i].OnClick:=Build_ButtonClick;
          Button_Build[i].Hint := fResource.HouseDat[GUIHouseOrder[i]].HouseName;
        end;

    Panel_Units := TKMPanel.Create(Panel_Village,0,28,196,400);

      //TKMLabel.Create(Panel_Units,100,10,0,0,'Citizens',fnt_Outline,taCenter);
      for i:=0 to High(Button_Citizen) do
      begin
        Button_Citizen[i] := TKMButtonFlat.Create(Panel_Units,8+(i mod 5)*37,8+(i div 5)*37,33,33,fResource.UnitDat[School_Order[i]].GUIIcon); //List of tiles 5x5
        Button_Citizen[i].Hint := fResource.UnitDat[School_Order[i]].UnitName;
        Button_Citizen[i].Tag := byte(School_Order[i]); //Returns unit ID
        Button_Citizen[i].OnClick := Unit_ButtonClick;
      end;
      Button_UnitCancel := TKMButtonFlat.Create(Panel_Units,8+((High(Button_Citizen)+1) mod 5)*37,8+(length(Button_Citizen) div 5)*37,33,33,340);
      Button_UnitCancel.Hint := fTextLibrary[TX_BUILD_CANCEL_HINT];
      Button_UnitCancel.OnClick := Unit_ButtonClick;

      //TKMLabel.Create(Panel_Units,100,140,0,0,'Warriors',fnt_Outline,taCenter);
      for i:=0 to High(Button_Warriors) do
      begin
        Button_Warriors[i] := TKMButtonFlat.Create(Panel_Units,8+(i mod 5)*37,124+(i div 5)*37,33,33, MapEd_Icon[i], rxGui);
        Button_Warriors[i].Hint := fResource.UnitDat[MapEd_Order[i]].UnitName;
        Button_Warriors[i].Tag := byte(MapEd_Order[i]); //Returns unit ID
        Button_Warriors[i].OnClick := Unit_ButtonClick;
      end;

      //TKMLabel.Create(Panel_Units,100,230,0,0,'Animals',fnt_Outline,taCenter);
      for i:=0 to High(Button_Animals) do
      begin
        Button_Animals[i] := TKMButtonFlat.Create(Panel_Units,8+(i mod 5)*37,240+(i div 5)*37,33,33, Animal_Icon[i], rxGui);
        Button_Animals[i].Hint := fResource.UnitDat[Animal_Order[i]].UnitName;
        Button_Animals[i].Tag := byte(Animal_Order[i]); //Returns animal ID
        Button_Animals[i].OnClick := Unit_ButtonClick;
      end;
      Unit_ButtonClick(Button_Citizen[0]); //Select serf as default

    Panel_Script := TKMPanel.Create(Panel_Village,0,28,196,400);
      TKMLabel.Create(Panel_Script,100,10,184,0,'Scripts',fnt_Outline,taCenter);
      {Button_ScriptReveal         := TKMButtonFlat.Create(Panel_Script,  8,28,33,33,335);
      Button_ScriptReveal.OnClick := Script_ButtonClick;
      Button_ScriptReveal.Hint    := 'Reveal a portion of map';}
end;


procedure TKMapEdInterface.Create_Player_Page;
var I: Integer; Col: array [0..255] of TColor4;
begin
  Panel_Player := TKMPanel.Create(Panel_Common,0,128,196,28);
    Button_Player[1] := TKMButton.Create(Panel_Player,   8, 4, 36, 24,  41);
    Button_Player[2] := TKMButton.Create(Panel_Player,  48, 4, 36, 24, 382);
    Button_Player[3] := TKMButton.Create(Panel_Player,  88, 4, 36, 24,  38);
    for I := 1 to 3 do Button_Player[I].OnClick := SwitchPage;

    Panel_Goals := TKMPanel.Create(Panel_Player,0,28,196,400);
      TKMLabel.Create(Panel_Goals,100,10,184,0,'Goals',fnt_Outline,taCenter);

    Panel_Color := TKMPanel.Create(Panel_Player,0,28,196,400);
      TKMLabel.Create(Panel_Color,100,10,184,0,'Colors',fnt_Outline,taCenter);
      TKMBevel.Create(Panel_Color,8,30,180,210);
      ColorSwatch_Color := TKMColorSwatch.Create(Panel_Color, 10, 32, 16, 16, 11);
      for I:=0 to 255 do Col[I] := fResource.Palettes.DefDal.Color32(I);
      ColorSwatch_Color.SetColors(Col);
      ColorSwatch_Color.OnClick := Player_ColorClick;

    Panel_Block := TKMPanel.Create(Panel_Player,0,28,196,400);
      TKMLabel.Create(Panel_Block, 100, 10, 184, 0, 'Block houses', fnt_Outline, taCenter);

      for I := 1 to GUI_HOUSE_COUNT do
      if GUIHouseOrder[I] <> ht_None then begin
        Button_BlockHouse[I] := TKMButtonFlat.Create(Panel_Block, 8+((I-1) mod 5)*37, 30 + ((I-1) div 5)*37,33,33,fResource.HouseDat[GUIHouseOrder[I]].GUIIcon);
        Button_BlockHouse[I].Hint := fResource.HouseDat[GUIHouseOrder[I]].HouseName;
        Button_BlockHouse[I].OnClick := Player_BlockClick;
        Button_BlockHouse[I].Tag := I;
        Image_BlockHouse[I] := TKMImage.Create(Panel_Block, 8+((I-1) mod 5)*37 + 13, 30 + ((I-1) div 5)*37 + 13, 16, 16, 0, rxGuiMain);
        Image_BlockHouse[I].Hitable := False;
        Image_BlockHouse[I].ImageCenter;
      end;
end;


procedure TKMapEdInterface.Create_Mission_Page;
var i,k:Integer;
begin
  Panel_Mission := TKMPanel.Create(Panel_Common,0,128,196,28);
    Button_Mission[1] := TKMButton.Create(Panel_Mission,  8, 4, 36, 24, 41);
    Button_Mission[2] := TKMButton.Create(Panel_Mission, 48, 4, 36, 24, 41);
    for i:=1 to 2 do Button_Mission[i].OnClick := SwitchPage;

    Panel_Alliances := TKMPanel.Create(Panel_Mission,0,28,196,400);
      TKMLabel.Create(Panel_Alliances,100,10,184,0,'Alliances',fnt_Outline,taCenter);
      for i:=0 to MAX_PLAYERS-1 do begin
        TKMLabel.Create(Panel_Alliances,32+i*20+2,30,20,20,inttostr(i+1),fnt_Outline,taLeft);
        TKMLabel.Create(Panel_Alliances,12,50+i*25,20,20,inttostr(i+1),fnt_Outline,taLeft);
        for k:=0 to MAX_PLAYERS-1 do begin
          CheckBox_Alliances[i,k] := TKMCheckBox.Create(Panel_Alliances, 28+k*20, 46+i*25, 20, 20, '', fnt_Metal);
          CheckBox_Alliances[i,k].Tag       := i * MAX_PLAYERS + k;
          CheckBox_Alliances[i,k].FlatStyle := true;
          CheckBox_Alliances[i,k].OnClick   := Mission_AlliancesChange;
        end;
      end;

      //It does not have OnClick event for a reason:
      // - we don't have a rule to make alliances symmetrical yet
      CheckBox_AlliancesSym := TKMCheckBox.Create(Panel_Alliances, 12, 50+MAX_PLAYERS*25, 176, 20, 'Symmetrical', fnt_Metal);
      CheckBox_AlliancesSym.Checked := true;
      CheckBox_AlliancesSym.Disable;

    Panel_PlayerTypes := TKMPanel.Create(Panel_Mission,0,28,196,400);
      TKMLabel.Create(Panel_PlayerTypes,100,10,184,0,'Player types',fnt_Outline,taCenter);
      for i:=0 to MAX_PLAYERS-1 do begin
        TKMLabel.Create(Panel_PlayerTypes,12,30,20,20,'#',fnt_Grey,taLeft);
        TKMLabel.Create(Panel_PlayerTypes,32,30,100,20,'Human',fnt_Grey,taLeft);
        TKMLabel.Create(Panel_PlayerTypes,102,30,100,20,'Computer',fnt_Grey,taLeft);
        TKMLabel.Create(Panel_PlayerTypes,12,50+i*25,20,20,inttostr(i+1),fnt_Outline,taLeft);
        for k:=0 to 1 do
        begin
          CheckBox_PlayerTypes[i,k] := TKMCheckBox.Create(Panel_PlayerTypes, 52+k*70, 48+i*25, 20, 20, '', fnt_Metal);
          CheckBox_PlayerTypes[i,k].Tag       := i;
          CheckBox_PlayerTypes[i,k].FlatStyle := true;
          CheckBox_PlayerTypes[i,k].OnClick   := Mission_PlayerTypesChange;
        end;
      end;
end;


{Menu page}
procedure TKMapEdInterface.Create_Menu_Page;
begin
  Panel_Menu:=TKMPanel.Create(Panel_Common,0,128,196,400);
    Button_Menu_Save:=TKMButton.Create(Panel_Menu,8,20,180,30,fTextLibrary[TX_MENU_SAVE_GAME],fnt_Metal);
    Button_Menu_Save.OnClick:=SwitchPage;
    Button_Menu_Save.Hint:=fTextLibrary[TX_MENU_SAVE_GAME];
    Button_Menu_Load:=TKMButton.Create(Panel_Menu,8,60,180,30,fTextLibrary[TX_MENU_LOAD_GAME],fnt_Metal);
    Button_Menu_Load.OnClick:=SwitchPage;
    Button_Menu_Load.Hint:=fTextLibrary[TX_MENU_LOAD_GAME];
    Button_Menu_Settings:=TKMButton.Create(Panel_Menu,8,100,180,30,fTextLibrary[TX_MENU_SETTINGS],fnt_Metal);
    Button_Menu_Settings.Hint:=fTextLibrary[TX_MENU_SETTINGS];
    Button_Menu_Settings.Disable;
    Button_Menu_Quit:=TKMButton.Create(Panel_Menu,8,180,180,30,fTextLibrary[TX_MENU_QUIT_MAPED],fnt_Metal);
    Button_Menu_Quit.Hint:=fTextLibrary[TX_MENU_QUIT_MAPED];
    Button_Menu_Quit.OnClick:=SwitchPage;
end;


{Save page}
procedure TKMapEdInterface.Create_MenuSave_Page;
begin
  Panel_Save := TKMPanel.Create(Panel_Common,0,128,196,400);
    TKMBevel.Create(Panel_Save, 8, 30, 180, 37);
    Radio_Save_MapType  := TKMRadioGroup.Create(Panel_Save,12,32,176,35,fnt_Grey);
    Radio_Save_MapType.ItemIndex := 0;
    Radio_Save_MapType.Items.Add(fTextLibrary[TX_MENU_MAPED_SPMAPS]);
    Radio_Save_MapType.Items.Add(fTextLibrary[TX_MENU_MAPED_MPMAPS]);
    Radio_Save_MapType.OnChange := Menu_Save;
    TKMLabel.Create(Panel_Save,100,90,184,20,'Save map',fnt_Outline,taCenter);
    Edit_SaveName       := TKMEdit.Create(Panel_Save,8,110,180,20, fnt_Grey);
    Edit_SaveName.AllowedChars := acFileName;
    Label_SaveExists    := TKMLabel.Create(Panel_Save,100,140,184,0,'Map already exists',fnt_Outline,taCenter);
    CheckBox_SaveExists := TKMCheckBox.Create(Panel_Save,8,160,180,20,'Overwrite', fnt_Metal);
    Button_SaveSave     := TKMButton.Create(Panel_Save,8,180,180,30,'Save',fnt_Metal);
    Button_SaveCancel   := TKMButton.Create(Panel_Save,8,220,180,30,'Cancel',fnt_Metal);
    Edit_SaveName.OnChange      := Menu_Save;
    CheckBox_SaveExists.OnClick := Menu_Save;
    Button_SaveSave.OnClick     := Menu_Save;
    Button_SaveCancel.OnClick   := SwitchPage;
end;


{Load page}
procedure TKMapEdInterface.Create_MenuLoad_Page;
begin
  Panel_Load := TKMPanel.Create(Panel_Common,0,108,196,400);
    TKMLabel.Create(Panel_Load, 8, 2, 184, 30, 'Available maps', fnt_Outline, taLeft);
    TKMBevel.Create(Panel_Load, 8, 20, 184, 38);
    Radio_Load_MapType := TKMRadioGroup.Create(Panel_Load,12,22,176,35,fnt_Grey);
    Radio_Load_MapType.ItemIndex := 0;
    Radio_Load_MapType.Items.Add(fTextLibrary[TX_MENU_MAPED_SPMAPS]);
    Radio_Load_MapType.Items.Add(fTextLibrary[TX_MENU_MAPED_MPMAPS]);
    Radio_Load_MapType.OnChange := Load_MapTypeChange;
    ListBox_Load := TKMListBox.Create(Panel_Load, 8, 75, 184, 205, fnt_Grey);
    Button_LoadLoad     := TKMButton.Create(Panel_Load,8,290,184,30,'Load',fnt_Metal);
    Button_LoadCancel   := TKMButton.Create(Panel_Load,8,325,184,30,'Cancel',fnt_Metal);
    Button_LoadLoad.OnClick     := Menu_Load;
    Button_LoadCancel.OnClick   := SwitchPage;
end;


{Quit page}
procedure TKMapEdInterface.Create_MenuQuit_Page;
begin
  Panel_Quit:=TKMPanel.Create(Panel_Common,0,128,200,400);
    TKMLabel.Create(Panel_Quit,100,40,184,60,'Any unsaved|changes will be lost',fnt_Outline,taCenter);
    Button_Quit_Yes   := TKMButton.Create(Panel_Quit,8,100,180,30,fTextLibrary[TX_MENU_QUIT_MISSION],fnt_Metal);
    Button_Quit_No    := TKMButton.Create(Panel_Quit,8,140,180,30,fTextLibrary[TX_MENU_DONT_QUIT_MISSION],fnt_Metal);
    Button_Quit_Yes.Hint      := fTextLibrary[TX_MENU_QUIT_MISSION];
    Button_Quit_No.Hint       := fTextLibrary[TX_MENU_DONT_QUIT_MISSION];
    Button_Quit_Yes.OnClick   := Menu_QuitMission;
    Button_Quit_No.OnClick    := SwitchPage;
end;


{Unit page}
procedure TKMapEdInterface.Create_Unit_Page;
begin
  Panel_Unit:=TKMPanel.Create(Panel_Common,0,112,200,400);
    Label_UnitName        := TKMLabel.Create(Panel_Unit,100,16,184,0,'',fnt_Outline,taCenter);
    Image_UnitPic         := TKMImage.Create(Panel_Unit,8,38,54,100,521);
    Label_UnitCondition   := TKMLabel.Create(Panel_Unit,132,40,116,0,fTextLibrary[TX_UNIT_CONDITION],fnt_Grey,taCenter);
    KMConditionBar_Unit   := TKMPercentBar.Create(Panel_Unit,73,55,116,15);
    Label_UnitDescription := TKMLabel.Create(Panel_Unit,8,152,184,200,'',fnt_Grey,taLeft); //Taken from LIB resource

  Panel_Army:=TKMPanel.Create(Panel_Unit,0,160,200,400);
    Button_Army_RotCCW   := TKMButton.Create(Panel_Army,  8, 0, 56, 40, 23);
    Button_Army_RotCW  := TKMButton.Create(Panel_Army,132, 0, 56, 40, 24);
    Button_Army_ForUp   := TKMButton.Create(Panel_Army,  8, 46, 56, 40, 33);
    ImageStack_Army     := TKMImageStack.Create(Panel_Army, 70, 46, 56, 40, 43, 50);
    Label_ArmyCount     := TKMLabel.Create(Panel_Army, 98, 60, 0, 0, '-', fnt_Outline, taCenter);
    Button_Army_ForDown := TKMButton.Create(Panel_Army,132, 46, 56, 40, 32);
    Button_Army_RotCW.OnClick   := Unit_ArmyChange1;
    Button_Army_RotCCW.OnClick  := Unit_ArmyChange1;
    Button_Army_ForUp.OnClick   := Unit_ArmyChange1;
    Button_Army_ForDown.OnClick := Unit_ArmyChange1;

    Button_ArmyDec      := TKMButton.Create(Panel_Army,  8,92,56,40,'-', fnt_Metal);
    Button_ArmyFood     := TKMButton.Create(Panel_Army, 70,92,56,40,29);
    Button_ArmyInc      := TKMButton.Create(Panel_Army,132,92,56,40,'+', fnt_Metal);
    Button_ArmyDec.OnClickEither := Unit_ArmyChange2;
    Button_ArmyFood.OnClick := Unit_ArmyChange1;
    Button_ArmyInc.OnClickEither := Unit_ArmyChange2;
end;


{House description page}
procedure TKMapEdInterface.Create_House_Page;
begin
  Panel_House:=TKMPanel.Create(Panel_Common,0,112,200,400);
    //Thats common things
    Label_House:=TKMLabel.Create(Panel_House,100,14,184,0,'',fnt_Outline,taCenter);
    Image_House_Logo:=TKMImage.Create(Panel_House,8,41,32,32,338);
    Image_House_Logo.ImageCenter;
    Image_House_Worker:=TKMImage.Create(Panel_House,38,41,32,32,141);
    Image_House_Worker.ImageCenter;
    Label_HouseHealth := TKMLabel.Create(Panel_House,130,41,60,20,fTextLibrary[TX_HOUSE_CONDITION],fnt_Mini,taCenter);
    Label_HouseHealth.FontColor := $FFE0E0E0;
    KMHealthBar_House := TKMPercentBar.Create(Panel_House,100,53,60,20);
    Button_HouseHealthDec := TKMButton.Create(Panel_House,80,53,20,20,'-', fnt_Metal);
    Button_HouseHealthInc := TKMButton.Create(Panel_House,160,53,20,20,'+', fnt_Metal);
    Button_HouseHealthDec.OnClickEither := House_HealthChange;
    Button_HouseHealthInc.OnClickEither := House_HealthChange;
end;


{Store page}
procedure TKMapEdInterface.Create_Store_Page;
var I: Integer;
begin
  Panel_HouseStore := TKMPanel.Create(Panel_House,0,76,200,400);
    for I := 1 to STORE_RES_COUNT do
    begin
      Button_Store[I] := TKMButtonFlat.Create(Panel_HouseStore, 8+((I-1)mod 5)*36,8+((I-1)div 5)*42,32,36,0);
      Button_Store[I].TexID := fResource.Resources[StoreResType[I]].GUIIcon;
      Button_Store[I].Tag := I;
      Button_Store[I].Hint := fResource.Resources[StoreResType[I]].Title;
      Button_Store[I].OnClick := Store_SelectWare;
    end;

    Button_StoreDec100      := TKMButton.Create(Panel_HouseStore,116,218,20,20,'<', fnt_Metal);
    Button_StoreDec100.Tag  := 100;
    Button_StoreDec       := TKMButton.Create(Panel_HouseStore,116,238,20,20,'-', fnt_Metal);
    Button_StoreDec.Tag   := 1;
    Label_Store_WareCount:= TKMLabel.Create (Panel_HouseStore,156,230,40,20,'',fnt_Metal,taCenter);
    Button_StoreInc100      := TKMButton.Create(Panel_HouseStore,176,218,20,20,'>', fnt_Metal);
    Button_StoreInc100.Tag  := 100;
    Button_StoreInc       := TKMButton.Create(Panel_HouseStore,176,238,20,20,'+', fnt_Metal);
    Button_StoreInc.Tag   := 1;
    Button_StoreDec100.OnClickEither := Store_EditWareCount;
    Button_StoreDec.OnClickEither    := Store_EditWareCount;
    Button_StoreInc100.OnClickEither := Store_EditWareCount;
    Button_StoreInc.OnClickEither    := Store_EditWareCount;
end;


{Barracks page}
procedure TKMapEdInterface.Create_Barracks_Page;
var i:Integer;
begin
  Panel_HouseBarracks:=TKMPanel.Create(Panel_House,0,76,200,400);
    for i:=1 to BARRACKS_RES_COUNT do
    begin
      Button_Barracks[i]:=TKMButtonFlat.Create(Panel_HouseBarracks, 8+((i-1)mod 6)*31,8+((i-1)div 6)*42,28,38,0);
      Button_Barracks[i].Tag := i;
      Button_Barracks[i].TexID := fResource.Resources[BarracksResType[i]].GUIIcon;
      Button_Barracks[i].TexOffsetX := 1;
      Button_Barracks[i].TexOffsetY := 1;
      Button_Barracks[i].CapOffsetY := 2;
      Button_Barracks[i].Hint := fResource.Resources[BarracksResType[i]].Title;
      Button_Barracks[i].OnClick := Barracks_SelectWare;
    end;
    Button_BarracksDec100     := TKMButton.Create(Panel_HouseBarracks,116,218,20,20,'<', fnt_Metal);
    Button_BarracksDec100.Tag := 100;
    Button_BarracksDec      := TKMButton.Create(Panel_HouseBarracks,116,238,20,20,'-', fnt_Metal);
    Button_BarracksDec.Tag  := 1;
    Label_Barracks_WareCount:= TKMLabel.Create (Panel_HouseBarracks,156,230,40,20,'',fnt_Metal,taCenter);
    Button_BarracksInc100     := TKMButton.Create(Panel_HouseBarracks,176,218,20,20,'>', fnt_Metal);
    Button_BarracksInc100.Tag := 100;
    Button_BarracksInc      := TKMButton.Create(Panel_HouseBarracks,176,238,20,20,'+', fnt_Metal);
    Button_BarracksInc.Tag  := 1;
    Button_BarracksDec100.OnClickEither := Barracks_EditWareCount;
    Button_BarracksDec.OnClickEither    := Barracks_EditWareCount;
    Button_BarracksInc100.OnClickEither := Barracks_EditWareCount;
    Button_BarracksInc.OnClickEither    := Barracks_EditWareCount;
end;


//Should update any items changed by game (resource counts, hp, etc..)
procedure TKMapEdInterface.UpdateState(aTickCount: Cardinal);
begin
  //
end;


procedure TKMapEdInterface.SetMinimap;
begin
  MinimapView.SetMinimap(fGame.Minimap);
  MinimapView.SetViewport(fGame.Viewport);
end;


procedure TKMapEdInterface.SetMapName(const aName: string);
begin
  Label_MissionName.Caption := aName;
end;


procedure TKMapEdInterface.Player_UpdateColors;
var i:Integer;
begin
  //Set player colors
  for i:=0 to MAX_PLAYERS-1 do
    Button_PlayerSelect[i].ShapeColor := fPlayers.Player[i].FlagColor;

  Button_Village[2].FlagColor := MyPlayer.FlagColor;
  for i:=Low(Button_Citizen) to High(Button_Citizen) do
    Button_Citizen[i].FlagColor := MyPlayer.FlagColor;
  for i:=Low(Button_Warriors) to High(Button_Warriors) do
    Button_Warriors[i].FlagColor := MyPlayer.FlagColor;
end;


procedure TKMapEdInterface.Player_ChangeActive(Sender: TObject);
begin
  if Panel_House.Visible or Panel_Unit.Visible then
    SwitchPage(nil);

  fPlayers.Selected := nil;

  if Sender <> nil then
    SetActivePlayer(TKMControl(Sender).Tag)
  else
    SetActivePlayer(-1);

  Player_BlockRefresh;
end;


procedure TKMapEdInterface.SetActivePlayer(aIndex: TPlayerIndex);
var I: Integer;
begin
  if aIndex <> -1 then
    MyPlayer := fPlayers.Player[aIndex]
  else
    MyPlayer := fPlayers.Player[0];

  for I := 0 to MAX_PLAYERS - 1 do
    Button_PlayerSelect[I].Down := (I = MyPlayer.PlayerIndex);

  Player_UpdateColors;
end;


procedure TKMapEdInterface.Terrain_HeightChange(Sender: TObject);
begin
  GameCursor.MapEdSize := HeightSize.Position;
  GameCursor.MapEdSlope := HeightShape.Position;

  if Sender = HeightCircle then
  begin
    HeightCircle.Down := true;
    HeightSquare.Down := false;
    GameCursor.MapEdShape := hsCircle;
  end else
  if Sender = HeightSquare then
  begin
    HeightSquare.Down := true;
    HeightCircle.Down := false;
    GameCursor.MapEdShape := hsSquare;
  end else
  if Sender = HeightElevate then
  begin
    HeightElevate.Down := True;
    HeightUnequalize.Down:=false;
    GameCursor.Mode := cm_Elevate;
  end;
  if Sender = HeightUnequalize then
  begin
    HeightElevate.Down  := false;
    HeightUnequalize.Down := true;
    GameCursor.Mode := cm_Equalize;
  end;
end;


procedure TKMapEdInterface.Terrain_TilesChange(Sender: TObject);

  function GetTileIDFromTag(aTag: byte):byte;
  var Tile:byte;
  begin
    Tile := 32*((aTag-1) div MAPED_TILES_COLS) + (aTag-1) mod MAPED_TILES_COLS + TilesScroll.Position;
    Result := MapEdTileRemap[EnsureRange(Tile+1,1,256)];
  end;

var i,k,TileID:Integer;
begin
  if Sender = TilesRandom then
    GameCursor.MapEdDir := 4 * byte(TilesRandom.Checked); //Defined=0..3 or Random=4

  if Sender = TilesScroll then //Shift tiles
    for i:=1 to MAPED_TILES_COLS do
    for k:=1 to MAPED_TILES_ROWS do
    begin
      if GetTileIDFromTag((k-1)*MAPED_TILES_COLS+i) <> 0 then
      begin
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].TexID := GetTileIDFromTag((k-1)*MAPED_TILES_COLS+i); //icons are in 2..9
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Enable;
      end
      else
      begin
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].TexID := 0;
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Disable;
      end;
      if GameCursor.Mode = cm_Tiles then
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Down := (GameCursor.Tag1+1 = GetTileIDFromTag((k-1)*MAPED_TILES_COLS+i));
    end;
  if Sender is TKMButtonFlat then
  begin
    TileID := GetTileIDFromTag(TKMButtonFlat(Sender).Tag);
    if TileID <> 0 then
    begin
      GameCursor.Mode := cm_Tiles;
      GameCursor.Tag1 := TileID-1; //MapEdTileRemap is 1 based, tag is 0 based
      if TilesRandom.Checked then
        GameCursor.MapEdDir := 4;
      for i:=1 to MAPED_TILES_COLS do
      for k:=1 to MAPED_TILES_ROWS do
        TilesTable[(i-1)*MAPED_TILES_ROWS+k].Down := (Sender = TilesTable[(i-1)*MAPED_TILES_ROWS+k]);
    end;
  end;
end;


procedure TKMapEdInterface.Terrain_ObjectsChange(Sender: TObject);
var I, ObjID: Integer;
begin
  for I := 0 to 8 do
    ObjectsTable[i].Down := False;

  ObjectErase.Down := False;

  if Sender = ObjectsScroll then
  begin
    for I := 0 to 8 do
    begin
      ObjID := ObjectsScroll.Position * 3 + I;
      if ObjID < fResource.MapElements.ValidCount then
      begin
        ObjectsTable[I].TexID := MapElem[fResource.MapElements.ValidToObject[ObjID]].Anim.Step[1] + 1;
        ObjectsTable[I].Caption := IntToStr(ObjID);
        ObjectsTable[I].Enable;
      end
      else
      begin
        ObjectsTable[I].TexID := 0;
        ObjectsTable[I].Caption := '';
        ObjectsTable[I].Disable;
      end;
      ObjectsTable[I].Down := ObjID = fResource.MapElements.ObjectToValid[GameCursor.Tag1]; //Mark the selected one using reverse lookup
    end;
    ObjectErase.Down := (GameCursor.Tag1 = 255); //or delete button
  end;

  if Sender is TKMButtonFlat then
  begin
    ObjID := ObjectsScroll.Position * 3 + TKMButtonFlat(Sender).Tag; //0..n-1

    if (not InRange(ObjID, 0, fResource.MapElements.ValidCount - 1))
    and not (TKMButtonFlat(Sender).Tag = 255) then
      Exit; //Don't let them click if it is out of range

    GameCursor.Mode := cm_Objects;
    if TKMButtonFlat(Sender).Tag = 255 then
      GameCursor.Tag1 := 255 //erase object
    else
      GameCursor.Tag1 := fResource.MapElements.ValidToObject[ObjID]; //0..n-1
    for I := 0 to 8 do
      ObjectsTable[I].Down := (Sender = ObjectsTable[I]); //Mark the selected one
    ObjectErase.Down := (Sender = ObjectErase); //or delete button
  end;
end;


procedure TKMapEdInterface.Build_ButtonClick(Sender: TObject);
var i:Integer;
begin
  //Release all buttons
  for i:=1 to Panel_Build.ChildCount do
    if Panel_Build.Childs[i] is TKMButtonFlat then
      TKMButtonFlat(Panel_Build.Childs[i]).Down:=false;

  //Press the button
  TKMButtonFlat(Sender).Down := true;

  //Reset cursor and see if it needs to be changed
  GameCursor.Mode:=cm_None;
  GameCursor.Tag1:=0;

  if Button_BuildCancel.Down then begin
    GameCursor.Mode:=cm_Erase;
  end;
  if Button_BuildRoad.Down then begin
    GameCursor.Mode:=cm_Road;
  end;
  if Button_BuildField.Down then begin
    GameCursor.Mode:=cm_Field;
  end;
  if Button_BuildWine.Down then begin
    GameCursor.Mode:=cm_Wine;
  end;
{  if Button_BuildWall.Down then begin
    GameCursor.Mode:=cm_Wall;
  end;}

  for i:=1 to GUI_HOUSE_COUNT do
  if GUIHouseOrder[i] <> ht_None then
  if Button_Build[i].Down then begin
     GameCursor.Mode := cm_Houses;
     GameCursor.Tag1 := byte(GUIHouseOrder[i]);
  end;
end;


procedure TKMapEdInterface.Unit_ButtonClick(Sender: TObject);
var i:Integer;
begin
  if Sender=nil then begin GameCursor.Mode:=cm_None; exit; end;

  //Release all buttons
  for i:=1 to Panel_Units.ChildCount do
    if Panel_Units.Childs[i] is TKMButtonFlat then
      TKMButtonFlat(Panel_Units.Childs[i]).Down := false;

  //Press the button
  TKMButtonFlat(Sender).Down:=true;

  //Reset cursor and see if it needs to be changed
  GameCursor.Mode:=cm_None;
  GameCursor.Tag1:=0;
  //Label_Build.Caption := '';

  if Button_UnitCancel.Down then begin
    GameCursor.Mode:=cm_Erase;
  end;

  if (TKMButtonFlat(Sender).Tag in [byte(UNIT_MIN)..byte(UNIT_MAX)]) then
  begin
    GameCursor.Mode := cm_Units;
    GameCursor.Tag1 := byte(TKMButtonFlat(Sender).Tag);
  end;

end;


procedure TKMapEdInterface.View_Passability(Sender: TObject);
begin
  SHOW_TERRAIN_WIRES := (TKMTrackBar(Sender).Position <> 0);
  SHOW_TERRAIN_PASS := TKMTrackBar(Sender).Position;

  if TKMTrackBar(Sender).Position <> 0 then
    Label_Passability.Caption := GetEnumName(TypeInfo(TPassability), SHOW_TERRAIN_PASS)
  else
    Label_Passability.Caption := 'Off';
end;


procedure TKMapEdInterface.ShowHouseInfo(Sender: TKMHouse);
begin
  if Sender = nil then
{'fraction_non_alphanumeric': 0.11659393649041315, 'fraction_numerical': 0.04147182269806388, 'mean_word_length': 4.487997256515775, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3187080', 'n_tokens_mistral': 38461, 'n_tokens_neox': 34272, 'n_words': 5628}