{****************************************************************************
 ***                                                                      ***
 *** New Fabbo Singing Dancing OOP                                        ***
 ***                          D O C U M E N T S                           ***
 ***                                                                      ***
 *** M Hill                                                        Mar 95 ***
 ****************************************************************************}
{Provides a parent for various document types - ie price lists, WP documents,
etc.  Meant to provide a multiple-reference point filing cabinet, eventually}
{$I compflgs}  {Compiler directives}

unit KDocs;

INTERFACE

uses jimmys, objects, edit, views, output, menus;

const
	TDocumentIndexSize = 40;
	TDocumentSize =  50;

type
	PDocument = ^TDocument;
	TDocument = object(TJimmy)


		Dat2Idx : longint;						{File Pointer to standard index item}
		Deleted : boolean;           {Marked for removal}

		DocType : string[11];					{Document type categories}
		Desc		: string[20];					{description of list}

		{-- Methods --}
		constructor Init;
		procedure CommonInit; virtual;
		destructor Done; virtual;

		function DisplayLine(Maxlen : integer; View : word) : string; virtual;

		{Database stuff}
		constructor Load(var S : TStream);
		procedure   Store(var S : TSTream);

		{indexing}
		function GetDat2Idx(const fiType, ixType : byte) : longint; virtual;
		procedure SetDat2Idx(const fiType, ixType : byte; NDat2Idx : longint); virtual;

		procedure LoadDat2Idx( const fiType, ixType : byte; var S : TStream); virtual;
		procedure StoreDat2Idx(const fiType, ixType : byte; var S : TSTream); virtual;

		procedure LoadLock(var S : TStream); virtual;
		procedure StoreLock(var S : TSTream); virtual;

		function GetKeyString(const fiType, ixType : byte) : string; virtual;
		procedure StoreSelf; virtual;

		procedure SetFormCodes(OutputStream : POutputStream; Prefix : string);  virtual; {Sets standard Document codes}

end;


var {Task lists}
		DocumentsNewMenu  : PMenu;

{***************************************************************************
 ***                 IMPLEMENTATION                                      ***
 ***************************************************************************}
IMPLEMENTATION

uses	indexes, idxjimmy,
      scodes,
      files,
			errors,
			minilib,
			mlist,
			displays, kamapp, app, tasks,
			jimhooks,
			global;



{****************************************************************************
 ***                                                                      ***
 ***                THE Document OBJECT                                     ***
 ***                                                                      ***
 ****************************************************************************}

function CreateDocument(P : pointer) : pointer; far;
begin	CreateDocument := New(PDocument, init); end;

constructor TDocument.Init;
begin
	inherited Init;
	DocType :='';
	Desc := '';
	Dat2Idx := -1;
	Deleted := False;
end;

procedure TDocument.CommonInit;
begin
	inherited CommonInit;
	ScodeAdmin[scDocument]^.LogOn;
end;


destructor TDocument.Done;
begin
	ScodeAdmin[scDocument]^.LogOff;
	inherited Done;
end;



{************************************************
 *** VARIOUS VIRTUAL METHODS TO BE OVERRIDEN  ***
 ************************************************}
{Used for list views}
function TDocument.DisplayLine;
begin
	DisplayLine := Desc;
end;



{**********************************************************
 ***                    SET FORM CODES                  ***
 **********************************************************}
procedure TDocument.SetFormCodes;
begin
	with OutputStream^ do begin
		SetCode(Prefix+'DESC', Desc);
  	SetCode(Prefix+'TYPE', DocType);
	end;
end;


{****************************************************
 *** STREAMING                                    ***
 ****************************************************}

{------- LOAD MAIN DATA ----------}
constructor TDocument.Load;
var Ver : byte;
begin
	CommonInit;

	S.Read(Ver,1);

	S.Read(Dat2Idx, 4);
	S.Read(Lock,1);       {NB Lock position fixed - see Load/StoreLock below}

	S.Read(Deleted, 1);

	S.Read(DocType, sizeof(DocType));
	S.Read(Desc, sizeof(Desc));

end;

