{
********************************************************************************

YaPeTaVi - Yet another Periodic Table Viewer
Copyright (C) 1997-2000, 2009-2012 Geoffray Levasseur <geoffray.levasseurbrandin@numericable.fr>.
All rights reserved.
http://www.geoffray-levasseur.org/

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA  02111-1307, USA.

********************************************************************************

Description:
  Periodic table (main) form unit

}
unit frmTable;

{$mode objfpc}{$H+}
interface

uses
  SysUtils, Classes, Graphics, TACustomSeries, TASeries, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, LResources, ComCtrls, Spin, Menus,
  CheckLst, Buttons, IniPropStorage, TAGraph, TATools, uConst, IniFiles,
  //project classes
  uElemListClass, uElecDistClass;

type

  { TTableForm }

  TTableForm = class(TForm)
    btnAddState: TBitBtn;
    btnSaveFilterSet: TBitBtn;
    btnOpenFilterSet: TBitBtn;
    btnAddFilterSet: TBitBtn;
    btnClearFilterSet: TBitBtn;
    btnAddFilter: TBitBtn;
    btnChangeFilter: TBitBtn;
    btnRemoveFilter: TBitBtn;
    btnWikipedia: TBitBtn;
    btnAdd: TButton;
    btnFullRange: TButton;
    cbListApplyFilter: TCheckBox;
    cbShowUnknown: TCheckBox;
    cbStateShowUnknown: TCheckBox;
    cbxSort: TComboBox;
    cbxState: TComboBox;
    Chart: TChart;
    cbTableApplyFilters: TCheckBox;
    cbxLayout: TComboBox;
    cbxXAxis: TComboBox;
    cbxYAxis: TComboBox;
    cbDrawLines: TCheckBox;
    cbChartApplyFilters: TCheckBox;
    cbChartUnknowVal: TCheckBox;
    ChartToolset: TChartToolset;
    cbxInvertSortOrder: TCheckBox;
    clbRange: TCheckListBox;
    cbxChartLabels: TComboBox;
    cbFilterKind: TComboBox;
    edRange: TEdit;
    gbState: TGroupBox;
    GroupBox10: TGroupBox;
    GroupBox11: TGroupBox;
    GroupBox3: TGroupBox;
    imgAtom: TImage;
    imgAtom1: TImage;
    IniPropStorage: TIniPropStorage;
    Label16: TLabel;
    Label17: TLabel;
    lbExpandedElecConf: TLabel;
    lbNoPic: TLabel;
    lbSecondIonisationEnergy: TLabel;
    lbThirdIonisationEnergy: TLabel;
    lbCASNumber: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label32: TLabel;
    Label33: TLabel;
    Label42: TLabel;
    lbPAtNum1: TLabel;
    lbPMass1: TLabel;
    lbPName1: TLabel;
    lvFilters: TListView;
    MenuItem5: TMenuItem;
    mmUse: TMemo;
    mmAspect: TMemo;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    mnuHeapStatus: TMenuItem;
    mnuShowFilterList: TMenuItem;
    mnuDiscoverer: TMenuItem;
    mnuOpenConsole: TMenuItem;
    dlgOpen: TOpenDialog;
    pnCn: TPanel;
    pnSelected: TPanel;
    rbStateCelcius: TRadioButton;
    rbStateKelvin: TRadioButton;
    dlgSave: TSaveDialog;
    sedFilterMax: TFloatSpinEdit;
    sedFilterMin: TFloatSpinEdit;
    sedStateTemp: TFloatSpinEdit;
    sedXStart: TFloatSpinEdit;
    sedYStart: TFloatSpinEdit;
    sedXEnd: TFloatSpinEdit;
    sedYEnd: TFloatSpinEdit;
    Label38: TLabel;
    Label39: TLabel;
    Label40: TLabel;
    Label41: TLabel;
    mnuFullZoom: TMenuItem;
    pmChart: TPopupMenu;
    MainMenu: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    mnuAbout: TMenuItem;
    mnuConfigure: TMenuItem;
    mnuExit: TMenuItem;
    mnuFile: TMenuItem;
    mnuHelp: TMenuItem;
    mnuManual: TMenuItem;
    mnuMassCalc: TMenuItem;
    mnuTools: TMenuItem;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    GroupBox4: TGroupBox;
    GroupBox5: TGroupBox;
    GroupBox7: TGroupBox;
    GroupBox8: TGroupBox;
    GroupBox9: TGroupBox;
    Isotopes: TTabSheet;
    Label1: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label19: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    lbAtNumber: TLabel;
    lbAverageX1: TLabel;
    lbAverageY1: TLabel;
    lbBoilingPt: TLabel;
    lbCovalentRd: TLabel;
    lbDiscovery: TLabel;
    lbElecAff: TLabel;
    lbElecConf: TLabel;
    lbElectroneg: TLabel;
    lbEtimology: TLabel;
    lbFamily: TLabel;
    lbFirsIonisationEnergy: TLabel;
    lbMass: TLabel;
    lbMaxX: TLabel;
    lbMaxX1: TLabel;
    lbMaxY1: TLabel;
    lbMeltingPt: TLabel;
    lbMinX: TLabel;
    lbAverageX: TLabel;
    lbMaxY: TLabel;
    lbMinX1: TLabel;
    lbMinY: TLabel;
    lbAverageY: TLabel;
    lbMinY1: TLabel;
    lbName: TLabel;
    lbNatRadio: TLabel;
    lbRadioHalfLife: TLabel;
    lbUnitX: TLabel;
    lbUnitX1: TLabel;
    lbUnitY: TLabel;
    lbUnitY1: TLabel;
    lbUnknownSort: TLabel;
    lbVanDerWalsRd: TLabel;
    lvList: TListView;
    PageControl2: TPageControl;
    Panel1: TPanel;
    Panel2: TPanel;
    pnNum1: TPanel;
    pnNum10: TPanel;
    pnNum11: TPanel;
    pnNum12: TPanel;
    pnNum13: TPanel;
    pnNum14: TPanel;
    pnNum15: TPanel;
    pnNum16: TPanel;
    pnNum17: TPanel;
    pnNum18: TPanel;
    pnNum2: TPanel;
    pnNum3: TPanel;
    pnNum4: TPanel;
    pnNum5: TPanel;
    pnNum6: TPanel;
    pnNum7: TPanel;
    pnNum8: TPanel;
    pnNum9: TPanel;
    rbSortFirst: TRadioButton;
    rbSortLast: TRadioButton;
    Splitter1: TSplitter;
    GroupBox6: TGroupBox;
    gbLegend: TGroupBox;
    lbContextInfo: TLabel;
    Label20: TLabel;
    lbPMass: TLabel;
    lbPAtNum: TLabel;
    lbPName: TLabel;
    PageControl1: TPageControl;
    pnHighlight: TPanel;
    pnGe: TPanel;
    pnI: TPanel;
    pnAc: TPanel;
    pnDy: TPanel;
    pnTb: TPanel;
    pnGd: TPanel;
    pnEu: TPanel;
    pnSm: TPanel;
    pnCe: TPanel;
    pnTh: TPanel;
    pnPa: TPanel;
    pnU: TPanel;
    pnNp: TPanel;
    pnLa2: TPanel;
    pnPu: TPanel;
    pnAm: TPanel;
    pnCm: TPanel;
    pnBk: TPanel;
    pnCf: TPanel;
    pnEs: TPanel;
    pnFm: TPanel;
    pnMd: TPanel;
    pnNo: TPanel;
    pnLr: TPanel;
    pnPr: TPanel;
    pnNd: TPanel;
    pnPm: TPanel;
    pnYb: TPanel;
    pnTm: TPanel;
    pnEr: TPanel;
    pnHo: TPanel;
    pnXe: TPanel;
    pnAl: TPanel;
    pnSi: TPanel;
    pnP: TPanel;
    pnS: TPanel;
    pnCl: TPanel;
    pnAr: TPanel;
    pnB: TPanel;
    pnC: TPanel;
    pnAs: TPanel;
    pnN: TPanel;
    pnO: TPanel;
    pnF: TPanel;
    pnNe: TPanel;
    pnHe: TPanel;
    pnBi: TPanel;
    pnPo: TPanel;
    pnPb: TPanel;
    pnTl: TPanel;
    pnAt: TPanel;
    pnSe: TPanel;
    pnRn: TPanel;
    pnBr: TPanel;
    pnKr: TPanel;
    pnIn: TPanel;
    pnSn: TPanel;
    pnSb: TPanel;
    pnTe: TPanel;
    pnH: TPanel;
    pnLi: TPanel;
    pnCa: TPanel;
    pnSc: TPanel;
    pnGa: TPanel;
    pnTi: TPanel;
    pnTa: TPanel;
    pnDb: TPanel;
    pnW: TPanel;
    pnSg: TPanel;
    pnMn: TPanel;
    pnTc: TPanel;
    pnRe: TPanel;
    pnBh: TPanel;
    pnFe: TPanel;
    pnCo: TPanel;
    pnY: TPanel;
    pnNi: TPanel;
    pnCu: TPanel;
    pnLa: TPanel;
    pnZn: TPanel;
    pnCd: TPanel;
    pnAg: TPanel;
    pnPd: TPanel;
    pnRh: TPanel;
    pnRu: TPanel;
    pnIr: TPanel;
    pnPt: TPanel;
    pnZr: TPanel;
    pnAu: TPanel;
    pnHg: TPanel;
    pnRg: TPanel;
    pnDs: TPanel;
    pnMt: TPanel;
    pnOs: TPanel;
    pnHs: TPanel;
    pnV: TPanel;
    pnNb: TPanel;
    pnHf: TPanel;
    pnRf: TPanel;
    pnCr: TPanel;
    pnMo: TPanel;
    pnSr: TPanel;
    pnBa: TPanel;
    pnRa: TPanel;
    pnBe: TPanel;
    pnNa: TPanel;
    pnMg: TPanel;
    pnK: TPanel;
    pnCs: TPanel;
    pnFr: TPanel;
    pnRb: TPanel;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    tsElecConf: TTabSheet;
    tsAspectUse: TTabSheet;
    tsElemDB: TTabSheet;
    tsGlobalInfo: TTabSheet;
    tsHistory: TTabSheet;
    tsTable: TTabSheet;
    tsList: TTabSheet;
    procedure btnAddFilterClick(Sender: TObject);
    procedure btnAddFilterSetClick(Sender: TObject);
    procedure btnAddStateClick(Sender: TObject);
    procedure btnChangeFilterClick(Sender: TObject);
    procedure btnClearFilterSetClick(Sender: TObject);
    procedure btnExitClick(Sender: TObject);
    procedure btnFullRangeClick(Sender: TObject);
    procedure btnMassCalcClick(Sender: TObject);
    procedure btnOpenFilterSetClick(Sender: TObject);
    procedure btnRemoveFilterClick(Sender: TObject);
    procedure btnSaveFilterSetClick(Sender: TObject);
    procedure btnWikipediaClick(Sender: TObject);
    procedure cbChartApplyFiltersChange(Sender: TObject);
    procedure cbFilterKindChange(Sender: TObject);
    procedure cbListApplyFilterChange(Sender: TObject);
    procedure cbShowUnknownChange(Sender: TObject);
    procedure cbTableApplyFiltersChange(Sender: TObject);
    procedure cbxChartLabelsChange(Sender: TObject);
    procedure cbxInvertSortOrderChange(Sender: TObject);
    procedure cbxLayoutChange(Sender: TObject);
    procedure cbxSortChange(Sender: TObject);
    procedure cbxXAxisChange(Sender: TObject);
    procedure cbxYAxisChange(Sender: TObject);
    procedure clbRangeClick(Sender: TObject);
    procedure edRangeChange(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure lbListClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnAddClick(Sender: TObject);
    procedure lbListDblClick(Sender: TObject);
    procedure lvFiltersChange(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure lvFiltersClick(Sender: TObject);
    procedure lvFiltersSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure lvListKeyPress(Sender: TObject; var Key: char);
    procedure lvListKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure MenuItem5Click(Sender: TObject);
    procedure mnuAboutClick(Sender: TObject);
    procedure mnuConfigureClick(Sender: TObject);
    procedure mnuDiscovererClick(Sender: TObject);
    procedure mnuFullZoomClick(Sender: TObject);
    procedure mnuHeapStatusClick(Sender: TObject);
    procedure mnuOpenConsoleClick(Sender: TObject);
    procedure mnuShowFilterListClick(Sender: TObject);
    procedure pnElmClick(Sender: TObject);
    procedure pnElmMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure rbSortFirstChange(Sender: TObject);
    procedure rbStateCelciusChange(Sender: TObject);
    procedure rbStateKelvinChange(Sender: TObject);
    procedure sedXEndChange(Sender: TObject);
    procedure sedXStartChange(Sender: TObject);
    procedure sedYEndChange(Sender: TObject);
    procedure sedYStartChange(Sender: TObject);
    procedure tsTableMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Déclarations privées }
    ActiveLegend: TForm;
    FLine: TLineSeries;
    ElecDist: TElecDistDisplay;
    CurrPanel: TPanel;
    procedure SetColorBloc;
    procedure SetLegendBloc;
    procedure SetColorFamily;
    procedure SetLegendFamily;
    procedure SetColorMass;
    procedure SetLegendMass;
    procedure SetColorDisco;
    procedure SetLegendDisco;
    procedure SetColorMelting;
    procedure SetLegendMelting;
    procedure SetColorBoiling;
    procedure SetLegendBoiling;
    procedure SetColorElecAff;
    procedure SetLegendElecAff;
    procedure SetColorCovalentRd;
    procedure SetLegendCovalentRd;
    procedure SetColorVanDerWaals;
    procedure SetLegendVanDerWaals;
    procedure SetColorFIE;
    procedure SetLegendFIE;
    procedure SetColorSIE;
    procedure SetLegendSIE;
    procedure SetColorTIE;
    procedure SetLegendTIE;
    procedure SetColorElectroneg;
    procedure SetLegendElectroneg;
    procedure BringToFront(ASeries: TChartSeries);
    procedure InitChart;
    procedure DrawChartGraph;
    procedure GraphAddXY(X, Y: Double; Index: integer);
    procedure ChangeIconSet;
    procedure ChangeColors;
    procedure ChangePaths;
    procedure ChangeBackup;
    procedure UpdateFilterList;
  public
    { Déclarations publiques }
    procedure UpdateFilterView;
    procedure FillList;
  end;

var
  TableForm: TTableForm;

implementation

uses
  uUtils, frmAdd, frmAbout, frmMassCalculator, frmBlocLegend, frmFamilyLegend,
  frmGradientLegend, TAChartUtils, uStrings, uIconManager, frmOptions, uCommon,
  frmdiscovererlist, TATypes, uDebug;


procedure TTableForm.SetColorBloc;
var
  I: integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
      case ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].Block of
        's': begin
               (tsTable.Controls[I] as TPanel).Color := clSBlocBG;
               (tsTable.Controls[I] as TPanel).Font.Color := clSBlocFG;
             end;
        'd': begin
               (tsTable.Controls[I] as TPanel).Color := clDBlocBG;
               (tsTable.Controls[I] as TPanel).Font.Color := clDBlocFG;
             end;
        'p': begin
               (tsTable.Controls[I] as TPanel).Color := clPBlocBG;
               (tsTable.Controls[I] as TPanel).Font.Color := clPBlocFG;
             end;
        'f': begin
               (tsTable.Controls[I] as TPanel).Color := clFBlocBG;
               (tsTable.Controls[I] as TPanel).Font.Color := clFBlocFG;
             end;
      end;
