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

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.TabControl,
  {$IFNDEF UPTOXE3}
  FMX.StdCtrls,
  {$ENDIF}
  FMX.Forms, FMX.Dialogs, FMX.Layouts, FMX.TreeView, FMX.ListBox, FMXTee.Chart,
  FMXTee.Engine, FMXTee.Procs, FMXTee.Editor.Gallery,

  {$IFNDEF TEELITEEMB}
  FMXTee.Chart.Grid,
  {$ENDIF}

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

  FMX.Objects, FMXTee.Chart.ListBox, FMX.Menus, FMX.ExtCtrls;

type
  TFormClass=class of TForm;

  TChartEditForm = class(TForm)
    Tree: TTreeView;
    PanBottom: TPanel;
    Button1: TButton;
    Panel2: TPanel;
    PanelTabs: TPanel;
    TopLayout: TLayout;
    BAdd: TButton;
    BDelete: TButton;
    BTitle: TButton;
    BClone: TButton;
    BChange: TButton;
    SplitterTree: TSplitter;
    SBUp: TButton;
    SBDown: TButton;
    SeriesNode: TTreeViewItem;
    LegendNode: TTreeViewItem;
    PagingNode: TTreeViewItem;
    PanelNode: TTreeViewItem;
    GeneralNode: TTreeViewItem;
    TitlesNode: TTreeViewItem;
    WallsNode: TTreeViewItem;
    AxesNode: TTreeViewItem;
    ChartNode: TTreeViewItem;
    Node3D: TTreeViewItem;
    ExportNode: TTreeViewItem;
    PrintNode: TTreeViewItem;
    TitleNode: TTreeViewItem;
    SubTitleNode: TTreeViewItem;
    FooterNode: TTreeViewItem;
    SubFooterNode: TTreeViewItem;
    DataNode: TTreeViewItem;
    PopupData: TPopupMenu;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    MenuItem5: TMenuItem;
    PanelGroups: TPanel;
    Groups: TListBox;
    SplitterGroups: TSplitter;
    PanelGroupButtons: TPanel;
    BAddGroup: TButton;
    BRenameGroup: TButton;
    BDeleteGroup: TButton;
    PanelList: TPanel;
    PopupListSeries: TPopupMenu;
    MenuItem6: TMenuItem;
    MenuItem7: TMenuItem;
    MenuItem8: TMenuItem;
    MenuItem9: TMenuItem;
    MenuItem10: TMenuItem;
    MenuItem11: TMenuItem;
    MenuItem12: TMenuItem;
    Text1: TText;
    ListSeries: TChartListBox;
    BEditSeries: TButton;
    Layout1: TLayout;
    SBView: TSpeedButton;
    LabelView: TText;
    ViewGroups: TCheckBox;
    ViewNames: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure BAddClick(Sender: TObject);
    procedure ListSeriesChange(Sender: TObject);
    procedure BDeleteClick(Sender: TObject);
    procedure BCloneClick(Sender: TObject);
    procedure TreeChange(Sender: TObject);
    procedure ListSeriesDblClick(Sender: TObject);
    procedure ListSeriesChangeCheck(Sender: TObject);
    procedure SBUpClick(Sender: TObject);
    procedure SBDownClick(Sender: TObject);
    procedure BTitleClick(Sender: TObject);
    procedure BChangeClick(Sender: TObject);
    procedure MenuItem5Click(Sender: TObject);
    procedure MenuItem2Click(Sender: TObject);
    procedure MenuItem3Click(Sender: TObject);
    procedure GroupsChangeCheck(Sender: TObject);
    procedure GroupsChange(Sender: TObject);
    procedure BAddGroupClick(Sender: TObject);
    procedure BRenameGroupClick(Sender: TObject);
    procedure BDeleteGroupClick(Sender: TObject);
    procedure MenuItem6Click(Sender: TObject);
    procedure MenuItem8Click(Sender: TObject);
    procedure MenuItem9Click(Sender: TObject);
    procedure MenuItem11Click(Sender: TObject);
    procedure MenuItem12Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Text1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure BEditSeriesClick(Sender: TObject);
    procedure ViewGroupsChange(Sender: TObject);
    procedure ViewNamesChange(Sender: TObject);
    procedure SBViewClick(Sender: TObject);
    procedure LabelViewClick(Sender: TObject);
    procedure PanBottomResize(Sender: TObject);
  private
    { Private declarations }
    FLastForm : TForm;

    {$IFNDEF TEELITEEMB}
    FChartGrid : TChartGrid;

    {$IFNDEF TEELITE}
    AnimsNode,
    ToolsNode,
    {$ENDIF}

    ImportNode,
    ThemesNode : TTreeViewItem;
    {$ENDIF}

    procedure AddSeries(const ASeries:TChartSeries);
    Function CurrentGroup:TSeriesGroup;
	{$IFNDEF TEELITEEMB}
    procedure DestroyGrid;
	{$ENDIF}
    procedure DestroyPreviousForm;
    procedure EnableGroupButtons;
    procedure ExchangeSeries(Index1, Index2:Integer);
    procedure FillAxes;
    procedure FillGroups;

    {$IFNDEF TEELITE}
    procedure FillAnimations;
    procedure FillTools;
    {$ENDIF}

    {$IFDEF D20}
    procedure GroupsDragOver(Sender: TObject; const Data: TDragObject; const Point: TPointF;
                             var Operation: TDragOperation);
    procedure GroupsDragDrop(Sender: TObject; const Data: TDragObject; const Point: TPointF);

    {$ELSE}
    procedure GroupsDragOver(Sender: TObject; const Data: TDragObject;
      const Point: TPointF; var Accept: Boolean);
    procedure GroupsDragDrop(Sender: TObject; const Data: TDragObject;
      const Point: TPointF);
    {$ENDIF}

    function SelectedSeries:TChartSeries;
    function TreeItemSeries(const ASeries:TChartSeries):TTreeViewItem;
  protected
    FChart : TCustomChart;

    procedure FillSeries;
    procedure SetupChart(const AChart:TCustomChart);
    procedure ShowHideGroups;
  public
    { Public declarations }
    RememberPosition,
    RememberSize : Boolean;

    class var ImportEditor:TFormClass;
    class var ThemesEditor:TFormClass;

    class procedure Edit(const AOwner:TComponent; const AChart:TCustomChart); overload;
    class procedure Edit(const AOwner:TComponent; const ASeries:TChartSeries); overload;

    property Chart:TCustomChart read FChart write SetupChart;
  end;

