{****************************************************************************
 ***                                                                      ***
 *** New Fabbo Singing Dancing OOP                                        ***
 ***                          COMPUTER SUPPORT                            ***
 ***                                                             Nov 1992 ***
 *** M Hill                                                  Rev Aug 1996 ***
 ****************************************************************************}
{combined hardware/software details, maybe site visits, etc}
{$I compdirs}  {Compiler directives}

unit KCompSup;

INTERFACE

uses  files,
			global, objects, scodes, dattime, views, jimmys, devices, forms,
			notes,
			ordproc,
			tuiedit;

const
 HWIndexItemSize = 30; 					{Hardware ID length for the id index}

type
	PHardWare = ^THardWare;
	THardWare = object(TJimmy)

		ForWho : longint;

		MachType  : TSCode;               {Just 3 char string for now}
		Make      : TSCode;
		Model     : string[15];
		Quantity  : byte;
		SerialNo  : string[20];
		DOI       : TDate;             {Date of installation}
		Warranty  : string[20];
		DOExpiry  : TDate;             {Date of Expiry (of Warranty!)}

		RAMQuant  : string[5];
		RAMType   : TScode;               {SIMMS or SIPPS for now}
		Graphics  : string[10];          {Graphics type}
		GraphicsRAM : string[5];         {RAM on board}
		MonMake   : string[15];
		MonModel  : string[15];
		MonSerialNo : string[10];
		DriveA   : TSCode;
		DriveB   : TSCode;
		HDiskMake  : string[15];
		HDiskCap   : string[5];
		HDiskType  : string[20];             {BIOS type...}
		Notes    	: PFreeTextData;

		WarrantyIdx : longint;

		{-- Methods --}
		constructor INit(Param : PJimmyInitParam);              {Params not actually used}
		procedure CommonInit; virtual;
		destructor Done; virtual;

		function DisplayLine(ListForWho : longint; lstype : byte; Maxlen : integer; View : word) : string; virtual;
		procedure MakeEditBox(var EditBox : PEditBox; Caller : PView);  virtual;

		function GetName(naType : byte; Maxlen : integer) : string; virtual; {used for various displays/prints -}

		procedure SetFormCodes(const FormCodes: PFormCodeCollection); virtual;
		procedure PrintSummary(const Device : PDeviceStream; const PrintAs : word); virtual;
		procedure PrintLine(const Device : PDeviceStream); virtual;

		{DataBase}
		constructor Load(var S : TDataStream);
		procedure   StoreFields(var S : TDataSTream); virtual;

		{for fixit, etc}
		function NumIDs : byte; virtual; {the number of jimmy ID ptrs in the data}
		function GetJimmyID(const jiType : byte) : PLongint; virtual; {each jimmy ID}

		{--- Indexing ----}
		function NumixTypes : byte; virtual;
		procedure GetIndex(const ixType : byte; var IdxRec : Plongint; var fiType : byte); virtual;
		function GetIndexKey(const ixType : byte) : string; virtual;

		{-- Hooking to others -----}
		function NumHookTo : byte; virtual;
		procedure GetHookTo(const htType : byte; var HookToID,SubHookToID : PLongint;
												var hkType : byte; var Key : longint; var InsertBias : boolean); virtual;

		function srType : word; virtual;
		function RecSize : word;virtual;

 end;

type
	PSoftware = ^TSoftware;
	TSoftware = object(TJimmy)

		ForWho : longint;

		Title     : string[11];               {scodes}
		Version   : string[15];
		Quantity  : byte;
		SerialNo  : string[20];
		DOI       : TDate;             {Date of installation}
		Warranty  : string[10];
		DOExpiry  : TDate;             {Date of Expiry (of Warranty!)}

		Notes			: PFreeTextData;

		{-- Methods --}
		constructor INit(Param : PJimmyInitParam);              {Params not actually used}
		procedure CommonInit; virtual;
		destructor Done; virtual;

		function DisplayLine(ListForWho : longint; lstype : byte; Maxlen : integer; View : word) : string; virtual;
		procedure MakeEditBox(var EditBox : PEditBox; Caller : PView); virtual;

		procedure SetFormCodes(const FormCodes: PFormCodeCollection); virtual;
		procedure PrintSummary(const Device : PDeviceStream; const PrintAs : word); virtual;
		procedure PrintLine(const Device : PDeviceStream); virtual;

		{DataBase}
		constructor Load(var S : TDataStream);
		procedure   StoreFields(var S : TDataSTream); virtual;

		{for fixit, etc}
		function NumIDs : byte; virtual; {the number of jimmy ID ptrs in the data}
		function GetJimmyID(const jiType : byte) : PLongint; virtual; {each jimmy ID}

		{-- Hooking to others -----}
		function NumHookTo : byte; virtual;
		procedure GetHookTo(const htType : byte; var HookToID,SubHookToID : PLongint;
												var hkType : byte; var Key : longint; var InsertBias : boolean); virtual;

		function srType : word; virtual;
		function RecSize : word; virtual;

 end;

	{==== PICK HARDWARE FOR JOB SHEETS ===============}
	PPickHWOrderItem = ^TPickHWOrderItem;
	TPickHWOrderItem = object(TOrderItem)

		HardwareID : longint;

		constructor Init(Param : PJimmyInitParam);

		procedure MakeEditBox(var EditBox : PEditBox; Caller : PView); virtual;

		{--- Viewing -----}
		function DisplayLine(ListForWho : longint; lstype : byte; Maxlen : integer; View : word) : string; virtual;

		{--- Database ----}
		function RecSize : word; virtual; {space to be reserved in jimmy file}
		function srType : word; virtual; {descendants set as fixed, so can be
																			used to identify jimmy for file operations, etc}


		procedure Storefields(var S : TDataStream); virtual;
		constructor Load(var S : TDataStream);

		function FormRoot : string; virtual; {for specifying CODED, FTEXT, etc for printing item}
		procedure SetFormCodes(const FormCodes: PFormCodeCollection); virtual;

		procedure PrintSummary(const Device : PDeviceStream; const PrintAs : word); virtual;
		procedure PrintLine(const Device : PDeviceStream); virtual;

		{for fixit, etc}

		function NumIDs : byte; virtual; {the number of jimmy ID ptrs in the data}
		function GetJimmyID(const jiType : byte) : PLongint; virtual; {each jimmy ID}
	end;