end;

procedure TTableForm.SetLegendBloc;
begin
  if BlocLegendForm = nil then
    Exit;
  ActiveLegend := BlocLegendForm;
  BlocLegendForm.Parent := gbLegend;
  BlocLegendForm.BorderStyle := bsNone;
  BlocLegendForm.Align := alClient;
  BlocLegendForm.Visible := True;
  BlocLegendForm.Show;
end;

procedure TTableForm.SetColorFamily;
var
  I: integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
      case ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].Family of
        atNonMetal: begin
                      (tsTable.Controls[I] as TPanel).Color := clNonMetalBG;
                      (tsTable.Controls[I] as TPanel).Font.Color := clNonMetalFG;
                    end;
        atNobleGas: begin
                      (tsTable.Controls[I] as TPanel).Color := clNobleGasBG;
                      (tsTable.Controls[I] as TPanel).Font.Color := clNobleGasFG;
                    end;
        atMetalloid: begin
                       (tsTable.Controls[I] as TPanel).Color := clMetalloidBG;
                       (tsTable.Controls[I] as TPanel).Font.Color := clMetalloidFG;
                     end;
        atHalogen: begin
                     (tsTable.Controls[I] as TPanel).Color := clHalogenBG;
                     (tsTable.Controls[I] as TPanel).Font.Color := clHalogenFG;
                   end;
        atAlkalieMetal: begin
                          (tsTable.Controls[I] as TPanel).Color := clAlkalieMetalBG;
                          (tsTable.Controls[I] as TPanel).Font.Color := clAlkalieMetalFG;
                        end;
        atAlkaline: begin
                      (tsTable.Controls[I] as TPanel).Color := clAlkalineBG;
                      (tsTable.Controls[I] as TPanel).Font.Color := clAlkalineFG;
                    end;
        atTransMetal: begin
                        (tsTable.Controls[I] as TPanel).Color := clTransMetalBG;
                        (tsTable.Controls[I] as TPanel).Font.Color := clTransMetalFG;
                      end;
        atRareEarth: begin
                       (tsTable.Controls[I] as TPanel).Color := clRareEarthBG;
                       (tsTable.Controls[I] as TPanel).Font.Color := clRareEarthFG;
                     end;
        atOtherMetal: begin
                        (tsTable.Controls[I] as TPanel).Color := clOtherMetalBG;
                        (tsTable.Controls[I] as TPanel).Font.Color := clOtherMetalFG;
                      end;
      end;
end;

procedure TTableForm.SetLegendFamily;
begin
  if LegendFamilyForm = nil then
    Exit;
  ActiveLegend := LegendFamilyForm;
  LegendFamilyForm.Parent := gbLegend;
  LegendFamilyForm.BorderStyle := bsNone;
  LegendFamilyForm.Align := alClient;
  LegendFamilyForm.Visible := True;
  LegendFamilyForm.Show;
end;

procedure TTableForm.SetColorMass;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].Mass <> 0 then
        (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
          ElementsList.MinMass, ElementsList.MaxMass,
          ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].Mass,
          clGradientMin, clGradientMax)
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendMass;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxMass;
  GradientLegendForm.lbMin.Caption := rsMinMass;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsMassDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorDisco;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].DiscoYear <> 0 then
        (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
          ElementsList.MinDiscoveryDate, ElementsList.MaxDiscoveryDate,
          ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].DiscoYear,
          clGradientMin, clGradientMax)
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendDisco;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxDate;
  GradientLegendForm.lbMin.Caption := rsMinDate;
  GradientLegendForm.lbUnknow.Caption := rsKnownFromAntiq;
  GradientLegendForm.lbInfo.Caption := rsDateDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorMelting;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].MeltingPt <> 0 then
        (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
          ElementsList.MinMeltingPoint, ElementsList.MaxMeltingPoint,
          ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].MeltingPt,
          clGradientMin, clGradientMax)
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendMelting;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxMeltingPt;
  GradientLegendForm.lbMin.Caption := rsMinMeltingPt;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsMeltingPtDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorBoiling;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].BoilingPt <> 0 then
        (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
          ElementsList.MinBoilingPoint, ElementsList.MaxBoilingPoint,
          ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].BoilingPt,
          clGradientMin, clGradientMax)
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendBoiling;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxBoilingPt;
  GradientLegendForm.lbMin.Caption := rsMinBoilingPt;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsBoilingPtDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorElecAff;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
        ElementsList.MinElectronicAffinity, ElementsList.MaxElectronicAffinity,
        ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].ElecAffinity,
        clGradientMin, clGradientMax);
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendElecAff;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxElecAffinity;
  GradientLegendForm.lbMin.Caption := rsMinElecAffinity;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsElecAffinityDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorCovalentRd;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].CovalentRd <> 0 then
        (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
          ElementsList.MinCovalentRadius, ElementsList.MaxCovalentRadius,
          ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].CovalentRd,
          clGradientMin, clGradientMax)
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendCovalentRd;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxCovalentRd;
  GradientLegendForm.lbMin.Caption := rsMinCovalentRd;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsCovalentRdDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorVanDerWaals;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].VanDerWaalsRd <> 0 then
        (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
          ElementsList.MinVanDerWaalsRadius, ElementsList.MaxVanDerWaalsRadius,
          ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].VanDerWaalsRd,
          clGradientMin, clGradientMax)
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendVanDerWaals;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxVanDerWaalsRd;
  GradientLegendForm.lbMin.Caption := rsMinVanDerWaalsRd;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsVanDerWaalsRdDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorFIE;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].IonisationEnergy.First <> 0 then
        (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
          ElementsList.MinFirstIonisationEnergy, ElementsList.MaxFirstIonisationEnergy,
          ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].IonisationEnergy.First,
          clGradientMin, clGradientMax)
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendFIE;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxFIE;
  GradientLegendForm.lbMin.Caption := rsMinFIE;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsFIEDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorSIE;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].IonisationEnergy.Second <> 0 then
        if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].IonisationEnergy.Second <> -1 then
          (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
            ElementsList.MinSecondIonisationEnergy, ElementsList.MaxSecondIonisationEnergy,
            ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].IonisationEnergy.Second,
            clGradientMin, clGradientMax)
        else (tsTable.Controls[I] as TPanel).Color := clGradientNonApp
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendSIE;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := True;
  GradientLegendForm.pnNonAppl.Visible := True;
  GradientLegendForm.lbMax.Caption := rsMaxSIE;
  GradientLegendForm.lbMin.Caption := rsMinSIE;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsSIEDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorTIE;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].IonisationEnergy.Third <> 0 then
        if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].IonisationEnergy.Third <> -1 then
          (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
            ElementsList.MinThirdIonisationEnergy, ElementsList.MaxThirdIonisationEnergy,
            ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].IonisationEnergy.Third,
            clGradientMin, clGradientMax)
        else (tsTable.Controls[I] as TPanel).Color := clGradientNonApp
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendTIE;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := True;
  GradientLegendForm.pnNonAppl.Visible := True;
  GradientLegendForm.lbMax.Caption := rsMaxTIE;
  GradientLegendForm.lbMin.Caption := rsMinTIE;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsTIEDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.SetColorElectroneg;
var
  I: Integer;
begin
  for I := 0 to tsTable.ControlCount - 1 do
    if (tsTable.Controls[I] is TPanel) and
      ((tsTable.Controls[I] as TPanel).Tag <> 0) then
    begin
      if ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].Electroneg <> -1 then
        (tsTable.Controls[I] as TPanel).Color := GetGradientColor(
          ElementsList.MinElectronegativity, ElementsList.MaxElectronegativity,
          ElementsList.Elements[(tsTable.Controls[I] as TPanel).Tag].Electroneg,
          clGradientMin, clGradientMax)
      else (tsTable.Controls[I] as TPanel).Color := clGradientUnknow;
      (tsTable.Controls[I] as TPanel).Font.Color := clGradientText;
    end;
end;

procedure TTableForm.SetLegendElectroneg;
begin
  if GradientLegendForm = nil then
    Exit;
  ActiveLegend := GradientLegendForm;
  GradientLegendForm.lbNonAppl.Visible := False;
  GradientLegendForm.pnNonAppl.Visible := False;
  GradientLegendForm.lbMax.Caption := rsMaxElectroneg;
  GradientLegendForm.lbMin.Caption := rsMinElectroneg;
  GradientLegendForm.lbUnknow.Caption := rsUnknowVal;
  GradientLegendForm.lbInfo.Caption := rsElectronegDetails;
  GradientLegendForm.Parent := gbLegend;
  GradientLegendForm.BorderStyle := bsNone;
  GradientLegendForm.Align := alClient;
  GradientLegendForm.Visible := True;
  GradientLegendForm.Show;
end;

procedure TTableForm.btnExitClick(Sender: TObject);
begin                {Click on Close}
  Application.Terminate;
end;

procedure TTableForm.btnAddFilterClick(Sender: TObject);
var
  Flt: TFilter;
begin
  case cbFilterKind.ItemIndex of
    0: Flt.Kind := fkDate;
    1: Flt.Kind := fkMass;
    2: Flt.Kind := fkElectronicAffinity;
    3: Flt.Kind := fkMeltingPoint;
    4: Flt.Kind := fkBoilingPoint;
    5: Flt.Kind := fkCovalentRadius;
    6: flt.Kind := fkVanDerWaalsRadius;
    7: Flt.Kind := fkFirstIonisationEnergy;
    8: Flt.Kind := fkSecondIonisationEnergy;
    9: Flt.Kind := fkThirdIonisationEnergy;
    10: Flt.Kind := fkElectronegativity;
  end;
  Flt.DisplayUnknow := cbShowUnknown.Checked;
  Flt.Max := sedFilterMax.Value;
  Flt.Min := sedFilterMin.Value;
  ElementsList.AddFilter(Flt);
  UpdateFilterList;