implementation

{$R *.fmx}

uses
  FMX.Edit, System.Math,

  {$IFDEF D22}
  FMX.Presentation.Style,
  {$ENDIF}

  FMXTee.Constants, FMXTee.Editor.Legend, FMXTee.Editor.Paging,
  FMXTee.Editor.Panel, FMXTee.Editor.Series, FMXTee.Editor.General,
  FMXTee.Editor.Title, FMXTee.Editor.Wall, FMXTee.Editor.Axis,
  FMXTee.Editor.Aspect, FMXTee.Canvas, FMXTee.Editor.Stroke,

  // Standard Version
  {$IFNDEF TEELITEEMB}
  FMXTee.Print.Preview, FMXTee.Editor.Export, FMXTee.Editor.Tools,
  FMXTee.Editor.Animations,
  FMXTee.Editor.Series.Arrow,
  FMXTee.Editor.Series.Bubble,
  FMXTee.Editor.Series.Gantt,
  FMXTee.Editor.Series.Shape,
  FMXTee.Chart.Functions,
  {$ENDIF}

  // Series
  FMXTee.Editor.Series.Area,
  FMXTee.Editor.Series.CustomBar,
  FMXTee.Editor.Series.Custom,
  FMXTee.Editor.Series.FastLine,
  FMXTee.Editor.Series.Pie,
  FMXTee.Editor.Series.Pointer;

procedure TChartEditForm.Button1Click(Sender: TObject);
begin
  Close;
end;

type
  TSeriesAccess=class(TChartSeries);

procedure TChartEditForm.BAddClick(Sender: TObject);
var tmp : TChartSeriesClass;
    tmpFunction : TTeeFunctionClass;
    tmpSub : Integer;

  procedure CreateNewSeries;
  var tmpSeries : TChartSeries;
  begin
    tmpSeries:=Chart.AddSeries(tmp);
    tmpSeries.Name:=GetNewSeriesName(Chart.Owner);

    if Assigned(tmpFunction) then
       CreateNewTeeFunction(tmpSeries, tmpFunction);

    if CurrentGroup<>nil then
       CurrentGroup.Add(tmpSeries);

    AddSeries(tmpSeries);

    if tmpSub>0 then
       TSeriesAccess(tmpSeries).SetSubGallery(tmpSeries,tmpSub);
  end;

var t,
    tmpCount : Integer;
begin
  tmp:=TChartGallery.ChooseSeries(Self, tmpFunction, tmpCount, tmpSub,
                                  Chart.ColorPaletteIndex,
                                  True);

  if Assigned(tmp) then
  begin
    for t := 1 to tmpCount do
        CreateNewSeries;

    ListSeries.ClearSelection;

    ListSeries.ItemIndex:=-1; // <-- do this, because is MultiSelect listbox

    ListSeries.ItemIndex:=ListSeries.Count-1;
  end;

  BringToFront;
end;

