(************************************************************************
*    This File is Part of the AHM Triton Tools                          *
*    for Borland Delphi and C++ Builder.                                *
*************************************************************************
* Copyright © 1995-1999 Alexander H. Mehlhorn (AHM) and Tritontools.com *
* All Rights reserved.                                                  *
*                                                                       *
*    For more Information contact us at                                 *
*    E-Mail : support@tritontools.com                                   *
*    URL : http://www.tritontools.com                                   *
*                                                                       *
*    AHM is copyright by Alexander H. Mehlhorn                          *
*    All Parts of this Collection were developed,                       *
*    designed and implemented by AHM                                    *
*                                                                       *
*    Under no Circumstances may you distribute this file                *
*    in this or any other format. This File is supplied                 *
*    as Evaluation of Source only. No Delphi Components may be developed*
*    using extracts or subsets of this code without expressed permission*
*    by AHM.                                                            *
*                                                                       *
*************************************************************************)
unit AHMTWaveHolder;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  AHMSystemClass,MMSystem;
type
  TAHMWaveHolder = class;
  TAHMExternalWaves = class;
  TAHMExternalWave = class(TCollectionItem)
  private
    FAHMWaveHolder : TAHMWaveHolder;
    FLooped: Boolean;
    FAsynchronous: Boolean;
    FFileName: String;
    procedure SetAsynchronous(const Value: Boolean);
    procedure SetFileName(const Value: String);
    procedure SetLooped(const Value: Boolean);
  protected
    function GetDisplayName: string; override;
  public
    function Play: Boolean;  
    constructor Create(Collection: TCollection); override;
    procedure Assign(Source: TPersistent); override;
    property Owner : TAHMWaveHolder read FAHMWaveHolder;
    property DisplayName : String read GetDisplayName;
  published
    property Asynchronous : Boolean read FAsynchronous write SetAsynchronous default True;
    property Looped : Boolean read FLooped write SetLooped default False;
    property WavFileName: String read FFileName write SetFileName;
  end;
  TAHMExternalWaves = class(TCollection)
  private
    FAHMWaveHolder : TAHMWaveHolder;
    function GetAHMExternalWave(Index: Integer): TAHMExternalWave;
    procedure SetAHMExternalWave(Index: Integer; Value: TAHMExternalWave);
  protected
    function GetOwner : TPersistent; override;
  public
    constructor Create(AOwner: TAHMWaveHolder);
    function Add : TAHMExternalWave;
   Function Delete(Index :Integer) :Boolean;
    property Owner : TAHMWaveHolder read FAHMWaveHolder;
    property Items[Index: Integer]: TAHMExternalWave read GetAHMExternalWave write SetAHMExternalWave; default;
  end;
  TAHMInternalWaves = class;
  TAHMInternalWave = class(TCollectionItem)
  private
    FWaveData: TMemoryStream;
    FWave: String;
    FAHMWaveHolder : TAHMWaveHolder;
    FLooped: Boolean;
    FAsynchronous: Boolean;
    procedure ReadData(Stream: TStream);
    procedure WriteData(Stream: TStream);
    function Empty: boolean;
    procedure SetWave(const Value: String);
    procedure SetLooped(const Value: Boolean);
    procedure SetAsynchronous(const Value: Boolean);
  protected
    function GetDisplayName: string; override;
    procedure DefineProperties( Filer: TFiler ); override;
  public
    procedure Clear;
    procedure LoadFromFile( FileName: string );
    procedure SaveToFile( FileName: string );
    procedure LoadFromStream( Stream: TStream );
    procedure SaveToStream( Stream: TStream );
    constructor Create(Collection: TCollection); override;
    procedure Assign(Source: TPersistent); override;
    property Owner : TAHMWaveHolder read FAHMWaveHolder;
    property DisplayName : String read GetDisplayName;
    destructor Destroy; override;
    function Play : Boolean;
  published
    property Asynchronous : Boolean read FAsynchronous write SetAsynchronous default True;
    property Looped : Boolean read FLooped write SetLooped;
    property Wave: String read FWave write SetWave;
  end;
  TAHMInternalWaves = class(TCollection)
  private
    FAHMWaveHolder : TAHMWaveHolder;
    function GetAHMInternalWave(Index: Integer): TAHMInternalWave;
    procedure SetAHMInternalWave(Index: Integer; Value: TAHMInternalWave);
  protected
    function GetOwner : TPersistent; override;
  public
    constructor Create(AOwner: TAHMWaveHolder);
    function Add : TAHMInternalWave;
    function Delete(Index :Integer) :Boolean;
    property Owner : TAHMWaveHolder read FAHMWaveHolder;
    property Items[Index: Integer]: TAHMInternalWave
             read GetAHMInternalWave write SetAHMInternalWave; default;
  end;
  TAHMWaveHolder = class(TAHMSystemsComponent)
  private
    FAHMInternalWaves : TAHMInternalWaves;
    FAHMExternalWaves : TAHMExternalWaves;
    procedure SetAHMExternalWaves(Value: TAHMExternalWaves);
    procedure SetAHMInternalWaves(Value: TAHMInternalWaves);
  protected
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    Function PlayInternal(Index : Integer) : Boolean;
    Function PlayExternal(Index: Integer): Boolean;    
    procedure StopSounds;
  published
    property Internals: TAHMInternalWaves read FAHMInternalWaves write SetAHMInternalWaves;
    property Externals: TAHMExternalWaves read FAHMExternalWaves write SetAHMExternalWaves;
  end;