end;

procedure TTableForm.btnAddFilterSetClick(Sender: TObject);
var
  Cnt, I: integer;
  Flt: TFilter;
begin
  dlgOpen.DefaultExt := sFilterExt;
  if dlgOpen.Execute then
  begin
    {$warning We should clear the list here if sender is btnOpenFilterset}
    //if Sender = btnOpenFilterSet then //don't work... why?
    IniPropStorage.IniFileName := dlgSave.FileName;
    IniPropStorage.IniSection := 'FilterSet';
    Cnt := IniPropStorage.ReadInteger('Count', 0);
    if Cnt = 0 then
      Exit; //probably invalid file triggering an error
    for I := 0 to Cnt - 1 do
    begin
      case IniPropStorage.ReadInteger('Kind' + IntToStr(I), -1) of
        0: Flt.Kind := fkDate;
        1: Flt.Kind := fkMass;
        2: Flt.Kind := fkElectronicAffinity;
        3: Flt.Kind := fkMeltingPoint;
        4: Flt.Kind := fkBoilingPoint;
        5: Flt.Kind := fkCovalentRadius;
        6: Flt.Kind := fkVanDerWaalsRadius;
        7: Flt.Kind := fkFirstIonisationEnergy;
        8: Flt.Kind := fkSecondIonisationEnergy;
        9: Flt.Kind := fkThirdIonisationEnergy;
        10: Flt.Kind := fkElectronegativity;
        else
          ShowMessage('Error at index ' + IntToStr(I)); //would be better to trigger an exception
      end;
      Flt.Min := StrToFloat(IniPropStorage.ReadString('Min' + IntToStr(I), '0'));
      Flt.Max := StrToFloat(IniPropStorage.ReadString('Max' + IntToStr(I), '0'));
      Flt.DisplayUnknow := IniPropStorage.ReadBoolean('DispUnknow' +
        IntToStr(I), True);
      ElementsList.AddFilter(Flt);
    end;
    UpdateFilterList;
  end;
end;

procedure TTableForm.btnAddStateClick(Sender: TObject);
var
  FltMelt: TFilter;
  FltBoil: TFilter;
  Temp: Double;
begin
  FltMelt.Kind := fkMeltingPoint;
  FltBoil.Kind := fkBoilingPoint;
  FltMelt.Max := ElementsList.MaxMeltingPoint;
  FltMelt.Min := ElementsList.MinMeltingPoint;
  FltBoil.Max := ElementsList.MaxBoilingPoint;
  FltBoil.Min := ElementsList.MinBoilingPoint;
  FltMelt.DisplayUnknow := cbStateShowUnknown.Checked;
  FltBoil.DisplayUnknow := cbStateShowUnknown.Checked;
  if rbStateCelcius.Checked then
    Temp := sedStateTemp.Value - 273.15
  else Temp := sedStateTemp.Value;
  case cbxState.ItemIndex of
    0: begin //Gas
         FltBoil.Min := Temp;
         ElementsList.AddFilter(FltBoil);
       end;
    1: begin //Liquid
         FltMelt.Min := Temp;
         FltBoil.Max := Temp;
         ElementsList.AddFilter(FltMelt);
         ElementsList.AddFilter(FltBoil);
       end;
    2: begin //Solid
         FltMelt.Max := Temp;
         ElementsList.AddFilter(FltMelt);
       end;
    3: begin //Not gas
         FltBoil.Max := Temp;
         ElementsList.AddFilter(FltBoil);
       end;
    4: begin //Not liquid
         FltMelt.Max := Temp;
         FltBoil.Min := Temp;
         ElementsList.AddFilter(FltMelt);
         ElementsList.AddFilter(FltBoil);
       end;
    5: begin //Not solid
         FltMelt.Max := Temp;
         ElementsList.AddFilter(FltMelt);
       end;
    else
      Exit; //strange error triggering an exception
  end;
  UpdateFilterList;
end;

procedure TTableForm.btnChangeFilterClick(Sender: TObject);
var
  Flt: TFilter;
  I: Integer;
begin
  case cbFilterKind.ItemIndex of
    0: Flt.Kind := fkDate;
    1: Flt.Kind := fkMass;
    2: Flt.Kind := fkElectronicAffinity;
    3: Flt.Kind := fkMeltingPoint;
    4: Flt.Kind := fkBoilingPoint;
    5: Flt.Kind := fkCovalentRadius;
    6: flt.Kind := fkVanDerWaalsRadius;
    7: Flt.Kind := fkFirstIonisationEnergy;
    8: Flt.Kind := fkSecondIonisationEnergy;
    9: Flt.Kind := fkThirdIonisationEnergy;
    10: Flt.Kind := fkElectronegativity;
  end;
  Flt.DisplayUnknow := cbShowUnknown.Checked;
  Flt.Max := sedFilterMax.Value;
  Flt.Min := sedFilterMin.Value;
  for I := 0 to lvFilters.Items.Count - 1 do
    if lvFilters.Items[I].Selected then
      Break;
  ElementsList.Filters[I] := Flt;
  UpdateFilterList;
end;

procedure TTableForm.btnClearFilterSetClick(Sender: TObject);
var
  I: integer;
begin
  for I := 0 to ElementsList.FiltersCount - 1 do
    ElementsList.RemoveFilter(I);
  ElementsList.ClearFilters;
  lvFilters.Items.Clear;
end;

procedure TTableForm.btnFullRangeClick(Sender: TObject);
var
  I: byte;
begin
  edRange.Text := '1-' + IntToStr(ElemNumber);
  for I := 0 to clbRange.Count - 1 do
    clbRange.Checked[I] := True;
  edRangeChange(nil);
  DrawChartGraph;
end;

procedure TTableForm.btnMassCalcClick(Sender: TObject);
begin
  if MassCalcForm <> nil then
  begin
    MassCalcForm.Visible := not MassCalcForm.Visible;
    MassCalcForm.BringToFront
  end else
  begin
    MassCalcForm := TMassCalcForm.Create(Application);
    MassCalcForm.Show;
  end {if};
end;

procedure TTableForm.btnOpenFilterSetClick(Sender: TObject);
begin
  btnClearFilterSetClick(Sender);
  btnAddFilterSetClick(Sender);
end;

procedure TTableForm.btnRemoveFilterClick(Sender: TObject);
var
  I: integer;
begin
  for I := 0 to lvFilters.Items.Count - 1 do
    if lvFilters.Items[I].Selected then
      ElementsList.RemoveFilter(I);
  UpdateFilterList;
end;

procedure TTableForm.btnSaveFilterSetClick(Sender: TObject);
var
  I, K: integer;
begin
  dlgSave.DefaultExt := sFilterExt;
  if dlgSave.Execute then
  begin
    IniPropStorage.IniFileName := dlgSave.FileName;
    IniPropStorage.IniSection := 'FilterSet';
    IniPropStorage.WriteInteger('Count', ElementsList.FiltersCount);
    for I := 0 to ElementsList.FiltersCount - 1 do
    begin
      case ElementsList.Filters[I].Kind of
        fkDate: K := 0;
        fkMass: K := 1;
        fkElectronicAffinity: K := 2;
        fkMeltingPoint: K := 3;
        fkBoilingPoint: K := 4;
        fkCovalentRadius: K := 5;
        fkVanDerWaalsRadius: K := 6;
        fkFirstIonisationEnergy: K := 7;
        fkSecondIonisationEnergy: K := 8;
        fkThirdIonisationEnergy: K := 9;
        fkElectronegativity: K := 10;
      end;
      IniPropStorage.WriteInteger('Kind' + IntToStr(I), K);
      IniPropStorage.WriteString('Min' + IntToStr(I),
        FloatToStr(ElementsList.Filters[I].Min));
      IniPropStorage.WriteString('Max' + IntToStr(I),
        FloatToStr(ElementsList.Filters[I].Max));
      IniPropStorage.WriteBoolean('DispUnknow' + IntToStr(I),
        ElementsList.Filters[I].DisplayUnknow);
    end;
  end;
end;

procedure TTableForm.btnWikipediaClick(Sender: TObject);
begin
  if not OpenURL(ElementsList.Elements[GetListIndexFromView(lvList,
    lvList.Selected.Index)].WikiLink) then
      MessageDlg(rsError, erOpenUrl, mtError, [mbOK], '');
end;

procedure TTableForm.cbChartApplyFiltersChange(Sender: TObject);
begin
  ElementsList.FilterGraph := cbChartApplyFilters.Checked;
  if not cbChartApplyFilters.Checked then
  begin
    FreeAndNil(FLine);
    DrawChartGraph;
  end;
  UpdateFilterView;
end;

procedure TTableForm.cbFilterKindChange(Sender: TObject);
begin
  case cbFilterKind.ItemIndex of
    0: begin
         sedFilterMin.MinValue := ElementsList.MinDiscoveryDate;
         sedFilterMin.MaxValue := ElementsList.MaxDiscoveryDate;
         sedFilterMax.MinValue := ElementsList.MinDiscoveryDate;
         sedFilterMax.MaxValue := ElementsList.MaxDiscoveryDate;
         sedFilterMin.Value := ElementsList.MinDiscoveryDate;
         sedFilterMax.Value := ElementsList.MaxDiscoveryDate;
       end;
    1: begin
         sedFilterMin.MinValue := ElementsList.MinMass;
         sedFilterMin.MaxValue := ElementsList.MaxMass;
         sedFilterMax.MinValue := ElementsList.MinMass;
         sedFilterMax.MaxValue := ElementsList.MaxMass;
         sedFilterMin.Value := ElementsList.MinMass;
         sedFilterMax.Value := ElementsList.MaxMass;
       end;
    2: begin
         sedFilterMin.MinValue := ElementsList.MinElectronicAffinity;
         sedFilterMin.MaxValue := ElementsList.MaxElectronicAffinity;
         sedFilterMax.MinValue := ElementsList.MinElectronicAffinity;
         sedFilterMax.MaxValue := ElementsList.MaxElectronicAffinity;
         sedFilterMin.Value := ElementsList.MinElectronicAffinity;
         sedFilterMax.Value := ElementsList.MaxElectronicAffinity;
       end;
    3: begin
         sedFilterMin.MinValue := ElementsList.MinMeltingPoint;
         sedFilterMin.MaxValue := ElementsList.MaxMeltingPoint;
         sedFilterMax.MinValue := ElementsList.MinMeltingPoint;
         sedFilterMax.MaxValue := ElementsList.MaxMeltingPoint;
         sedFilterMin.Value := ElementsList.MinMeltingPoint;
         sedFilterMax.Value := ElementsList.MaxMeltingPoint;
       end;
    4: begin
         sedFilterMin.MinValue := ElementsList.MinBoilingPoint;
         sedFilterMin.MaxValue := ElementsList.MaxBoilingPoint;
         sedFilterMax.MinValue := ElementsList.MinBoilingPoint;
         sedFilterMax.MaxValue := ElementsList.MaxBoilingPoint;
         sedFilterMin.Value := ElementsList.MinBoilingPoint;
         sedFilterMax.Value := ElementsList.MaxBoilingPoint;
       end;
    5: begin
         sedFilterMin.MinValue := ElementsList.MinCovalentRadius;
         sedFilterMin.MaxValue := ElementsList.MaxCovalentRadius;
         sedFilterMax.MinValue := ElementsList.MinCovalentRadius;
         sedFilterMax.MaxValue := ElementsList.MaxCovalentRadius;
         sedFilterMin.Value := ElementsList.MinCovalentRadius;
         sedFilterMax.Value := ElementsList.MaxCovalentRadius;
       end;
    6: begin
         sedFilterMin.MinValue := ElementsList.MinVanDerWaalsRadius;
         sedFilterMin.MaxValue := ElementsList.MaxVanDerWaalsRadius;
         sedFilterMax.MinValue := ElementsList.MinVanDerWaalsRadius;
         sedFilterMax.MaxValue := ElementsList.MaxVanDerWaalsRadius;
         sedFilterMin.Value := ElementsList.MinVanDerWaalsRadius;
         sedFilterMax.Value := ElementsList.MaxVanDerWaalsRadius;
       end;
    7: begin
         sedFilterMin.MinValue := ElementsList.MinFirstIonisationEnergy;
         sedFilterMin.MaxValue := ElementsList.MaxFirstIonisationEnergy;
         sedFilterMax.MinValue := ElementsList.MinFirstIonisationEnergy;
         sedFilterMax.MaxValue := ElementsList.MaxFirstIonisationEnergy;
         sedFilterMin.Value := ElementsList.MinFirstIonisationEnergy;
         sedFilterMax.Value := ElementsList.MaxFirstIonisationEnergy;
       end;
    8: begin
         sedFilterMin.MinValue := ElementsList.MinSecondIonisationEnergy;
         sedFilterMin.MaxValue := ElementsList.MaxSecondIonisationEnergy;
         sedFilterMax.MinValue := ElementsList.MinSecondIonisationEnergy;
         sedFilterMax.MaxValue := ElementsList.MaxSecondIonisationEnergy;
         sedFilterMin.Value := ElementsList.MinSecondIonisationEnergy;
         sedFilterMax.Value := ElementsList.MaxSecondIonisationEnergy;
       end;
    9: begin
         sedFilterMin.MinValue := ElementsList.MinThirdIonisationEnergy;
         sedFilterMin.MaxValue := ElementsList.MaxThirdIonisationEnergy;
         sedFilterMax.MinValue := ElementsList.MinThirdIonisationEnergy;
         sedFilterMax.MaxValue := ElementsList.MaxThirdIonisationEnergy;
         sedFilterMin.Value := ElementsList.MinThirdIonisationEnergy;
         sedFilterMax.Value := ElementsList.MaxThirdIonisationEnergy;
       end;
    10: begin
          sedFilterMin.MinValue := ElementsList.MinElectronegativity;
          sedFilterMin.MaxValue := ElementsList.MaxElectronegativity;
          sedFilterMax.MinValue := ElementsList.MinElectronegativity;
          sedFilterMax.MaxValue := ElementsList.MaxElectronegativity;
          sedFilterMin.Value := ElementsList.MinElectronegativity;
          sedFilterMax.Value := ElementsList.MaxElectronegativity;
        end;
  end;
