1+ // We can reuse the problem generation logic
2+ // No need for animationSystem here unless we add feedback animations
3+
4+ let currentProblem = null ;
5+ let isVertical = false ; // State for orientation
6+
7+ // DOM Elements
8+ const problemTextElement = document . getElementById ( 'problem-text' ) ;
9+ const answerTextElement = document . getElementById ( 'answer-text' ) ;
10+ const flashcardElement = document . getElementById ( 'flashcard' ) ;
11+ const flashcardContainer = document . getElementById ( 'flashcard-container' ) ; // Need container for size change
12+ const flipButton = document . getElementById ( 'flip-btn' ) ;
13+ const nextButton = document . getElementById ( 'next-btn' ) ;
14+ const orientationSwitch = document . getElementById ( 'orientation-switch' ) ;
15+ const horizontalLabel = document . querySelector ( '.toggle-label.horizontal' ) ;
16+ const verticalLabel = document . querySelector ( '.toggle-label.vertical' ) ;
17+ const sliderBg = document . querySelector ( '.slider-bg' ) ;
18+
19+ // --- Problem Generation (copied/adapted from addition-subtraction-0-20.js) ---
20+ function generateProblem ( vertical = false ) { // Accept orientation flag
21+ const isAddition = Math . random ( ) < 0.5 ;
22+ let num1 , num2 , correctAnswer , questionText ;
23+ const maxVal = 20 ;
24+
25+ let displayNum1 , displayNum2 ; // Numbers specifically for display
26+
27+ if ( isAddition ) {
28+ correctAnswer = Math . floor ( Math . random ( ) * ( maxVal + 1 ) ) ; // Result between 0 and 20
29+ num1 = Math . floor ( Math . random ( ) * ( correctAnswer + 1 ) ) ; // First number <= result
30+ num2 = correctAnswer - num1 ; // Second number ensures sum is correctAnswer
31+
32+ // Ensure larger number is first for display
33+ if ( num2 > num1 ) {
34+ displayNum1 = num2 ;
35+ displayNum2 = num1 ;
36+ } else {
37+ displayNum1 = num1 ;
38+ displayNum2 = num2 ;
39+ }
40+
41+ if ( vertical ) {
42+ // Format for vertical display using HTML
43+ const num1Str = String ( displayNum1 ) . padStart ( 2 , ' ' ) ; // Pad for alignment
44+ const num2Str = String ( displayNum2 ) . padStart ( 2 , ' ' ) ;
45+ // Structure for better CSS control
46+ questionText = `<span class="num-line"> ${ num1Str } </span>
47+ <span class="num-line op">+ ${ num2Str } </span>
48+ <span class="op-line"></span>
49+ <span class="num-line q-mark"> ?</span>` ;
50+ } else {
51+ questionText = `${ displayNum1 } + ${ displayNum2 } = ?` ;
52+ }
53+ } else { // Subtraction
54+ num1 = Math . floor ( Math . random ( ) * ( maxVal + 1 ) ) ; // First number between 0 and 20
55+ num2 = Math . floor ( Math . random ( ) * ( num1 + 1 ) ) ; // Second number <= first number (ensures non-negative result)
56+ correctAnswer = num1 - num2 ;
57+
58+ // For subtraction, num1 is already >= num2, so use them directly
59+ displayNum1 = num1 ;
60+ displayNum2 = num2 ;
61+
62+ if ( vertical ) {
63+ // Format for vertical display using HTML
64+ const num1Str = String ( displayNum1 ) . padStart ( 2 , ' ' ) ; // Pad for alignment
65+ const num2Str = String ( displayNum2 ) . padStart ( 2 , ' ' ) ;
66+ // Structure for better CSS control
67+ questionText = `<span class="num-line"> ${ num1Str } </span>
68+ <span class="num-line op">- ${ num2Str } </span>
69+ <span class="op-line"></span>
70+ <span class="num-line q-mark"> ?</span>` ;
71+ } else {
72+ questionText = `${ displayNum1 } - ${ displayNum2 } = ?` ;
73+ }
74+ }
75+
76+ return {
77+ questionText : questionText , // Can be HTML string now
78+ correctAnswer : correctAnswer // Use the original calculated answer
79+ } ;
80+ }
81+
82+ // --- Flashcard Logic ---
83+
84+ // Loads new problem data and updates ONLY the front text
85+ function loadNewProblemData ( ) {
86+ currentProblem = generateProblem ( isVertical ) ; // Pass current orientation
87+ if ( isVertical ) {
88+ problemTextElement . innerHTML = currentProblem . questionText ; // Use innerHTML for vertical format
89+ flashcardElement . classList . add ( 'vertical' ) ;
90+ flashcardContainer . classList . add ( 'vertical' ) ;
91+ } else {
92+ problemTextElement . textContent = currentProblem . questionText ; // Use textContent for horizontal
93+ flashcardElement . classList . remove ( 'vertical' ) ;
94+ flashcardContainer . classList . remove ( 'vertical' ) ;
95+ }
96+ // Answer is updated in flipCard
97+ }
98+
99+ // Handles flipping the card to show the answer
100+ function flipCard ( ) {
101+ // Update the answer text JUST BEFORE flipping
102+ if ( currentProblem ) {
103+ answerTextElement . textContent = currentProblem . correctAnswer ;
104+ answerTextElement . style . visibility = 'visible' ; // Ensure it's visible
105+ }
106+ flashcardElement . classList . add ( 'is-flipped' ) ;
107+ flipButton . style . display = 'none' ;
108+ nextButton . style . display = 'inline-block' ;
109+ }
110+
111+ // Handles going to the next card
112+ function displayNextProblem ( ) {
113+ // Hide the answer content immediately
114+ answerTextElement . style . visibility = 'hidden' ;
115+
116+ // Start flip back animation
117+ flashcardElement . classList . remove ( 'is-flipped' ) ;
118+
119+ // Wait for the flip back animation to start visually before changing front content
120+ setTimeout ( ( ) => {
121+ loadNewProblemData ( ) ; // Load and display new problem data on the FRONT only
122+
123+ // Reset button visibility
124+ flipButton . style . display = 'inline-block' ;
125+ nextButton . style . display = 'none' ;
126+ } , 100 ) ; // Shorter delay might be sufficient now
127+ }
128+
129+ // Handle orientation toggle - UPDATED for new design
130+ function handleOrientationChange ( ) {
131+ isVertical = orientationSwitch . checked ;
132+
133+ // Update the visual state of the toggle
134+ if ( isVertical ) {
135+ horizontalLabel . classList . remove ( 'active' ) ;
136+ verticalLabel . classList . add ( 'active' ) ;
137+ sliderBg . classList . add ( 'vertical' ) ;
138+ } else {
139+ horizontalLabel . classList . add ( 'active' ) ;
140+ verticalLabel . classList . remove ( 'active' ) ;
141+ sliderBg . classList . remove ( 'vertical' ) ;
142+ }
143+
144+ loadNewProblemData ( ) ; // Load a new problem in the new orientation
145+
146+ // Reset card state regardless
147+ flashcardElement . classList . remove ( 'is-flipped' ) ;
148+ answerTextElement . style . visibility = 'hidden' ;
149+ flipButton . style . display = 'inline-block' ;
150+ nextButton . style . display = 'none' ;
151+ }
152+
153+ // --- Event Listeners ---
154+ // Add click events on the labels for better UX
155+ horizontalLabel . addEventListener ( 'click' , ( ) => {
156+ if ( orientationSwitch . checked ) {
157+ orientationSwitch . checked = false ;
158+ handleOrientationChange ( ) ;
159+ }
160+ } ) ;
161+
162+ verticalLabel . addEventListener ( 'click' , ( ) => {
163+ if ( ! orientationSwitch . checked ) {
164+ orientationSwitch . checked = true ;
165+ handleOrientationChange ( ) ;
166+ }
167+ } ) ;
168+
169+ flipButton . addEventListener ( 'click' , flipCard ) ;
170+ nextButton . addEventListener ( 'click' , displayNextProblem ) ;
171+ orientationSwitch . addEventListener ( 'change' , handleOrientationChange ) ;
172+
173+ // Add click listener to the flashcard itself
174+ flashcardElement . addEventListener ( 'click' , ( ) => {
175+ if ( flashcardElement . classList . contains ( 'is-flipped' ) ) {
176+ // If card is flipped (showing answer), clicking goes to next
177+ displayNextProblem ( ) ;
178+ } else {
179+ // If card is not flipped (showing question), clicking flips it
180+ flipCard ( ) ;
181+ }
182+ } ) ;
183+
184+ // Initial Load
185+ document . addEventListener ( 'DOMContentLoaded' , ( ) => {
186+ isVertical = orientationSwitch . checked ; // Check initial state
187+ // Update visual state to match initial checkbox state
188+ if ( isVertical ) {
189+ horizontalLabel . classList . remove ( 'active' ) ;
190+ verticalLabel . classList . add ( 'active' ) ;
191+ sliderBg . classList . add ( 'vertical' ) ;
192+ }
193+ loadNewProblemData ( ) ; // Load the first problem's front data
194+ answerTextElement . style . visibility = 'hidden' ; // Ensure answer starts hidden
195+ flipButton . style . display = 'inline-block' ;
196+ nextButton . style . display = 'none' ;
197+ } ) ;
0 commit comments