unit Unit0;

	{$mode objfpc}{$H+}   // Object Pascal Mode / Delphi compatible

	{$LINK	/home/roger/_dev1/source/languageONE/@lazarus-fp/_Application/V3.10.o}
	{$LINK	/home/roger/_dev1/source/languageONE/lib/languageONE.lib}
		{ Use $LINK for library (instead of $LINKLIB) cuz it's a static link }

{ ============================================================================= }
{ INTERFACE - Gloablity                                                         }
{ ============================================================================= }
{	The "interface" section of a Pascal UNIT exports PUBLIC variables, constants	}
{ types, and routines, while the USES clause imports exported identifiers from	}
{ another UNITS interface section }

	interface

	{	EXTERNAL }
		uses
			SysUtils, Dialogs, StrUtils;

			procedure L1_PROCESS() ; external;
			function  l1_Call (TableNo, Request, RecNo, AcctNo, Accts: Int64) : pointer;
			procedure l1_Initialisation();
			function	l1_findAcct(AcctNo, All: Int64) : Int64; external;
			function	l1_findConsAcct(AcctNo, All: Int64) : Int64; external;
			function  l1_getDate (dd, mm, ccyy : string ) : string;

			function  ACCT_SPINNER(AcctNo : Int64; Direction : Int64 ) : Int64;

	{	GLOBAL/PUBLIC -> all that follows until "implementation" }
 		const
			c_Initial         = 0;
			c_A01							= 1;
			c_B01							= 2;
			c_B02							= 3;
			c_B03							= 4;
			c_B04							= 5;
			c_B07							= 7;
			c_B99							= 99;
				c_B99_GetDate		= 1;
				c_B99_ValidDate	= 2;

			c_Read						= 1;
			c_Write						= 2;
			c_Start						= 3;
			c_PreviousNext		= 4;
			c_Delete					= 5;
			c_Commit					= 6;
			c_Print						= 7;
			c_Enquire					= 11;
			c_EOY							= 99;

		type

			Search = record
				ID		: Int64;
				Acct	: Int64;
			end;

		var
			{$include include/interface.ptr}

			S										: Search;

			l1_False						: Int64 = 0;
			l1_True							: Int64 = 1;

			newRecord						: boolean = true;

			aFinancialYear			: string;
			nFinancialYear			: Int64;

			X  									: Int64;
			Y  									: Int64;
			Z  									: Int64;
			Str									: string;

			a01_system_recno		: Int64 = 0;
			a01_recNo						: Int64 = 0;
			b01_recNo						: Int64 = 0;
			b02_recNo						: Int64 = 0;
			b01_AllAccts				: Int64 = 0;

{ ============================================================================= }
{ IMPLEMENTATION- private/Local                                                 }
{ ============================================================================= }
{	The "inplementation" section declares1 PRIVATE variables, constants, types, 		}
{ and routines. }

	Implementation

{ ***************************************************************************** }
{ Call languageONE                                                              }
{ ***************************************************************************** }
function  l1_Call (TableNo, Request, RecNo, AcctNo, Accts: Int64) : pointer;
begin
{$asmMode intel}
	asm
		movq xmm0,qword[TableNo]
		movq xmm1,qword[Request]
		movq xmm2,qword[RecNo]
		movq xmm3,qword[AcctNo]
		movq xmm4,qword[Accts]
		mov rax,qword[Accts]
  	Call L1_PROCESS
	end;

end;

{ -----------------------------------------------------------------------------}
{ languageONE Initialisation                                                   }
{ -----------------------------------------------------------------------------}
procedure l1_Initialisation();
begin

	{$include include/interface.cde}

	{ ----------------------------------------------}
	{ Get the System date startup parameter         }
	{ ----------------------------------------------}
		Val (ParamStr (1),nFinancialYear,X);														{ Program parameter ? }
		If nFinancialYear=0 then																				{ If not              }
			begin																													{ begin               }
				l1_Call(c_B99,c_B99_GetDate,0,0,0);													{ Get the System Date }
				aFinancialYear := LeftStr(w_Date,4);												{ as Pascal text      }
				Val (aFinancialYear, nFinancialYear,X);											{ and as an Int64     }

				X := StrToInt(MidStr(w_Date,6,2));													{ Get the month				}
				If (X > 6) then																							{ If less than 7			}
					nFinancialYear	:= nFinancialYear + 1											{ We are in the next	}
				; // END IF																									{ year								}

				aFinancialYear		:= IntToStr(nFinancialYear);							{ and as an Int64     }
			end
		else
			aFinancialYear := ParamStr(1)
  	; // End If

	{ ----------------------------------------------}
	{ Open files & get 1st Company                  }
	{ ----------------------------------------------}
		l1_Call(0,c_Initial,nFinancialYear,0,0);												{ Initialise Tables }
		If RETURN_CODE = 0 then
			begin
					a01_recNo					:= A01_Record_NO;
					a01_system_recno 	:= A01_Record_NO;
			end
		else
			begin
				case RETURN_CODE of
					01: MessageDlgPos('A01 System parameter file has exceeded its bounds',
								mtConfirmation, [mbOk],0,150,150);
					02: MessageDlgPos('B01 Chart of Account file has exceeded its bounds',
								mtConfirmation, [mbOk],0,150,150);
					03: MessageDlgPos('B02 General Journal file has exceeded its bounds',
								mtConfirmation, [mbOk],0,150,150);
				end; // END CASE
        halt;
			end // END BEGIN
		; // END IF

	end;


{ -----------------------------------------------------------------------------}
{ ACCOUNT SPINNERS					                                                   }
{ -----------------------------------------------------------------------------}
	function ACCT_SPINNER(AcctNo : Int64; Direction : Int64 ) : Int64;
	begin

	{ ------------------- }
	{ Get the record no		}
	{ ------------------- }
	{ In previous versions I have kept track of each individual	spinners		}
	{ record no. Because this is quick enough, here we just search for the	}
	{ passed account no.                                                   	}

 		X := l1_findAcct(AcctNo,l1_False);

	{	If NOT FOUND : return zero back to the caller telling it NOT to 			}
	{	update the acct no and description																		}
		If RETURN_CODE = 10 then
			begin
				ACCT_SPINNER := 0;
				exit;
			end // END BEGIN
		; // END IF

	{ If not EOF then returning 23 means the record was not found							}
	{ This occurs when an account no has been manually entered prior to 			}
	{ using	the spinner																												}

		If RETURN_CODE = 23 then

			begin
			{	For the NEXT function this is fine as l1_findAcct will have				}
			{ returned the account following the requested acct 								}
			{ the																																}

				If (Direction = +1) then
					begin
						ACCT_SPINNER := B01_AcctNo;
						exit;
					end
				; // END IF                             20206

			{	For the PREV function we need to take another shot at a read 			}
				l1_Call(c_B01,c_PreviousNext,Direction,0,b01_AllAccts);
				If RETURN_CODE = 10 then
						ACCT_SPINNER := 0						{ If we have hit the beginning then return the saved acct }
				else														{ else }
 						ACCT_SPINNER := B01_AcctNo  { return what we find }
				; //0 END IF
				exit;

			end // END BEGIN

		; // END IF

	{ ----------------------------- }
	{ Find the Next/Previous record }
	{ ----------------------------- }
		l1_Call(c_B01,c_PreviousNext,Direction,0,0);
		If RETURN_CODE = 10 then
			ACCT_SPINNER := 0
		else
			ACCT_SPINNER := B01_AcctNo
		; // END.IF

	end;

{ -----------------------------------------------------------------------------}
{ Get Date									 	                                             		 }
{ -----------------------------------------------------------------------------}
	function l1_getDate (dd, mm, ccyy : string ) : string;
  begin

		if (dd.length = 1) then dd := '0' + dd;
		if (mm.length = 1) then mm := '0' + mm;

		l1_getDate := ccyy + '/' + mm + '/' + dd;

	end;

{ -----------------------------------------------------------------------------}
{ End Of Program						 	                                             		 }
{ -----------------------------------------------------------------------------}
end.