end;

procedure TTableForm.cbListApplyFilterChange(Sender: TObject);
begin
  ElementsList.FilterList := cbListApplyFilter.Checked;
  if not cbListApplyFilter.Checked then
    FillList;
  UpdateFilterView;
end;

procedure TTableForm.cbShowUnknownChange(Sender: TObject);
begin

end;

procedure TTableForm.cbTableApplyFiltersChange(Sender: TObject);
begin
  ElementsList.FilterTable := cbTableApplyFilters.Checked;
  UpdateFilterView;
end;

procedure TTableForm.cbxChartLabelsChange(Sender: TObject);
begin
  FreeAndNil(FLine);
  DrawChartGraph;
end;

procedure TTableForm.cbxInvertSortOrderChange(Sender: TObject);
begin
  ElementsList.SortUpToDown := cbxInvertSortOrder.Checked;
  FillList;
end;

procedure TTableForm.cbxLayoutChange(Sender: TObject);
begin
  case cbxLayout.ItemIndex of
    0: SetColorBloc;
    1: SetColorFamily;
    2: SetColorMass;
    3: SetColorDisco;
    4: SetColorMelting;
    5: SetColorBoiling;
    6: SetColorElecAff;
    7: SetColorCovalentRd;
    8: SetColorVanDerWaals;
    9: SetColorFIE;
    10: SetColorSIE;
    11: SetColorTIE;
    12: SetColorElectroneg;
  end {case};
  if ActiveLegend <> nil then
  begin
    ActiveLegend.Visible := False;
    ActiveLegend.Parent := nil;
  end;
  case cbxLayout.ItemIndex of
    0: SetLegendBloc;
    1: SetLegendFamily;
    2: SetLegendMass;
    3: SetLegendDisco;
    4: SetLegendMelting;
    5: SetLegendBoiling;
    6: SetLegendElecAff;
    7: SetLegendCovalentRd;
    8: SetLegendVanDerWaals;
    9: SetLegendFIE;
    10: SetLegendSIE;
    11: SetLegendTIE;
    12: SetLegendElectroneg;
  end {case};
end;

procedure TTableForm.cbxSortChange(Sender: TObject);
begin
  PrintLnDbg('cbxSort changed to item index #' + IntToStr(cbxSort.ItemIndex), vlHigh);
  case cbxSort.ItemIndex of
    1: ElementsList.SortType := estName;
    2: ElementsList.SortType := estSymbol;
    3: ElementsList.SortType := estDiscoveryDate;
    4: ElementsList.SortType := estMass;
    5: ElementsList.SortType := estMeltingPoint;
    6: ElementsList.SortType := estBoilingPoint;
    7: ElementsList.SortType := estElectronicAffinity;
    8: ElementsList.SortType := estCovalentRadius;
    9: ElementsList.SortType := estVanDerWaalsRadius;
    10: ElementsList.SortType := estFirstIonisationEnergy;
    11: ElementsList.SortType := estSecondIonisationEnergy;
    12: ElementsList.SortType := estThirdIonisationEnergy;
    13: ElementsList.SortType := estElectronegativity;
    else ElementsList.SortType := estNumber;
  end;
  FillList;
end;

procedure TTableForm.cbxXAxisChange(Sender: TObject);
begin
  FreeAndNil(FLine);
  case cbxXAxis.ItemIndex of
    0: begin
      lbMinX.Caption := '1';
      lbMaxX.Caption := IntToStr(ElemNumber);
      lbAverageX.Caption := FloatToStr((ElemNumber + 1) / 2);
      lbUnitX.Caption := rsNone;
    end;
    1: begin
      lbMinX.Caption := FloatToStr(ElementsList.MinMass);
      lbMaxX.Caption := FloatToStr(ElementsList.MaxMass);
      lbAverageX.Caption := FloatToStr((ElementsList.MinMass +
        ElementsList.MaxMass) / 2);
      lbUnitX.Caption := rsUgstrom;
    end;
    2: begin
      lbMinX.Caption := FloatToStr(ElementsList.MinMeltingPoint);
      lbMaxX.Caption := FloatToStr(ElementsList.MaxMeltingPoint);
      lbAverageX.Caption := FloatToStr((ElementsList.MinMeltingPoint +
        ElementsList.MaxMeltingPoint) / 2);
      lbUnitX.Caption := rsKelvin;
    end;
    3: begin
      lbMinX.Caption := FloatToStr(ElementsList.MinBoilingPoint);
      lbMaxX.Caption := FloatToStr(ElementsList.MaxBoilingPoint);
      lbAverageX.Caption := FloatToStr((ElementsList.MinBoilingPoint +
        ElementsList.MaxBoilingPoint) / 2);
      lbUnitX.Caption := rsKelvin;
    end;
    4: begin
      lbMinX.Caption := FloatToStr(ElementsList.MinElectronicAffinity);
      lbMaxX.Caption := FloatToStr(ElementsList.MaxElectronicAffinity);
      lbAverageX.Caption := FloatToStr((ElementsList.MinElectronicAffinity +
        ElementsList.MaxElectronicAffinity) / 2);
      lbUnitX.Caption := rsElectroVolt;
    end;
    5: begin
      lbMinX.Caption := IntToStr(ElementsList.MinCovalentRadius);
      lbMaxX.Caption := IntToStr(ElementsList.MaxCovalentRadius);
      lbAverageX.Caption := FloatToStr((ElementsList.MinCovalentRadius +
        ElementsList.MaxCovalentRadius) / 2);
      lbUnitX.Caption := rsPicoMeter;
    end;
    6: begin
      lbMinX.Caption := IntToStr(ElementsList.MinVanDerWaalsRadius);
      lbMaxX.Caption := IntToStr(ElementsList.MaxVanDerWaalsRadius);
      lbAverageX.Caption := FloatToStr((ElementsList.MinVanDerWaalsRadius +
        ElementsList.MaxVanDerWaalsRadius) / 2);
      lbUnitX.Caption := rsPicoMeter;
    end;
    7: begin
      lbMinX.Caption := FloatToStr(ElementsList.MinFirstIonisationEnergy);
      lbMaxX.Caption := FloatToStr(ElementsList.MaxFirstIonisationEnergy);
      lbAverageX.Caption := FloatToStr((ElementsList.MinFirstIonisationEnergy +
        ElementsList.MaxFirstIonisationEnergy) / 2);
      lbUnitX.Caption := rsKiloJouleByVolt;
    end;
  end;
  DrawChartGraph;
end;

procedure TTableForm.cbxYAxisChange(Sender: TObject);
begin
  FreeAndNil(FLine);
  case cbxYAxis.ItemIndex of
    0: begin
      lbMinY.Caption := '1';
      lbMaxY.Caption := IntToStr(ElemNumber);
      lbAverageY.Caption := FloatToStr((ElemNumber + 1) / 2);
      lbUnitY.Caption := rsNone;
    end;
    1: begin
      lbMinY.Caption := FloatToStr(ElementsList.MinMass);
      lbMaxY.Caption := FloatToStr(ElementsList.MaxMass);
      lbAverageY.Caption := FloatToStr((ElementsList.MinMass +
        ElementsList.MaxMass) / 2);
      lbUnitY.Caption := rsUgstrom;
    end;
    2: begin
      lbMinY.Caption := FloatToStr(ElementsList.MinMeltingPoint);
      lbMaxY.Caption := FloatToStr(ElementsList.MaxMeltingPoint);
      lbAverageY.Caption := FloatToStr((ElementsList.MinMeltingPoint +
        ElementsList.MaxMeltingPoint) / 2);
      lbUnitY.Caption := rsKelvin;
    end;
    3: begin
      lbMinY.Caption := FloatToStr(ElementsList.MinBoilingPoint);
      lbMaxY.Caption := FloatToStr(ElementsList.MaxBoilingPoint);
      lbAverageY.Caption := FloatToStr((ElementsList.MinBoilingPoint +
        ElementsList.MaxBoilingPoint) / 2);
      lbUnitY.Caption := rsKelvin;
    end;
    4: begin
      lbMinY.Caption := FloatToStr(ElementsList.MinElectronicAffinity);
      lbMaxY.Caption := FloatToStr(ElementsList.MaxElectronicAffinity);
      lbAverageY.Caption := FloatToStr((ElementsList.MinElectronicAffinity +
        ElementsList.MaxElectronicAffinity) / 2);
      lbUnitY.Caption := rsElectroVolt;
    end;
    5: begin
      lbMinY.Caption := IntToStr(ElementsList.MinCovalentRadius);
      lbMaxY.Caption := IntToStr(ElementsList.MaxCovalentRadius);
      lbAverageY.Caption := FloatToStr((ElementsList.MinCovalentRadius +
        ElementsList.MaxCovalentRadius) / 2);
      lbUnitY.Caption := rsPicoMeter;
    end;
    6: begin
      lbMinY.Caption := IntToStr(ElementsList.MinVanDerWaalsRadius);
      lbMaxY.Caption := IntToStr(ElementsList.MaxVanDerWaalsRadius);
      lbAverageY.Caption := FloatToStr((ElementsList.MinVanDerWaalsRadius +
        ElementsList.MaxVanDerWaalsRadius) / 2);
      lbUnitY.Caption := rsPicoMeter;
    end;
    7: begin
      lbMinY.Caption := FloatToStr(ElementsList.MinFirstIonisationEnergy);
      lbMaxY.Caption := FloatToStr(ElementsList.MaxFirstIonisationEnergy);
      lbAverageY.Caption := FloatToStr((ElementsList.MinFirstIonisationEnergy +
        ElementsList.MaxFirstIonisationEnergy) / 2);
      lbUnitY.Caption := rsKiloJouleByVolt;
    end;
  end;
  DrawChartGraph;
end;

procedure TTableForm.clbRangeClick(Sender: TObject);
begin
  FreeAndNil(FLine);
  DrawChartGraph;
end;

procedure TTableForm.edRangeChange(Sender: TObject);
begin
  FreeAndNil(FLine);
  if not SetRange(edRange.Text) then
    FullRange;
  DrawChartGraph;
end;

procedure TTableForm.FormShow(Sender: TObject);
begin
  pnHighlight.Visible := False;
  lbContextInfo.Visible := False;
  //initializing display
  PageControl1.ActivePage := tsTable;
  BlocLegendForm := TBlocLegendForm.Create(Application);
  LegendFamilyForm := TLegendFamilyForm.Create(Application);
  GradientLegendForm := TGradientLegendForm.Create(Application);
  //set min max values for SpinEdit components
  UpdateFilterView;
  //init graph system
  cbxLayoutChange(nil);
  cbxXAxisChange(nil);
  cbxYAxisChange(nil);
  btnFullRangeClick(nil);
  InitBtnGlyphs(Self);
