{********************************************************************
 ****                EXPORT                                       ***
 ********************************************************************}
{$I compdirs}

{written 20/6/94 to convert Solitaire's mess to a nice, tidy v3}
program Kexport;

uses
	kamapp, errors, messages, {display}

	kdirctry, kperson, kcompany,{}
	khrdware, ksftware, kppmedcl, kdetcomm,{more items}
	kjob, kwplink, kevent, {history items}

	pchain, files, jimmys, nodes,

	doslink,

	views, {cmcancel}

	global, setup,
	minilib;

var
	ExportFile : text;
	ChainRec,	RecNo : longint;
	ChainItem : PPureChainItem;

{*********************************************************************
 ***                      EXPORT DIRECTORY ITEMS                   ***
 *********************************************************************}
procedure ExportPerson(P : pointer);
var I : integer;
begin
	with PPerson(P)^ do begin
		writeln(ExportFile,'PERSON');
		writeln(ExportFile, Surname);
		writeln(ExportFile, Forname);
		writeln(ExportFile, Title);
		writeln(ExportFile, DearName);
		writeln(ExportFile, CategoryCode);
		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(ContactFor));
		for I := 1 to 7 do
			writeln(ExportFile, Address[I]);
		writeln(ExportFile, PostCode);
		writeln(ExportFile, Country);
		for I := 1 to 4 do
			writeln(ExportFile, TelNo[I]);
		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(Ptr2Inv));
		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(Ptr2Ref));
		writeln(ExportFile, SearchCodes);
		writeln(ExportFile, Comment);
		writeln(ExportFile, L2Str(RecNo));
		writeln(ExportFile, 'ENDOBJECT');
	end;
end;

procedure ExportCompany(P : pointer);
var I : integer;
begin
	with PCompany(P)^ do  begin
		writeln(ExportFile,'COMPANY');
		writeln(ExportFile, CompanyName);
		writeln(ExportFile,DearName);
		writeln(ExportFile, CategoryCode);
		for I := 1 to 5 do
			writeln(ExportFile, Address[I]);
		writeln(ExportFile, PostCode);
		writeln(ExportFile,Country);

		for I := 1 to 4 do
			writeln(ExportFile, TelNo[I]);

		for I := 1 to 4 do begin
			writeln(ExportFile, Contact[I].Desc);
			writeln(ExportFile,'ID');
			writeln(ExportFile,L2Str(Contact[I].FilePtr));
		end;

		writeln(ExportFile, SearchCodes);
		writeln(ExportFile,Comment);
		writeln(ExportFile, L2Str(RecNo));
		writeln(ExportFile, 'ENDOBJECT');
	end;
end;


{*********************************************************************
 ***                      EXPORT HARDWARE                          ***
 *********************************************************************}
