{RAlly reports}
{$I compdirs}

unit KRLYRPTS;

INTERFACE

IMPLEMENTATION

uses reports,
			dattime,
			objects,
			app,
			devices,
			tuiedit,
			dialogs, views,
			tuimsgs,
			global,
			printers,
			files,
			forms,
			krlyview,
			jimmys,
			jimindxs,
			jimhooks,
			scodes,
			jimprint,
			inpjimmy,
			krally,
			kwplink,
			krlysetu,
			tui,
			tasks,
			tables,
			indexes,
			inplist,
			idindex,
			minilib;


{**********************************************************
 ***             BULLSHIT SHEETS                        ***
 **********************************************************}
{Essentially a printed version of the timing matrix, plus any
penalties added by the steward, totalled in the last column:


		TC01	TC02	TC03	TC04 .... Penalties	Total
100  xx    xx
101  xx
102  xx
:

{Pass FromCP and ToCP as pointers to actual cp's, not routepos}

procedure PrintTimingsSheet(Device : PDeviceStream;
														FromCPID,ToCPID : longint;
														fiIdxType : word;
														Cumulative : boolean;
														Title, Form, Class, Event : string;
														CPsToPage : word;
														CompOnly : boolean);
var TimingID, CarID, COntrolID : longint;
		Timing : PTiming;
		Control : PControl;
		CarIDx, FromPos, ToPos, CPPos : longint;
		Car : PCar;
		S,SS : string;
		Width : word;
		Penalty : PPenalty;
		TotalTime : TTime;
		PenaltyTime : TTime;
		Time : TTime;
		Match : boolean;
		LastCarPos : longint;
		LastEvent : string;
		NumCars : word;


begin
	ThinkingOn('Printing');

	FileAdmin(fiJimmys)^.LogOn;
	FileAdmin(fiTimingsTable)^.LogOn;
	FileAdmin(fiIdxType)^.LogOn;
	FileAdmin(fiHooks)^.LogOn;
	FileAdmin(fiRouteIDIdx)^.LogOn;

	{get routepos of from/to}
	Control := PControl(GetJimmy(FromCPID)); 	FromPos := Control^.RoutePos; dispose(Control, done);
	Control := PControl(GetJImmy(ToCPID));		ToPos		:= Control^.RoutePos; dispose(Control, done);

	Device^.FormCodes^.SetStr('RTITLE',Title);

	if CPsToPage=0 then CPsToPage := 99;
	Width := 10;

	CPPos := FromPos;
	LastEvent := '*START*';

	while FromPos<ToPos do begin {do in steps of cpstopage}

		{--- make up list header ---}
		S := 'Car ';
		for CPPos := FromPos to FromPos+CPsToPage-1 do if CPPos<=ToPos then begin
			Control := PControl(GetJImmy(IDStream(fiRouteIDIdx)^.GetIDPtr(CPPos)));
			if not CompOnly or (Control^.CType=ctCOmp) then
				S := S + setlength('  '+Control^.GetName(naRef,0),Width);
			dispose(Control, done);
		end;
		if FromPos+CPsToPage>=ToPos then S := S +'Penalties  TOTAL  ';
		Device^.FormCodes^.SetStr('LISTHDR', S);

		{--- header ---}
		if not Device^.Active then
			Device^.StartPrint(Form, 'REPORT') {only want to start printing once
																						listhdr is set}
		else
			Device^.NewPage;

		{for all cars}
		Control := nil;
		NumCars := 0;

		for CarIdx := 0 to Stream(fiIdxType)^.NoRecs-1 do begin
			Car := PCar(PIndexedJimmyStream(Stream(fiIdxType))^.GetJimmyAtIdx(CarIdx));

			{validate car for group/event}
			Match := True;
			if (Car<>nil) then begin
				if (Event<>'') and (Event<>delspace(Car^.Event)) then Match := False;

				if (Class<>'') and	(Class<>delspace(Car^.Class)) then begin
					{doesn't match directly}
					Match := False;
					if (Class[2]='*') and (Class[1]=Car^.Class[1]) then Match := True;
					if (Class[1]='*') and (Class[2]=Car^.Class[2]) then Match := True;
				end;

				if Car^.LastCPPos<=0 then Match := False; {no timings - complete non-starter}
			end;

			if not Match then begin
				dispose(Car, done);
				Car := nil;
			end;

			if Car<>nil then begin

{				Control := PControl(GetJimmy(Car^.LastCP));
				LastCarPos := Control^.RoutePos;
				dispose(Control, done);

				if LastCarPos>=FromPos then begin
					{it *does* have a timing in this list}
					ThinkingOff;
					ThinkingOn('Printing CP '+N2Str(FromPos)+'+ Car '+N2Str(Car^.Number));

					inc(NumCars);

{					if delspace(Car^.Event)<>LastEvent then begin
						if LastEvent<>'*START*' then Device^.NewPage;
						LastEvent := delspace(Car^.Event);
					end;{}

					S := Setlength(Car^.GetName(naRef,0),4);
					TotalTime.Clear;

					{set up timings line}
					for CPPos := FromPos to FromPos+CPsToPage-1 do if CPPos<=ToPos then begin

						if CompOnly then Control := PControl(GetJimmy(IDStream(fiRouteIDIdx)^.GetIDPtr(CPPos))) else Control := nil;
						if not CompOnly or (Control^.CType=ctComp) then begin

							Timing := PTiming(GetJimmy(TableStream(fiTimingsTable)^.GetPtr(CPPos, Car^.Number)));
							if Timing = nil then
								SS := '   ***'
							else begin
								if Cumulative then
									Time.SetTo(Timing^.CumTotal)
								else
									Time.SetTo(Timing^.Penalty);
								if Time.Blank then SS := '' else SS := Time.Digit8;
								if Timing^.Early then SS := SS + 'E';
								TotalTime.Add(Timing^.Penalty);
								dispose(Timing, done);
							end;
							S := S + Setlength(SS, Width);
						end;
						if Control<>nil then dispose(Control, done);
					end;


					if FromPos+CPsToPAge>=ToPos then begin
						{last page - penalties and current total}
						{work out penalties total}
						PenaltyTime.Clear;
						Penalty := PPenalty(HookFile^.GetFirst(Car^.TimingsHook, srPenalty));
						while Penalty<>nil do begin
							PenaltyTime.Add(Penalty^.Penalty);
							dispose(Penalty, done);
							Penalty := PPenalty(HookFile^.GetNextJImmy);
						end;
						TotalTime.Add(PenaltyTime);

						{add to last page}
						if PenaltyTime.Blank then
							S := S + Setlength('   --', Width)
						else
							S := S + SetLength(PenaltyTime.Digit8,Width);

						S := S + Car^.CumulTime.Digit8;

					end;
					Device^.Writeln(S);
					if NumCars mod 5 = 0 then Device^.writeln('');
{				end; {last control within range}

				dispose(Car, done);

			end; {car<>nil}

		end; {for all cars}

		FromPos := FromPos + CPsToPage;

	end; {stepping}

	FileAdmin(fiIdxType)^.LogOff;
	FileAdmin(fiHooks)^.LogOff;

	FileAdmin(fiJimmys)^.LogOff;
	FileAdmin(fiTimingsTable)^.LogOff;
	FileAdmin(fiRouteIDIdx)^.LogOff;

	Device^.EndPrint;

	ThinkingOff;
end;


{===== DOING BULLSHIT SHEETS =========}
procedure DoFullBullshitSheet; far;
var EditBox : PEditBox;
begin
end;



procedure DoLegBullshitSheet; far;
var EditBox : PEditBox;
		R : TREct;
		Data : record
			FromCP, ToCP : longint;
			Editor : word;
			ByWhat : word;
			Cum : word;
			Comp : word;
			Class : string[6];
			Event : TSCode;
			Width : word;
		end;
		C : word;
		InpLine : PInputJimmy;
		fiType : word;
		Title : string;
		Device : PDeviceStream;

begin
	R.ASsign(0,0,43,22);
	New(EditBox, init(R, 'Print Timings Sheet',nil));
	with EditBox^ do begin
		Options := Options or ofCentered;

		R.XYLD(9,2,10,1); Insert(New(PInputCP, init(R, 10, ''))); AddLabel('~F~rom', Current);
		PInputELine(Current)^.MustInput := True;
		{$IFDEF RallyPress}
			PInputCP(Current)^.ListOptions := PInputCP(Current)^.ListOptions and not loAllowList;
		{$ENDIF}

		R.XYLD(23,2,10,1); Insert(New(PInputCP, init(R, 10, ''))); AddLabel('~T~o', Current);
		PInputELine(Current)^.MustInput := True;
		{$IFDEF RallyPress}
			PInputCP(Current)^.ListOptions := PInputCP(Current)^.ListOptions and not loAllowList;
		{$ENDIF}

		R.XYLD(9,4,21,2); Insert(New(PERadioButtons, init(R,
												NewSITem('~I~nternal',
												NewSItem('~W~ordPerfect',nil)))));
		{$IFNDEF kwplink} PCluster(Current)^.EnableMask := PCLuster(Current)^.EnableMask and not Exp2(edWP51);{} {$ENDIF}

		R.XYLD(9,7,21,2); Insert(New(PERadioButtons, init(R,
												NewSITem('~N~umber',
												NewSItem('~R~ace Position',
{												NewSItem('C~l~ass/Race Pos',{}
												nil))))); AddLabel('~B~y Car', Current);

		R.XYLD(9,10,21,2); Insert(New(PERadioButtons, init(R,
												NewSITem('C~u~mulative',
												NewSItem('S~e~ction Times',nil)))));

		R.XYLD(9,13,21,2); Insert(New(PERadioButtons, init(R,
												NewSITem('~A~ll Controls',
												NewSItem('C~o~mpetitive Only',nil)))));

		R.XYLD(13,17, 6,1); Insert(New(PInputELine, init(R, 6))); AddLabel('C~l~ass', Current);
		R.XYLD(13,18,13,1); Insert(New(PInputSCode, init(R, scCarEvent))); AddLabel('Event', Current);

		R.XYLD(13,20, 6,1); Insert(New(PInputWord, init(R, 3))); AddLabel('C~P~s/Page', Current);

		InsOKButton(Size.X-11, 		Size.Y-5, @Data);
		InsCancelButton(Size.X-11, Size.Y-3);
		EndInit;
	end;

	C := Desktop^.ExecView(EditBox);

	dispose(EditBox, done);

	if (C=cmOK) then begin
		case Data.Editor of
			0 : Device := PDeviceStream(Printer);
			1 : Device := PDeviceStream(WPStream);
		end;

		case Data.ByWhat of
			0 : fiType := fiCarNumberIdx;
			1 : fitype := fiCarRacePosIdx;
{			2 : fitype := fiCarRacePosClassIdx;{}
		end;

		case Data.Cum of
			0 : Title := 'Cumulative Scores at each Section';
			1 : Title := 'Section Times';
		end;

		if delspace(Data.Class)<>'' then begin
			Device^.FormCodes^.SetStr('CLASS',Data.Class);
{			Title := Title+#13#10+Data.Class;{}
		end else
			Device^.FormCodes^.SetStr('CLASS','All Classes');

		if delspace(Data.Event)<>'' then begin
			Device^.FormCodes^.SetStr('EVENT',ExpandScode(scCarEvent, Data.Event));
{			Title := Title+#13#10+ExpandScode(scCarEvent, Data.Event);{}
		end else
			Device^.FormCodes^.SetStr('EVENT','');

		PrintTimingsSheet(Device, Data.FromCP, Data.ToCP,
											fiType, Data.Cum=0,
											Title, 'TIMINGS', delspace(Data.Class), delspace(Data.Event),
											Data.Width,
											Data.Comp=1);{}
	end;
end;

{*******************************************************************
 ***                                                             ***
 ***                    START LIST                               ***
 ***                                                             ***
 *******************************************************************}

procedure PrintStartList; far;
var StartListView : PStartListView;
		R : TRect;
begin
	R.Assign(0,0,80,10);
	New(StartListView, init(R, srCar, 1, lsStartList));
	StartListView^.Tabs := #3#6#35#40;
	StartListView^.DoStartup;
	StartListView^.PrintList(False,-1,0);
	dispose(StartListView, done);
end;


{*******************************************************************
 ***                                                             ***
 ***                     CONTROL REPORT                          ***
 ***                                                             ***
 *******************************************************************}
procedure PrintControlTimings(Cum : boolean; Title : string);
var Control : PControl;
		EditBox : PEditBox;
		R : TRect;
		ControlID : longint;
		PrintType : TJimmyPrintType;
		PrintAs : PSitem;
		PrintAsLink : pointer;
		C : word;

begin
	R.ASsign(0,0,35,8);
	New(EditBox, init(R, Title,nil));
	with EditBox^ do begin
		Options := Options or ofCentered;

		R.XYLD(9,2,20,1); Insert(New(PInputCP, init(R, 20, ''))); AddLabel('Control', Current);
		PInputELine(Current)^.MustInput := True;

		InsOKButton(9, 		Size.Y-3, @ControlID);
		InsCancelButton(19, Size.Y-3);
		EndInit;
	end;

	C := Desktop^.ExecView(EditBox);

	dispose(EditBox, done);

	if C<>cmOK then exit;

	Control := PControl(GetJimmy(ControlID));

{	if (Control^.CType<>ctComp) and not Cum then begin
		InputWarning('Not a competitive section!');
		dispose(Control, done);
		exit;
	end;{}

	with Control^ do begin
		Print;
{		GetDefaultPrintType(PrintType, PrintAs, PrintAsLink);
		if Cum then begin
			PrintType.PrintAs := 1;
			PrintType.FormName := 'CONTROLO';
		end;
		PrintPrintType(PrintType);{}
	end;

	dispose(Control, done);
	exit;
end;

procedure PrintSectionTimes; far;
begin
	PrintControlTimings(False,'Section Times');
end;

procedure PrintOverallSectionTimes; far;
begin
	PrintControlTimings(True, 'Overall Section Times');
end;



{*******************************************************************
 ***                                                             ***
 ***                    WEB REPORT                               ***
 ***                                                             ***
 *******************************************************************}
var WRUSecs : longint;

procedure WebReportUpdate; far;

var Form : string[8];
		IdxRec : longint;
		Device : PDeviceStream;
		Jimmy : PJimmy;
		CarPos : word;
		fiType : word;

begin
	if (RallySetup.WebReportInt<>0) and (TimeNow.Secs>WRUSecs + RallySetup.WebReportInt) then begin

		THinkingOn('Printing Web Report');

		fiType := fiCarRacePosIdx;

		New(Device, init('Dos File', 'WEB.HTM'));

		Device^.StartPrint('WEBRPT','');

		CarPos := 0;
		IdxRec := 0;

		FileAdmin(fiJimmys)^.LogOn;

		{=== DO RUNNING =====}
		FileAdmin(fiType)^.LogOn;
		for IdxRec := 0 to Stream(fiType)^.NoRecs-1 do begin

			Jimmy := PIndexedJimmyStream(Stream(fiType))^.GetJimmyAtIdx(IdxRec);

			if Jimmy<>nil then begin
				Device^.FormCodes^.SetPrefix('');

				inc(CarPos); Device^.FormCodes^.SetStr('POS',N2Str(CarPos));

				Jimmy^.SetFormCodes(Device^.FOrmCodes);

				Device^.PrintForm('WEBRPT.FRM');

				dispose(Jimmy, done);
			end;

		end;
		FileAdmin(fiType)^.LogOff;

		Device^.PrintForm('WEBRPTBK.FRM'); {break form}

		{=== DO NON-RUNNING ====}
		FileAdmin(fiCarNumberIdx)^.LogOn;

		for IdxREc := 0 to Stream(fiCarNumberIdx)^.NoRecs-1 do begin
			Jimmy := PIndexedJimmyStream(Stream(fiCarNumberIdx))^.GetJimmyAtIdx(IdxRec);

			if Jimmy<>nil then begin

				if PCar(Jimmy)^.Status and stRunning = 0 then begin
					Device^.FormCodes^.SetPrefix('');

					inc(CarPos); Device^.FormCodes^.SetStr('POS',N2Str(CarPos));

					Jimmy^.SetFormCodes(Device^.FOrmCodes);

					Device^.PrintForm('WEBRPT.FRM');
				end;
				dispose(Jimmy, done);
			end;

		end;
		FileAdmin(fiCarNumberIdx)^.LogOff;

		FileAdmin(fiJimmys)^.LogOff;

		Device^.EndPrint;
		dispose(Device, done);


		ThinkingOff;

		WRUSecs := TimeNow.Secs;
	end;
end;

{*******************************************************************
 ***                                                             ***
 ***                    FINAL RESULTS                            ***
 ***                                                             ***
 *******************************************************************}
procedure PrintFinalResults; far;
var Form : string[8];
		IdxRec : longint;
		Device : PDeviceStream;
		Match : boolean;
		Car : PCar;
		CarPos : word;
		fiType : word;
		EditBox : PEditBox;
		R : TREct;
		Title : string;
		InpData : record
			Editor : word;
			Class : string[6];
			Event : TSCode;
		end;
		Time : TTime;
		C : word;

begin
	R.ASsign(0,0,35,15);
	New(EditBox, init(R, 'FINAL RESULTS',nil));
	with EditBox^ do begin
		Options := Options or ofCentered;

		R.XYLD( 9, 2,21,2); Insert(New(PERadioButtons, init(R,
												NewSITem('~I~nternal',
												NewSItem('~W~ordPerfect',nil)))));
		{$IFNDEF kwplink} PCluster(Current)^.EnableMask := PCLuster(Current)^.EnableMask and not Exp2(edWP51);{} {$ENDIF}

		R.XYLD(13, 5, 6,1); Insert(New(PInputELine, init(R, 6))); AddLabel('C~l~ass', Current);
		R.XYLD(13, 7,13,1); Insert(New(PInputSCode, init(R, scCarEvent))); AddLabel('Event', Current);

		InsOKButton(9, 		Size.Y-3, @InpData);
		InsCancelButton(20, Size.Y-3);
		EndInit;
	end;

	C := Desktop^.ExecView(EditBox);

	dispose(EditBox, done);

	if (C=cmOK) then begin

		THinkingOn('Printing Results');

		fiType := fiCarRacePosIdx;

		case InpData.Editor of
			0 : Device := PDeviceStream(Printer);
			1 : Device := PDeviceStream(WPStream);
		end;

		InpData.Class := delspace(InpData.Class);
		InpData.Event := delspace(InpData.Event);

		if (InpData.Class = '') then begin
			Form := 'FINALRES';
			Title := 'FINAL RESULTS';
			Device^.FormCodes^.SetStr('CLASS','All Classes');
		end else begin
			Form := 'CLASSRES';
			Title := 'FINAL CLASS RESULTS'+#13#10+InpData.Class;
			if pos('*',InpData.Class)=0 then begin
				Title := Title + ' '+ExpandSCode(scCarClass, InpData.Class);
				Device^.FormCodes^.SetStr('CLASS','Class '+InpData.Class);
			end else
				Device^.FormCodes^.SetStr('CLASS','Group '+InpData.Class[1]);
		end;

		if delspace(InpData.Event)<>'' then begin
			Device^.FormCodes^.SetStr('EVENT',ExpandScode(scCarEvent, InpData.Event));
			Title := Title+#13#10+ExpandScode(scCarEvent, InpData.Event);
		end else
			Device^.FormCodes^.SetStr('EVENT','');

		Device^.FormCodes^.SetStr('RTITLE',Title);
		Device^.FormCodes^.SetStr('LDRTIME','');

		Device^.StartPrint(Form,'REPORT');

		CarPos := 0;

		FileAdmin(fiJimmys)^.LogOn;
		FileAdmin(fiCarRacePosIdx)^.LogOn;

		for IdxRec := 0 to Stream(fiCarRacePosIdx)^.NoRecs-1 do begin

			Car := PCar(PIndexedJimmyStream(Stream(fiCarRacePosIdx))^.GetJimmyAtIdx(IdxRec));

			{validate car for group/event}
			Match := True;
			if (Car<>nil) then begin
				if (InpData.Event<>'') and (InpData.Event<>delspace(Car^.Event)) then Match := False;

				if (InpData.Class<>'') and	(InpData.Class<>delspace(Car^.Class)) then begin
					{doesn't match directly}
					Match := False;
					if (InpData.Class[2]='*') and (InpData.Class[1]=Car^.Class[1]) then Match := True;
					if (InpData.Class[1]='*') and (InpData.Class[2]=Car^.Class[2]) then Match := True;
				end;
			end;

			if not Match then begin
				dispose(Car, done);
				Car := nil;
			end;

			if Car<>nil then begin

				{set position, etc}
				with Device^.FormCodes^ do begin
					SetPrefix('');
					inc(CarPos); SetStr('POS',N2Str(CarPos));
					if QDecode('LDRTIME')='' then SetStr('LDRTIME',Car^.CumulTime.Digit8);
					Time.SetToStr(QDecode('LDRTIME'));
					Time.SetToSecs(Car^.CumulTime.Secs - Time.Secs);
					SetStr('LDRDIFF',Time.Digit8);
				end;

				Car^.SetFormCodes(Device^.FOrmCodes);

				Device^.PrintForm('FINALRES.FRM');
				if not Device^.FormFound then Device^.PRintForm('CARRESLT.FRM');

				dispose(Car, done);
			end;

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

		Device^.EndPrint;

		ThinkingOff;
	end;
end;



begin
	RegisterTask(DesktopTasks, cmDoLegBullshitSheet, @DoLegBullshitSheet);

	RegisterTask(DesktopTasks, cmPrintSectionTimes, @PrintSectionTimes);{}
	RegisterTask(DesktopTasks, cmPrintOverallSectionTimes, @PrintOverallSectionTimes);{}

	RegisterTask(DesktopTasks, cmPrintFinalResults, @PrintFinalResults);{}

	RegisterTask(IdleTasks, 0, @WebReportUpdate);
	WRUSecs := TimeNow.Secs;
end.
