unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TFlatButtonUnit, ExtCtrls, ComCtrls, xmldoc, xmlintf, mmSystem, WaveUtils, WaveStorage,
  WaveIn, WaveRecorders, WaveIO, WaveOut, WavePlayers, strutils, zlib, folderBrowse;

type
  TWavInfo = Class(TObject)
  public
    samplefile: String;
    recfile: String;
    constructor Create(tn: TTreenode; nd: iXmlNode);
  end;

  TDlgSndRecMain = class(TForm)
    tv: TTreeView;
    Panel2: TPanel;
    btnRec: TFlatButton;
    btnStop: TFlatButton;
    btnPause: TFlatButton;
    btnPlayRecord: TFlatButton;
    btnExit: TFlatButton;
    Recorder: TStockAudioRecorder;
    btnPlaySample: TFlatButton;
    Player: TStockAudioPlayer;
    btnCompressAndUpload: TFlatButton;
    procedure FormCreate(Sender: TObject);
    procedure btnExitClick(Sender: TObject);
    procedure btnPlaySampleClick(Sender: TObject);
    procedure btnPlayRecordClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure btnPauseClick(Sender: TObject);
    procedure tvChange(Sender: TObject; Node: TTreeNode);
    procedure btnRecClick(Sender: TObject);
    procedure tvCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure btnCompressAndUploadClick(Sender: TObject);
  private
    fxd: ixmldocument;
    fPath: String;
    procedure LoadXml;
    function  LoadNode(pnd: TTreenode; xnd: iXmlNode): String;
    procedure StopPlayer;
    procedure StopRecorder;
    procedure UpdateButtons;
    function  SampleFileExists: Boolean;
    function  RecordFileExists: Boolean;
  public
  end;

var DlgSndRecMain: TDlgSndRecMain;
implementation

uses udlgftpupload, ufileutils;

{$R *.dfm}

constructor TWavInfo.Create(tn: TTreenode; nd: iXmlNode);
begin
  inherited create;
  samplefile:= ReplaceStr(nd.Attributes['caption'], ' ', '');
  samplefile:= ReplaceStr(samplefile, '!', '');
  samplefile:= ReplaceStr(samplefile, '.', '');
  samplefile:= ReplaceStr(samplefile, ',', '');
  samplefile:= ReplaceStr(samplefile, '?', '')+'.wav';

  if nd.Attributes['wav'] <> null then begin
    recfile:= nd.Attributes['wav']+'.wav';
    if not fileexists(ExtractFilePath(Application.ExeName)+'samples\'+samplefile) then
      samplefile:= recfile;
  end;
  tn.Data:= self;
end;

procedure TDlgSndRecMain.FormCreate(Sender: TObject);
begin
  fPath:= ExtractFilePath(Application.ExeName);
  LoadXml;
end;

procedure TDlgSndRecMain.LoadXml;
begin
  fxd:= NewXMLDocument;
  fxd.LoadFromFile(ChangeFileExt(Application.ExeName, '.xml'));
  LoadNode(nil, fxd.DocumentElement);
  tv.Items[0].Expand(false);
end;

function TDlgSndRecMain.LoadNode(pnd: TTreenode; xnd: iXmlNode): String;
var i: integer;
    NewTreeNode: TTreeNode;
begin
  NewTreeNode:= tv.Items.AddChild(pnd, xnd.Attributes['caption']);
  TWavInfo.Create(NewTreeNode, xnd);
  for i:= 0 to xnd.ChildNodes.Count-1 do
    LoadNode(NewTreeNode, xnd.ChildNodes[i]);
end;

procedure TDlgSndRecMain.StopPlayer;
begin
  if Player.Active then begin
    Player.Active:= false;
    while Player.Active do
      Application.ProcessMessages;
  end;
end;

procedure TDlgSndRecMain.StopRecorder;
begin
  if Recorder.Active then begin
    Recorder.Active:= false;
    while Recorder.Active do
      Application.ProcessMessages;
  end;
end;

procedure TDlgSndRecMain.tvChange(Sender: TObject; Node: TTreeNode);
begin
  if Player.Active then StopPlayer;
  UpdateButtons;
end;

procedure TDlgSndRecMain.tvCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);

begin
  if assigned(tv.Selected) and assigned(tv.Selected.Data) then begin
    if (TWavInfo(node.Data).recfile <> '') and FileExists(fPath+'recorded\'+TWavInfo(node.Data).recfile) then
      sender.Canvas.Font.Color:= clgreen
    else
    if assigned(node.Parent) and (TWavInfo(node.Parent.Data).recfile <> '') and fileexists(fPath+'recorded\'+TWavInfo(node.Parent.Data).recfile) then
      sender.Canvas.Font.Color:= clgreen
  end;
end;

procedure TDlgSndRecMain.UpdateButtons;
begin
  btnPlaySample.Enabled:= SampleFileExists and not Recorder.Active;
  btnPlayRecord.Enabled:= RecordFileExists and not Recorder.Active;
  btnRec.Enabled:=
    not Recorder.Active and
    ((TWavInfo(tv.Selected.Data).recfile <> '') or (assigned(tv.Selected.Parent) and (TWavInfo(tv.Selected.Parent.Data).recfile <> '')));
  btnPause.Enabled:= Player.Active or Recorder.Active;
  btnStop.Enabled:= Player.Active or Recorder.Active;
end;

function TDlgSndRecMain.SampleFileexists: Boolean;
begin
  result:= assigned(tv.Selected) and fileexists(fPath+'samples\'+TWavInfo(tv.Selected.Data).samplefile);
end;

function TDlgSndRecMain.RecordFileexists: Boolean;
begin
  result:= assigned(tv.Selected) and fileexists(fPath+'recorded\'+TWavInfo(tv.Selected.Data).recfile);
end;

procedure TDlgSndRecMain.btnPlaySampleClick(Sender: TObject);
begin
  if player.Paused then player.Paused:= false
  else begin
    StopPlayer;
    Player.PlayFile(fPath+'samples\'+TWavInfo(tv.Selected.Data).samplefile);
    UpdateButtons;
  end;
end;

procedure TDlgSndRecMain.btnRecClick(Sender: TObject);
begin
  Recorder.RecordToFile(fPath+'recorded\'+TWavInfo(tv.Selected.Data).recfile);
  UpdateButtons;
end;

procedure TDlgSndRecMain.btnPlayRecordClick(Sender: TObject);
begin
  if player.Paused then player.Paused:= false
  else begin
    StopPlayer;
    Player.PlayFile(fPath+'recorded\'+TWavInfo(tv.Selected.Data).recfile);
    UpdateButtons;
  end;
end;


procedure TDlgSndRecMain.btnStopClick(Sender: TObject);
begin
  StopPlayer;
  StopRecorder;
  UpdateButtons;
  tv.Invalidate;
end;


procedure TDlgSndRecMain.btnPauseClick(Sender: TObject);
begin
  if player.Active then
    player.Paused:= true
  else
  if Recorder.Active then
    Recorder.Paused:= true;
  UpdateButtons;
end;

procedure TDlgSndRecMain.btnCompressAndUploadClick(Sender: TObject);
var ftpdlg: TDlgFtpUpload;
begin
  ftpdlg:= nil;
  try
    ftpdlg:= TDlgFtpUpload.Create(self);
    ftpdlg.ShowModal;
  finally
    ftpdlg.Free;
  end;
end;

procedure TDlgSndRecMain.btnExitClick(Sender: TObject);
begin
  Close;
end;


end.