procedure ExportHardware(P :pointer; JimmyID : longint);
begin
	with PHardware(P)^ do begin
    writeln(ExportFile, 'HARDWARE');

		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(Who)); {who it's for}

		writeln(ExportFile, MachType);
		writeln(ExportFile, Make);
		writeln(ExportFile, Model);
		writeln(ExportFile, Quantity);
		writeln(ExportFile, SerialNo);
		writeln(ExportFile, DOI.Digit10);
		writeln(ExportFile, Warranty);
		writeln(ExportFile, DOExpiry.Digit10);

		writeln(ExportFile, RAMQuant);
		writeln(ExportFile, RAMType);               {SIMMS or SIPPS for now}
		writeln(ExportFile, Graphics);
		writeln(ExportFile, GraphicsRAM);
		writeln(ExportFile, MonMake);
		writeln(ExportFile, MonModel);
		writeln(ExportFile, MonSerialNo);
		writeln(ExportFile, DriveA);
		writeln(ExportFile, DriveB);
		writeln(ExportFile, HDiskMake);
		writeln(ExportFile, HDiskCap);
		writeln(ExportFile, HDiskType);
		writeln(ExportFile, Extras[1]);
		writeln(ExportFile, JimmyID);
    writeln(ExportFile, 'ENDOBJECT');
	end;
end;

{*********************************************************************
 ***                      EXPORT Software                          ***
 *********************************************************************}
procedure ExportSoftware(P :pointer; JimmyID : longint);
begin
	with PSoftware(P)^ do begin
    writeln(ExportFile, 'SOFTWARE');

		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(Who)); {who it's for}

		writeln(ExportFile,	 Title);
		writeln(ExportFile,	 Version);
		writeln(ExportFile,	 l2sTR(Quantity));
		writeln(ExportFile,	 SerialNo);
		writeln(ExportFile,	 DOI.Digit10);
		writeln(ExportFile,	 Warranty);
		writeln(ExportFile,	 DOExpiry.Digit10);

		writeln(ExportFile, JimmyID);
    writeln(ExportFile, 'ENDOBJECT');
	end;
end;


{*********************************************************************
 ***                      EXPORT COMMENT/DETAIL                    ***
 *********************************************************************}
procedure ExportCommentDetail(P :pointer; JimmyID : longint);
begin
	with PCommentDetail(P)^ do begin
    writeln(ExportFile, 'COMMENTDETAIL');

		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(Who)); {who it's for}

		writeln(ExportFile,	 Code);
		writeln(ExportFile,	 Text^.First);
		writeln(ExportFile,	 Text^.DataLength);

		writeln(ExportFile, JimmyID);
    writeln(ExportFile, 'ENDOBJECT');
	end;
end;


{*********************************************************************
 ***                      EXPORT WP LETTER                         ***
 *********************************************************************}
procedure ExportWPLtr(P :pointer; JimmyID : longint);
begin
	with PWPltr(P)^ do begin
    writeln(ExportFile, 'WPLETTER');

		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(ToWho)); {who it's for}

		writeln(ExportFile, Date.Digit10);                 {Date of writing}
		writeln(ExportFile,	'ID');
		writeln(ExportFile, L2Str(ReWho));
		writeln(ExportFile,	'ID');
		writeln(ExportFile, L2Str(ByWho));               {Who typed it}
		writeln(ExportFile,	 Codes);
{	 Comment   : string[10];						{Small comment box}
		writeln(ExportFile,	 Ref);
		writeln(ExportFile,	 Header);
		writeln(ExportFile,	 B2Str(Copies));

		writeln(ExportFile,	 L2Str(FirstTextRec));

		writeln(ExportFile,	 B2Str(WPVer));

    writeln(ExportFile, 'ENDOBJECT');
	end;
end;


{*********************************************************************
 ***                      EXPORT GENERAL EVENT                     ***
 *********************************************************************}
procedure ExportDiaryEvent(P :pointer; JimmyID : longint);
begin
	with PDiaryEvent(P)^ do begin
    writeln(ExportFile, 'DIARYEVENT');

		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(ToWho)); {who it's for}
		writeln(ExportFile,	'ID');
		writeln(ExportFile, L2Str(ByWho));               {Who typed it}

		writeln(ExportFile, Date.Digit10);                 {Date of writing}
		writeln(ExportFile, Time.Digit5);
		writeln(ExportFile, Duration.Digit5);
		writeln(ExportFile, LeadTime.Digit5);

		writeln(ExportFile,	 Code);
		writeln(ExportFile, Comment^.First);
		if Alarm then writeln(ExportFile, 'X') else writeln(ExportFile, ' ');
		if ToDo then writeln(ExportFile, 'X') else writeln(ExportFile, ' ');
		writeln(ExportFile, Outcome);

    writeln(ExportFile, 'ENDOBJECT');
	end;
end;


{*********************************************************************
 ***                      EXPORT JOB                               ***
 *********************************************************************}
procedure ExportJob(P :pointer; JimmyID : longint);

	procedure ExportNode(NodeID : longint);
	var Node : PNodeItem;
	begin
		if NodeID<>-1 then begin
			Node := PNodeItem(PNodeStream(FileAdmin[fiInvoiceNodes]^.FilePtr)^.GetAt(NodeID));
			if typeof(Node^)=typeof(THWJobNode) then begin
				writeln(ExportFile, 'HWJOBITEM');
				writeln(ExportFile, PHWJobNode(Node)^.HardwareID);
			end;
			ExportNode(Node^.Disk.FirstChild); {export children}
			ExportNode(Node^.Disk.Next); 			{export peers}
			dispose(Node, done);
		end;
	end;


begin
	with PJob(P)^ do begin
    writeln(ExportFile, 'JOB');

		writeln(ExportFile, 'ID');
		writeln(ExportFile, L2Str(ForWho));

		writeln(ExportFile, CustRef);
		writeln(ExportFile, 'ID');
		writeln(ExportFile, +L2Str(ByWho));
		writeln(ExportFile, OurRef);
		writeln(ExportFile, CallDate.Digit10);
		writeln(ExportFile, VisitDate.digit10);
		writeln(ExportFile, VisitTime);

		writeln(ExportFile, Notes^.First); {pointer to first text item}
		writeln(ExportFile, OutCome);

		if Invoiced then writeln(ExportFile, 'X') else writeln(ExportFile, ' ');

		{--- need to list items, esp old versions, laying out pointers to machines/etc}
		{just exports in straightforward list - no tree structure!}
		FileAdmin[fiInvoiceNodes]^.LogOn;
		ExportNode(RootNodeID);
		FileAdmin[fiInvoiceNodes]^.LogOff;

    writeln(ExportFile, 'ENDOBJECT');
	end;
end;




{*********************************************************************
 ***                 MAIN EXPORT PROCEDURE                         ***
 *********************************************************************}


var
	DirectoryItem : PDirectoryItem;
  ProBox : PProgressBox;
	Jimmy : PJimmy;
	OldMoreStream : PDataStream;

begin
	New(Kameleon, init);
	Kameleon^.Draw;

	ProBox := NewProgressBox('EXPORT',space(30),'');

	DirectoryStreamLogOn;
	FileADmin[fiMore]^.LogOn;
	FileADmin[fiHistory]^.LogOn;
	FileADmin[fiJimmys]^.LogOn;
	New(OldMoreStream, init(DataPath+'MSMORE.DAT',1));

	Assign(ExportFile, 'EXPORT.$$$');
	rewrite(ExportFile);

	{=========== DIRECTORY ================}
  for RecNo := 0 to {DirectoryStream^.NoDatRecs{}-1 do begin

		if (RecNo div 10) = (RecNo/10) then ProBox^.Update('Exporting Directory','',RecNo,DirectoryStream^.NoDatRecs-1);

		if ProBox^.Command = cmCancel then break; {break out of for loop}

{need to do this for v2's - where not all data is stored in main file}
		DirectoryItem := PDirectoryItem(DirectoryStream^.GetAtId(recNo, lkIgnore));

{		DirectoryItem := PDirectoryItem(DirectoryStream^.GEtAt(RecNo));{}

    if (DirectoryItem<>nil) and not DirectoryItem^.Deleted{} then begin

    	if typeof(DirectoryItem^)=typeof(TPerson) then ExportPerson(DirectoryItem);{}
	    if typeof(DirectoryItem^)=typeof(TCompany) then ExportCompany(DirectoryItem); {}

		end;

		if DirectoryItem<>nil then dispose(DirectoryItem, done);

	end;

	{save export so far - when we export the whole lot to one file it has trouble at about 2mb}
	close(ExportFile);
	DOSCommand('COPY EXPORT.$$$ EXPORT.DIR',rnNone);
	rewrite(ExportFile); {re-open at start}

  for RecNo := 0 to DirectoryStream^.NoDatRecs-1{} do begin

		if (RecNo div 10) = (RecNo/10) then ProBox^.Update('Exporting Chains','',RecNo,DirectoryStream^.NoDatRecs-1);

		if ProBox^.Command = cmCancel then break; {break out of for loop}

		DirectoryItem := PDirectoryItem(DirectoryStream^.GetAt(recNo));

{		DirectoryItem := PDirectoryItem(DirectoryStream^.GEtAt(RecNo));{}

    if (DirectoryItem<>nil) and not DirectoryItem^.Deleted then begin
		  {========== MORE ABOUT LISTS ===========}
		  {do first so that hardware items are stored before jobs}
      ChainRec := DirectoryItem^.Ptr2Det;
			while ChainRec<>-1 do begin
				ChainItem := PPureChainItem(PDataStream(FileAdmin[fiMore]^.FilePtr)^.GetAt(ChainRec));

	{version 2 export botch}
				Jimmy := PJimmy(OldMoreStream^.GetAt(ChainItem^.Ptr2Dat));
				OldMoreStream^.CheckStatus('Getting at '+L2Str(ChainItem^.Ptr2Dat));{}

				{normal export retrieval}
{				Jimmy := PJimmy(JimmyStream^.GetAT(ChainItem^.Ptr2Dat));{}

				if Jimmy<>nil then begin
					if typeof(Jimmy^)=typeof(THardware) then ExportHardware(Jimmy, ChainItem^.ptr2Dat)
          else if typeof(Jimmy^)=typeof(TSoftware) then ExportSoftware(Jimmy, ChainItem^.ptr2Dat)
	          else if typeof(Jimmy^)=typeof(TCommentDetail) then ExportCommentDetail(Jimmy, ChainItem^.ptr2Dat)
							else if ChainItem^.srType = 1021 then RecordError('EXPORT WARNING',
																															'Not bothering to export more item type 1021',
																															'ChainRec'+L2Str(ChainRec)+'  Dir ID'+L2Str(RecNo))
							else DbaseWarning('No export method for more item type '+L2Str(CHainItem^.srType),
															' (Dir ID'+L2Str(RecNo)+' '+DirectoryItem^.GetName(naSurFull,0)+')');
					dispose(Jimmy, done);
				end;

				ChainRec := ChainItem^.Next;
				dispose(ChainItem, done);
			end;

			{========== HISTORY LIST ===========}
{			ChainRec := {DirectoryItem^.Ptr2His;
{			while ChainRec<>-1 do begin
				ChainItem := PPureChainItem(PDataStream(FileAdmin[fiHistory]^.FilePtr)^.GetAt(ChainRec));

				{normal export retrieval}
{				Jimmy := PJimmy(JimmyStream^.GetAT(ChainItem^.Ptr2Dat));{}

{				if Jimmy<>nil then begin
					if typeof(Jimmy^)=typeof(TJob) then ExportJob(Jimmy, ChainItem^.ptr2Dat)
					else if typeof(Jimmy^)=typeof(TWPLtr) then ExportWPLtr(Jimmy, ChainItem^.Ptr2Dat)
						else if typeof(Jimmy^)=typeof(TDiaryEvent) then ExportDiaryEvent(Jimmy, ChainItem^.Ptr2Dat)
							else RecordError( 'EXPORT WARNING',
																'No export method for history item type '+L2Str(CHainItem^.srType),
																' (Dir ID'+L2Str(RecNo)+' '+DirectoryItem^.GetName(naSurFull,0)+')');
					dispose(Jimmy, done);
				end else
					RecordError('EXPORT ERROR',
											'Could not read Jimmy type '+L2Str(ChainItem^.srType)+' ID '+L2Str(ChainItem^.Ptr2Dat),
											'Dir '+L2Str(RecNo)+' '+DirectoryItem^.GetName(naSurFull,0)
												+' Stream'+L2Str(JimmyStream^.Status)+'/'+L2Str(JimmyStream^.ErrorInfo));

				ChainRec := ChainItem^.Next;
				dispose(ChainItem, done);
			end;{end history chain}
		end; {not deleted}

		if DirectoryItem<>nil then dispose(DirectoryItem, done);

	end; {loop}

	close(ExportFile);
	DOSCommand('COPY EXPORT.$$$ EXPORT.CHA',rnNone);
	rewrite(ExportFile); {re-open at start}

	PauseMessage('Finished','');

	close(ExportFile);
	DirectoryStreamLogOff;
	FileADmin[fiJimmys]^.LogOff;
	FileADmin[fiMore]^.LogOff;
	FileADmin[fiHistory]^.LogOff;

	dispose(Kameleon, done);

end.