{$IFDEF FPC}
// TODO
function InputQuery(const Title,Caption:String; var S:WideString):Boolean;
begin
  ShowMessage(Title+' '+Caption);
  result:=False;
end;
{$ENDIF}

procedure TChartEditForm.BAddGroupClick(Sender: TObject);
var tmpSt : {$IFDEF FMI}WideString{$ELSE}String{$ENDIF};
begin
  tmpSt:='';

  repeat
    if not TeeInputQuery(TeeMsg_AddNewGroup, TeeMsg_GroupName, tmpSt) then
       break;

  until tmpSt<>'';

  if tmpSt<>'' then
  begin
    Chart.SeriesList.AddGroup(tmpSt);
    FillGroups;

    Groups.ItemIndex:=Groups.Count-1;
    GroupsChange(Self);
  end;
end;

function TChartEditForm.SelectedSeries:TChartSeries;
begin
  result:=ListSeries.SelectedSeries;
end;

function TChartEditForm.TreeItemSeries(const ASeries:TChartSeries):TTreeViewItem;
var t: Integer;
begin
  result:=nil;

  for t := 0 to SeriesNode.Count-1 do
      if SeriesNode.Items[t].TagObject=ASeries then
      begin
        result:=SeriesNode.Items[t];
        break;
      end;
end;

procedure TChartEditForm.BChangeClick(Sender: TObject);
var tmp : TChartSeriesClass;
    s   : TChartSeries;
    i   : TTreeViewItem;
begin
  s:=SelectedSeries;
  i:=TreeItemSeries(s);
  tmp:=TChartGallery.ChangeSeries(Self, s);

  if Assigned(tmp) then
  begin
    s:=ChangeSeriesType(s,tmp);
    ListSeries.SelectedSeries:=s;
    i.TagObject:=s;
  end;

  BringToFront;
end;

procedure TChartEditForm.BCloneClick(Sender: TObject);
begin
  AddSeries(CloneChartSeries(SelectedSeries, Chart));
  ListSeries.ClearSelection;
  ListSeries.ItemIndex:=ListSeries.Count-1;
end;

procedure TChartEditForm.BDeleteClick(Sender: TObject);
begin
  if ListSeries.DeleteSeries then
     FillSeries;
end;

procedure TChartEditForm.BDeleteGroupClick(Sender: TObject);
begin
  if YesNo(Format(TeeMsg_SureToDelete, [Groups.Items[Groups.ItemIndex]])) then
  begin
    CurrentGroup.DisposeOf;
    FillGroups;
  end;
end;

procedure TChartEditForm.BEditSeriesClick(Sender: TObject);
begin
  ListSeriesDblClick(Sender);
end;

procedure TChartEditForm.BRenameGroupClick(Sender: TObject);
var tmpSt : {$IFDEF FMI}WideString{$ELSE}String{$ENDIF};
begin
  tmpSt:=Groups.Items[Groups.ItemIndex];

  if TeeInputQuery(TeeMsg_ChangeGroupName, TeeMsg_GroupName, tmpSt) then
  begin
    CurrentGroup.Name:=tmpSt;
    FillGroups;
  end;
end;

procedure TChartEditForm.BTitleClick(Sender: TObject);
begin
  if ListSeries.RenameSeries and Tree.Visible then
     TreeItemSeries(ListSeries.SelectedSeries).Text:=ListSeries.Selected.Text;
end;

class procedure TChartEditForm.Edit(const AOwner:TComponent; const AChart:TCustomChart);
begin
  with TChartEditForm.Create(AOwner) do
  try
    Chart:=AChart;

    {$IFDEF ANDROID}
    Show;  // No ShowModal for Android platform (XE5)
    {$ELSE}
    ShowModal;
    {$ENDIF}
  finally
    {$IFNDEF ANDROID}
    Free;
    {$ENDIF}
  end;
end;

class procedure TChartEditForm.Edit(const AOwner:TComponent; const ASeries:TChartSeries);
begin
  with TChartEditForm.Create(AOwner) do
  try
    Chart:=TCustomChart(ASeries.ParentChart);
    ListSeries.SelectedSeries:=ASeries;
    ListSeriesDblClick(nil);

    ShowModal;
  finally
    Free;
  end;
end;

// Creates a new Tree Item
function AddNode(const AParent:TFMXObject; const ATitle:String; const AObject:TObject=nil):TTreeViewItem;
begin
  result:=TTreeViewItem.Create(AParent.Owner);
  result.Text:=ATitle;
  result.TextSettings.WordWrap:=False;

  result.TagObject:=AObject;
  result.Parent:=AParent;
end;

