unit FMXTee.Editor.Series.Organizational;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMXTee.Chart.ListBox,
  FMX.TabControl, FMXTee.Series.Organizational, FMXTee.Editor.CustomShape,
  FMXTee.Editor.Margins, FMX.Edit, FMX.ListBox, FMX.Colors, FMX.Layouts,
  FMX.TreeView, FMX.Memo;

type
  TOrgSeriesEditor = class(TForm)
    TabControl1: TTabControl;
    TabOptions: TTabItem;
    BLines: TButton;
    CBLineStyle: TComboBox;
    Label1: TLabel;
    ListBoxItem1: TListBoxItem;
    ListBoxItem2: TListBoxItem;
    GroupBox1: TGroupBox;
    Label2: TLabel;
    Label3: TLabel;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    TabNodes: TTabItem;
    Panel1: TPanel;
    TreeNodes: TTreeView;
    Splitter1: TSplitter;
    TabControl2: TTabControl;
    TabText: TTabItem;
    TabSize: TTabItem;
    TabMargins: TTabItem;
    SBAdd: TButton;
    SBDelete: TButton;
    BDefaultFormat: TButton;
    Label4: TLabel;
    Memo1: TMemo;
    CBVisible: TCheckBox;
    BEdit: TButton;
    CBCursor: TComboBox;
    Label5: TLabel;
    ComboAlign: TComboBox;
    ListBoxItem3: TListBoxItem;
    ListBoxItem4: TListBoxItem;
    ListBoxItem5: TListBoxItem;
    Label7: TLabel;
    CBDefaultFormat: TCheckBox;
    UDWidth: TSpinBox;
    UDHeight: TSpinBox;
    Label8: TLabel;
    Label9: TLabel;
    CBAutoSize: TCheckBox;
    CBClip: TCheckBox;
    TabShape: TTabItem;
    procedure FormActivate(Sender: TObject);
    procedure BLinesClick(Sender: TObject);
    procedure CBLineStyleChange(Sender: TObject);
    procedure CBCursorChange(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure TrackBar2Change(Sender: TObject);
    procedure SBAddClick(Sender: TObject);
    procedure SBDeleteClick(Sender: TObject);
    procedure BDefaultFormatClick(Sender: TObject);
    procedure Memo1Change(Sender: TObject);
    procedure CBVisibleChange(Sender: TObject);
    procedure BEditClick(Sender: TObject);
    procedure ComboAlignChange(Sender: TObject);
    procedure CBDefaultFormatChange(Sender: TObject);
    procedure CBAutoSizeChange(Sender: TObject);
    procedure UDWidthChange(Sender: TObject);
    procedure UDHeightChange(Sender: TObject);
    procedure CBClipChange(Sender: TObject);
    procedure TreeNodesChange(Sender: TObject);
  private
    { Private declarations }
    ShapeEditor   : TTeeShapeEditor;
    MarginsEditor : TForm;
    procedure AddListNodes(Current:Integer);
    function CurrentItem:TOrgItem;
    procedure ShowHideFormatTabs(OrgItem: TOrgItem; DoShow:Boolean);
  protected
    Org       : TCustomOrgSeries;
    IChanging : Boolean;
    function CurrentIndex:Integer;
    procedure RefreshNode(Index:Integer);
    procedure SetItemProperties(Index:Integer); virtual;
  public
    { Public declarations }
  end;

implementation

{$R *.fmx}

uses
  System.UIConsts, Math, FMXTee.Editor.Stroke, FMXTee.Editor.Series,
  FMXTee.Editor.Strings, FMXTee.Engine, FMXTee.Procs;

const
  TeeCursorPrefix='cr';

procedure TOrgSeriesEditor.CBAutoSizeChange(Sender: TObject);
var OrgItem: TOrgItem;
begin
  if not IChanging then
  begin
    CBDefaultFormat.IsChecked:=False;
    OrgItem:=CurrentItem;
    if Assigned(OrgItem) then
      OrgItem.Format.AutoSize:=CBAutoSize.IsChecked;
  end;
end;

procedure TOrgSeriesEditor.CBClipChange(Sender: TObject);
var OrgItem: TOrgItem;
begin
  if not IChanging then
  begin
    CBDefaultFormat.IsChecked:=False;
    OrgItem:=CurrentItem;
    if Assigned(OrgItem) then
      OrgItem.Format.ClipText:=CBClip.IsChecked;
  end;
end;

procedure TOrgSeriesEditor.CBCursorChange(Sender: TObject);
var OrgItem: TOrgItem;
begin
  if not IChanging then
  begin
    CBDefaultFormat.IsChecked:=False;

    OrgItem:=CurrentItem;
    if Assigned(OrgItem) then
    with OrgItem.Format do
      Cursor:=StringToCursor(TeeCursorPrefix+CBCursor.Selected.Text);
  end;
end;

procedure TOrgSeriesEditor.ShowHideFormatTabs(OrgItem: TOrgItem; DoShow:Boolean);
//var t : Integer;
begin
  if not Assigned(ShapeEditor) and Assigned(OrgItem) then
  begin
    ShapeEditor:=TTeeShapeEditor.CreateEditor(Self, OrgItem.Format);
    ShapeEditor.Name:=TeeGetUniqueName(Self,'ShapeEditor');
    EmbeddForm(ShapeEditor, TabShape);

    MarginsEditor:=TMarginsEditor.CreateEditor(Self, OrgItem.Format.Margins);
    MarginsEditor.Name:=TeeGetUniqueName(Self,'MarginsEditor');
    EmbeddForm(MarginsEditor, TabMargins);
  end;

  TabMargins.Visible:=DoShow;
  TabShape.Visible:=DoShow;
end;

procedure TOrgSeriesEditor.CBDefaultFormatChange(Sender: TObject);
var OrgItem: TOrgItem;
begin
  BDefaultFormat.Enabled:=CBDefaultFormat.IsChecked;

  OrgItem:=CurrentItem;
  if CBDefaultFormat.IsChecked then
  begin
    if Assigned(OrgItem) then
      OrgItem.RemoveFormat;
    ShowHideFormatTabs(OrgItem,False);
  end
  else
  begin
    ShowHideFormatTabs(OrgItem,True);
    if Assigned(OrgItem) then
    begin
      ShapeEditor.RefreshShape(OrgItem.Format);
      TMarginsEditor(MarginsEditor).RefreshMargins(CurrentItem.Format.Margins);
    end;
  end;
end;

procedure TOrgSeriesEditor.CBLineStyleChange(Sender: TObject);
begin
  if Assigned(Org) then
    TOrgSeries(Org).LineStyle:=TOrgLineStyle(CBLineStyle.ItemIndex);
end;

procedure TOrgSeriesEditor.CBVisibleChange(Sender: TObject);
var OrgItem: TOrgItem;
begin
  if not IChanging then
  begin
    CBDefaultFormat.IsChecked:=False;

    OrgItem:=CurrentItem;
    if Assigned(OrgItem) then
      OrgItem.Format.Visible:=CBVisible.IsChecked;
  end;
end;

procedure TOrgSeriesEditor.ComboAlignChange(Sender: TObject);
var OrgItem: TOrgItem;
begin
  if not IChanging then
  begin
    CBDefaultFormat.IsChecked:=False;
    OrgItem:=CurrentItem;
    if Assigned(OrgItem) then
      OrgItem.Format.TextAlignment:=TAlignment(ComboAlign.ItemIndex);
  end;
end;

procedure TOrgSeriesEditor.BDefaultFormatClick(Sender: TObject);
begin
  TTeeShapeEditor.Edit(Self,Org.Format);
    Org.Repaint;
end;

procedure TOrgSeriesEditor.BEditClick(Sender: TObject);
begin
  TStringsEditor.Edit(Self,Memo1.Lines);
end;

procedure TOrgSeriesEditor.BLinesClick(Sender: TObject);
begin
  if Assigned(Org) then
    TStrokeEditor.Edit(Self, Org.Pen);
end;

procedure TOrgSeriesEditor.AddListNodes(Current:Integer);

  procedure AddNodes(Node:TTreeViewItem=nil; Parent:Integer=-1);

    function FirstLine(const s:String):String;
    var i : Integer;
    begin
      i:=Pos(TeeLineSeparator,s);
      if i=0 then
         result:=s
      else
         result:=Copy(s,1,i-1);
    end;

  var t : Integer;
      n : TTreeViewItem;
  begin
    with Org do
    for t:=0 to Min(Count,Items.Count)-1 do
    if NotMandatoryValueList.Value[t]=Parent then
    begin
      n:=TTreeViewItem.Create(Self);
      n.Text:=FirstLine(XLabel[t]);
      n.TagObject:=TObject(t);
      if Node=nil then
        TreeNodes.AddObject(n)
      else
        Node.AddObject(n);
      AddNodes(n,t);
    end;
  end;

begin
  TreeNodes.Clear;
  AddNodes;

  TreeNodes.Enabled:=TreeNodes.Count>0;
  TabNodes.Enabled:=TreeNodes.Enabled;

  if Org.Count=0 then
     TabControl2.Visible:=False
  else
  if (Current<>-1) and (TreeNodes.Count>0) then
  begin
    TreeNodes.Items[0].IsExpanded:=True;
    RefreshNode(Current);
  end;

  SBDelete.Enabled:=Org.Count>0;
end;

function TOrgSeriesEditor.CurrentIndex:Integer;
begin
  if Assigned(TreeNodes.Selected) then
    result:=Integer(TreeNodes.Selected.TagObject)
  else
    result:=-1;
end;

function TOrgSeriesEditor.CurrentItem:TOrgItem;
var i: Integer;
begin
  i:=CurrentIndex;
  if i>=0 then
    result:=Org.Items[i]
  else
    result:=nil;
end;

procedure TOrgSeriesEditor.RefreshNode(Index:Integer);
var t : Integer;
begin
  for t:=0 to TreeNodes.Count-1 do
  if Integer(TreeNodes.Items[t].TagObject)=Index then
  begin
    TreeNodes.Selected:=TreeNodes.Items[t];
    TreeNodesChange(Self);
    Break;
  end;
end;

procedure TOrgSeriesEditor.SBAddClick(Sender: TObject);
var tmp : Integer;
begin
  if TreeNodes.Selected=nil then
     tmp:=-1
  else
     tmp:=CurrentItem.Index;

  AddListNodes(Org.Add('#'+IntToStr(Org.Count),tmp));
end;

procedure TOrgSeriesEditor.SBDeleteClick(Sender: TObject);
var tmp : Integer;
begin
  tmp:=CurrentIndex;
  if tmp>=0 then
  begin
    Org.Delete(tmp);
    AddListNodes(tmp-1);
  end;
end;

procedure TOrgSeriesEditor.TrackBar1Change(Sender: TObject);
begin
  if Assigned(Org) then
    Org.Spacing.Horizontal:=Round(TrackBar1.Value);
end;

procedure TOrgSeriesEditor.TrackBar2Change(Sender: TObject);
begin
  if Assigned(Org) then
    Org.Spacing.Vertical:=Round(TrackBar2.Value);
end;

{$IFNDEF CLR}
type
  TOrgItemAccess=class(TOrgItem);
{$ENDIF}

procedure TOrgSeriesEditor.SetItemProperties(Index:Integer);
var OrgItem: TOrgItem;
begin
  OrgItem:=CurrentItem;
  if Assigned(OrgItem) then
  begin
    CBDefaultFormat.IsChecked:=not {$IFNDEF CLR}TOrgItemAccess{$ENDIF}(OrgItem).HasFormat;

    with {$IFNDEF CLR}TOrgItemAccess{$ENDIF}(OrgItem) do
    begin
      CBDefaultFormatChange(Self);

      Memo1.Lines.Text:=Text;
      UDWidth.Value:=Width;
      UDHeight.Value:=Height;

      with ActiveFormat do
      begin
        CBVisible.IsChecked:=Visible;
        CBAutoSize.IsChecked:=AutoSize;
        CBClip.IsChecked:=ClipText;
        ComboAlign.ItemIndex:=Ord(TextAlignment);
        TeeFillCursors(CBCursor,Cursor);
      end;
    end;
  end;
end;

procedure TOrgSeriesEditor.TreeNodesChange(Sender: TObject);
begin
  IChanging:=True;
  try
    SetItemProperties(CurrentIndex);
  finally
    IChanging:=False;
  end;

  SBAdd.Enabled:=True;
  SBDelete.Enabled:=True;

  if not TabControl2.Visible then
     TabControl2.Visible:=True;
end;

procedure TOrgSeriesEditor.UDHeightChange(Sender: TObject);
var OrgItem: TOrgItem;
begin
  OrgItem:=CurrentItem;
  if Assigned(OrgItem) and (not IChanging) and (OrgItem.Height<>Round(UDHeight.Value)) then
  begin
    OrgItem.Height:=Round(UDHeight.Value);
    CBAutoSize.IsChecked:=False;
  end;
end;

procedure TOrgSeriesEditor.UDWidthChange(Sender: TObject);
var OrgItem: TOrgItem;
begin
  OrgItem:=CurrentItem;
  if Assigned(OrgItem) and (not IChanging) and (OrgItem.Width<>Round(UDWidth.Value)) then
  begin
    OrgItem.Width:=Round(UDWidth.Value);
    CBAutoSize.IsChecked:=False;
  end;
end;

procedure TOrgSeriesEditor.FormActivate(Sender: TObject);
begin
  if not Assigned(Org) then
  begin
    Org:=TOrgSeries(TagObject);
    TabControl1.ActiveTab:=TabText;

    if Assigned(Org) then
    begin
      TrackBar1.Value:=Org.Spacing.Horizontal;
      TrackBar2.Value:=Org.Spacing.Vertical;

      if Org is TOrgSeries then
        CBLineStyle.ItemIndex:=Ord(TOrgSeries(Org).LineStyle);

      TeeFillCursors(CBCursor,Org.Cursor);

      AddListNodes(0);

      //if Assigned(Series.ParentChart) then
      //   {$IFNDEF CLR}TTeePanelAccess{$ENDIF}(Series.ParentChart).Listeners.Add(Self);
    end;
  end;
end;

procedure TOrgSeriesEditor.Memo1Change(Sender: TObject);
var OrgItem: TOrgItem;
begin
  if not IChanging then
  begin
    OrgItem:=CurrentItem;
    if Assigned(OrgItem) then
      OrgItem.Text:=Memo1.Lines.Text;
  end;
end;

initialization
  RegisterSeriesEditor(TOrgSeriesEditor);
end.
