{ Dialog for creating new chromatographic analysis }
unit FileNewDlg;
{
  (C) 2000 - 2001 Jindrich Jindrich, Pavel Pisa, PiKRON Ltd.

  Originators of the CHROMuLAN project:

  Jindrich Jindrich - http://www.jindrich.com
                      http://orgchem.natur.cuni.cz/Chromulan/
                      software developer, project coordinator
  Pavel Pisa        - http://cmp.felk.cvut.cz/~pisa
                      embeded software developer
  PiKRON Ltd.       - http://www.pikron.com
                      project initiator, sponsor, instrument developer

  The CHROMuLAN project is distributed under the GNU General Public Licence.
  See file COPYING for details.

  Originators reserve the right to use and publish sources
  under different conditions too. If third party contributors
  do not accept this condition, they can delete this statement
  and only GNU license will apply.
}

{$I define.pas}
interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ImgList, ComCtrls, StdCtrls, ExtCtrls, IniFiles,
  UtlType, WinUtl, PropUtl, ULRecTyp, UlanType, UlanGlob, Spectrum,
  ExtDevIntu, ModuType
  {$IFDEF USEDLL}
  ,ModuProc
  {$ELSE}
  {$ENDIF}
  ;

type
  TFileNewDialog = class(TForm)
    AnalSmallImageList: TImageList;
    AnalImageList: TImageList;
    TopPanel: TPanel;
    BottomPanel: TPanel;
    OKBtn: TButton;
    CancelBtn: TButton;
    PageControl: TPageControl;
    AnalTabSheet: TTabSheet;
    AnalListView: TListView;
    SeqTabSheet: TTabSheet;
    SeqListView: TListView;
    SeqImageList: TImageList;
    procedure OKBtnClick(Sender: TObject);
    procedure ListViewDblClick(Sender: TObject);
    procedure ListViewClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure PageControlChange(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormDeactivate(Sender: TObject);
  private
    { Private declarations }
  protected
    function GetActivePageBaseName: string;
      { return base name of current TabSheet (without 'TabSheet' suffix,
         = base name of ListView) }
    function GetActiveListView: TListView;
    function GetActiveListViewItem: TListItem;
    procedure LoadTemplates;
    {v0.41}
    procedure LoadSequenceTemplates;
    {/v0.41}
    procedure SelectDefaults;
  public
    { Public declarations }
    procedure UpdateOK;
    procedure UpdatePageControl;
      { call when current tab changed }
    property ActivePageBaseName: string read GetActivePageBaseName;
    property ActiveListView: TListView read GetActiveListView;
    property ActiveListViewItem: TListItem read GetActiveListViewItem;
  end;

function FileNewDialog: TFileNewDialog;

var
  FFileNewDialog: TFileNewDialog;

implementation

{$R *.DFM}

function FileNewDialog: TFileNewDialog;
begin
  if FFileNewDialog = nil then begin
    FFileNewDialog := TFileNewDialog.Create(Application.MainForm);
  end;
  Result := FFileNewDialog;
end;

procedure TFileNewDialog.OKBtnClick(Sender: TObject);
{var s: string;}
begin
  {
  s := PageControl.ActivePage.Name;
  if s = 'AnalTabSheet' then begin
    ... AnalListView.Items
  end else begin
  end;
  ... leave the decision on the caller }
end;

procedure TFileNewDialog.ListViewDblClick(Sender: TObject);
begin
  if OKBtn.Enabled then
    ModalResult := mrOK;
end;

procedure TFileNewDialog.ListViewClick(Sender: TObject);
begin
  UpdateOK;
end;

procedure TFileNewDialog.UpdateOK;
var
  c: TComponent;
  oken: boolean;
  i, sel: integer;
begin
  oken := false;
  c := FindComponent(ActivePageBaseName + 'ListView');
  if (c <> nil) then with c as TListView do begin
    sel := 0;
    for i := 0 to Items.Count - 1 do begin
      if Items.Item[i].Selected then
        inc(sel);
    end;
    oken := sel > 0;
  end;
  OKBtn.Enabled := oken;
end;

function TFileNewDialog.GetActivePageBaseName: string;
var
  s: string;
begin
  s := PageControl.ActivePage.Name;
  Result := copy(s, 1, length(s) - length('TabSheet'));
end;

function TFileNewDialog.GetActiveListView: TListView;
var
  c: TComponent;
begin
  c := FindComponent(ActivePageBaseName + 'ListView');
  if (c <> nil) and (c is TListView) then
    Result := TListView(c)
  else
    Result := nil;
end;

function TFileNewDialog.GetActiveListViewItem: TListItem;
var
  lv: TListView;
  i: integer;
begin
  Result := nil;
  lv := ActiveListView;
  if lv <> nil then begin
    for i := 0 to lv.Items.Count - 1 do begin
      if lv.Items.Item[i].Selected then begin
        Result := lv.Items.Item[i];
        exit;
      end;
    end;
  end;
end;

procedure TFileNewDialog.UpdatePageControl;
var
{  s: string;}
  lv: TListView;
begin
  lv := ActiveListView;
  if lv <> nil then begin
    ActiveControl := TWinControl(lv);
    UpdateOK;
  end;
end;

procedure TFileNewDialog.FormCreate(Sender: TObject);
var f: TIniFile;
begin
  PageControl.ActivePage := AnalTabSheet;
  {AnalListView.UpdateItems(0,0);}
  f := TIniFile.Create(FindIniFile);
  try
    ConfigReadWriteValue(f, rwRead, SpecSection, 'DefAnalTemplate', @DefAnalTemplate, ptString);
    ConfigReadWriteValue(f, rwRead, SpecSection, 'DefAnalSeq', @DefAnalSeq, ptString);
  finally
    f.Free;
  end;
  UpdatePageControl;
  LoadTemplates;
end;

procedure TFileNewDialog.FormActivate(Sender: TObject);
begin
  {AnalListView.Items.Item[0].Focused := true;
  AnalListView.Items.Item[0].Selected := true;
  AnalListView.UpdateItems(0,0);}
  UpdatePageControl;
  LoadTemplates;
end;

procedure TFileNewDialog.PageControlChange(Sender: TObject);
begin
  UpdatePageControl;
end;

procedure TFileNewDialog.SelectDefaults;
var
  i, j: integer;
  fnd: boolean;
begin
  for i := 0 to ComponentCount - 1 do begin
    if Components[i] is TListView then with Components[i]
      as TListView do
    begin
      if (Items.Count > 0) then begin
        if Name = 'AnalListView' then begin
          fnd := false;
          for j := 0 to Items.Count - 1 do begin
            if Items.Item[j].Caption = DefAnalTemplate then begin
              Items.Item[j].Focused := true;
              Items.Item[j].Selected := true;
              fnd := true;
              break;
            end;
          end;
          if not fnd then begin
            Items.Item[0].Focused := true;
            Items.Item[0].Selected := true;
          end;
        end;
        if Name = 'SeqListView' then begin
          fnd := false;
          for j := 0 to Items.Count - 1 do begin
            if Items.Item[j].Caption = DefAnalSeq then begin
              Items.Item[j].Focused := true;
              Items.Item[j].Selected := true;
              fnd := true;
              break;
            end;
          end;
          if not fnd then begin
            Items.Item[0].Focused := true;
            Items.Item[0].Selected := true;
          end;
        end;

      end;
    end;
  end;
end;

type
  TDefTemp = record
    Name:string;
    Found:boolean;
    Channel:string;
    {v0.40}
    DeviceMode: TDeviceMode;
    {/v0.40}
  end;

const
  DefTempCount = 4;{ulanglob ulantype}
  DefTemps:array[0..DefTempCount-1] of TDefTemp = (
    (Name: pvUlanDefaultTemplate; Found: false; Channel: {v0.41}pvUlanDefaultChannel{/v0.41 pvUlanDefaultTemplate}
      {v0.40}; DeviceMode:dmUlan{/v0.40}),
    (Name: pvPasiveDefaultTemplate; Found: false; Channel: pvPasiveDefaultChannel
      {v0.40}; DeviceMode:dmPasive{/v0.40}),
    (Name: pvEmptyTemplate; Found: false; Channel: pvEmptyChannel
      {v0.40}; DeviceMode:dmUnspecified{/v0.40}),
    (Name: pvFromFileTemplate; Found: false; Channel: pvFromFileChannel
      {v0.40}; DeviceMode:dmUnspecified{/v0.40})
  );

  procedure CreateTemplate(fn, chn:string);
  var a: TAcqData;
  begin
    a := TAcqData.Create(TemplateDir + fn, omCreateTemplate);
    {v0.50}
    a.ULI.SequenceKind := skStandalone;
    {/v0.50}
    {v0.18}
    if (chn = pvEmptyChannel) or (chn = pvFromFileChannel) then begin
      {don't assing channel name for these special cases}
    end else
    {/v0.18}
    begin
      a.ULI.ChannelName := chn;
    end;
    a.Free;
  end;

procedure TFileNewDialog.LoadTemplates;

var
  li: TListItem;
  f: TSearchRec;
  {v0.18}
  {/v0.18
  ulfound:boolean;
  apfound:boolean;
  }
var
  ed: TExtDev;
  i: integer;
  di:integer;


begin
  try
    with AnalListView do begin
      while Items.Count > 0 do
        Items.Item[0].Free;
      {v0.18}
      {/v0.18
      ulfound := false;
      apfound := false;}
      if FindFirst(TemplateDir + '*' + ULTExt, faAnyFile, f) = 0 then
      repeat
        {v0.41}
        if pos('SEQ', Uppercase(f.Name)) = 0 then
        {/v0.41}
        begin
          li := Items.Add;
          li.Caption := f.Name;
          ExtDevs.TemplateRegister(f.Name);
          {v0.18}
          for di := 0 to DefTempCount - 1 do begin
            with DefTemps[di] do begin
              if Name = f.Name then
                DefTemps[di].Found := true;
            end;
          end;
          {/v0.18
          if f.Name = pvUlanDefaultTemplate then
            ulfound := true;
          if f.Name = pvApexDefaultTemplate then
            apfound := true;
          }
        end;
      until FindNext(f) <> 0;
      FindClose(f);
      {v0.18}
      for di := 0 to DefTempCount - 1 do begin
        with DefTemps[di] do begin
          if (not Found)
          and ((DeviceMode <> dmUlan) or
            {$IFDEF USEDLL}
            (ModulesGetPropInt(Modules, mpCurDeviceMode) = ord(dmUlan))
            {$ELSE}
            (CurDeviceMode = dmUlan)
            {$ENDIF}
          )
          then
          begin
            CreateTemplate(Name, Channel);
            li := Items.Add;
            li.Caption := Channel;
          end;
        end;
      end;
      {/v0.18
      if not ulfound then begin
        CreateTemplate(pvUlanDefaultTemplate, pvUlanDefaultChannel);
        li := Items.Add;
        li.Caption := pvUlanDefaultTemplate;
      end;
      if not apfound then begin
        CreateTemplate(pvApexDefaultTemplate, pvApexDefaultChannel);
        li := Items.Add;
        li.Caption := pvApexDefaultTemplate;
      end;
      }
      for i := 0 to ExtDevs.Count - 1 do begin
        ed := TExtDev(ExtDevs[i]);
        if not ed.TemplateExists then begin
          {v0.65}
          CreateTemplate(ed.DeviceName + ULTExt, ed.DeviceName);
          li := Items.Add;
          li.Caption := ed.DeviceName + ULTExt;
          {/v0.65
          CreateTemplate(ChangeFileExt(ed.ExtDevDrvName, ULTExt),
            ed.ExtDevDrvName);
          li := Items.Add;
          li.Caption := ChangeFileExt(ed.ExtDevDrvName, ULTExt);
          }
        end;
      end;
      Caption := 'New Items (' + TemplateDir + ')';
    end;
    SelectDefaults;
  finally
  end;
  {v0.41}
  LoadSequenceTemplates;
  {/v0.41}
end;


{v0.41}
procedure TFileNewDialog.LoadSequenceTemplates;

var
  li: TListItem;
  f: TSearchRec;

{v0.50}{/v0.50
type
  TDefTemp = record
    Name:string;
    Found:boolean;
    Channel:string;
    DeviceMode: TDeviceMode;
  end;

const
  DefSeqCount = 4;
  DefSeqs:array[0..DefSeqCount-1] of TDefTemp = (
    (Name: pvUlanDefaultSeq; Found: false; Channel: pvUlanDefaultChannel
      ; DeviceMode:dmUlan),
    (Name: pvPasiveDefaultSeq; Found: false; Channel: pvPasiveDefaultChannel
      ; DeviceMode:dmPasive),
    (Name: pvEmptySeq; Found: false; Channel: pvEmptyChannel
      ; DeviceMode:dmUnspecified),
    (Name: pvFromFileSeq; Found: false; Channel: pvFromFileChannel
      ; DeviceMode:dmUnspecified)
  );
}
{var}
  {ed: TExtDev;}
  {i: integer;}
{  di:integer;}


begin
  try
    with SeqListView do begin
      while Items.Count > 0 do
        Items.Item[0].Free;
      if FindFirst(TemplateDir + '*' + ULTExt, faAnyFile, f) = 0 then
      repeat

        if pos('SEQ', Uppercase(f.Name)) {v0.50}= 0{/v0.50 <> 0} then
        begin
          li := Items.Add;
          li.Caption := f.Name;
          {v0.50}{/v0.50
          for di := 0 to DefSeqCount - 1 do begin
            with DefSeqs[di] do begin
              if Name = f.Name then
                DefSeqs[di].Found := true;
            end;
          end;}
        end;
      until FindNext(f) <> 0;
      FindClose(f);
      {v0.18}
      {v0.50}{/v0.50
      for di := 0 to DefSeqCount - 1 do begin
        with DefSeqs[di] do begin
          if (not Found)
          and ((DeviceMode <> dmUlan) or (CurDeviceMode = dmUlan))
          then
          begin
            CreateTemplate(Name, Channel);
            li := Items.Add;
            li.Caption := Channel;
          end;
        end;
      end;}
      Caption := 'New Items (' + TemplateDir + ')';
    end;
    SelectDefaults;
  finally
  end;
end;
{/v0.41}

procedure TFileNewDialog.FormDestroy(Sender: TObject);
begin
  ConfigReadWriteValue(nil, rwWrite, SpecSection,'DefAnalTemplate', @DefAnalTemplate, ptString);
  ConfigReadWriteValue(nil, rwWrite, SpecSection,'DefAnalSeq', @DefAnalSeq, ptString);
end;

procedure TFileNewDialog.FormDeactivate(Sender: TObject);
var i, j: integer;
begin
  for i := 0 to ComponentCount - 1 do begin
    if Components[i] is TListView then with Components[i] as TListView do
    begin
      if (Items.Count > 0) then begin
        if Name = 'AnalListView' then begin
          for j := 0 to Items.Count - 1 do begin
            if Items.Item[j].Focused and Items.Item[j].Selected then
              DefAnalTemplate := Items.Item[j].Caption;
          end;
        end;
        {v0.41}
        if Name = 'SeqListView' then begin
          for j := 0 to Items.Count - 1 do begin
            if Items.Item[j].Focused and Items.Item[j].Selected then
              DefAnalSeq := Items.Item[j].Caption;
          end;
        end;
        {/v0.41}
      end;
    end;
  end;
end;

initialization
  FFileNewDialog := nil;
end.