procedure TChartEditForm.AddSeries(const ASeries:TChartSeries);
begin
  if (csDesigning in Chart.ComponentState) or ASeries.ShowInEditor then
     AddNode(SeriesNode,SeriesTitleOrName(ASeries),ASeries);
end;

procedure TChartEditForm.FillAxes;

  procedure AddAxis(const Axis:TChartAxis);
  begin
    AddNode(AxesNode,Chart.AxisTitleOrName(Axis),Axis);
  end;

var
  t: Integer;
begin
  for t := 0 to Chart.Axes.Count-1 do
      AddAxis(Chart.Axes[t]);
end;

procedure TChartEditForm.FillGroups;

  function AddGroup(const S:String):TListBoxItem;
  begin
    result:=TListBoxItem.Create(Self);
    result.Text:=S;
    Groups.AddObject(result);
  end;

var Old : Integer;
    t   : Integer;
    tmpItem : TListBoxItem;
begin
  Old:=Groups.ItemIndex;
  if Old=-1 then Old:=0;

  while Groups.Count>1 do
    Groups.ListItems[1].DisposeOf;

  if Groups.Count=0 then
     AddGroup(TeeMsg_All).IsChecked:=Chart.SeriesList.AllActive;

  with Chart.SeriesList.Groups do
  for t:=0 to Count-1 do
  begin
    tmpItem:=AddGroup(Items[t].Name);

    case Items[t].Active of
      gaYes: tmpItem.IsChecked:=True;
      gaSome: begin
                tmpItem.Enabled:=False;
                tmpItem.IsChecked:=True;
              end;
      gaNo: ;
    end;
  end;

  if Old>Groups.Count-1 then
     Old:=Groups.Count-1;

  Groups.ItemIndex:=Old;
  GroupsChange(Self);
end;

procedure TChartEditForm.FillSeries;
var t : Integer;
begin
  while SeriesNode.Count>0 do
        SeriesNode.Items[0].DisposeOf;

  for t:=0 to ListSeries.Count-1 do
      AddSeries(ListSeries.Series[t]);
end;

{$IFNDEF TEELITE}
procedure TChartEditForm.FillAnimations;
var t : Integer;
    tmp : TTeeCustomAnimation;
begin
  for t:=0 to FChart.Animations.Count-1 do
  begin
    tmp:=FChart.Animations[t];
    AddNode(AnimsNode,tmp.Title,tmp);
  end;
end;

procedure TChartEditForm.FillTools;
var t : Integer;
    tmp : TTeeCustomTool;
begin
  for t:=0 to FChart.Tools.Count-1 do
  begin
    tmp:=FChart.Tools[t];
    AddNode(ToolsNode,tmp.Description,tmp);
  end;
end;
{$ENDIF}

procedure TChartEditForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose:=(not Assigned(FLastForm)) or FLastForm.CloseQuery;
end;

procedure TChartEditForm.FormCreate(Sender: TObject);
begin
  {$IFDEF TEELITEEMB}
  (* "Special offer text" removed for XE5.
     TeeAbout Box already contains it.
  Text1.Text:=TeeRADXE2_SpecialOffer;

  // Workaround:
  Text1.AutoSize:=False;
  Text1.AutoSize:=True;
  *)

  DataNode.Visible:=False;
  ExportNode.Visible:=False;
  PrintNode.Visible:=False;
  {$ELSE}

  {$IFNDEF TEELITE}
  ToolsNode:=AddNode(Tree,'Tools'); // Do not localize
  ToolsNode.Index:=ExportNode.Index;

  AnimsNode:=AddNode(Tree,'Animations'); // Do not localize
  AnimsNode.Index:=ExportNode.Index;

  if Assigned(ThemesEditor) then
     ThemesNode:=AddNode(Tree,'Themes'); // Do not localize

  if Assigned(ImportEditor) then
     ImportNode:=AddNode(Tree,'Import'); // Do not localize

  Text1.Visible:=False;
  {$ENDIF}

  {$IFNDEF IOS}
  MenuItem4.Visible:=False;
  MenuItem5.Visible:=False;
  {$ENDIF}

  {$ENDIF}

  Groups.OnDragOver:=GroupsDragOver;
  Groups.OnDragDrop:=GroupsDragDrop;

  TopLayout.Height:=33;
end;

procedure TChartEditForm.FormDestroy(Sender: TObject);
begin
  DestroyPreviousForm;
end;

procedure TChartEditForm.GroupsChange(Sender: TObject);
begin
  ListSeries.SeriesGroup:=CurrentGroup;
  EnableGroupButtons;
end;

const
  DeltaGroup = 1;

