{*********************************************}
{  TeeChart Charting Library for FireMonkey   }
{  Copyright (c) 2012-2020 by Steema Software }
{  All Rights Reserved                        }
{*********************************************}
unit FMXTee.Editor.Series.WorldMap;
{$I TeeDefs.inc}

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,
  System.Variants,

  {$IFDEF D17}
  System.Rtti,
  {$ENDIF}

  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMXTee.Chart.ListBox,

  {$IFNDEF UPTOXE3}
  FMX.StdCtrls,
  {$ENDIF}

  {$IFNDEF UPTOXE7}
  FMX.SpinBox, FMX.Controls.Presentation, FMX.EditBox,
  {$ENDIF}

  FMXTee.Editor.Series.Map, FMX.ListBox, FMX.Colors, FMX.Edit,
  FMX.Layouts, FMX.TabControl, FMXTee.Series.World;

type
  TWorldSeriesEditor = class(TMapSeriesEditor)
    TabLayers: TTabItem;
    CBFlags: TCheckBox;
    CBStates: TCheckBox;
    CBCities: TCheckBox;
    Panel1: TPanel;
    LayoutTop: TLayout;
    LMap: TLabel;
    LWorldMap: TListBox;
    CBKeepAspect: TCheckBox;
    LCitySize: TLabel;
    CBCitySize: TComboBox;
    ECitySize: TEdit;
    LRender: TLabel;
    CBRender: TComboBox;
    procedure CBFlagsChange(Sender: TObject);
    procedure CBStatesChange(Sender: TObject);
    procedure CBCitiesChange(Sender: TObject);
    procedure CBKeepAspectChange(Sender: TObject);
    procedure LWorldMapChange(Sender: TObject);
    procedure CBCitySizeChange(Sender: TObject);
    procedure ECitySizeChangeTracking(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure CBRenderChange(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }

    PreparedMapList : Boolean;

    procedure FreeWorldMapListObjects;
    function World:TWorldSeries;
  public
    { Public declarations }

    class procedure PrepareWorldMapListBox(const AItems:TStrings);
  end;

implementation

{$R *.fmx}

uses
  FMXTee.Series.Map, FMXTee.Engine;

function TWorldSeriesEditor.World:TWorldSeries;
begin
  result:=TWorldSeries(Map);
end;

procedure TWorldSeriesEditor.CBCitiesChange(Sender: TObject);
begin
  World.Layers.Cities.Visible:=CBCities.IsChecked;
  CBCitySize.Enabled:=CBCities.IsChecked;
end;

procedure TWorldSeriesEditor.CBCitySizeChange(Sender: TObject);
var Cities : TWorldCities;
begin
  Cities:=World.Layers.Cities;

  Cities.Size:=TWorldCitiesSize(CBCitySize.ItemIndex);
  ECitySize.Enabled:=Cities.Size=csCustom;
end;

procedure TWorldSeriesEditor.CBFlagsChange(Sender: TObject);
begin
  World.Flags.Visible:=CBFlags.IsChecked;
end;

procedure TWorldSeriesEditor.CBKeepAspectChange(Sender: TObject);
begin
  World.KeepAspect:=CBKeepAspect.IsChecked;
end;

procedure TWorldSeriesEditor.CBRenderChange(Sender: TObject);
begin
  World.RenderMode:=TMapRenderMode(CBRender.ItemIndex);
end;

procedure TWorldSeriesEditor.CBStatesChange(Sender: TObject);
begin
  World.Layers.States:=CBStates.IsChecked;
end;

procedure TWorldSeriesEditor.ECitySizeChangeTracking(Sender: TObject);
var tmp : Single;
    P : TSeriesPointer;
begin
  P:=World.Layers.Cities.Series.Pointer;
  tmp:=P.SizeFloat;
  P.SizeFloat:=StrToFloatDef(ECitySize.Text,tmp);
end;

type
  TMapObject=class
  public
    Value : TWorldMap;

    Constructor Create(const AValue:TWorldMap);
  end;

Constructor TMapObject.Create(const AValue:TWorldMap);
begin
  inherited Create;
  Value:=AValue;
end;

procedure TWorldSeriesEditor.FormActivate(Sender: TObject);

  function FindMapItem(const AMap:TWorldMap):Integer;
  var t : Integer;
  begin
    for t:=0 to LWorldMap.Items.Count-1 do
        if TMapObject(LWorldMap.Items.Objects[t]).Value=AMap then
        begin
          result:=t;
          Exit;
        end;


    result:=-1;
  end;

var Cities : TWorldCities;
begin
  inherited;

  if CBCitySize.Items.Count=0 then
  begin
    CBCitySize.Items.Add('Population');
    CBCitySize.Items.Add('Value');
    CBCitySize.Items.Add('Custom');
  end;

  if not PreparedMapList then
  begin
    PrepareWorldMapListBox(LWorldMap.Items);
    PreparedMapList:=True;
  end;

  if Assigned(Map) then
  begin
    LWorldMap.ItemIndex:=FindMapItem(World.Map);
    CBKeepAspect.IsChecked:=World.KeepAspect;
    CBFlags.IsChecked:=World.Flags.Visible;
    CBStates.IsChecked:=World.Layers.States;

    Cities:=World.Layers.Cities;

    CBCities.IsChecked:=Cities.Visible;
    CBCitySize.Enabled:=CBCities.IsChecked;
    CBCitySize.ItemIndex:=Ord(Cities.Size);

    ECitySize.Enabled:=Cities.Size=csCustom;
    ECitySize.Text:=IntToStr(Round(Cities.Series.Pointer.SizeFloat));

    CBRender.ItemIndex:=Ord(World.RenderMode);
  end;
end;

procedure TWorldSeriesEditor.FreeWorldMapListObjects;
var t : Integer;
begin
  for t:=0 to LWorldMap.Items.Count-1 do
      LWorldMap.Items.Objects[t].{$IFDEF AUTOREFCOUNT}DisposeOf{$ELSE}Free{$ENDIF};
end;

procedure TWorldSeriesEditor.FormDestroy(Sender: TObject);
begin
  FreeWorldMapListObjects;
  inherited;
end;

procedure TWorldSeriesEditor.LWorldMapChange(Sender: TObject);
var tmp : TMapObject;
begin
  if not (csDestroying in ComponentState) then
  begin
    tmp:=TMapObject(LWorldMap.Items.Objects[LWorldMap.ItemIndex]);
    World.Map:=tmp.Value;

    DirtyList:=True;
  end;
end;

class procedure TWorldSeriesEditor.PrepareWorldMapListBox(const AItems:TStrings);
var t : Integer;
    s : String;
begin
  AItems.BeginUpdate;
  try
    for t:=0 to AItems.Count-1 do
    begin
      s:=AItems[t];

      AItems.Objects[t]:=TMapObject.Create(TWorldMap(StrToInt(Copy(s,1,2))));
      AItems[t]:=Copy(s,4,Length(s));
    end;
  finally
    AItems.EndUpdate;
  end;
end;

initialization
  RegisterClass(TWorldSeriesEditor);
end.
