unit Prefs;
interface
uses
	Windows, Geomet;

type
	TPrefScope = (psGlobal, psUser, psProject, psUserAndProject); 	//	Preferenses scope

const
	PrefScopeNames: array[TPrefScope] of String =
		('Global', 'User', 'Project', 'UserAndProject');

type

	TPrefs = class
	public
		function GetStr(aScope: TPrefScope; const anID, aKey,
			aDefault: string): string; virtual;
		procedure PutStr(aScope: TPrefScope; const anID, aKey,
			aValue: string); virtual;
		procedure Remove(aScope: TPrefScope; const anID, aKey: string); virtual;
		function  KeyExist(aScope: TPrefScope; const anID, aKey: string): Boolean; virtual; abstract;

		function GetInt(aScope: TPrefScope; const anID, aKey: string;
			aDefault: Longint): Longint;
		procedure PutInt(aScope: TPrefScope; const anID, aKey: string;
			aValue: Longint);
		function GetID(aScope: TPrefScope; const anID, aKey: string;
			const aDefault: String): String;
		procedure PutID(aScope: TPrefScope; const anID, aKey: string;
			const aValue: String);
		function GetBool(aScope: TPrefScope; const anID, aKey: string;
			aDefault: Boolean): Boolean;
		procedure PutBool(aScope: TPrefScope; const anID, aKey: string;
			aValue: Boolean);
		procedure PutBoolDef(aScope: TPrefScope; const anID, aKey: string;
			aValue, aDefValue: Boolean);
		function GetDouble(aScope: TPrefScope; const anID, aKey: string;
			aDefault: Double): Double;
		procedure PutDouble(aScope: TPrefScope; const anID, aKey: string;
			aValue: Double);
		function GetRect(aScope: TPrefScope; const anID, aKey: String;
			aDefault: TRect): TRect;
		procedure PutRect(aScope: TPrefScope; const anID, aKey: String;
			aValue: TRect);
		function GetDRect(aScope: TPrefScope; const anID, aKey: String;
			aDefault: TDRect): TDRect;
		procedure PutDRect(aScope: TPrefScope; const anID, aKey: String;
			aValue: TDRect);
		function GetDPoint(aScope: TPrefScope; const anID, aKey: String;
			aDefault: TDPoint): TDPoint;
		procedure PutDPoint(aScope: TPrefScope; const anID, aKey: String;
			aValue: TDPoint);
	end;

implementation
uses
	SysUtils, InSysUtils, AClasses;
	
function TPrefs.GetStr(aScope: TPrefScope; const anID: String; const aKey,
	aDefault: string): string;
begin
	Result := aDefault;
end;

procedure TPrefs.PutStr(aScope: TPrefScope; const anID: String; const aKey,
	aValue: string);
begin
end;

procedure TPrefs.Remove(aScope: TPrefScope; const anID: String; const aKey: string);
begin
end;

function TPrefs.GetInt(aScope: TPrefScope; const anID: String; const aKey: string;
	aDefault: Longint): Longint;
begin
	Result := StrToInt(GetStr(aScope, anID, aKey, IntToStr(aDefault)));
end;

procedure TPrefs.PutInt(aScope: TPrefScope; const anID: String; const aKey: string;
	aValue: Longint);
begin
	PutStr(aScope, anID, aKey, IntToStr(aValue));
end;

function TPrefs.GetID(aScope: TPrefScope; const anID: String; const aKey: string;
	const aDefault: String): String;
begin
	Result := GetStr(aScope, anID, aKey, aDefault);
end;

procedure TPrefs.PutID(aScope: TPrefScope; const anID: String; const aKey: string;
	const aValue: String);
begin
	PutStr(aScope, anID, aKey, aValue);
end;


const
	BoolChar: array [Boolean] of Char = ('0', '1');

function TPrefs.GetBool(aScope: TPrefScope; const anID: String; const aKey: string;
	aDefault: Boolean): Boolean;