procedure TChartEditForm.GroupsChangeCheck(Sender: TObject);
begin
  if (DeltaGroup=1) and (Groups.ItemIndex=0) then
     Chart.SeriesList.AllActive:=Groups.Selected.IsChecked
  else
  begin
    if Groups.Selected.IsChecked then
       if Groups.Selected.Enabled then
          CurrentGroup.Active:=gaYes
       else
          CurrentGroup.Active:=gaSome
    else
      CurrentGroup.Active:=gaNo;

    if DeltaGroup=1 then
       Groups.ListItems[0].IsChecked:=Chart.SeriesList.AllActive;
  end;

  EnableGroupButtons;
end;

{$IFDEF D20}
procedure TChartEditForm.GroupsDragDrop(Sender: TObject; const Data: TDragObject;
  const Point: TPointF);
{$ELSE}
procedure TChartEditForm.GroupsDragDrop(Sender: TObject; const Data: TDragObject;
  const Point: TPointF);
{$ENDIF}

   Procedure RefreshGroups(const Item:TListBoxItem);
   begin
     FillGroups;
     Item.IsSelected:=True;
     GroupsChange(Groups);
   end;

var tmp : TListBoxItem;
    tmpSeries : TChartSeries;
begin
  tmp:=Groups.ItemByPoint(Point.X,Point.Y);

  if Assigned(tmp) and (Data.Source is TChartListBox) then
  begin
    tmpSeries:=TChartListBox(Data.Source).SelectedSeries;

    if (tmp.Index=0) and (DeltaGroup=1) then
    begin
      if Groups.ItemIndex>=DeltaGroup then
         CurrentGroup.Series.Remove(tmpSeries);

      RefreshGroups(tmp);
    end
    else
    with Chart.SeriesList.Groups[tmp.Index-DeltaGroup].Series do
    begin
      if IndexOf(tmpSeries)=-1 then
      begin
        Add(tmpSeries);

        if Groups.ItemIndex>=DeltaGroup then
           CurrentGroup.Series.Remove(tmpSeries);

        RefreshGroups(tmp);
      end;
    end;
  end;
end;

{$IFDEF D20}
procedure TChartEditForm.GroupsDragOver(Sender: TObject; const Data: TDragObject; const Point: TPointF;
                             var Operation: TDragOperation);
var Accept : Boolean;
{$ELSE}
procedure TChartEditForm.GroupsDragOver(Sender: TObject; const Data: TDragObject;
  const Point: TPointF; var Accept: Boolean);
{$ENDIF}
var tmp : TListBoxItem;
begin
  tmp:=Groups.ItemByPoint(Point.X, Point.Y);

  Accept:={$IFDEF D20}(Operation=TDragOperation.Move) and{$ENDIF}
          Assigned(tmp) and (Data.Source is TChartListBox);

  if Accept and (tmp.Index>=DeltaGroup) then
     Accept:=Accept and
       (Chart.SeriesList.Groups[tmp.Index-DeltaGroup].Series.IndexOf(TChartListBox(Data.Source).SelectedSeries)=-1);

  {$IFDEF D20}
  if Accept then
     Operation:=TDragOperation.Move;
  {$ENDIF}
end;

procedure TChartEditForm.EnableGroupButtons;
begin
  BDeleteGroup.Enabled:=Groups.ItemIndex>=DeltaGroup;
  BRenameGroup.Enabled:=BDeleteGroup.Enabled;
end;

procedure TChartEditForm.ViewGroupsChange(Sender: TObject);
begin
  //with ViewGroups do IsChecked:=not IsChecked;
  ShowHideGroups;
end;

procedure TChartEditForm.ViewNamesChange(Sender: TObject);
begin
//  ViewNames.IsChecked:=not ViewNames.IsChecked;

  ListSeries.ShowSeriesNames:=ViewNames.IsChecked;

  if ViewNames.IsChecked then
     BTitle.Text:='Name...'
  else
     BTitle.Text:=TeeMsg_Title+'...';
end;

Function TChartEditForm.CurrentGroup:TSeriesGroup;
begin
  if Groups.ItemIndex=-1 then
     result:=nil
  else
  if (DeltaGroup=1) and (Groups.ItemIndex=0) then
     result:=nil
  else
     result:=Chart.SeriesList.Groups[Groups.ItemIndex-DeltaGroup];
end;

procedure TChartEditForm.LabelViewClick(Sender: TObject);
begin
  SBView.IsPressed:=not SBView.IsPressed;
  SBViewClick(Self);
end;

procedure TChartEditForm.ListSeriesChange(Sender: TObject);
begin
  BDelete.Enabled:=ListSeries.Selected<>nil;
  BTitle.Enabled:=BDelete.Enabled;
  BClone.Enabled:=BDelete.Enabled;
  BChange.Enabled:=BDelete.Enabled;
  BEditSeries.Enabled:=BDelete.Enabled;

  SBUp.Enabled:=ListSeries.ItemIndex>0;
  SBDown.Enabled:=(ListSeries.ItemIndex>=0) and (ListSeries.ItemIndex<ListSeries.Count-1);