implementation

constructor TAHMExternalWave.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FAHMWaveHolder :=(((Collection as TAHMExternalWaves).GetOwner) as TAHMWaveHolder);
  FAsynchronous:=True;
  FLooped:=False;
end;

function TAHMExternalWave.GetDisplayName: string;
begin
  if FFileName<>'' then
  Result := ExtractFileName(FFIleName)
  else Result:='No Wave specified';
end;

function TAHMExternalWaves.GetOwner: TPersistent;
begin
  Result := FAHMWaveHolder;
end;

procedure TAHMExternalWave.Assign(Source: TPersistent);
begin
  if Source is TAHMExternalWave then
  begin
    WavFileName := TAHMExternalWave(Source).WavFileName;
    Asynchronous := TAHMExternalWave(Source).Asynchronous;
    Looped := TAHMExternalWave(Source).Looped;
    Exit;
  end;
  inherited Assign(Source);
end;

constructor TAHMExternalWaves.Create(AOwner: TAHMWaveHolder);
begin
  inherited Create(TAHMExternalWave);
  FAHMWaveHolder := AOwner;
end;

function TAHMExternalWaves.Add: TAHMExternalWave;
begin
  Result := TAHMExternalWave(inherited Add);
end;

function TAHMExternalWaves.GetAHMExternalWave(Index: Integer): TAHMExternalWave;
begin
  Result := TAHMExternalWave(inherited GetItem(Index));
end;

procedure TAHMExternalWaves.SetAHMExternalWave(Index: Integer; Value: TAHMExternalWave);
begin
  inherited SetItem(Index, Value);
end;

procedure TAHMWaveHolder.SetAHMExternalWaves(Value: TAHMExternalWaves);
begin
  FAHMExternalWaves.Assign(Value);
end;

function TAHMExternalWaves.Delete(Index: Integer): Boolean;
begin
  result := true;
  Try
    Items[Index].free;
  Except
    result := false;
    Application.handleexception(self);
  End;
end;

constructor TAHMInternalWave.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FAHMWaveHolder :=(((Collection as TAHMInternalWaves).GetOwner) as TAHMWaveHolder);
  FAsynchronous := True;
  FWaveData := TMemoryStream.Create;
end;

Destructor TAHMInternalWave.Destroy;
begin
  FWaveData.Free;
  inherited Destroy;
end;

function TAHMInternalWave.GetDisplayName: string;
begin
  if FWave<>'' then Result := FWave else Result := 'No Wave Stored';
end;

function TAHMInternalWaves.GetOwner: TPersistent;
begin
  Result := FAHMWaveHolder;
end;

procedure TAHMInternalWave.Assign(Source: TPersistent);
var TS: TMemoryStream;
begin
  ts := TMemoryStream.Create;
  FWave := TAHMInternalWave(Source).FWave;
  TAHMInternalWave(Source).SaveToStream(Ts);
  FWaveData.LoadFromStream(ts);
  Ts.Destroy;
end;

constructor TAHMInternalWaves.Create(AOwner: TAHMWaveHolder);
begin
  inherited Create(TAHMInternalWave);
  FAHMWaveHolder := AOwner;
end;

function TAHMInternalWaves.Add: TAHMInternalWave;
begin
  if (csDesigning in FAHMWaveHolder.Componentstate) then
       Result := TAHMInternalWave(inherited Add)
  else Result:=nil;
end;

function TAHMInternalWaves.GetAHMInternalWave(Index: Integer): TAHMInternalWave;
begin
  Result := TAHMInternalWave(inherited GetItem(Index));
end;

procedure TAHMInternalWaves.SetAHMInternalWave(Index: Integer; Value: TAHMInternalWave);
begin
  inherited SetItem(Index, Value);
