diff --git a/btc-UI/src/app/components/selection.service/selection.service.ts b/btc-UI/src/app/components/selection.service/selection.service.ts index fb7cea9..6c120ac 100644 --- a/btc-UI/src/app/components/selection.service/selection.service.ts +++ b/btc-UI/src/app/components/selection.service/selection.service.ts @@ -1,4 +1,3 @@ -// ✅ Final SelectionService.ts with special TAN (three-group) logic import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @@ -81,12 +80,18 @@ export class SelectionService { break; } - case 'TRE': - case 'MJP': - case 'JKP': { - const legs = this.splitToLegs(numbers, this.getLegCount(label)); - const comb = legs.reduce((acc, leg) => acc * (leg.length || 1), 1); - updated.total = comb * value * 10; + case 'TRE': // TBP: 3 legs + case 'MJP': // MJP: 4 legs + case 'JKP': { // JPP: 5 legs + const legs = this.splitToLegs(updated.numbers, this.getLegCount(label)); + const requiredLegs = this.getLegCount(label); + // Calculate partial total if at least second-to-last leg has numbers + const filledLegs = legs.filter(leg => leg.length > 0).length; + if (filledLegs >= requiredLegs - 1) { + // Assume remaining legs have at least 1 horse + const combinations = legs.reduce((acc, leg) => acc * (leg.length || 1), 1); + updated.total = combinations * value * 10; // fUBA = 10 + } break; } @@ -124,20 +129,42 @@ export class SelectionService { return n >= 2 ? n * (n - 1) : 0; // nP2 } - private splitToLegs(numbers: number[], legCount: number): number[][] { + private splitToLegs(numbers: (number | string)[], legCount: number): number[][] { const result: number[][] = []; - const perLeg = Math.floor(numbers.length / legCount); - for (let i = 0; i < legCount; i++) { - result.push(numbers.slice(i * perLeg, (i + 1) * perLeg)); + let currentLeg: number[] = []; + let separatorCount = 0; + + for (const item of numbers) { + if (item === '-') { + if (currentLeg.length > 0) { + result.push([...currentLeg]); + currentLeg = []; + separatorCount++; + } + if (separatorCount >= legCount - 1) break; + } else if (typeof item === 'number') { + currentLeg.push(item); + } } - return result; + + // Push the last leg if it has numbers + if (currentLeg.length > 0) { + result.push([...currentLeg]); + } + + // Fill remaining legs with empty arrays if needed + while (result.length < legCount) { + result.push([]); + } + + return result.slice(0, legCount); } private getLegCount(label: string): number { switch (label) { - case 'TRE': return 3; - case 'MJP': return 4; - case 'JKP': return 5; + case 'TRE': return 3; // TBP + case 'MJP': return 4; // MJP + case 'JKP': return 5; // JPP default: return 3; } } diff --git a/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.ts b/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.ts index 9e2675c..2a6795c 100755 --- a/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.ts +++ b/btc-UI/src/app/components/touch-pad-menu/touch-pad-menu.component.ts @@ -1,4 +1,3 @@ -// ... same imports import { Component, Input, OnInit } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SelectionService } from '../selection.service/selection.service'; @@ -12,7 +11,9 @@ import { SelectionService } from '../selection.service/selection.service'; }) export class TouchPadMenuComponent implements OnInit { @Input() ticketingActive: boolean = false; + public twoGroupLabels = ['FOR', 'QUI']; + public multiLegLabels = ['TRE', 'MJP', 'JKP']; labels: string[] = [ 'WIN', 'SHP', 'THP', 'PLC', 'SHW', 'FOR', @@ -34,15 +35,19 @@ export class TouchPadMenuComponent implements OnInit { disabledLabels: string[] = ['SHW', 'SJP']; - // TAN logic + // ✅ Original TAN logic tanGroupStage = 0; tanGroups: number[][] = [[], [], []]; - // FOR/QUI logic + // ✅ FOR/QUI logic isFirstGroupComplete = false; firstGroup: number[] = []; secondGroup: number[] = []; + // ✅ Multi-leg logic (TRE, MJP, JKP) + multiLegStage = 0; + multiLegGroups: number[][] = [[], [], [], [], []]; + isBoxed: boolean = false; // FIELD modal @@ -73,13 +78,16 @@ export class TouchPadMenuComponent implements OnInit { } get showShashEnter(): boolean { - const specialLabels = ['FOR', 'QUI', 'TAN', 'EXA', 'WSP', 'TRE', 'MJP', 'JKP', 'SJP', '.']; + const specialLabels = ['FOR', 'QUI', 'TAN', 'EXA', 'WSP', 'TRE', 'MJP', 'JKP', '.']; return specialLabels.includes(this.selectedLabel || ''); } get isShashEnterDisabled(): boolean { if (this.selectedLabel === 'TAN') { return this.tanGroupStage >= 2 || this.tanGroups[this.tanGroupStage].length === 0; + } else if (this.multiLegLabels.includes(this.selectedLabel || '')) { + const maxLegs = this.getMaxLegs(this.selectedLabel || ''); + return this.multiLegStage >= maxLegs - 1 || this.multiLegGroups[this.multiLegStage].length === 0; } else if (this.twoGroupLabels.includes(this.selectedLabel || '')) { return this.isFirstGroupComplete || this.firstGroup.length === 0; } @@ -109,15 +117,19 @@ export class TouchPadMenuComponent implements OnInit { this.canPrint = false; this.isBoxed = false; - // Reset TAN state + // ✅ Reset TAN this.tanGroupStage = 0; this.tanGroups = [[], [], []]; - // Reset FOR/QUI state + // ✅ Reset FOR/QUI this.isFirstGroupComplete = false; this.firstGroup = []; this.secondGroup = []; + // ✅ Reset Multi-leg + this.multiLegStage = 0; + this.multiLegGroups = [[], [], [], [], []]; + this.selectionService.updatePartial({ label }); } @@ -136,6 +148,14 @@ export class TouchPadMenuComponent implements OnInit { return; } + if (this.multiLegLabels.includes(this.selectedLabel)) { + if (!this.multiLegGroups[this.multiLegStage].includes(number)) { + this.multiLegGroups[this.multiLegStage].push(number); + this.updateMultiLegSelection(); + } + return; + } + if (this.twoGroupLabels.includes(this.selectedLabel || '')) { if (!this.isFirstGroupComplete) { if (!this.firstGroup.includes(number)) { @@ -158,12 +178,23 @@ export class TouchPadMenuComponent implements OnInit { } } + private updateMultiLegSelection() { + const combined: (number | string)[] = []; + for (let i = 0; i <= this.multiLegStage; i++) { + if (i > 0) combined.push('-'); + combined.push(...this.multiLegGroups[i]); + } + this.selectedNumbers = combined; + this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] }); + } + isNumberDisabled(number: number): boolean { - if (this.twoGroupLabels.includes(this.selectedLabel || '') || this.selectedLabel === 'TAN') return false; + if (this.selectedLabel === 'TAN' || this.multiLegLabels.includes(this.selectedLabel || '') || this.twoGroupLabels.includes(this.selectedLabel || '')) { + return false; + } return this.selectedNumbers.includes(number); } - // 👉 Changed from padEnter to split into two handlers onPadEnter() { if (this.canPrint) { this.print(); @@ -183,13 +214,21 @@ export class TouchPadMenuComponent implements OnInit { return; } + if (this.multiLegLabels.includes(this.selectedLabel || '')) { + const maxLegs = this.getMaxLegs(this.selectedLabel || ''); + if (this.multiLegStage < maxLegs - 1) { + this.multiLegStage++; + this.updateMultiLegSelection(); + } + return; + } + if (this.twoGroupLabels.includes(this.selectedLabel || '')) { if (!this.isFirstGroupComplete && this.firstGroup.length > 0) { this.isFirstGroupComplete = true; this.secondGroup = []; this.selectedNumbers = [...this.firstGroup, '-']; this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] }); - return; } } } @@ -233,16 +272,16 @@ export class TouchPadMenuComponent implements OnInit { this.canPrint = false; this.isBoxed = false; - // Reset FOR/QUI + this.tanGroupStage = 0; + this.tanGroups = [[], [], []]; + this.isFirstGroupComplete = false; this.firstGroup = []; this.secondGroup = []; - // Reset TAN - this.tanGroupStage = 0; - this.tanGroups = [[], [], []]; + this.multiLegStage = 0; + this.multiLegGroups = [[], [], [], [], []]; - // Reset field modal this.fieldModalOpen = false; this.fieldInput = ''; this.fieldFEntered = false; @@ -260,22 +299,9 @@ export class TouchPadMenuComponent implements OnInit { this.updateCanPrint(); } - // ✅ New method for BKP logic removeLastNumber() { if (!this.selectedLabel || this.selectedNumbers.length === 0) return; - if (this.twoGroupLabels.includes(this.selectedLabel)) { - if (!this.isFirstGroupComplete && this.firstGroup.length > 0) { - this.firstGroup.pop(); - this.selectedNumbers = [...this.firstGroup]; - } else if (this.secondGroup.length > 0) { - this.secondGroup.pop(); - this.selectedNumbers = [...this.firstGroup, '-', ...this.secondGroup]; - } - this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] }); - return; - } - if (this.selectedLabel === 'TAN') { const currentGroup = this.tanGroups[this.tanGroupStage]; if (currentGroup.length > 0) { @@ -289,11 +315,41 @@ export class TouchPadMenuComponent implements OnInit { return; } + if (this.multiLegLabels.includes(this.selectedLabel)) { + const currentGroup = this.multiLegGroups[this.multiLegStage]; + if (currentGroup.length > 0) { + currentGroup.pop(); + this.updateMultiLegSelection(); + } + return; + } + + if (this.twoGroupLabels.includes(this.selectedLabel)) { + if (!this.isFirstGroupComplete && this.firstGroup.length > 0) { + this.firstGroup.pop(); + this.selectedNumbers = [...this.firstGroup]; + } else if (this.secondGroup.length > 0) { + this.secondGroup.pop(); + this.selectedNumbers = [...this.firstGroup, '-', ...this.secondGroup]; + } + this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] }); + return; + } + this.selectedNumbers.pop(); this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] }); } - // Calculator and Field Modal methods (unchanged)... + private getMaxLegs(label: string): number { + switch (label) { + case 'TRE': return 3; + case 'MJP': return 4; + case 'JKP': return 5; + default: return 3; + } + } + + // Calculator and Field Modal methods (unchanged) openCalculator() { this.calculatorOpen = true; this.calcDisplay = ''; } closeCalculator() { this.calculatorOpen = false; } press(val: string) { if (this.calcDisplay === 'Error') this.calcDisplay = ''; this.calcDisplay += val; }