end;

procedure TTableForm.lbListClick(Sender: TObject);
var
  I, J, ElemIndex, Err, P: integer;
begin
  //initialization
  //Writeln('Selcount = ', lvList.SelCount);
  if lvList.SelCount < 1 then
  begin
    PrintLnDbg('*** frmTable.TTableFor.lbListClick: ERROR: no item selected ' +
      '(this should not happen)!', vlLow);
    btnAdd.Enabled := False;
    btnWikipedia.Enabled := False;
    lvList.OnDblClick := nil;
    Exit;
  end else
  begin
    btnAdd.Enabled := True;
    pnSelected.Visible := True;
    btnWikipedia.Enabled := True;
    lvList.OnDblClick := @lbListDblClick;
  end;
  //getting the good atom index
  for J := lvList.Items.Count - 1 downto 0 do
    if lvList.Items[J].Selected then
    begin
      for I := 1 to ElemNumber do
        if lvList.Items[J].Caption = IntToStr(ElementsList.Elements[I].Number) then
        begin
          PrintLnDbg('J = ' + IntToStr(J) + ' / I = ' + IntToStr(I) + ' / ' +
            ElementsList.Elements[I].ShortName, vlFull);
          ElemIndex := ElementsList.Elements[I].Number;
          Break;
        end; {if}
      Break;
    end; {if}
  PrintLnDbg('Showing information on element at index #' + IntToStr(ElemIndex),
    vlLow);
  {showing informations}
  case ElementsList.Elements[ElemIndex].Block of
    's': begin
           pnSelected.Color := clSBlocBG;
           pnSelected.Font.Color := clSBlocFG;
           lbPName1.Font.Color := clSBlocFG; //on windows colors are not properly herited at runtime
           lbPAtNum1.Font.Color := clSBlocFG;
           lbPMass1.Font.Color := clSBlocFG;
         end;
    'p': begin
           pnSelected.Color := clPBlocBG;
           pnSelected.Font.Color := clPBlocFG;
           lbPName1.Font.Color := clPBlocFG; //on windows colors are not properly herited at runtime
           lbPAtNum1.Font.Color := clPBlocFG;
           lbPMass1.Font.Color := clPBlocFG;
         end;
    'f': begin
           pnSelected.Color := clFBlocBG;
           pnSelected.Font.Color := clFBlocFG;
           lbPName1.Font.Color := clFBlocFG; //on windows colors are not properly herited at runtime
           lbPAtNum1.Font.Color := clFBlocFG;
           lbPMass1.Font.Color := clFBlocFG;
         end;
    'd': begin
           pnSelected.Color := clDBlocBG;
           pnSelected.Font.Color := clDBlocFG;
           lbPName1.Font.Color := clDBlocFG; //on windows colors are not properly herited at runtime
           lbPAtNum1.Font.Color := clDBlocFG;
           lbPMass1.Font.Color := clDBlocFG;
         end;
  end;
  case ElemIndex of
    57..71 : lbName.Caption := ElementsList.Elements[ElemIndex].Name + rsLanthanids;
    89..103: lbName.Caption := ElementsList.Elements[ElemIndex].Name + rsActinids;
    else lbName.Caption := ElementsList.Elements[ElemIndex].Name;
  end {case};
  lbCASNumber.Caption := ElementsList.Elements[ElemIndex].CAS;
  if ElementsList.Elements[ElemIndex].Radioactivity <> '' then
    case ElementsList.Elements[ElemIndex].Radioactivity[Length(
      ElementsList.Elements[ElemIndex].Radioactivity)] of
        'y': lbRadioHalfLife.Caption := Copy(ElementsList.Elements[ElemIndex].Radioactivity,
               1, Length(ElementsList.Elements[ElemIndex].Radioactivity) - 1) +
               rsYears;
        'd': lbRadioHalfLife.Caption := Copy(ElementsList.Elements[ElemIndex].Radioactivity,
               1, Length(ElementsList.Elements[ElemIndex].Radioactivity) - 1) +
               rsDays;
        'h': lbRadioHalfLife.Caption := Copy(ElementsList.Elements[ElemIndex].Radioactivity,
               1, Length(ElementsList.Elements[ElemIndex].Radioactivity) - 1) +
               rsHours;
        'm': lbRadioHalfLife.Caption := Copy(ElementsList.Elements[ElemIndex].Radioactivity,
               1, Length(ElementsList.Elements[ElemIndex].Radioactivity) - 1) +
               rsMins;
        's': lbRadioHalfLife.Caption := Copy(ElementsList.Elements[ElemIndex].Radioactivity,
               1, Length(ElementsList.Elements[ElemIndex].Radioactivity) - 1) +
               rsSecs;
      end {case}
  else lbRadioHalfLife.Caption := rsNoRadioactivity;
  if ElementsList.Elements[ElemIndex].Mass <> 0 then
    lbMass.Caption := FloatToStr(ElementsList.Elements[ElemIndex].Mass) + ' u'
  else lbMass.Caption := rsUnknown;
  lbAtNumber.Caption := IntToStr(ElemIndex) + rsBlock +
    ElementsList.Elements[ElemIndex].Block;
  if ElementsList.Elements[ElemIndex].MeltingPt <> 0 then
    lbMeltingPt.Caption := FloatToStr(ElementsList.Elements[ElemIndex].MeltingPt) +
      ' K, ' + FloatToStr(ElementsList.Elements[ElemIndex].MeltingPt - 273.15)
      + ' °C'
  else lbMeltingPt.Caption := rsUnknown;
  if ElementsList.Elements[ElemIndex].BoilingPt <> 0 then
    lbBoilingPt.Caption := FloatToStr(ElementsList.Elements[ElemIndex].BoilingPt) +
      ' K, ' + FloatToStr(ElementsList.Elements[ElemIndex].BoilingPt - 273.15)
      + ' °C'
  else lbBoilingPt.Caption := rsUnknown;
  if ElementsList.Elements[ElemIndex].ElecAffinity <> -1 then
    lbElecAff.Caption := FloatToStr(ElementsList.Elements[ElemIndex].ElecAffinity)
    + ' eV'
  else lbElecAff.Caption := rsUnknown;
  if ElementsList.Elements[ElemIndex].ElecConf <> '' then
    lbElecConf.Caption := ElementsList.Elements[ElemIndex].ElecConf
  else lbElecConf.Caption := rsUnknown;
  if ElementsList.Elements[ElemIndex].CovalentRd <> 0 then
    lbCovalentRd.Caption := IntToStr(ElementsList.Elements[ElemIndex].CovalentRd)
    + ' pm'
  else lbCovalentRd.Caption := rsUnknown;
  if ElementsList.Elements[ElemIndex].VanDerWaalsRd <> 0 then
    lbVanDerWalsRd.Caption := IntToStr(ElementsList.Elements[ElemIndex].VanDerWaalsRd)
    + ' pm'
  else lbVanDerWalsRd.Caption := rsUnknown;
  if ElementsList.Elements[ElemIndex].IonisationEnergy.First <> 0 then
    lbFirsIonisationEnergy.Caption := FloatToStr(ElementsList.Elements[ElemIndex].IonisationEnergy.First)
      + ' kJ/mol' + rsFirst
  else lbFirsIonisationEnergy.Caption := rsUnknown + rsFirst;
  if ElementsList.Elements[ElemIndex].IonisationEnergy.Second <> 0 then
    if ElementsList.Elements[ElemIndex].IonisationEnergy.Second <> -1 then
      lbSecondIonisationEnergy.Caption := FloatToStr(ElementsList.Elements[ElemIndex].IonisationEnergy.Second)
        + ' kJ/mol' + rsSecond
    else lbSecondIonisationEnergy.Caption := rsImpossible + rsSecond
  else lbSecondIonisationEnergy.Caption := rsUnknown + rsSecond;
  if ElementsList.Elements[ElemIndex].IonisationEnergy.Third <> 0 then
    if ElementsList.Elements[ElemIndex].IonisationEnergy.Third <> -1 then
      lbThirdIonisationEnergy.Caption := FloatToStr(ElementsList.Elements[ElemIndex].IonisationEnergy.Third)
        + ' kJ/mol' + rsThird
    else lbThirdIonisationEnergy.Caption := rsImpossible + rsThird
  else lbThirdIonisationEnergy.Caption := rsUnknown + rsThird;
  if ElementsList.Elements[ElemIndex].Electroneg <> -1 then
    lbElectroneg.Caption := FloatToStr(ElementsList.Elements[ElemIndex].Electroneg) +
      ' ' + rsPaulingScale
  else lbElectroneg.Caption := rsUnknown;
  if ElementsList.Elements[ElemIndex].DiscoYear <> 0 then
    if ElementsList.Elements[ElemIndex].Discoverer <> '' then
      lbDiscovery.Caption := Format(rsDiscoInBy,
        [ElementsList.Elements[ElemIndex].DiscoYear,
        ElementsList.Elements[ElemIndex].Discoverer])
    else
      lbDiscovery.Caption := Format(rsDiscoInByUnknow,
        [ElementsList.Elements[ElemIndex].DiscoYear])
  else
    lbDiscovery.Caption := rsDiscoAntiq;
  lbEtimology.Caption := ElementsList.Elements[ElemIndex].Etymology;
  if ElementsList.Elements[ElemIndex].Radioactivity <> '' then
    lbNatRadio.Caption := rsYes
  else lbNatRadio.Caption := rsNo;
  case ElementsList.Elements[ElemIndex].Family of
    atOtherMetal: lbFamily.Caption := rsOtherMetal;
    atRareEarth: lbFamily.Caption := rsRareEarth;
    atTransMetal: lbFamily.Caption := rsTransMetal;
    atAlkaline: lbFamily.Caption := rsAlcaline;
    atAlkalieMetal: lbFamily.Caption := rsAlkalieMetal;
    atHalogen: lbFamily.Caption := rsHalogen;
    atMetalloid: lbFamily.Caption := rsMetalloid;
    atNobleGas: lbFamily.Caption := rsNobleGas;
    atNonMetal: lbFamily.Caption := rsNonMetal;
    else lbFamily.Caption := rsUnknown;
  end {case};
  ElecDist.ElecronicConf := lbElecConf.Caption;
  lbExpandedElecConf.Caption := ElecDist.ExpandedElecConf;
  if lbExpandedElecConf.Caption = '' then
    lbExpandedElecConf.Caption := rsUnknoxElecDist;
  lbPName1.Caption := ElementsList.Elements[ElemIndex].Name;
  lbPAtNum1.Caption := IntToStr(ElementsList.Elements[ElemIndex].Number);
  pnSelected.Caption := ElementsList.Elements[ElemIndex].ShortName;
  lbPMass1.Caption := FloatToStr(ElementsList.Elements[ElemIndex].Mass) + ' u';
  lbPAtNum1.Left := 47 - lbPAtNum1.Width;
  lbPMass1.Left := 109 - lbPMass1.Width;
  try
    lbNopic.Visible := False;
    imgAtom.Visible := True;
    imgAtom.Picture.LoadFromFile(GetPicRessource(ElementsList.Elements[ElemIndex].ShortName));
  except
    imgAtom.Picture.Clear;
    imgAtom.Visible := False;
    lbNopic.Visible := True;
  end;;
end;

procedure TTableForm.FormCreate(Sender: TObject);
var
  I, J: Byte;
begin
  ActiveLegend := nil;
  btnChangeFilter.Enabled := False;
  btnRemoveFilter.Enabled := False;
  btnClearFilterSet.Enabled := False;
  pnSelected.Visible := False;
  pnSelected.ParentColor := False;
  pnSelected.FullRepaint := True;
  pnHighlight.FullRepaint := True;
  pnHighlight.ParentColor := False;
  PrintLnDbg('Filling list...', vlLow);
  FillList;
  {creating list}
  PrintLnDbg('Initializing table...', vlLow);
  for I := 1 to ElemNumber do
    for J := 0 to tsTable.ControlCount - 1 do
      if (tsTable.Controls[J] is TPanel) then
        if (tsTable.Controls[J] as TPanel).Caption = ElementsList.Elements[I].ShortName then
          (tsTable.Controls[J] as TPanel).Tag := I;
  //load icons
  PrintLnDbg('-- Loading icon set...', vlLow);
  Inc(VerboseLevel);
  LoadIconSet(sIconsBase, 'oxygen', is16x16);
  MainMenu.Images := ilDefault;
  PageControl2.TabIndex := 0;
  PageControl1.TabIndex := 0;
  ElecDist := TElecDistDisplay.Create(tsElecConf);
  ElecDist.ElecronicConf := '';
  cbFilterKindChange(nil);