end;

procedure TChartEditForm.ListSeriesChangeCheck(Sender: TObject);
begin
  ListSeries.SelectedSeries.Visible:=ListSeries.Selected.IsChecked;
  FillGroups;
end;

procedure TChartEditForm.ListSeriesDblClick(Sender: TObject);
begin
  if SeriesNode.Count>ListSeries.ItemIndex then 
     Tree.Selected:=SeriesNode.Items[ListSeries.ItemIndex];
end;

procedure TChartEditForm.MenuItem11Click(Sender: TObject);
begin
  ListSeries.SelectAll;
  ListSeriesChange(Self);
end;

procedure TChartEditForm.MenuItem12Click(Sender: TObject);
begin
  ListSeries.ClearSelection;
  ListSeries.ItemIndex:=-1;
end;

procedure TChartEditForm.MenuItem2Click(Sender: TObject);
begin
  {$IFNDEF TEELITEEMB}
  FChartGrid.Insert;
  {$ENDIF}
end;

procedure TChartEditForm.MenuItem3Click(Sender: TObject);
begin
  {$IFNDEF TEELITEEMB}
  FChartGrid.Delete;
  {$ENDIF}
end;

procedure TChartEditForm.MenuItem5Click(Sender: TObject);
begin
  {$IFNDEF TEELITEEMB}
  // FChartGrid.Columns[0].CellControlByRow(...) as TEdit... ??
  {$ENDIF}
end;

procedure TChartEditForm.MenuItem6Click(Sender: TObject);
var Old, t : Integer;
begin
  Old:=ListSeries.ItemIndex;

  for t:=0 to Chart.SeriesCount-1 do
  begin
    ListSeries.ListItems[t].IsChecked:=ListSeries.ListItems[t].IsSelected;
    ListSeries.ListItems[t].IsSelected:=False;
  end;

  ListSeries.ItemIndex:=Old;
end;

procedure TChartEditForm.MenuItem8Click(Sender: TObject);
var
  Old, t: Integer;
begin
  Chart.SeriesList.AllActive:=(Sender=MenuItem8);

  Old:=ListSeries.ItemIndex;

  for t := 0 to ListSeries.Count-1 do
  begin
    ListSeries.ListItems[t].IsChecked:=ListSeries.Series[t].Visible;
    ListSeries.ListItems[t].IsSelected:=False;
  end;

  ListSeries.ItemIndex:=Old;
end;

procedure TChartEditForm.MenuItem9Click(Sender: TObject);
begin
  MenuItem8Click(Self);
end;

procedure TChartEditForm.PanBottomResize(Sender: TObject);
begin
  // RX10 bug, Text1 is not autosized
  Text1.Width:=Max(20,PanBottom.Width-120);
end;

procedure TChartEditForm.ExchangeSeries(Index1, Index2:Integer);
begin
  Chart.ExchangeSeries(Index1, Index2);
  ListSeries.ItemIndex:=Index2;
  ListSeriesChange(Self);
end;

procedure TChartEditForm.SBDownClick(Sender: TObject);
begin
  ExchangeSeries(ListSeries.ItemIndex, ListSeries.ItemIndex+1);
end;

procedure TChartEditForm.SBUpClick(Sender: TObject);
begin
  ExchangeSeries(ListSeries.ItemIndex, ListSeries.ItemIndex-1);
end;

procedure TChartEditForm.SetupChart(const AChart:TCustomChart);
var tmpDesign : Boolean;
begin
  FChart:=AChart;

  ListSeries.Chart:=AChart;
  ListSeriesChange(Self);

  tmpDesign:=Assigned(FChart) and (csDesigning in FChart.ComponentState);

  ViewNames.Visible:=tmpDesign;

  {$IFDEF TEELITEEMB}
  Text1.Visible:=tmpDesign;
  {$ENDIF}

  if Assigned(FChart) then
  begin
    FillAxes;
    FillSeries;

    {$IFNDEF TEELITE}
    FillTools;
    FillAnimations;
    {$ENDIF}

    ShowHideGroups;

    Caption:=Format(TeeMsg_Editing, [FChart.Name]);
  end
  else
     Caption:='';
end;

procedure TChartEditForm.ShowHideGroups;
begin
  // Series Groups
  BAddGroup.Visible:=ViewGroups.IsChecked;
  BDeleteGroup.Visible:=BAddGroup.Visible;
  BRenameGroup.Visible:=BAddGroup.Visible;

  PanelGroups.Visible:=BAddGroup.Visible;
  SplitterGroups.Visible:=PanelGroups.Visible;
  PanelGroupButtons.Visible:=PanelGroups.Visible;

  if PanelGroups.Visible then
     FillGroups;