end;

constructor TAHMWaveHolder.Create(AOwner: TComponent);
begin
  inherited create(AOwner);
  FAHMInternalWaves:=TAHMInternalWaves.Create(self);
  FAHMExternalWaves:=TAHMExternalWaves.Create(self);
end;

destructor TAHMWaveHolder.Destroy;
begin
  FAHMExternalWaves.Free;
  FAHMInternalWaves.Free;
  inherited Destroy;
end;

function TAHMWaveHolder.PlayInternal(Index: Integer): Boolean;
begin
  if (Index<=Internals.Count-1) and (Index>-1) then
  result:=Internals[Index].Play else Result:=False;
end;

function TAHMWaveHolder.PlayExternal(Index: Integer): Boolean;
begin
  if (Index<=Externals.Count-1) and (Index>-1) then
  result:=Externals[Index].Play else Result:=False;
end;


procedure TAHMWaveHolder.SetAHMInternalWaves(Value: TAHMInternalWaves);
begin
  FAHMInternalWaves.Assign(Value);
end;

function TAHMInternalWaves.Delete(Index: Integer): Boolean;
begin
  result := true;
  Try
    Items[Index].free;
  Except
    result := false;
    Application.handleexception(self);
  End;
end;

procedure TAHMInternalWave.DefineProperties(Filer: TFiler);
begin
  Filer.DefineBinaryProperty( 'FileContents',ReadData,WriteData,FWaveData<>nil);
end;

procedure TAHMInternalWave.LoadFromFile(FileName: string);
var SearchRec: TSearchRec;
begin
  if FileExists( FileName ) then
  begin
    FindFirst( FileName, faAnyFile, SearchRec );
    FWaveData.LoadFromFile( FileName );
    FWave := ExtractFileName( FileName );
  end;
end;

procedure TAHMInternalWave.LoadFromStream(Stream: TStream);
begin
  FWaveData.LoadFromStream(Stream);
end;

procedure TAHMInternalWave.ReadData(Stream: TStream);
begin
  FWaveData.LoadFromStream(Stream);
end;

procedure TAHMInternalWave.SaveToFile(FileName: string);
begin
  if not(Empty) then FWaveData.SaveToFile( FileName );
end;

procedure TAHMInternalWave.SaveToStream(Stream: TStream);
begin
  TMemoryStream( Stream ).LoadFromStream(FWaveData);
end;

procedure TAHMInternalWave.WriteData(Stream: TStream);
begin
  FWaveData.SaveToStream(Stream);
end;

function TAHMInternalWave.Empty: boolean;
begin
  Result :=FWaveData.Size = 0;
end;

procedure TAHMInternalWave.Clear;
begin
  FWaveData.Clear;
  FWave:='';
end;

procedure TAHMInternalWave.SetWave(const Value: String);
begin
  if (csLoading in FAHMWaveHolder.Componentstate) then FWave:=Value;
end;

function TAHMInternalWave.Play: Boolean;
Var Flags : Integer;
begin
  result:=False;
  if FAsynchronous then
  begin
    Flags:=SND_Memory or SND_ASYNC OR SND_NoDefault;
    if FLooped then Flags:=Flags or SND_LOOP;
  end else Flags:=SND_Memory or SND_SYNC OR SND_NoDefault;
  if not(Empty) then result:=SndPlaySound(FWaveData.Memory,Flags);
end;

function TAHMExternalWave.Play: Boolean;
Var Flags : Integer;
begin
  result:=False;
  if FAsynchronous then
  begin
    Flags:=SND_ASYNC OR SND_NoDefault;
    if FLooped then Flags:=Flags or SND_LOOP;
  end else Flags:=SND_SYNC OR SND_NoDefault;
  if FileExists(FFileName) then result:=SndPlaySound(PChar(FFileName),Flags);
end;

procedure TAHMInternalWave.SetLooped(const Value: Boolean);
begin
  FLooped := Value;
end;

procedure TAHMWaveHolder.StopSounds;
begin
  SndPlaySound(nil,0)
end;

procedure TAHMInternalWave.SetAsynchronous(const Value: Boolean);
begin
  FAsynchronous := Value;
end;

procedure TAHMExternalWave.SetAsynchronous(const Value: Boolean);
begin
  FAsynchronous := Value;
end;

procedure TAHMExternalWave.SetFileName(const Value: String);
begin
  FFileName := Value;
end;

procedure TAHMExternalWave.SetLooped(const Value: Boolean);
begin
  FLooped := Value;
end;

end.