end;

procedure TTableForm.FillList;
var
  I: integer;
  LI: TListItem;
begin
  lvList.Clear;
  case cbxSort.ItemIndex of
    0, 1, 2: lvList.Columns[2].Caption := rsName;
    3: lvList.Columns[2].Caption := rsDiscoveryDate;
    4: lvList.Columns[2].Caption := rsMass;
    5: lvList.Columns[2].Caption := rsMeltingPoint;
    6: lvList.Columns[2].Caption := rsBoilingPoint;
    7: lvList.Columns[2].Caption := rsElectronicAffinity;
    8: lvList.Columns[2].Caption := rsCovalentRadius;
    9: lvList.Columns[2].Caption := rsVanDerWaalsRadius;
    10: lvList.Columns[2].Caption := rsFirstIonisationEnergy;
    11: lvList.Columns[2].Caption := rsSecondIonisationEnergy;
    12: lvList.Columns[2].Caption := rsThirdIonisationEnergy;
    13: lvList.Columns[2].Caption := rsElectronegativity;
  end;
  btnAdd.Enabled := False;
  for I := 1 to ElemNumber do
    if (not cbListApplyFilter.Checked) or ElementsList.Filtered(I) then
  begin
    LI := lvList.Items.Add;
    LI.Caption := IntToStr(ElementsList.SortedElements[I].Number);
    LI.SubItems.Add(ElementsList.SortedElements[I].ShortName);
    case cbxSort.ItemIndex of
      0, 1, 2: LI.SubItems.Add(ElementsList.SortedElements[I].Name);
      3: if ElementsList.SortedElements[I].DiscoYear <> 0 then
           LI.SubItems.Add(IntToStr(ElementsList.SortedElements[I].DiscoYear))
         else LI.SubItems.Add(rsKnownFromAntiq);
      4: LI.SubItems.Add(FloatToStr(ElementsList.SortedElements[I].Mass));
      5: if ElementsList.SortedElements[I].MeltingPt <> 0 then
           LI.SubItems.Add(FloatToStr(ElementsList.SortedElements[I].MeltingPt))
         else LI.SubItems.Add(rsUnknown);
      6: if ElementsList.SortedElements[I].BoilingPt <> 0 then
           LI.SubItems.Add(FloatToStr(ElementsList.SortedElements[I].BoilingPt))
         else LI.SubItems.Add(rsUnknown);
      7: LI.SubItems.Add(FloatToStr(ElementsList.SortedElements[I].ElecAffinity));
      8: if ElementsList.SortedElements[I].CovalentRd <> 0 then
           LI.SubItems.Add(IntToStr(ElementsList.SortedElements[I].CovalentRd))
         else LI.SubItems.Add(rsUnknown);
      9: if ElementsList.SortedElements[I].VanDerWaalsRd <> 0 then
           LI.SubItems.Add(IntToStr(ElementsList.SortedElements[I].VanDerWaalsRd))
         else LI.SubItems.Add(rsUnknown);
      10: if ElementsList.SortedElements[I].IonisationEnergy.First <> 0 then
           LI.SubItems.Add(FloatToStr(ElementsList.SortedElements[I].IonisationEnergy.First))
         else LI.SubItems.Add(rsUnknown);
      11: if ElementsList.SortedElements[I].IonisationEnergy.Second <> 0 then
            if ElementsList.SortedElements[I].IonisationEnergy.Second <> -1 then
              LI.SubItems.Add(FloatToStr(ElementsList.SortedElements[I].IonisationEnergy.Second))
            else LI.SubItems.Add(rsImpossible)
         else LI.SubItems.Add(rsUnknown);
      12: if ElementsList.SortedElements[I].IonisationEnergy.Third <> 0 then
            if ElementsList.SortedElements[I].IonisationEnergy.Third <> -1 then
              LI.SubItems.Add(FloatToStr(ElementsList.SortedElements[I].IonisationEnergy.Third))
            else LI.SubItems.Add(rsImpossible)
         else LI.SubItems.Add(rsUnknown);
      13: if ElementsList.SortedElements[I].Electroneg <> -1 then
            LI.SubItems.Add(FloatToStr(ElementsList.SortedElements[I].Electroneg))
          else LI.SubItems.Add(rsUnknown);
    end;
  end;
  lvList.Column[0].Width := 50;
  lvList.Column[1].Width := 50;
end;

procedure TTableForm.btnAddClick(Sender: TObject);
begin     {Add button click}
  with TAddForm.Create(Application) do
  try
    Label2.Caption := lvList.Selected.Caption;
    Label4.Caption := Self.lbName.Caption;
    ShowModal;
  finally
    Free;
  end {try};
end;

procedure TTableForm.lbListDblClick(Sender: TObject);
begin
  btnAddClick(Sender);
end;