end;

procedure TChartEditForm.SBViewClick(Sender: TObject);
begin
  if SBView.IsPressed then
     if ViewNames.Visible then
        TopLayout.Height:=ViewNames.Position.Y+(ViewNames.Height*1.5)
     else
        TopLayout.Height:=ViewGroups.Position.Y+(ViewGroups.Height*1.5)
  else
     TopLayout.Height:=LabelView.Position.Y+(LabelView.Height*1.5);
end;

procedure TChartEditForm.Text1Click(Sender: TObject);
begin
  {$IFDEF TEELITE}
  TeeGotoURL({$IFDEF D18}NativeUInt{$ENDIF}(Handle),TeeRADXE2_SpecialWWW);
  {$ENDIF}
end;

{$IFNDEF TEELITEEMB}
procedure TChartEditForm.DestroyGrid;
begin
  if FChartGrid<>nil then
  begin
    {$IFDEF AUTOREFCOUNT}
    FChartGrid.Parent:=nil;
    FChartGrid.DisposeOf;
    {$ENDIF}

    FreeAndNil(FChartGrid);
  end;
end;
{$ENDIF}

procedure TChartEditForm.DestroyPreviousForm;
begin
  if FLastForm<>nil then
  begin
    {$IFDEF AUTOREFCOUNT}
    FLastForm.Parent:=nil;
    FLastForm.DisposeOf;
    {$ENDIF}

    FreeAndNil(FLastForm);
  end;
end;

type
  TOpenStyled=class(TStyledControl);

procedure TChartEditForm.TreeChange(Sender: TObject);

  procedure AddForm(const AForm:TForm);
  begin
    DestroyPreviousForm;

    PanelList.Visible:=False;
    TopLayout.Visible:=False;
    Panel2.Visible:=False;

    EmbeddForm(AForm,PanelTabs);

    FLastForm:=AForm;
  end;

  procedure ShowSeriesTab;
  var t : Integer;
      tmp : TFMXObject;
  begin
    DestroyPreviousForm;

    if not PanelList.Visible then
    begin
      t:=0;

      // Risk point here:

      with TOpenStyled(PanelTabs) do
      while t<ChildrenCount do
      begin
        tmp:=Children[t];

        if (tmp<>PanelList) and
           (tmp<>TopLayout) and
           (tmp<>ResourceLink) and
           (tmp<>ResourceControl)

           {$IFDEF D22}
           and (not (tmp is TStyledPresentation)) // XE8
           {$ENDIF}

           then
             tmp.DisposeOf
        else
           Inc(t);
      end;
      
      PanelList.Visible:=True;
      TopLayout.Visible:=True;
      Panel2.Visible:=True;
    end;
  end;

  function SelectedTitle:TChartTitle;
  begin
    if Tree.Selected=TitleNode then
       result:=Chart.Title
    else
    if Tree.Selected=SubTitleNode then
       result:=Chart.SubTitle
    else
    if Tree.Selected=FooterNode then
       result:=Chart.Foot
    else
       result:=Chart.SubFoot;
  end;

  function SelectedAxis:TChartAxis;
  begin
    result:=Tree.Selected.TagObject as TChartAxis;
  end;

  {$IFNDEF TEELITE}
  procedure CreateAnimsEditor;
  begin
    AddForm(TChartAnimationsEditor.CreateEditor(Self, Chart.Animations));
    TChartAnimationsEditor(FLastForm).EditorNode:=AnimsNode;
  end;

  procedure CreateToolsEditor;
  begin
    AddForm(TToolsEditor.CreateEditor(Self, Chart));
    TToolsEditor(FLastForm).EditorNode:=ToolsNode;
  end;
  {$ENDIF}

  procedure TryAddForm(const AClass:TFormClass);
  begin
    if Assigned(AClass) then
    begin
      AddForm(AClass.Create(Self));

      FLastForm.TagObject:=Chart;

      FLastForm.OnActivate(Self);
      //FLastForm.Activate;  <-- XE2
    end;
  end;

var tmpOldTab : String;
    tmpComp   : TComponent;
    tmpTab    : TTabItem;