IMPLEMENTATION

uses inpdnt, dialogs, minilib,
			idindex, indexes,
			jimHooks,
			jimindxs,
			help,
			kdirctry,
			menus, tasks, tuiapp, drivers, {task registration}
			app,
			lstrings,
			tui,
			dbg,
			inpjimmy,
			tuijimmy, tuimsgs;


{**************************************************************
 ***                                                        ***
 ***               DEFINE HardWare OBJECT                     ***
 ***                                                        ***
 **************************************************************}

constructor THardWare.Init;
begin
	 inherited INit;

	 if Param<>nil then ForWho := Param^.ForWho;

	 Quantity := 1;  {Default}
end;

procedure THardWare.CommonInit;
{Basically makes sure they are open, and opens them if not}
begin
	inherited CommonInit;
	SCodeCollection[SCMachineType]^.LogOn;
	SCodeCollection[SCMachineMake]^.LogOn;
	SCodeCollection[SCFloppyType ]^.LogOn;
	SCodeCollection[SCRAMType    ]^.LogOn;
	New(Notes, init);
end;

destructor THardWare.Done;
begin
	dispose(Notes, done);
	SCodeCollection[SCMachineType]^.LogOff;
	SCodeCollection[SCMachineMake]^.LogOff;
	SCodeCollection[SCFloppyType ]^.LogOff;
	SCodeCollection[SCRAMType    ]^.LogOff;
	inherited Done;
end;


{==== CREATE DISPLAY-LINE-FORMAT STRING ============}
function THardWare.DisplayLine;
var S : string;

begin
 S := UCase(SCodeCollection[SCMachineType]^.Desc(MachType))
			+ ' ' + SCodeCollection[SCMachineMake]^.Desc(Make)
			+ ' ' + delspace(Model) + ' ' + delspace(serialNo) + ' '+Delspace(Warranty)+' ';

	if DOExpiry.Blank then S := S + 'NO CONTRCT'
	else if Today.Days>DOExpiry.Days then S := S + 'EXPIRED';

	DisplayLine := S;
end;

function THardWare.GetName;
var S : string;
begin
	S := SCodeCollection[SCMachineType]^.Desc(MachType) +
				SCodeCollection[SCMachineMake]^.Desc(Make) + ' '+ Model;

	if Maxlen<>0 then GetName :=Copy(S,1,Maxlen) else GetName := S;
end;


{*****************************************
 ***        SCREEN INPUT BOX           ***
 *****************************************}

procedure THardWare.MakeEditBox;
var
	R: TRect;
	I : integer;
	S : String;