{-------- STORE MAIN DATA ----------}
procedure TDocument.Store;
var	Ver : byte;

begin
	{SEE ALSO STOREDAT2IDX ETC BELOW}
	Ver := 1; S.Write(Ver, 1);
	S.Write(Dat2Idx, 4);
	S.Write(Lock,1);       {NB Lock position fixed - see Load/StoreLock below}
	S.Write(Deleted, 1);

	S.Write(DocType, sizeof(DocType));
	S.Write(Desc, sizeof(Desc));
end;

{****************************
 *** STORE INDEX PTR ONLY ***
 ****************************}
{ used to speed up inserts}
procedure TDocument.StoreDat2Idx;
begin
	if ixType = 1 then
		case fiType of
			fiDocumentIdx : begin
				S.Seek(S.GetPos + 2 +1);    {Skip object stream registration ID + version no.}
				S.Write(Dat2Idx, 4);
			end;
		end;
end;

{==== LOAD INDEX PTR ONLY ========}
procedure TDocument.LoadDat2Idx;
begin
	if ixType = 1 then
		case fiType of
			fiDocumentIdx : begin
				S.Seek(S.GetPos +2 +1);     {Skip object streaming registration ID + version no}
				S.Read(Dat2Idx, sizeof(Dat2Idx));
			end;
		end;
end;


{======= STORE LOCK ONLY ============}
procedure TDocument.StoreLock;
begin
	S.Seek(S.GetPos + 2 + 1 + 4); {skip reg ID, ver, index pointers}
	S.Write(Lock, 1);
end;

{======= LOAD LOCK ONLY ============}
procedure TDocument.LoadLock;
begin
	S.Seek(S.GetPos + 2 + 1 + 4);
	S.Read(Lock, 1);
end;


{===== RETURN VALUES OF POINTERS =====}
function TDocument.GetDat2Idx(const fiType,ixtype : byte) : longint;
begin
	GetDat2Idx := -1;
	if ixType =1 then
		case fiType of
			fiDocumentIdx : {if not deleted then} GetDat2Idx := Dat2Idx; {double check}
		end;
end;

procedure TDocument.SetDat2Idx(const fiType, ixtype : byte; NDat2Idx : longint);
begin
	if ixType =1 then
		case fiType of
			fiDocumentIdx : {if not deleted then} Dat2Idx := NDat2Idx;
		end;
end;

function TDocument.GetKeyString;
begin
	GetKeyString := '';

	if ixType = 1 then
		if ((fiType = fiDocumentIdx) and not Deleted) then
			GetKeyString := Desc;
end;


{******************************
 ***       STORE SELF       ***
 ******************************}
procedure TDocument.StoreSelf;
begin
{	StoreJimmy(@Self); method below stores self}
	StoreIndexedJimmy(@Self, fiDocumentIdx, fiDocumentIdx);
end;




{**********************************
 ***   ADMIN CREATION FUNCTIONS ***
 **********************************}

function NewDocumentIndex : PStream;
begin NewDocumentIndex := New(PIndexStream, init('DOCUMENT.IDX',TDocumentIndexSize,fiJimmys)); end;


procedure NewDocumentList;
var Bounds : TRect;
begin
	Desktop^.GetExtent(Bounds);
	Desktop^.Insert(New(PListWindow, init(Bounds, 'Documents', Desktop,
													new(PIndexListView, init(Bounds, DocumentsNewMenu, fiDocumentIdx)))));
end;

{******************************************
 ***         UNIT INSTALLATION          ***
 ******************************************}
{unit initialisation procedure}
begin
	{Various sentence codes}
	New(ScodeAdmin[scDocument], Init('DOCUMENT.SC', 'Document Types', CreateSCodeItem));

	{Task registration}
	AppMenuBar^.Add2EndMenu(mnList,
		NewLine(
		NewItem('~D~ocuments',   '', kbNone, cmNewDocumentList, hcNoContext,
	nil)));

	RegisterTask(DesktopTasks, cmNewDocumentList, NewDocumentList);

	NewFileAdmin(fiDocumentIdx, 'Document Index',NewDocumentIndex);

	DocumentsNewMenu := nil;
end.