begin
  // XE7 protection:
  if not Assigned(Tree.Selected) then
     Exit;

  {$IFNDEF TEELITEEMB}
  DestroyGrid;
  {$ENDIF}

  if Tree.Selected.ParentItem=AxesNode then
  begin
    if FLastForm is TAxisEditor then
       TAxisEditor(FLastForm).RefreshAxis(SelectedAxis)
    else
       AddForm(TAxisEditor.CreateEditor(Self, SelectedAxis));
  end
  else
  if Tree.Selected.ParentItem=TitlesNode then
  begin
    if FLastForm is TTitleEditor then
       TTitleEditor(FLastForm).RefreshTitle(SelectedTitle)
    else
       AddForm(TTitleEditor.CreateEditor(Self, SelectedTitle));
  end
  else
  begin
    tmpOldTab:='';

    if FLastForm is TSeriesEditor then
    begin
      tmpTab:=TSeriesEditor(FLastForm).PageSeries.ActiveTab;

      if Assigned(tmpTab) then
         tmpOldTab:=tmpTab.Name;
    end;

    DestroyPreviousForm;
  end;

  if Tree.Selected=SeriesNode then
     ShowSeriesTab
  else
  if Tree.Selected.ParentItem=SeriesNode then
  begin
    AddForm(TSeriesEditor.CreateEditor(Self, Tree.Selected.TagObject as TChartSeries));

    if tmpOldTab<>'' then
    begin
      tmpComp:=TSeriesEditor(FLastForm).FindComponent(tmpOldTab);

      if Assigned(tmpComp) and (tmpComp is TTabItem) then
         TSeriesEditor(FLastForm).PageSeries.ActiveTab:=TTabItem(tmpComp);
    end;
  end
  else
  if Tree.Selected=LegendNode then
     AddForm(TLegendEditor.CreateEditor(Self, Chart.Legend))
  else
  if Tree.Selected=PagingNode then
     AddForm(TPagingEditor.CreateEditor(Self, Chart.Pages))
  else
  if Tree.Selected=PanelNode then
     AddForm(TPanelEditor.CreateEditor(Self, Chart))
  else
  if Tree.Selected=GeneralNode then
     AddForm(TGeneralEditor.CreateEditor(Self, Chart))
  else
  if Tree.Selected=TitlesNode then
     AddForm(TTitleEditor.CreateEditor(Self, Chart.Title))
  else
  if Tree.Selected=WallsNode then
     AddForm(TWallEditor.CreateEditor(Self, Chart.Walls))
  else
  if Tree.Selected=AxesNode then
     AddForm(TAxisEditor.CreateEditor(Self, Chart.Axes))
  else
  {$IFNDEF TEELITEEMB}

  {$IFNDEF TEELITE}
  if Tree.Selected=ToolsNode then
     CreateToolsEditor
  else
  if Tree.Selected.ParentItem=ToolsNode then
  begin
    if not (FLastForm is TToolsEditor) then
       CreateToolsEditor;

    TToolsEditor(FLastForm).EditTool(TTeeCustomTool(Tree.Selected.TagObject));
  end
  else
  {$ENDIF}

  if Tree.Selected=ExportNode then
     AddForm(TExportEditor.CreateEditor(nil, Chart))
  else
  if Tree.Selected=PrintNode then
     AddForm(TChartPreview.CreateEditor(nil, Chart))
  else
  if Tree.Selected=DataNode then
  begin
    {$IFNDEF TEELITEEMB} 
    if not Assigned(FChartGrid) then
    begin
      FChartGrid:=TChartGrid.Create(Self);
      FChartGrid.Align:=TAlignLayout.{$IFDEF D20}Client{$ELSE}alClient{$ENDIF};
      FChartGrid.Chart:=Chart;
      //FChartGrid.PopupMenu:=PopupData;
    end;
    {$ENDIF}
    DestroyPreviousForm;

    PanelList.Visible:=False;
    TopLayout.Visible:=False;
    Panel2.Visible:=False;

    {$IFNDEF TEELITEEMB} 
    if FChartGrid.Parent<>PanelTabs then
       PanelTabs.AddObject(FChartGrid);
    {$ENDIF}	   
  end
  else
  if Tree.Selected=ThemesNode then
     TryAddForm(ThemesEditor)
  else
  if Tree.Selected=ImportNode then
     TryAddForm(ImportEditor)
  else

  {$IFNDEF TEELITE}
  if Tree.Selected=AnimsNode then
  begin
    CreateAnimsEditor;
    TChartAnimationsEditor(FLastForm).FormShow(FLastForm);
  end
  else
  if Tree.Selected.ParentItem=AnimsNode then
  begin
    if not (FLastForm is TChartAnimationsEditor) then
    begin
      CreateAnimsEditor;
      TChartAnimationsEditor(FLastForm).FormShow(FLastForm);
    end;

    TChartAnimationsEditor(FLastForm).EditAnimation(TTeeCustomAnimation(Tree.Selected.TagObject));
  end
  else
  {$ENDIF}

  {$ENDIF}
  if Tree.Selected=Node3D then
     AddForm(TFormTee3D.CreateEditor(Self, Chart));
end;

end.