begin
	R.Assign(0,0,68,20);
	EditBox := New(PJimmyEditBox, init(R, 'Hardware Details',Caller,@Self));
	inherited MakeEditBox(EditBox, Caller);

	with EditBox^ do begin
		Insert(New(PSkipBytes, init(4))); {skip forwho}

		InsTitledField(11, 2,20, 1, 'Type', 			New(PInputSCode, Init(R, scMachineType)));  {Replace with sentence code}
		InsTitledField(11, 3,15, 1, 'Make', 			New(PInputSCode, Init(R, scMachineMake)));
		InsTitledField(11, 4,15, 1, 'Model', 			New(PInputELine, Init(R, 15)));
		InsTitledField(11, 5, 5, 1, 'Quantity', 	New(PInputByte, Init(R, 5)));
		InsTitledField(11, 6,20, 1, 'Serial #', 	New(PInputELine, Init(R, 20)));
		InsTitledField(11, 7,10, 1, 'DOInst', 		New(PInputDate, Init(R)));
		InsTitledField(11, 8,20, 1, 'Maint'#39'ce', New(PInputELine, Init(R, 20)));
		InsTitledField(11, 9,10, 1, 'DOExp', 			New(PInputDate, Init(R)));

		InsTitledField(11,11, 5, 1, 'RAM Qty', 		New(PInputELine, Init(R, 5)));
		InsTitledField(11,12,15, 1, '   Type', 		New(PInputSCode, Init(R, scRAMType)));   {Replace with SCOde}

		InsTitledField(44, 2,10, 1, 'Graphics', 	New(PInputELine, Init(R, 10)));
		InsTitledField(44, 3, 5, 1, 'RAM', 				New(PInputELine, Init(R, 5)));

		InsTitledField(44, 4,15, 1, 'Mon. Make', 	New(PInputELine, Init(R, 15)));
		InsTitledField(44, 5,15, 1, 'Model', 			New(PInputELine, Init(R, 15)));
		InsTitledField(44, 6,10, 1, 'Serial #', 	New(PInputELine, Init(R, 10)));

		InsTitledField(44, 8,20, 1, 'Drive A', 		New(PInputSCode, Init(R, SCFloppyType)));
		InsTitledField(44, 9,20, 1, '      B', 		New(PInputSCode, Init(R, SCFloppyType)));
		InsTitledField(44,10,15, 1, 'Hard Disk Make', New(PInputELine, Init(R, 15)));
		InsTitledField(44,11, 5, 1, 'Capacity', 	New(PInputELine, Init(R, 5)));
		InsTitledField(44,12,20, 1, 'Type', 			New(PInputELine, Init(R, 20)));

		R.XYLD(11,15,30,4); Insert(New(PInputFreeText, Init(R,200,30,nil)));
		AddLabel('~E~xtras', Current);
		Insert(PInputFreeText(Current)^.VScrollBar);

		{-- Buttons --}
		Insert(New(PJimmyOKButton, Init(45,17, @Self)));
		InsCancelButton(55,17);

		EndInit;
	end;
end;


{*****************************************
 ***     STREAMING DEFINITIONS         ***
 *****************************************}
function THardware.RecSize;
begin RecSize := 250; end;

function THardware.srType;
begin srTYpe := srHardware; end;

constructor THardWare.Load;
var I : integer;
		Ver : byte;
		TL : longint; {Rubbish longint}
		TS : string;  {Temporary string}

begin
	S.Read(Ver, 1);
	case Ver of
		6 : begin
			{v4.3a - changed extras to freetext}
			inherited Load(S);

			S.Read(MachType   ,sizeof(MachType));               {Just 3 char string for now}
			S.Read(SerialNo   ,sizeof(SerialNo));
			S.Read(Make       ,sizeof(Make));
			S.Read(Model      ,sizeof(Model));
			S.Read(Quantity,   sizeof(Quantity));
			DOI.Load(S);                              {Date of installation}
			S.Read(Warranty   ,sizeof(Warranty));
			DOExpiry.Load(S);
			S.Read(RAMType    ,sizeof(RAMType));      {SIMMS or SIPPS for now}
			S.Read(RAMQuant   ,sizeof(RAMQuant));
			S.Read(Graphics   ,sizeof(Graphics));          {Graphics type}
			S.Read(GraphicsRAM,sizeof(GraphicsRAM));         {RAM on board}
			S.Read(MonMake    ,sizeof(MonMake));
			S.Read(MonModel   ,sizeof(MonModel));
			S.Read(MonSerialNo,sizeof(MonSerialNo));
			S.Read(DriveA     ,sizeof(DriveA));
			S.Read(DriveB     ,sizeof(DriveB));
			S.Read(HDiskMake  ,sizeof(HDiskMake));  {}
			S.Read(HDiskCap   ,sizeof(HDiskCap));
			HDiskType := S.ReadStr;
			Notes^.Load(S);
			S.Read(ForWho, 4);
		end;
		5 : begin
			{v4.1}
			inherited Load(S);

			S.Read(MachType   ,sizeof(MachType));               {Just 3 char string for now}
			S.Read(SerialNo   ,sizeof(SerialNo));
			S.Read(Make       ,sizeof(Make));
			S.Read(Model      ,sizeof(Model));
			S.Read(Quantity,   sizeof(Quantity));
			DOI.Load(S);                              {Date of installation}
			S.Read(Warranty   ,sizeof(Warranty));
			DOExpiry.Load(S);
			S.Read(RAMType    ,sizeof(RAMType));      {SIMMS or SIPPS for now}
			S.Read(RAMQuant   ,sizeof(RAMQuant));
			S.Read(Graphics   ,sizeof(Graphics));          {Graphics type}
			S.Read(GraphicsRAM,sizeof(GraphicsRAM));         {RAM on board}
			S.Read(MonMake    ,sizeof(MonMake));
			S.Read(MonModel   ,sizeof(MonModel));
			S.Read(MonSerialNo,sizeof(MonSerialNo));
			S.Read(DriveA     ,sizeof(DriveA));
			S.Read(DriveB     ,sizeof(DriveB));
			S.Read(HDiskMake  ,sizeof(HDiskMake));  {}
			S.Read(HDiskCap   ,sizeof(HDiskCap));
			HDiskType := S.ReadStr;
			for I := 1 to 4 do begin
				TS := S.ReadStr;
				if TS<>'' then LSAppendStr(Notes^.Text, TS+EndParaChar+CRLF);
			end;
			S.Read(ForWho, 4);
		end;
		4 : begin
			{New Jimmy item structure}
			CommonInit;
			S.Read(MachType   ,sizeof(MachType));               {Just 3 char string for now}
			S.Read(SerialNo   ,sizeof(SerialNo));
			S.Read(Make       ,sizeof(Make));
			S.Read(Model      ,sizeof(Model));
			S.Read(Quantity,   sizeof(Quantity));
			DOI.Load(S);                              {Date of installation}
			S.Read(Warranty   ,sizeof(Warranty));
			DOExpiry.Load(S);
			S.Read(RAMType    ,sizeof(RAMType));      {SIMMS or SIPPS for now}
			S.Read(RAMQuant   ,sizeof(RAMQuant));
			S.Read(Graphics   ,sizeof(Graphics));          {Graphics type}
			S.Read(GraphicsRAM,sizeof(GraphicsRAM));         {RAM on board}
			S.Read(MonMake    ,sizeof(MonMake));
			S.Read(MonModel   ,sizeof(MonModel));
			S.Read(MonSerialNo,sizeof(MonSerialNo));
			S.Read(DriveA     ,sizeof(DriveA));
			S.Read(DriveB     ,sizeof(DriveB));
			S.Read(HDiskMake  ,sizeof(HDiskMake));  {}
			S.Read(HDiskCap   ,sizeof(HDiskCap));
			HDiskType := S.ReadStr;
			for I := 1 to 4 do begin
				TS := S.ReadStr;
				if TS<>'' then LSAppendStr(Notes^.Text, TS+EndParaChar+CRLF);
			end;

			WarrantyIDx := -1;
			S.Read(ForWho, 4);
		end;
		3 : begin
			CommonInit;
			{changed make into sentence code}
			S.Read(MachType   ,sizeof(MachType));               {Just 3 char string for now}
			S.Read(SerialNo   ,sizeof(SerialNo));
			S.Read(Make       ,sizeof(Make));
			S.Read(Model      ,sizeof(Model));
			S.Read(Quantity,   sizeof(Quantity));
			DOI.Load(S);                              {Date of installation}
			S.Read(Warranty   ,sizeof(Warranty));
			DOExpiry.Load(S);
			S.Read(RAMType    ,sizeof(RAMType));      {SIMMS or SIPPS for now}
			S.Read(RAMQuant   ,sizeof(RAMQuant));
			S.Read(Graphics   ,sizeof(Graphics));          {Graphics type}
			S.Read(GraphicsRAM,sizeof(GraphicsRAM));         {RAM on board}
			S.Read(MonMake    ,sizeof(MonMake));
			S.Read(MonModel   ,sizeof(MonModel));
			S.Read(MonSerialNo,sizeof(MonSerialNo));
			S.Read(DriveA     ,sizeof(DriveA));
			S.Read(DriveB     ,sizeof(DriveB));
			S.Read(HDiskMake  ,sizeof(HDiskMake));  {}
			S.Read(HDiskCap   ,sizeof(HDiskCap));
			HDiskType := S.ReadStr;
			for I := 1 to 4 do begin
				TS := S.ReadStr;
				if TS<>'' then LSAppendStr(Notes^.Text, TS+EndParaChar+CRLF);
			end;

			S.Read(TL, 4); {old ptr2cha}

			S.Read(ForWho, 4);
			WarrantyIDx := -1;
		end;
		2 : begin
			CommonInit;
			S.Read(MachType   ,sizeof(MachType));               {Just 3 char string for now}
			S.Read(SerialNo   ,sizeof(SerialNo));
			S.Read(TS       ,16); Make := UCase(Copy(TS, 1, 3));
			S.Read(Model      ,sizeof(Model));
			S.Read(Quantity,   sizeof(Quantity));
			DOI.Load(S);                              {Date of installation}
			S.Read(Warranty   ,sizeof(Warranty));
			DOExpiry.Load(S);
			S.Read(RAMType    ,sizeof(RAMType));      {SIMMS or SIPPS for now}
			S.Read(RAMQuant   ,sizeof(RAMQuant));
			S.Read(Graphics   ,sizeof(Graphics));          {Graphics type}
			S.Read(GraphicsRAM,sizeof(GraphicsRAM));         {RAM on board}
			S.Read(MonMake    ,sizeof(MonMake));
			S.Read(MonModel   ,sizeof(MonModel));
			S.Read(MonSerialNo,sizeof(MonSerialNo));
			S.Read(DriveA     ,sizeof(DriveA));
			S.Read(DriveB     ,sizeof(DriveB));
			S.Read(HDiskMake  ,sizeof(HDiskMake));  {}
			S.Read(HDiskCap   ,sizeof(HDiskCap));
			HDiskType := S.ReadStr;
			for I := 1 to 4 do begin
				TS := S.ReadStr;
				if TS<>'' then LSAppendStr(Notes^.Text, TS+EndParaChar+CRLF);
			end;

			S.Read(TL, 4); {old ptr2cha}

			S.Read(ForWho, 4);
			WarrantyIDx := -1;
		end;
		1 : begin
			CommonInit;
			S.Read(MachType   ,sizeof(MachType));               {Just 3 char string for now}
			S.Read(SerialNo   ,sizeof(SerialNo));
			S.Read(TS       ,16); Make := ucase(Copy(TS, 1, 3));
			S.Read(Model      ,sizeof(Model));
			Quantity := 1;
			DOI.Load(S);                              {Date of installation}
			S.Read(Warranty   ,sizeof(Warranty));
			DOExpiry.Load(S);
			S.Read(RAMType    ,sizeof(RAMType));      {SIMMS or SIPPS for now}
			S.Read(RAMQuant   ,sizeof(RAMQuant));
			S.Read(Graphics   ,sizeof(Graphics));          {Graphics type}
			S.Read(GraphicsRAM,sizeof(GraphicsRAM));         {RAM on board}
			S.Read(MonMake    ,sizeof(MonMake));
			S.Read(MonModel   ,sizeof(MonModel));
			S.Read(MonSerialNo,sizeof(MonSerialNo));
			S.Read(DriveA     ,sizeof(DriveA));
			S.Read(DriveB     ,sizeof(DriveB));
			S.Read(HDiskMake  ,sizeof(HDiskMake));  {}
			S.Read(HDiskCap   ,sizeof(HDiskCap));
			HDiskType := S.ReadStr;
			for I := 1 to 4 do begin
				TS := S.ReadStr;
				if TS<>'' then LSAppendStr(Notes^.Text, TS+EndParaChar+CRLF);
			end;

			S.Read(TL, 4); {old ptr2cha}
			{Up to 1st Dec 92}
			S.Read(ForWho, 4);
			WarrantyIDx := -1;

		end
	else
		DBaseMessage(@S, 'Version '+N2Str(Ver)+' not understood'#13#10'THardware.Load',mfError,hcInternalErrorMsg);
		fail;
	end;
{	Debug.Writeln('Read h/w item for: '+N2Str(ForWho));{}

end;

procedure THardWare.StoreFields;
var I : integer;
		Ver : byte;

begin
	Ver := 6; S.Write(ver ,1);

	inherited StoreFields(S);

	S.Write(MachType   ,sizeof(MachType));               {Just 3 char string for now}
	S.Write(SerialNo   ,sizeof(SerialNo));
	S.Write(Make       ,sizeof(Make));
	S.Write(Model      ,sizeof(Model));
	S.Write(Quantity,   sizeof(Quantity));
	DOI.Store(S);                              {Date of installation}
	S.Write(Warranty,   sizeof(Warranty));
	DOExpiry.Store(S);

	S.Write(RAMType    ,sizeof(RAMType));      {SIMMS or SIPPS for now}
	S.Write(RAMQuant   ,sizeof(RAMQuant));
	S.Write(Graphics   ,sizeof(Graphics));          {Graphics type}
	S.Write(GraphicsRAM,sizeof(GraphicsRAM));         {RAM on board}
	S.Write(MonMake    ,sizeof(MonMake));
	S.Write(MonModel   ,sizeof(MonModel));
	S.Write(MonSerialNo,sizeof(MonSerialNo));
	S.Write(DriveA     ,sizeof(DriveA));
	S.Write(DriveB     ,sizeof(DriveB));
	S.Write(HDiskMake  ,sizeof(HDiskMake));
	S.Write(HDiskCap   ,sizeof(HDiskCap));
	S.WriteStr(@HDiskType);
	Notes^.Store(S);

	S.Write(ForWho, 4);
end;

{============== POINTERS TO OTHER JIMMYS===================}
function THardware.NumIDs;
begin NumIDs := 1; end;

function THardware.GetJImmyID;
begin
	case jiType of
		1 : GetJImmyID := @ForWho;
	else
		GetJimmyID := nil;
	end;
end;

{--- Indexing ----}
function THardware.NumixTypes : byte;
begin NumixTypes := 1; end;

procedure THardware.GetIndex;
begin
	inherited getIndex(ixType, IdxRec, fiType);

	case ixType of
		1 : begin IdxRec := @WarrantyIdx; fitype := fiWarrantyIdx; end;
	end;
end;

function THardware.GetIndexKey;
begin
	GetIndexKey := '';
	case ixType of
		1 : GetIndexKey := ucase(Warranty);
	end;
end;

{-- Hooking to others -----}
function THardware.NumHookTo;
begin NumHookTo := 1; end; {only hooked to company's history}

{for returning which jimmys ID's this jimmys should be hooked *to*}
procedure THardware.GetHookTo;
begin
	inherited GetHookTo(htType, HookToID,SubHookToID, hkType, Key, InsertBias);
	Key := 10; {allow comments and alternative addresses to appear first}
	InsertBias := biStart;
	case htType of
		1 : begin
			HookToID := @ForWho;
			hkType := hkMore;
		end;
	end;
end;

{*******************************************
 ***            PRINT SUMMARY            ***
 *******************************************}
procedure THardware.SetFormCodes;
begin
	inherited SetFormCodes(FormCodes);
	with FormCodes^ do begin
		SetStr('TYPE', SCodeCollection[SCMachineType]^.Desc(Machtype));
		SetStr('MAKE', SCodeCollection[SCMachineMake]^.Desc(Make));
		SetStr('MODEL', Model);
		SetStr('QTY',	N2Str(Quantity));
		SetStr('SERNO',	SerialNo);
		SetStr('WARNO',	Warranty);
		SetDate('DOI', DOI);
		SetDate('DOE', DOExpiry);

		SetStr('RAMQ', RamQuant);
		SetStr('RAMT', SCodeCollection[scRamType]^.Desc(RamType));

		SetStr('GRAPH', Graphics);
		SetStr('GRAM', GraphicsRAM);

		SetStr('MMAKE', MonMake);
		SetStr('MMODEL', MonModel);
		SetStr('MSERNO', MonSerialNo);

		SetStr('A:', DriveA);
		SetStr('B:', DriveB);

		SetStr('HDMAKE', HDiskMake);
		SetStr('HDCAP', HDiskCap);
		SetStr('HDTYPE', HDiskType);

		Insert(new(PJimmyFormCode, init('FOR', ForWho)));

		Insert(New(PFreeTextFormCode, init('NOTES', Notes^)));

	end;
end;

procedure THardWare.PrintSummary;
var S : string;
		Printed : boolean; {flag}
		I : integer;
		DirectoryItem : PDirectoryItem;

begin
	case PrintAs of
		{for person details or job sheets}
		0,1 : with Device^ do begin

			{worksheet/job details}
			CheckForNewPage(+7);

			S :=ucase(SCodeCollection[SCMachineType]^.Desc(MachType))
					+ ': ' + SCodeCollection[SCMachineMake]^.Desc(Make)
					+ ' '+Model;
			if Quantity >1 then S := S + ' x'+N2Str(Quantity);  {Only put on xQuantity if more than one}
			S := PadSpaceR(S, 49)  + '  Ser No: '+ SerialNo;
			writeln(S);

			if delspace(Warranty)<>'' then writeln(Space(49)      + 'Warranty: '+Warranty);

			if (RamQuant+RamTYpe)<>space(length(RamQuant+RamType)) then
				S :='       RAM: '+RAMQuant + ' '+SCodeCollection[SCRAMType]^.Desc(RAMType)
			else
				S := '';
			if DOExpiry.Days >= Today.Days then
				writeln(PadSpaceR(S,49)+ ' Expires: '+DOExpiry.Digit10)
			else
				writeln(PadSpaceR(S,49)+ ' EXPIRED: '+DOExpiry.Digit10);

			if MachType = 'COM' then S :='  Graphics: '+Graphics + ' ' + GraphicsRAM else S:='';
			writeln(PadSpaceR(S,49)+ '     DOI: '+DOI.DIgit10);

			if MachType = 'COM' then begin {bit of a botch check I guess}
				writeln('   Monitor: ' + MonMake + ' ' + MonModel + ' ' + MonSerialNo);
				writeln('');

				S :='  Floppy A: ' + SCodeCollection[SCFloppyType]^.Desc(DriveA);
				writeln(PadSpaceR(S,40) + 'Hard Disk: ' + HDiskCap + ' ' + HDiskMake);

				S :='         B: ' + SCodeCollection[SCFloppyType]^.Desc(DriveB);
				writeln(PadSpaceR(S,40) + '     Type: ' + HDiskType);
			end;

			Printed := False; {Flag - set if any extras printed}
			for I := 1 to 4 do if LSGetLine(Notes^.Text,I)<>'' then begin
				if Printed = False then begin writeln(''); Printed := True; end; {put an extra spacer line in}
				writeln('      ' + LSGetLine(Notes^.Text, I));
				Printed := True;
			end;

		end; {if job/person}
	end; {case}
end;

procedure THardware.PrintLine;
var S : string;
begin
	{=== ONE-LINE PRINT - SUITABLE FOR REPORTS, ETC ===============}
	with Device^ do begin
		S :='  '+SCodeCollection[scMachineType]^.Desc(MachType)+', '
				 +SCodeCollection[scMachineMake]^.Desc(Make)+' '+Model;
		S := PadSpaceR(S, 38)+' '+SerialNo;
		S := PadSpaceR(S, 56)+' '; {pad up to "tab stop"}
		if DOExpiry.Blank then S := S+'NO ENTRY' else S:= S+DoExpiry.Digit8;
		S := S + ' '+Warranty;
{used for warranty report, this is unnecessary		S := S + ' '+ GetJimmyIDName(ForWho, naReport,0);	{print who owns it}
		writeln(S);
	end;
end; {proc}

{**************************************************
 ***             PICK HARDWARE                 ***
 **************************************************}
constructor TPickHWOrderItem.Init;
begin
	inherited Init(Param);
	HardwareID := -1;
end;


{======= DISPLAY LINE ====================}
function TPickHWOrderItem.DisplayLine;
var Jimmy : PJImmy;
begin
	Jimmy := GetJimmy(HardwareID);

	if Jimmy = nil then
		DisplayLine := 'Cant get Hardware ID '+N2Str(HardwareID)
	else begin
		DisplayLine := Jimmy^.DisplayLine(ListForWho, lstype, Maxlen, View);
		dispose(JImmy, done);
	end;
end;

function TPickHWOrderItem.FormRoot : string;
begin
	FormRoot := 'HWARE';
end;

{================ EDIT BOX ============================}
procedure TPickHWOrderItem.MakeEditBox;
var Bounds, R : TRect;
		Order : POrder;

begin
	Bounds.Assign(0, 0, 45,7);
	CentreOnView(Bounds, Caller);
	EditBox := New(PJimmyEditBox, init(Bounds, 'Pick Hardware',Caller,@Self));

	{----Position box, in centre of calling view----}
	with EditBox^ do begin
		Insert(New(PSkipBytes, init(sizeof(TOrderItem))));  {Skip detail fields & VMT}

		Order := POrder(GetJimmy(ForOrder));

		if Order=nil then
			ProgramError('Not attached to an order?'#13#10'TPickHWOrderItem.MakeEditBox',hcNoContext)
		else begin
			InsTitledField(10,  2, 29, 1, 'Hardware',	New(PInputHookedJimmy, Init(
						R,29,hkMore, lsMoreAbout, srHardware, Order^.ForWho)));
			PInputELine(Current)^.MustInput := True;
			PINputJimmy(Current)^.DoList := True;

			dispose(Order, done);

			{-- Buttons --}
			Insert(New(PJimmyOKButton, Init(2,Size.Y-3, @Self)));
		end;
		Insert(New(PjimmyCancelButton, init(12,Size.Y-3, @Self)));

		EndInit;
	end;

end;

{************************************
 ***         DATABASE             ***
 ************************************}
const
	{--- Required for Stream ----}
	RPickHWOrderItem : TStreamRec = (
		ObjType : srPickHWOrderItem;
		VmtLink : Ofs(TypeOf(TPickHWOrderItem)^);
		Load : @TPickHWOrderItem.Load;
		Store : @TPickHWOrderItem.Store
	);

function TPickHWOrderItem.RecSize;
begin RecSize := 100; end;

function TPickHWOrderItem.srType;
begin srType := srPickHWOrderItem; end;


{========== LOAD ===================}
constructor TPickHWOrderItem.Load;
var Ver : byte;
begin
	S.Read(Ver, 1);

	case Ver of
		1 : begin
			inherited Load(S);
			S.Read(HardwareID, 4);
		end;
	else
		DBaseMessage(@S,'Version '+N2Str(Ver)+' not known'#13'TPickHWOrderItem.Load', mfError,hcInternalErrorMsg)
	end;
end;

{========== STORE ===================}
procedure TPickHWOrderItem.StoreFields;
var
	ver : byte;

begin
	Ver := 1; S.Write(Ver, 1);

	inherited StoreFields(S);

	S.Write(HardwareID, 4);
end;


{============== POINTERS TO OTHER JIMMYS===================}
function TPickHWOrderItem.NumIDs;
begin NumIDs := 5; end;

function TPickHWOrderItem.GetJImmyID;
begin
	case jiType of
		5 : GetJimmyID := @HardwareID;
	else
		GetJimmyID := inherited GetJimmyID(jiType);
	end;
end;


procedure TPickHWOrderItem.SetFormCodes;
begin
	inherited SetFormCodes(FormCodes);

	FormCodes^.Insert(New(PJImmyFormCode, init('HW', HardwareID)));
end;

procedure TPickHWOrderItem.PrintSummary;
var HW : PHardware;
begin
	HW := PHardware(GetJimmy(HardwareID));
	if HW<>nil then begin
		HW^.PrintSummary(Device,PrintAs);
		dispose(Hw, done);
	end;
end;


procedure TPickHWOrderItem.PrintLine;
var HW : PHardware;
begin
	HW := PHardware(GetJimmy(HardwareID));
	if HW<>nil then begin
		HW^.PrintLine(Device);
		dispose(Hw, done);
	end;
end;


{**********************************************************************
 ***																																***
 ***                 SELECT BY ID                                   ***
 ***																																***
 **********************************************************************}
{Returns rec no of ID of owning person}
procedure FindHardwareByID;
var	ID : longint;
		Hardware : PHardware;

begin
{	ID := SearchIDIndex('Select Hardware','Maint #',fiHardwareIDIdx);

	{Even if not found, will locate at nearest}
	if ID<>-1 then begin
		FileAdmin(fiJimmys)^.LogOn;
		Hardware := PHardware(JimmyStream^.GetAt(ID));

		if (Hardware <> nil) and (typeof(Hardware^)=typeof(THardware)) then begin
			Hardware^.Edit(Desktop, nil);
			dispose(Hardware, done);
		end;

		FileAdmin(fiJimmys)^.LogOff;
	end;
end;


{**************************************************************
 ***                                                        ***
 ***               DEFINE Software OBJECT                   ***
 ***                                                        ***
 **************************************************************}

constructor TSoftware.Init;
begin
	 inherited INit;
	 if Param<>nil then ForWho := Param^.ForWho;
	 Quantity := 1;  {Default}
end;

procedure TSoftware.CommonInit;
{Basically makes sure they are open, and opens them if not}
begin
	inherited CommonInit;
	SCodeCollection[SCSoftwareTitle]^.LogOn;
	New(Notes, init);
end;

destructor TSoftware.Done;
begin
	dispose(Notes, done);
	SCodeCollection[scSoftwareTitle]^.LogOff;
	inherited Done;
end;

{==== CREATE DISPLAY-LINE-FORMAT STRING ============}
function TSoftware.DisplayLine;
var S : string;
		Today : TDate;
begin
	S := UCase(SCodeCollection[SCSoftwareTitle]^.Desc(Title))
			+ ' '+ Version +' ';
	if DOExpiry.Blank then S := S + 'NO CONTRCT'
		else begin
			Today.SetToToday;
			if Today.Days>DOExpiry.Days then S := S + 'SUPPORT EXPIRED'
				else if DOExpiry.Days<(Today.Days+30) then S := S + 'SUPPORT EXPIRES IN '+N2Str(DOExpiry.Days - Today.Days)+' DAYS';
		end;

	DisplayLine := S;
end;


{*****************************************
 ***        SCREEN INPUT BOX           ***
 *****************************************}

procedure TSoftware.MakeEditBox;
var
	R: TRect;

begin
	R.Assign(0, 0, 35, 14);
	EditBox := New(PJimmyEditBox, Init(R, 'Software Details',Caller,@Self));

	inherited MakeEditBox(EditBox, Caller);

	with EditBox^ do begin
		Insert(New(PSkipBytes, init(4)));

		InsTitledField(11, 2,20, 1,'Title',    New(PInputSCLine, Init(R, 11, scSoftwareTitle)));
		InsTitledField(11, 3,15, 1,'Version',  New(PInputELine, Init(R, 15)));
		InsTitledField(11, 5, 5, 1,'Quantity', New(PInputByte,  Init(R, 5)));
		InsTitledField(11, 6,20, 1,'Serial #', New(PInputELine, Init(R, 20)));
		InsTitledField(11, 7,10, 1,'DOInst',   New(PInputDate, Init(R)));
		InsTitledField(11, 8,10, 1,'Warranty', New(PInputELine, Init(R, 10)));
		InsTitledField(11, 9,10, 1,'DOExp',    New(PInputDate, Init(R)));

		R.XYLD(11,15,30,4); Insert(New(PInputFreeText, Init(R,200,30,nil)));
		AddLabel('~N~otes', Current);
		Insert(PInputFreeText(Current)^.VScrollBar);

		{-- Buttons --}
		Insert(New(PJimmyOKButton, Init(12,11, @Self)));
		InsCancelButton(23,11);

		EndInit;
	end;
end;

{*****************************************
 ***     STREAMING DEFINITIONS         ***
 *****************************************}
function TSoftware.RecSize;
begin RecSize := 100; end;

function TSoftware.srType;
begin srTYpe := srSoftware; end;

constructor TSoftware.Load(var S : TDataStream);
var Ver : byte;
		Rubbish : longint;

begin
	S.Read(Ver, 1);
	case Ver of
		1 : begin
			CommonInit;

			S.Read(Title,     sizeof(Title));
			S.Read(Version,   sizeof(Version));
			S.Read(Quantity,   sizeof(Quantity));
			DOI.Load(S);                              {Date of installation}
			DOExpiry.Load(S);
			S.Read(Warranty, sizeof(Warranty));

			S.Read(Rubbish, 4);

			S.REad(ForWho, 4);
			SerialNo := '';
		end;
		2 : begin
			CommonInit;

			S.Read(Title,     sizeof(Title));
			S.Read(Version,   sizeof(Version));
			S.Read(Quantity,   sizeof(Quantity));
			S.Read(SerialNo,   sizeof(SerialNo));
			DOI.Load(S);                              {Date of installation}
			S.Read(Warranty, sizeof(Warranty));
			DOExpiry.Load(S);

			S.Read(ForWho, 4);
		end;
		3 : begin
			inherited Load(S);
			S.Read(ForWho, 4);
			S.Read(Title, 4);
			Version := S.ReadStr;
			S.Read(Quantity, 1);
			SerialNo := S.ReadStr;
			DOI.Load(S);                              {Date of installation}
			Warranty := S.ReadStr;
			DOExpiry.Load(S);
		end;
		4 : begin
			{v4.3a, lengthened Title, added Notes}
			inherited Load(S);
			S.Read(ForWho, 4);
			Title := S.ReadStr;
			Version := S.ReadStr;
			S.Read(Quantity, 1);
			SerialNo := S.ReadStr;
			DOI.Load(S);                              {Date of installation}
			Warranty := S.ReadStr;
			DOExpiry.Load(S);
			Notes^.Load(S);
		end;
	else
		DBaseMessage(@S, 'Version '+N2Str(Ver)+' not understood'#13#10'TSoftware.Load',mfError,hcInternalErrorMsg);
		fail;
	end;
end;

procedure TSoftware.StoreFields(var S : TDataStream);
var	Ver : byte;
begin
	Ver := 4; S.Write(ver ,1);
	inherited StoreFields(S);  {Store chain & person pointers}

	S.Write(ForWho, 4);

	S.WriteStr(@Title);
	S.WriteStr(@Version);
	S.Write(Quantity, 1);
	S.WriteStr(@SerialNo);
	DOI.Store(S);                              {Date of installation}
	S.WriteStr(@Warranty);
	DOExpiry.Store(S);
	Notes^.Store(S);
end;

{============== POINTERS TO OTHER JIMMYS===================}
function TSoftware.NumIDs;
begin NumIDs := 1; end;

function TSoftware.GetJImmyID;
begin
	case jiType of
		1 : GetJImmyID := @ForWho;
	else
		GetJimmyID := nil;
	end;
end;



{-- Hooking to others -----}
function TSoftware.NumHookTo;
begin NumHookTo := 1; end; {only hooked to company's history}

{for returning which jimmys ID's this jimmys should be hooked *to*}
procedure TSoftware.GetHookTo;
begin
	inherited GetHookTo(htType, HookToID,SubHookToID, hkType, Key, InsertBias);
	Key := 10;
	InsertBias := biStart;
	case httype of
		1 : begin
			HookToID := @ForWho;
			hkType := hkMore;
		end;
	end;
end;



{**************************************************************
 ***                     PRINT                              ***
 **************************************************************}
procedure TSoftware.SetFormCodes;
begin
	inherited SetFormCodes(FormCodes);

	with FormCodes^ do begin
	end;
end;

procedure TSoftware.PrintSummary;
var S : string;

begin
	{==== PRINT SUMMARY - FOR JOB SHEETS, ETC =====================}
	with Device^ do begin
		S :=ucase(SCodeCollection[scSoftwareTitle]^.Desc(Title)) + ': ' + Version;
		if Quantity >1 then S := S + ' x'+N2Str(Quantity);  {Only put on xQuantity if more than one}
		S := PadSpaceR(S, 49)  + '  Ser No: '+ SerialNo;
		writeln(S);

		S := '     DOI: '+DOI.Text(daAbbr);
		writeln(PadSpaceR(S,49)+ ' Expires: '+DOExpiry.Text(daAbbr));
	end;
end;

procedure TSoftware.PrintLine;
var S : String;
begin
	{=== PRINT ONE-LINE - FOR REPORTS, ETC =========================}
	{Format matches hardware one-line report - title, serial no, expiry}
	S :='  '+SCodeCollection[scSoftwareTitle]^.Desc(Title) + ' ' + Version;
	if Quantity >1 then S := S + ' x'+N2Str(Quantity);  {Only put on xQuantity if more than one}
	S := PadSpaceR(S, 38) +' '+SerialNo;
	S := PadSpaceR(S, 56) +' ';
	S := S + DOExpiry.Digit8;
	Device^.Writeln(S);
end;


{**************************
 **    REG, ETC         ***
 **************************}
function CreateSoftware(P : pointer) : Pointer; far;
begin CreateSoftware := New(PSoftware, Init(P)); end;

function CreateHardWare(P : pointer) : pointer; far;
begin	CreateHardWare := New(PHardWare, Init(P)); end;

function CreatePickHWOrderItem(P : pointer) : pointer; far;
begin	CreatePickHWOrderItem := New(PPickHWOrderItem, Init(P)); end;

function NewWarrantyIdxStream : PStream; far;
begin
	NewWarrantyIdxStream := New(PIndexedJimmyStream, init('WARRANTY.IDX', HWindexItemSize));  {hardware ID ref list}
end;

const
	{--- Required for Stream ----}
	RSoftware : TStreamRec = (
		ObjType : srSoftware;
		VmtLink : Ofs(TypeOf(TSoftware)^);
		Load : @TSoftware.Load;
		Store : @TSoftware.Store
	);

	{--- Required for Stream ----}
	RHardWare : TStreamRec = (
		ObjType : srHardWare;
		VmtLink : Ofs(TypeOf(THardWare)^);
		Load : @THardWare.Load;
		Store : @THardWare.Store
	);

{************************************
 ***         INITIALISATION       ***
 ************************************}
begin
	{-- Software ----}
	{Register Various sentence codes}
	New(SCodeCollection[scSoftwareTitle], Init('SWTITLE.SC', 'Software Titles', StdSCodeCreator));

	RegisterJimmy(RSoftware, CreateSoftware, lsMoreAbout, '~S~oftware'); {Register for streams}

	{---- Hardware ---}
	{Register Various sentence codes}
	New(SCodeCollection[SCMachineType], Init('KMachine.SC', 'Hardware Types', StdSCodeCreator));
	New(SCodeCollection[SCMachineMake], Init('KHWmakes.SC', 'Hardware Makes', StdSCodeCreator));
	New(SCodeCollection[SCFloppyType ], Init('KFloppys.SC', 'Floppy Types', StdSCodeCreator));
	New(SCodeCollection[scRAMType    ], Init('KRAM    .SC', 'RAM Types', StdSCodeCreator));

	RegisterJimmy(RHardware, CreateHardware, lsMoreAbout, '~H~ardware');
	RegisterJimmy(RPickHWOrderItem, CreatePickHWOrderItem, lsSalesItems, '~H~ardware');

{	AppMenuBar^.Add2EndMenu(mnFind,   NewItem('~W~arranty No','', kbNone,    cmFindHardwareByID, hcNoContext, nil));{}
{	RegisterTask(DesktopTasks, cmFindHardwarebyID, FindWarranty);{}

	NewFileAdmin(fiWarrantyIdx, 'Warranty Index', NewWarrantyIdxStream);

end.