procedure TTableForm.lvFiltersChange(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
  btnClearFilterSet.Enabled := lvFilters.Items.Count > 0;
end;

procedure TTableForm.lvFiltersClick(Sender: TObject);
var
  LI: TListItem;
  I: integer;
begin
  if ElementsList.FiltersCount <= 0 then
  begin
    btnRemoveFilter.Enabled := False;
    btnClearFilterSet.Enabled := False;
    Exit;
  end else
    btnClearFilterSet.Enabled := True;
  for I := 0 to lvFilters.Items.Count - 1 do
    if lvFilters.Items[I].Selected then
    begin
      LI := lvFilters.Items[I];
      btnChangeFilter.Enabled := True;
      btnRemoveFilter.Enabled := True;
      Break;
    end else
      if I >= lvFilters.Items.Count - 1 then
      begin
        btnChangeFilter.Enabled := False;
        btnRemoveFilter.Enabled := False;
      end;
  for I := 0 to cbFilterKind.Items.Count - 1 do
    if LI.Caption = cbFilterKind.Items[I] then
      cbFilterKind.ItemIndex := I;
  case cbFilterKind.ItemIndex of
    0: begin
         sedFilterMin.MinValue := ElementsList.MinDiscoveryDate;
         sedFilterMin.MaxValue := ElementsList.MaxDiscoveryDate;
         sedFilterMax.MinValue := ElementsList.MinDiscoveryDate;
         sedFilterMax.MaxValue := ElementsList.MaxDiscoveryDate;
       end;
    1: begin
         sedFilterMin.MinValue := ElementsList.MinMass;
         sedFilterMin.MaxValue := ElementsList.MaxMass;
         sedFilterMax.MinValue := ElementsList.MinMass;
         sedFilterMax.MaxValue := ElementsList.MaxMass;
       end;
    2: begin
         sedFilterMin.MinValue := ElementsList.MinElectronicAffinity;
         sedFilterMin.MaxValue := ElementsList.MaxElectronicAffinity;
         sedFilterMax.MinValue := ElementsList.MinElectronicAffinity;
         sedFilterMax.MaxValue := ElementsList.MaxElectronicAffinity;
       end;
    3: begin
         sedFilterMin.MinValue := ElementsList.MinMeltingPoint;
         sedFilterMin.MaxValue := ElementsList.MaxMeltingPoint;
         sedFilterMax.MinValue := ElementsList.MinMeltingPoint;
         sedFilterMax.MaxValue := ElementsList.MaxMeltingPoint;
       end;
    4: begin
         sedFilterMin.MinValue := ElementsList.MinBoilingPoint;
         sedFilterMin.MaxValue := ElementsList.MaxBoilingPoint;
         sedFilterMax.MinValue := ElementsList.MinBoilingPoint;
         sedFilterMax.MaxValue := ElementsList.MaxBoilingPoint;
       end;
    5: begin
         sedFilterMin.MinValue := ElementsList.MinCovalentRadius;
         sedFilterMin.MaxValue := ElementsList.MaxCovalentRadius;
         sedFilterMax.MinValue := ElementsList.MinCovalentRadius;
         sedFilterMax.MaxValue := ElementsList.MaxCovalentRadius;
       end;
    6: begin
         sedFilterMin.MinValue := ElementsList.MinVanDerWaalsRadius;
         sedFilterMin.MaxValue := ElementsList.MaxVanDerWaalsRadius;
         sedFilterMax.MinValue := ElementsList.MinVanDerWaalsRadius;
         sedFilterMax.MaxValue := ElementsList.MaxVanDerWaalsRadius;
       end;
    7: begin
         sedFilterMin.MinValue := ElementsList.MinFirstIonisationEnergy;
         sedFilterMin.MaxValue := ElementsList.MaxFirstIonisationEnergy;
         sedFilterMax.MinValue := ElementsList.MinFirstIonisationEnergy;
         sedFilterMax.MaxValue := ElementsList.MaxFirstIonisationEnergy;
       end;
    8: begin
         sedFilterMin.MinValue := ElementsList.MinSecondIonisationEnergy;
         sedFilterMin.MaxValue := ElementsList.MaxSecondIonisationEnergy;
         sedFilterMax.MinValue := ElementsList.MinSecondIonisationEnergy;
         sedFilterMax.MaxValue := ElementsList.MaxSecondIonisationEnergy;
       end;
    9: begin
         sedFilterMin.MinValue := ElementsList.MinThirdIonisationEnergy;
         sedFilterMin.MaxValue := ElementsList.MaxThirdIonisationEnergy;
         sedFilterMax.MinValue := ElementsList.MinThirdIonisationEnergy;
         sedFilterMax.MaxValue := ElementsList.MaxThirdIonisationEnergy;
       end;
    10: begin
          sedFilterMin.MinValue := ElementsList.MinElectronegativity;
          sedFilterMin.MaxValue := ElementsList.MaxElectronegativity;
          sedFilterMax.MinValue := ElementsList.MinElectronegativity;
          sedFilterMax.MaxValue := ElementsList.MaxElectronegativity;
        end;
  end;
  sedFilterMin.Value := StrToFloat(LI.SubItems[0]);
  sedFilterMax.Value := StrToFloat(LI.SubItems[1]);
  cbShowUnknown.Checked := LI.SubItems[2] = rsYes;
end;

procedure TTableForm.lvFiltersSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  btnRemoveFilter.Enabled := lvFilters.SelCount <> 0;
  btnChangeFilter.Enabled := lvFilters.SelCount <> 0;
  btnSaveFilterSet.Enabled := lvFilters.Items.Count <> 0;
end;

procedure TTableForm.lvListKeyPress(Sender: TObject; var Key: char);
begin
  if Key = #13 then
    lbListDblClick(Sender);
end;

procedure TTableForm.lvListKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  Start, I, J: integer;
begin
  inherited;
  Start := 0;
  if (Key <> 13) and (Key <> 10) then
  begin
    if (Key in [Ord('a')..Ord('z')]) or (Key in [Ord('A')..Ord('Z')]) then
    begin
      for I := 0 to lvList.Items.Count - 1 do
        if lvList.Items[I].Selected then
        begin
          lvList.Items[I].Selected := False;
          Start := I + 1;
        end;
      //ShowMessage('Start = ' + IntToStr(Start));
      for I := 0 to lvList.Items.Count - 1 do
      begin
        if I + Start < lvList.Items.Count then
          J := I + Start
        else J := I + Start - lvList.Items.Count;
        if Ord(lvList.Items[J].SubItems[0][1]) = Key then
        begin
          lvList.Items[J].Selected := True;
          Break;
        end;
      end;
    end;
    lbListClick(Sender);
  end;
end;

procedure TTableForm.MenuItem5Click(Sender: TObject);
var
  ini: TIniFile;
  I: Integer;
begin
  for I := 1 to ElemNumber do
  begin
    Ini := TIniFile.Create(GetProgramPrefix + 'datas/' +
      ElementsList.Elements[I].ShortName + '.dat');
    Ini.WriteInteger('Global', 'Number', ElementsList.Elements[I].Number);
    Ini.WriteString('Global', 'ShortName', ElementsList.Elements[I].ShortName);
    Ini.WriteString('Global', 'CAS', ElementsList.Elements[I].CAS);
    Ini.WriteString('Global', 'Name', ElementsList.Elements[I].Name);
    Ini.WriteString('Global', 'Bloc', ElementsList.Elements[I].Block);
    Ini.WriteString('Global', 'Family', AFamilyStr[ElementsList.Elements[I].Family]);
    Ini.WriteString('Global', 'Wikipedia', ElementsList.Elements[I].WikiLink);
    Ini.WriteInteger('History', 'Year', ElementsList.Elements[I].DiscoYear);
    Ini.WriteString('History', 'Discoverer', ElementsList.Elements[I].Discoverer);
    Ini.WriteString('History', 'Etymology', ElementsList.Elements[I].Etymology);
    Ini.WriteFloat('Values', 'MeltingPoint', ElementsList.Elements[I].MeltingPt);
    Ini.WriteFloat('Values', 'BoilingPoint', ElementsList.Elements[I].BoilingPt);
    Ini.WriteFloat('Values', 'Mass', ElementsList.Elements[I].Mass);
    Ini.WriteInteger('Values', 'CovalentRadius', ElementsList.Elements[I].CovalentRd);
    Ini.WriteInteger('Values', 'VanDerWaalsRadius', ElementsList.Elements[I].VanDerWaalsRd);
    Ini.WriteFloat('Values', 'ElectronicAffinity', ElementsList.Elements[I].ElecAffinity);
    Ini.WriteFloat('Values', 'Electronegativity', ElementsList.Elements[I].Electroneg);
    Ini.WriteString('Values', 'ElectronicConf', ElementsList.Elements[I].ElecConf);
    Ini.WriteFloat('Values', 'FirstIonistionEnergy', ElementsList.Elements[I].IonisationEnergy.First);
    Ini.WriteFloat('Values', 'SecondIonisationEnergy', ElementsList.Elements[I].IonisationEnergy.Second);
    Ini.WriteFloat('Values', 'ThirdIonisationEnergy', ElementsList.Elements[I].IonisationEnergy.Third);
  end;
end;

procedure TTableForm.mnuAboutClick(Sender: TObject);
begin
  ShowAboutBox;
end;

procedure TTableForm.mnuConfigureClick(Sender: TObject);
begin
  with TOptionsForm.Create(Application) do
  try
    if ShowModal = mrOK then
    begin
      if ChangedColors then
      begin
        clSBlocBG := pnSBloc.Color;
        clSBlocFG := pnSBloc.Font.Color;
        clPBlocBG := pnPBloc.Color;
        clPBlocFG := pnPBloc.Font.Color;
        clFBlocBG := pnFBloc.Color;
        clFBlocFG := pnFBloc.Font.Color;
        clDBlocBG := pnDBloc.Color;
        clDBlocFG := pnDBloc.Font.Color;
        ChangeColors;
      end;
      if ChangedBackup then
        ChangeBackup;
      if ChangedIconSet then
        ChangeIconSet;
      if ChangedPaths then
        ChangePaths;
    end;
  finally
    Free;
  end;
end;

procedure TTableForm.mnuDiscovererClick(Sender: TObject);
begin
  if (DiscovererListForm <> nil) and Assigned(DiscovererListForm) then
    DiscovererListForm.Visible := not DiscovererListForm.Visible
  else
  begin
    DiscovererListForm := TDiscovererListForm.Create(Application);
    DiscovererListForm.Show;
  end;
end;

procedure TTableForm.mnuFullZoomClick(Sender: TObject);
begin
  Chart.Extent.UseXMax := False;
  Chart.Extent.UseXMin := False;
  Chart.Extent.UseYMax := False;
  Chart.Extent.UseYMin := False;
  Chart.ZoomFull;
end;

procedure TTableForm.mnuHeapStatusClick(Sender: TObject);
begin
  //ShowMessage(GetHeapStatus);
end;

procedure TTableForm.mnuOpenConsoleClick(Sender: TObject);
begin

end;

procedure TTableForm.mnuShowFilterListClick(Sender: TObject);
begin
  ElementsList.DbgShowFilters;
end;

procedure TTableForm.pnElmClick(Sender: TObject);
var
  N: integer;
begin
  PageControl1.ActivePage := tsList;
  for N := 0 to ElemNumber - 1 do
    lvList.Items[N].Selected :=
      lvList.Items[N].SubItems[0] = (Sender as TPanel).Caption;
  lbListClick(Sender);
end;

procedure TTableForm.pnElmMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  N, Err, P: integer;
begin
  if (Sender is TPanel) then
  begin
    pnHighlight.Visible := True;
    lbContextInfo.Visible := True;
  end else
  begin
    pnHighlight.Visible := False;
    lbContextInfo.Visible := False;
    CurrPanel := nil;
    Exit;
  end {if};
  if (Sender as TPanel) = CurrPanel then
    Exit
  else
    CurrPanel := (Sender as TPanel);
  pnHighlight.Caption := CurrPanel.Caption;
  pnHighlight.Color := CurrPanel.Color;
  pnHighlight.Font.Color := CurrPanel.Font.Color;
  lbPName.Font.Color := CurrPanel.Font.Color;
  lbPAtNum.Font.Color := CurrPanel.Font.Color;
  lbPMass.Font.Color := CurrPanel.Font.Color;
  for N := 1 to ElemNumber do
    if CurrPanel.Caption = ElementsList.Elements[N].ShortName then
    begin
      lbPName.Caption := ElementsList.Elements[N].Name;
      lbPAtNum.Caption := IntToStr(ElementsList.Elements[N].Number);
      lbPMass.Caption := FloatToStr(ElementsList.Elements[N].Mass) + ' u';
      lbPAtNum.Left := 47 - lbPAtNum.Width;
      lbPMass.Left := 109 - lbPMass.Width;
      case cbxLayout.ItemIndex of
        0: lbContextInfo.Caption := '';
        1: lbContextInfo.Caption := '';
        2: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%n u', [ElementsList.Elements[N].Mass]);
        3: if ElementsList.Elements[N].DiscoYear <> 0 then
          lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%d', [ElementsList.Elements[N].DiscoYear])
        else
          lbContextInfo.Caption := rsKnownFromAntiq;
        4: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%n K', [ElementsList.Elements[N].MeltingPt]);
        5: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%n K', [ElementsList.Elements[N].BoilingPt]);
        6: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%n eV', [ElementsList.Elements[N].ElecAffinity]);
        7: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%d pm', [ElementsList.Elements[N].CovalentRd]);
        8: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%d pm', [ElementsList.Elements[N].VanDerWaalsRd]);
        9: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%n kJ/mol', [ElementsList.Elements[N].IonisationEnergy.First]);
        10: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%n kJ/mol', [ElementsList.Elements[N].IonisationEnergy.Second]);
        11: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%n kJ/mol', [ElementsList.Elements[N].IonisationEnergy.Third]);
        12: lbContextInfo.Caption := Format(cbxLayout.Items[cbxLayout.ItemIndex] +
             ':' + LineBreak + '%n', [ElementsList.Elements[N].Electroneg]);
      end;
      try
        imgAtom1.Picture.LoadFromFile(GetPicRessource(ElementsList.Elements[N].ShortName));
      except
        imgAtom1.Picture.Clear;
      end;
    end {if};
end;

procedure TTableForm.rbSortFirstChange(Sender: TObject);
begin
  ElementsList.SortUnknowFirst := rbSortFirst.Checked;
  FillList;
end;

procedure TTableForm.rbStateCelciusChange(Sender: TObject);
begin
  if rbStateCelcius.Checked then
    sedStateTemp.Value := sedStateTemp.Value + 273.15;
end;

procedure TTableForm.rbStateKelvinChange(Sender: TObject);
begin
  if rbStateKelvin.Checked then
    sedStateTemp.Value := sedStateTemp.Value - 273.15;
end;

procedure TTableForm.sedXEndChange(Sender: TObject);
begin
  if sedXEnd.Value > sedXStart.Value then
  begin
    Chart.Extent.UseXMax := True;
    Chart.Extent.XMax := sedXEnd.Value;
  end else
    if (Sender = sedXEnd) then
      sedXEnd.Value := sedXStart.Value
    else if (Sender = sedXStart) then
      sedXStart.Value := sedXEnd.Value;
end;

procedure TTableForm.sedXStartChange(Sender: TObject);
begin
  if sedXEnd.Value > sedXStart.Value then
  begin
    Chart.Extent.UseXMin := True;
    Chart.Extent.XMin := sedXStart.Value;
  end else
    if (Sender = sedXEnd) then
      sedXEnd.Value := sedXStart.Value
    else if (Sender = sedXStart) then
      sedXStart.Value := sedXEnd.Value;
end;

procedure TTableForm.sedYEndChange(Sender: TObject);
begin
  if sedYEnd.Value > sedYStart.Value then
  begin
    Chart.Extent.UseYMax := True;
    Chart.Extent.YMax := sedYEnd.Value;
  end else
    if (Sender = sedYEnd) then
      sedYEnd.Value := sedYStart.Value
    else if (Sender = sedYStart) then
      sedYStart.Value := sedYEnd.Value;
end;

procedure TTableForm.sedYStartChange(Sender: TObject);
begin
  if sedYEnd.Value > sedYStart.Value then
  begin
    Chart.Extent.UseYMin := True;
    Chart.Extent.YMin := sedYStart.Value;
  end else
    if (Sender = sedYEnd) then
      sedYEnd.Value := sedYStart.Value
    else if (Sender = sedYStart) then
      sedYStart.Value := sedYEnd.Value;
end;

procedure TTableForm.tsTableMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  pnHighlight.Visible := False;
  lbContextInfo.Visible := False;
  imgAtom1.Picture.Clear;
end;

procedure TTableForm.UpdateFilterView;
var
  I: integer;
begin
  //FillList;
  for I := 0 to tsTable.ControlCount - 1 do
    if tsTable.Controls[I] is TPanel then
      if (tsTable.Controls[I] as TPanel).Tag <> 0 then
        if ElementsList.FilterTable then
          (tsTable.Controls[I] as TPanel).Visible :=
            ElementsList.Filtered((tsTable.Controls[I] as TPanel).Tag)
        else (tsTable.Controls[I] as TPanel).Visible := True;
  if cbChartApplyFilters.Checked then
  begin
    FreeAndNil(FLine);
    DrawChartGraph;
  end;
  if cbListApplyFilter.Checked then
    FillList;
end;

procedure TTableForm.BringToFront(ASeries: TChartSeries);
var
  I: Integer;
begin
  for I := 0 to Chart.SeriesCount - 1 do
    Chart.Series[I].ZPosition := Ord(Chart.Series[I] = ASeries);
end;

procedure TTableForm.GraphAddXY(X, Y: Double; Index: integer);
begin
  if RangeArray[Index] then
    if (clbRange.Checked[0] and (ElementsList.Elements[Index].Block = 's')) or
      (clbRange.Checked[1] and (ElementsList.Elements[Index].Block = 'p')) or
      (clbRange.Checked[2] and (ElementsList.Elements[Index].Block = 'd')) or
      (clbRange.Checked[3] and (ElementsList.Elements[Index].Block = 'f')) or
      (clbRange.Checked[4] and (ElementsList.Elements[Index].Family = atAlkaline)) or
      (clbRange.Checked[5] and (ElementsList.Elements[Index].Family = atAlkalieMetal)) or
      (clbRange.Checked[6] and (ElementsList.Elements[Index].Family = atTransMetal)) or
      (clbRange.Checked[7] and (ElementsList.Elements[Index].Family = atOtherMetal)) or
      (clbRange.Checked[8] and (ElementsList.Elements[Index].Family = atMetalloid)) or
      (clbRange.Checked[9] and (ElementsList.Elements[Index].Family = atNonMetal)) or
      (clbRange.Checked[10] and (ElementsList.Elements[Index].Family = atHalogen)) or
      (clbRange.Checked[11] and (ElementsList.Elements[Index].Family = atNobleGas)) or
      (clbRange.Checked[12] and (ElementsList.Elements[Index].Family = atRareEarth)) then
      if cbxChartLabels.ItemIndex = 1 then
        FLine.AddXY(X, Y, ElementsList.Elements[Index].Name, clLime)
      else FLine.AddXY(X, Y, ElementsList.Elements[Index].ShortName, clLime);
end;

procedure TTableForm.InitChart;
begin
  Chart.Extent.UseXMax := False;
  Chart.Extent.UseXMin := False;
  Chart.Extent.UseYMax := False;
  Chart.Extent.UseYMin := False;
  FLine := TLineSeries.Create(Chart);
  FLine.ShowLines := cbDrawLines.Checked;
  FLine.ShowPoints := True;
  FLine.Pointer.Style := psRectangle;
  FLine.Pointer.Brush.Color := clLime;
  FLine.Title := 'line';
  FLine.SeriesColor := clTeal;
  case cbxChartLabels.ItemIndex of
    0: FLine.Marks.Style := smsNone;
    1: FLine.Marks.Style := smsLabel;
    2: FLine.Marks.Style := smsLabel;
    3: FLine.Marks.Style := smsXValue;
    4: FLine.Marks.Style := smsValue;
  end;
  FLine.Marks.Frame.Color := clWhite;
  FLine.Marks.LabelBrush.Color := clNavy;
  Fline.Marks.LabelFont.Color := clWhite;
  Chart.AddSeries(FLine);
end;

procedure TTableForm.DrawChartGraph;
var
  I: integer;
begin
  if FLine = nil then InitChart;
  BringToFront(FLine);
  for I := 1 to ElemNumber do
    if (not cbChartApplyFilters.Checked) or ElementsList.Filtered(I) then
  case cbxXAxis.ItemIndex of
    0: case cbxYAxis.ItemIndex of
      0: GraphAddXY(I, I, I);
      1: GraphAddXY(I, ElementsList.Elements[I].Mass, I);
      2: if ElementsList.Elements[I].MeltingPt <> 0 then
           GraphAddXY(I, ElementsList.Elements[I].MeltingPt, I);
      3: if ElementsList.Elements[I].BoilingPt <> 0 then
           GraphAddXY(I, ElementsList.Elements[I].BoilingPt, I);
      4: GraphAddXY(I, ElementsList.Elements[I].ElecAffinity, I);
      5: if ElementsList.Elements[I].CovalentRd <> 0 then
           GraphAddXY(I, ElementsList.Elements[I].CovalentRd, I);
      6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then
           GraphAddXY(I, ElementsList.Elements[I].VanDerWaalsRd, I);
      7: if ElementsList. Elements[I].IonisationEnergy.First <> 0 then
           GraphAddXY(I, ElementsList.Elements[I].IonisationEnergy.First, I);
    end;
    1: case cbxYAxis.ItemIndex of
      0: GraphAddXY(ElementsList.Elements[I].Mass, I, I);
      1: GraphAddXY(ElementsList.Elements[I].Mass,
           ElementsList.Elements[I].Mass, I);
      2: if ElementsList.Elements[I].MeltingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].Mass,
             ElementsList.Elements[I].MeltingPt, I);
      3: if ElementsList.Elements[I].BoilingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].Mass,
             ElementsList.Elements[I].BoilingPt, I);
      4: GraphAddXY(ElementsList.Elements[I].Mass,
           ElementsList.Elements[I].ElecAffinity, I);
      5: if ElementsList.Elements[I].CovalentRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].Mass,
             ElementsList.Elements[I].CovalentRd, I);
      6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].Mass,
             ElementsList.Elements[I].VanDerWaalsRd, I);
      7: if ElementsList.Elements[I].IonisationEnergy.First <> 0 then
           GraphAddXY(ElementsList.Elements[I].Mass,
             ElementsList.Elements[I].IonisationEnergy.First, I);
    end;
    2: if ElementsList.Elements[I].MeltingPt <> 0 then case cbxYAxis.ItemIndex of
      0: GraphAddXY(ElementsList.Elements[I].MeltingPt, I, I);
      1: GraphAddXY(ElementsList.Elements[I].MeltingPt,
           ElementsList.Elements[I].Mass, I);
      2: if ElementsList.Elements[I].MeltingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].MeltingPt,
             ElementsList.Elements[I].MeltingPt, I);
      3: if ElementsList.Elements[I].BoilingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].MeltingPt,
             ElementsList.Elements[I].BoilingPt, I);
      4: GraphAddXY(ElementsList.Elements[I].MeltingPt,
           ElementsList.Elements[I].ElecAffinity, I);
      5: if ElementsList.Elements[I].CovalentRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].MeltingPt,
             ElementsList.Elements[I].CovalentRd, I);
      6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].MeltingPt,
             ElementsList.Elements[I].VanDerWaalsRd, I);
      7: if ElementsList.Elements[I].IonisationEnergy.First <> 0 then
           GraphAddXY(ElementsList.Elements[I].MeltingPt,
             ElementsList.Elements[I].IonisationEnergy.First, I);
    end;
    3: if ElementsList.Elements[I].BoilingPt <> 0 then case cbxYAxis.ItemIndex of
      0: GraphAddXY(ElementsList.Elements[I].BoilingPt, I, I);
      1: GraphAddXY(ElementsList.Elements[I].BoilingPt,
           ElementsList.Elements[I].Mass, I);
      2: if ElementsList.Elements[I].MeltingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].BoilingPt,
             ElementsList.Elements[I].MeltingPt, I);
      3: if ElementsList.Elements[I].BoilingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].BoilingPt,
             ElementsList.Elements[I].BoilingPt, I);
      4: if ElementsList.Elements[I].ElecAffinity <> 0 then
           GraphAddXY(ElementsList.Elements[I].BoilingPt,
             ElementsList.Elements[I].ElecAffinity, I);
      5: if ElementsList.Elements[I].CovalentRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].BoilingPt,
             ElementsList.Elements[I].CovalentRd, I);
      6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].BoilingPt,
             ElementsList.Elements[I].VanDerWaalsRd, I);
      7: GraphAddXY(ElementsList.Elements[I].BoilingPt,
           ElementsList.Elements[I].IonisationEnergy.First, I);
    end;
    4: case cbxYAxis.ItemIndex of
      0: GraphAddXY(ElementsList.Elements[I].ElecAffinity, I, I);
      1: GraphAddXY(ElementsList.Elements[I].ElecAffinity,
           ElementsList.Elements[I].Mass, I);
      2: if ElementsList.Elements[I].MeltingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].ElecAffinity,
             ElementsList.Elements[I].MeltingPt, I);
      3: if ElementsList.Elements[I].BoilingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].ElecAffinity,
             ElementsList.Elements[I].BoilingPt, I);
      4: GraphAddXY(ElementsList.Elements[I].ElecAffinity,
           ElementsList.Elements[I].ElecAffinity, I);
      5: if ElementsList.Elements[I].CovalentRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].ElecAffinity,
             ElementsList.Elements[I].CovalentRd, I);
      6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].ElecAffinity,
             ElementsList.Elements[I].VanDerWaalsRd, I);
      7: if ElementsList.Elements[I].IonisationEnergy.First <> 0 then
           GraphAddXY(ElementsList.Elements[I].ElecAffinity,
             ElementsList.Elements[I].IonisationEnergy.First, I);
    end;
    5: if ElementsList.Elements[I].CovalentRd <> 0 then case cbxYAxis.ItemIndex of
      0: GraphAddXY(ElementsList.Elements[I].CovalentRd, I, I);
      1: GraphAddXY(ElementsList.Elements[I].CovalentRd,
           ElementsList.Elements[I].Mass, I);
      2: if ElementsList.Elements[I].MeltingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].CovalentRd,
             ElementsList.Elements[I].MeltingPt, I);
      3: if ElementsList.Elements[I].BoilingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].CovalentRd,
             ElementsList.Elements[I].BoilingPt, I);
      4: GraphAddXY(ElementsList.Elements[I].CovalentRd,
           ElementsList.Elements[I].ElecAffinity, I);
      5: if ElementsList.Elements[I].CovalentRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].CovalentRd,
             ElementsList.Elements[I].CovalentRd, I);
      6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].CovalentRd,
             ElementsList.Elements[I].VanDerWaalsRd, I);
      7: if ElementsList.Elements[I].IonisationEnergy.First <> 0 then
           GraphAddXY(ElementsList.Elements[I].CovalentRd,
             ElementsList.Elements[I].IonisationEnergy.First, I);
    end;
    6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then case cbxYAxis.ItemIndex of
      0: GraphAddXY(ElementsList.Elements[I].VanDerWaalsRd, I, I);
      1: GraphAddXY(ElementsList.Elements[I].VanDerWaalsRd,
           ElementsList.Elements[I].Mass, I);
      2: if ElementsList.Elements[I].MeltingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].VanDerWaalsRd,
             ElementsList.Elements[I].MeltingPt, I);
      3: if ElementsList.Elements[I].BoilingPt <> 0 then
           GraphAddXY(ElementsList.Elements[I].VanDerWaalsRd,
             ElementsList.Elements[I].BoilingPt, I);
      4: GraphAddXY(ElementsList.Elements[I].VanDerWaalsRd,
           ElementsList.Elements[I].ElecAffinity, I);
      5: if ElementsList.Elements[I].CovalentRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].VanDerWaalsRd,
             ElementsList.Elements[I].CovalentRd, I);
      6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then
           GraphAddXY(ElementsList.Elements[I].VanDerWaalsRd,
             ElementsList.Elements[I].VanDerWaalsRd, I);
      7: if ElementsList.Elements[I].IonisationEnergy.First <> 0 then
           GraphAddXY(ElementsList.Elements[I].VanDerWaalsRd,
             ElementsList.Elements[I].IonisationEnergy.First, I);
    end;
    7: if ElementsList.Elements[I].IonisationEnergy.First <> 0 then
         case cbxYAxis.ItemIndex of
           0: GraphAddXY(ElementsList.Elements[I].IonisationEnergy.First, I, I);
           1: GraphAddXY(ElementsList.Elements[I].IonisationEnergy.First,
                ElementsList.Elements[I].Mass, I);
           2: if ElementsList.Elements[I].MeltingPt <> 0 then
                GraphAddXY(ElementsList.Elements[I].IonisationEnergy.First,
                  ElementsList.Elements[I].MeltingPt, I);
           3: if ElementsList.Elements[I].BoilingPt <> 0 then
                GraphAddXY(ElementsList.Elements[I].IonisationEnergy.First,
                  ElementsList.Elements[I].BoilingPt, I);
           4: GraphAddXY(ElementsList.Elements[I].IonisationEnergy.First,
                ElementsList.Elements[I].ElecAffinity, I);
           5: if ElementsList.Elements[I].CovalentRd <> 0 then
                GraphAddXY(ElementsList.Elements[I].IonisationEnergy.First,
                  ElementsList.Elements[I].CovalentRd, I);
           6: if ElementsList.Elements[I].VanDerWaalsRd <> 0 then
                GraphAddXY(ElementsList.Elements[I].IonisationEnergy.First,
                  ElementsList.Elements[I].VanDerWaalsRd, I);
           7: if ElementsList.Elements[I].IonisationEnergy.First <> 0 then
                GraphAddXY(ElementsList.Elements[I].IonisationEnergy.First,
                  ElementsList.Elements[I].IonisationEnergy.First, I);
         end;
  end;
  {$warning Get the value when Extent.UseXXXX is set to false}
  sedXStart.Value := Chart.Extent.XMin;
  sedYStart.Value := Chart.Extent.YMin;
  sedXEnd.Value := Chart.Extent.XMax;
  sedYEnd.Value := Chart.Extent.YMax;
  Chart.ZoomFull;