begin
	Result := GetStr(aScope, anID, aKey, BoolChar[aDefault]) = '1';
end;

procedure TPrefs.PutBool(aScope: TPrefScope; const anID: String; const aKey: string;
	aValue: Boolean);
begin
	PutStr(aScope, anID, aKey, BoolChar[aValue]);
end;

procedure TPrefs.PutBoolDef(aScope: TPrefScope; const anID, aKey: string;
	aValue, aDefValue: Boolean);
begin
	if aValue = aDefValue then
		Remove(aScope, anID, aKey)
	else
		PutBool(aScope, anID, aKey, aValue);
end;

function TPrefs.GetDouble(aScope: TPrefScope; const anID: String; const aKey: string;
	aDefault: Double): Double;
begin
	Result := StringToFloat(GetStr(aScope, anID, aKey, FloatToStr(aDefault)));
end;

procedure TPrefs.PutDouble(aScope: TPrefScope; const anID: String; const aKey: string;
	aValue: Double);
begin
	PutStr(aScope, anID, aKey, FloatToStr(aValue));
end;

function TPrefs.GetRect(aScope: TPrefScope; const anID: String; const aKey: String;
	aDefault: TRect): TRect;
var
	s: String;
	aScan: TStrScan;

	function FetchValue(aDef: Integer): Integer;
	begin
		if aScan.FetchNumbers then
			Result := StrToInt(aScan.Token)
		else
			Result := aDef;
	end;

begin
	s := GetStr(aScope, anID, aKey, '');
	aScan.Init(s);
	Result.Left := FetchValue(aDefault.Left);
	Result.Top := FetchValue(aDefault.Top);
	Result.Right := FetchValue(aDefault.Right);
	Result.Bottom := FetchValue(aDefault.Bottom);
end;

procedure TPrefs.PutRect(aScope: TPrefScope; const anID: String; const aKey: String;
	aValue: TRect);
begin
	with aValue do
		PutStr(aScope, anID, aKey, Format('%d %d %d %d', [Left, Top, Right, Bottom]));
end;

function TPrefs.GetDRect(aScope: TPrefScope; const anID: String; const aKey: String;
	aDefault: TDRect): TDRect;
var
	s: String;
	aScan: TStrScan;

	function FetchValue(aDef: Double): Double;
	begin
		if aScan.FetchFloat then
			Result := StringToFloat(aScan.Token)
		else
			Result := aDef;
	end;

begin
	s := GetStr(aScope, anID, aKey, '');
	aScan.Init(s);
	Result.X1 := FetchValue(aDefault.X1);
	Result.Y1 := FetchValue(aDefault.Y1);
	Result.X2 := FetchValue(aDefault.X2);
	Result.Y2 := FetchValue(aDefault.Y2);
end;

procedure TPrefs.PutDRect(aScope: TPrefScope; const anID: String; const aKey: String;
	aValue: TDRect);
begin
	with aValue do
		PutStr(aScope, anID, aKey, Format('%f %f %f %f', [X1, Y1, X2, Y2]));
end;


function TPrefs.GetDPoint(aScope: TPrefScope; const anID: String; const aKey: String;
	aDefault: TDPoint): TDPoint;
var
	s: String;
	aScan: TStrScan;

	function FetchValue(aDef: Double): Double;
	begin
		if aScan.FetchFloat then
			Result := StringToFloat(aScan.Token)
		else
			Result := aDef;
	end;

begin
	s := GetStr(aScope, anID, aKey, '');
	aScan.Init(s);
	Result.X := FetchValue(aDefault.X);
	Result.Y := FetchValue(aDefault.Y);
end;

procedure TPrefs.PutDPoint(aScope: TPrefScope; const anID: String; const aKey: String;
	aValue: TDPoint);
begin
	with aValue do
		PutStr(aScope, anID, aKey, Format('%f %f', [X, Y]));
end;

end.