end;

procedure TTableForm.ChangeIconSet;
begin
  {$warning TTableForm.ChangeIconSet: to be done}
end;

procedure TTableForm.ChangeColors;
begin
  cbxLayoutChange(nil);
  lbListClick(nil);
end;

procedure TTableForm.ChangeBackup;
begin
    {$warning TTableForm.ChangeBackup: to be done}
end;

procedure TTableForm.ChangePaths;
begin
    {$warning TTableForm.ChangePaths: to be done}
end;

procedure TTableForm.UpdateFilterList;
var
  LI: TListItem;
  I: Integer;
begin
  lvFilters.Items.Clear;
  for I := 0 to ElementsList.FiltersCount - 1 do
  begin
    LI := lvFilters.Items.Add;
    case ElementsList.Filters[I].Kind of
      fkDate: LI.Caption := cbFilterKind.Items[0];
      fkElectronicAffinity: LI.Caption := cbFilterKind.Items[2];
      fkMass: LI.Caption := cbFilterKind.Items[1];
      fkMeltingPoint: LI.Caption := cbFilterKind.Items[3];
      fkBoilingPoint: LI.Caption := cbFilterKind.Items[4];
      fkCovalentRadius: LI.Caption := cbFilterKind.Items[5];
      fkVanDerWaalsRadius: LI.Caption := cbFilterKind.Items[6];
      fkFirstIonisationEnergy: LI.Caption := cbFilterKind.Items[7];
      fkSecondIonisationEnergy: LI.Caption := cbFilterKind.Items[8];
      fkThirdIonisationEnergy: LI.Caption := cbFilterKind.Items[9];
      fkElectronegativity: LI.Caption := cbFilterKind.Items[10];
    end;
    LI.SubItems.Add(FloatToStr(ElementsList.Filters[I].Min));
    LI.SubItems.Add(FloatToStr(ElementsList.Filters[I].Max));
    if ElementsList.Filters[I].DisplayUnknow then
      LI.SubItems.Add(rsYes)
    else LI.SubItems.Add(rsNo);
  end;
  lvFiltersClick(nil);
end;

initialization
  {$i frmtable.lrs}
end.
