1 | #include <string.h> |
2 | #include <time.h> |
3 | #include <conio.h> |
4 | #include <dos.h> |
5 | #include <stdio.h> |
6 | #include <stdlib.h> |
7 | #include <windows.h> |
8 | |
9 | #define MAX_USERS 100 |
10 | #define MAX_SESSIONS 100 |
11 | #define MAX_TODO 100 |
12 | #define MAX_POMODOROS 100 |
13 | |
14 | |
15 | typedef struct { |
16 | char description[100]; |
17 | int completed; |
18 | } ToDoItem; |
19 | |
20 | typedef struct { |
21 | char category[50]; |
22 | struct tm startTime; |
23 | struct tm endTime; |
24 | int duration; |
25 | int sessionActive; |
26 | int countdownActive; |
27 | int countdownDuration; |
28 | char sessionType[20]; |
29 | } StudySession; |
30 | |
31 | typedef struct { |
32 | int studyDuration; |
33 | int breakDuration; |
34 | } PomodoroSession; |
35 | |
36 | typedef struct { |
37 | char username[50]; |
38 | int sessionCount; |
39 | StudySession sessions[MAX_SESSIONS]; |
40 | ToDoItem todos[MAX_TODO]; |
41 | int todoCount; |
42 | PomodoroSession pomodoros[MAX_POMODOROS]; |
43 | int pomodoroCount; |
44 | } User; |
45 | |
46 | |
47 | |
48 | User users[MAX_USERS]; |
49 | int userCount = 0; |
50 | int loggedIn = -1; |
51 | |
52 | |
53 | void clearScreen(); |
54 | void displayHeader(const char* header); |
55 | void displayMainMenu(); |
56 | void displayUserMenu(); |
57 | void createUser(); |
58 | void loginUser(); |
59 | void startStudyOption(); |
60 | void endSession(); |
61 | void showStatistics(); |
62 | void manageToDoList(); |
63 | int findUserIndex(const char* username); |
64 | void pressEnterToContinue(); |
65 | void startTimer(); |
66 | void startCountdown(); |
67 | int updateCountdown(int totalSeconds); |
68 | void pomodoro(int userIndex); |
69 | |
70 | |
71 | void clearScreen() { |
72 | #ifdef _WIN32 |
73 | system("cls"); |
74 | #else |
75 | system("clear"); |
76 | #endif |
77 | } |
78 | |
79 | |
80 | void displayHeader(const char* header) { |
81 | clearScreen(); |
82 | printf("== %s ==\n\n", header); |
83 | } |
84 | |
85 | |
86 | void displayMainMenu() { |
87 | system("color 3F"); |
88 | displayHeader("Main Menu"); |
89 | printf("1. Create new user\n"); |
90 | printf("2. Login\n"); |
91 | printf("3. Exit\n"); |
92 | printf("Enter your choice: "); |
93 | } |
94 | |
95 | |
96 | void displayUserMenu() { |
97 | displayHeader("User Menu"); |
98 | printf("1. Start a study session\n"); |
99 | printf("2. Show statistics\n"); |
100 | printf("3. Manage to-do list\n"); |
101 | printf("4. Logout\n"); |
102 | printf("Enter your choice: "); |
103 | } |
104 | |
105 | |
106 | void createUser() { |
107 | displayHeader("Create New User"); |
108 | if (userCount >= MAX_USERS) { |
109 | printf("Error: Maximum number of users reached.\n"); |
110 | pressEnterToContinue(); |
111 | return; |
112 | } |
113 | printf("Enter username: "); |
114 | scanf("%49s", users[userCount].username); |
115 | users[userCount].sessionCount = 0; |
116 | users[userCount].todoCount = 0; |
117 | userCount++; |
118 | printf("User created successfully.\n"); |
119 | pressEnterToContinue(); |
120 | } |
121 | |
122 | |
123 | void loginUser() { |
124 | displayHeader("Login"); |
125 | printf("Enter username: "); |
126 | char username[50]; |
127 | scanf("%49s", username); |
128 | int index = findUserIndex(username); |
129 | if (index == -1) { |
130 | printf("Error: User not found.\n"); |
131 | pressEnterToContinue(); |
132 | } else { |
133 | loggedIn = index; |
134 | printf("Login successful.\n"); |
135 | pressEnterToContinue(); |
136 | } |
137 | } |
138 | |
139 | |
140 | int findUserIndex(const char* username) { |
141 | for (int i = 0; i < userCount; i++) { |
142 | if (strcmp(users[i].username, username) == 0) { |
143 | return i; |
144 | } |
145 | } |
146 | return -1; |
147 | } |
148 | |
149 | |
150 | void pressEnterToContinue() { |
151 | printf("\nPress Enter to continue..."); |
152 | getchar(); |
153 | while (getchar() != '\n'); |
154 | } |
155 | |
156 | |
157 | void startStudyOption() { |
158 | if (loggedIn == -1 || users[loggedIn].sessionCount >= MAX_SESSIONS) { |
159 | printf("Error: No user logged in or maximum sessions reached.\n"); |
160 | pressEnterToContinue(); |
161 | return; |
162 | } |
163 | displayHeader("Study Session Options"); |
164 | printf("1. Timer\n"); |
165 | printf("2. Countdown\n"); |
166 | printf("3. Pomodoro\n"); |
167 | printf("4. Exit to User Menu\n"); |
168 | printf("Enter your choice: "); |
169 | int choice; |
170 | scanf("%d", &choice); |
171 | getchar(); |
172 | |
173 | switch (choice) { |
174 | case 1: |
175 | startTimer(); |
176 | break; |
177 | case 2: |
178 | startCountdown(); |
179 | break; |
180 | case 3: |
181 | pomodoro(loggedIn); |
182 | break; |
183 | case 4: |
184 | return; |
185 | default: |
186 | printf("Invalid choice. Please try again.\n"); |
187 | pressEnterToContinue(); |
188 | } |
189 | } |
190 | |
191 | |
192 | void startTimer() { |
193 | if (users[loggedIn].sessions[users[loggedIn].sessionCount].sessionActive) { |
194 | printf("Error: A session is already active. Please end the current session before starting a new one.\n"); |
195 | pressEnterToContinue(); |
196 | return; |
197 | } |
198 | displayHeader("Starting a New Study Session"); |
199 | printf("Enter study category: "); |
200 | scanf("%49s", users[loggedIn].sessions[users[loggedIn].sessionCount].category); |
201 | getchar(); |
202 | |
203 | users[loggedIn].sessions[users[loggedIn].sessionCount].sessionActive = 1; |
204 | strcpy(users[loggedIn].sessions[users[loggedIn].sessionCount].sessionType, "Timer"); |
205 | |
206 | time_t start = time(NULL); |
207 | users[loggedIn].sessions[users[loggedIn].sessionCount].startTime = *localtime(&start); |
208 | int elapsedTime = 0; |
209 | char key; |
210 | |
211 | displayHeader("Timer is on"); |
212 | printf("Press 'Enter' to stop the timer, 'p' to pause, 'q' to quit...\n"); |
213 | |
214 | time_t current; |
215 | while (1) { |
216 | current = time(NULL); |
217 | int elapsed = elapsedTime + (int)difftime(current, start); |
218 | int hours = elapsed / 3600; |
219 | int minutes = (elapsed % 3600) / 60; |
220 | int seconds = elapsed % 60; |
221 | |
222 | printf("\rElapsed time: %02d:%02d:%02d", hours, minutes, seconds); |
223 | fflush(stdout); |
224 | |
225 | Sleep(1000); |
226 | |
227 | if (_kbhit()) { |
228 | key = _getch(); |
229 | if (key == '\r') { |
230 | break; |
231 | } else if (key == 'p') { |
232 | printf("\nPaused. Press any key to resume, 'q' to quit...\n"); |
233 | while (1) { |
234 | if (_kbhit()) { |
235 | key = _getch(); |
236 | if (key == 'q') { |
237 | users[loggedIn].sessions[users[loggedIn].sessionCount].sessionActive = 0; |
238 | return; |
239 | } |
240 | break; |
241 | } |
242 | } |
243 | start = time(NULL); |
244 | elapsedTime = elapsed; |
245 | } else if (key == 'q') { |
246 | users[loggedIn].sessions[users[loggedIn].sessionCount].sessionActive = 0; |
247 | return; |
248 | } |
249 | } |
250 | } |
251 | |
252 | time_t end = time(NULL); |
253 | users[loggedIn].sessions[users[loggedIn].sessionCount].endTime = *localtime(&end); |
254 | users[loggedIn].sessions[users[loggedIn].sessionCount].duration = (int)difftime(end, start) + elapsedTime; |
255 | users[loggedIn].sessions[users[loggedIn].sessionCount].sessionActive = 0; |
256 | users[loggedIn].sessionCount++; |
257 | |
258 | printf("\nStudy session ended. Duration: %02d:%02d:%02d.\n", |
259 | users[loggedIn].sessions[users[loggedIn].sessionCount - 1].duration / 3600, |
260 | (users[loggedIn].sessions[users[loggedIn].sessionCount - 1].duration % 3600) / 60, |
261 | users[loggedIn].sessions[users[loggedIn].sessionCount - 1].duration % 60); |
262 | |
263 | |
264 | for (int i = 0; i < 3; i++) { |
265 | Beep(750, 300); |
266 | } |
267 | |
268 | pressEnterToContinue(); |
269 | } |
270 | |
271 | |
272 | void startCountdown() { |
273 | if (users[loggedIn].sessions[users[loggedIn].sessionCount].countdownActive) { |
274 | printf("Error: A countdown is already active. Please end the current countdown before starting a new one.\n"); |
275 | pressEnterToContinue(); |
276 | return; |
277 | } |
278 | displayHeader("Starting a New Countdown"); |
279 | printf("Enter countdown duration (minutes): "); |
280 | int duration; |
281 | scanf("%d", &duration); |
282 | getchar(); |
283 | |
284 | users[loggedIn].sessions[users[loggedIn].sessionCount].countdownActive = 1; |
285 | users[loggedIn].sessions[users[loggedIn].sessionCount].countdownDuration = duration * 60; |
286 | strcpy(users[loggedIn].sessions[users[loggedIn].sessionCount].sessionType, "Countdown"); |
287 | |
288 | time_t start = time(NULL); |
289 | users[loggedIn].sessions[users[loggedIn].sessionCount].startTime = *localtime(&start); |
290 | int totalSeconds = duration * 60; |
291 | |
292 | while (totalSeconds > 0) { |
293 | totalSeconds = updateCountdown(totalSeconds); |
294 | if (totalSeconds < 0) { |
295 | users[loggedIn].sessions[users[loggedIn].sessionCount].countdownActive = 0; |
296 | return; |
297 | } |
298 | } |
299 | |
300 | time_t end = time(NULL); |
301 | users[loggedIn].sessions[users[loggedIn].sessionCount].endTime = *localtime(&end); |
302 | users[loggedIn].sessions[users[loggedIn].sessionCount].duration = (int)difftime(end, start); |
303 | users[loggedIn].sessions[users[loggedIn].sessionCount].countdownActive = 0; |
304 | users[loggedIn].sessionCount++; |
305 | |
306 | printf("\nCountdown ended. Duration: %02d:%02d:%02d.\n", |
307 | users[loggedIn].sessions[users[loggedIn].sessionCount - 1].duration / 3600, |
308 | (users[loggedIn].sessions[users[loggedIn].sessionCount - 1].duration % 3600) / 60, |
309 | users[loggedIn].sessions[users[loggedIn].sessionCount - 1].duration % 60); |
310 | |
311 | |
312 | for (int i = 0; i < 3; i++) { |
313 | Beep(750, 300); |
314 | } |
315 | |
316 | pressEnterToContinue(); |
317 | } |
318 | |
319 | |
320 | int updateCountdown(int totalSeconds) { |
321 | time_t start = time(NULL); |
322 | time_t current; |
323 | char key; |
324 | |
325 | while (1) { |
326 | current = time(NULL); |
327 | int elapsed = (int)difftime(current, start); |
328 | int remaining = totalSeconds - elapsed; |
329 | |
330 | if (remaining <= 0) { |
331 | break; |
332 | } |
333 | |
334 | int minutes = remaining / 60; |
335 | int seconds = remaining % 60; |
336 | |
337 | printf("\rTime remaining: %02d:%02d", minutes, seconds); |
338 | fflush(stdout); |
339 | |
340 | Sleep(1000); |
341 | |
342 | if (_kbhit()) { |
343 | key = _getch(); |
344 | if (key == 'q') { |
345 | printf("\nCountdown canceled.\n"); |
346 | return -1; |
347 | } |
348 | } |
349 | } |
350 | |
351 | return 0; |
352 | } |
353 | |
354 | |
355 | void pomodoro(int userIndex) { |
356 | displayHeader("Pomodoro Session"); |
357 | printf("Enter study duration (minutes): "); |
358 | int studyDuration; |
359 | scanf("%d", &studyDuration); |
360 | getchar(); |
361 | printf("Enter break duration (minutes): "); |
362 | int breakDuration; |
363 | scanf("%d", &breakDuration); |
364 | getchar(); |
365 | |
366 | users[userIndex].pomodoros[users[userIndex].pomodoroCount].studyDuration = studyDuration * 60; |
367 | users[userIndex].pomodoros[users[userIndex].pomodoroCount].breakDuration = breakDuration * 60; |
368 | strcpy(users[loggedIn].sessions[users[loggedIn].sessionCount].sessionType, "Pomodoro"); |
369 | |
370 | int totalStudySeconds = studyDuration * 60; |
371 | int totalBreakSeconds = breakDuration * 60; |
372 | int pomodoroRounds = 4; |
373 | |
374 | for (int i = 0; i < pomodoroRounds; i++) { |
375 | printf("Pomodoro Round %d: Study Time\n", i + 1); |
376 | while (totalStudySeconds > 0) { |
377 | totalStudySeconds = updateCountdown(totalStudySeconds); |
378 | if (totalStudySeconds < 0) { |
379 | users[userIndex].pomodoroCount++; |
380 | return; |
381 | } |
382 | } |
383 | |
384 | printf("Pomodoro Round %d: Break Time\n", i + 1); |
385 | while (totalBreakSeconds > 0) { |
386 | totalBreakSeconds = updateCountdown(totalBreakSeconds); |
387 | if (totalBreakSeconds < 0) { |
388 | users[userIndex].pomodoroCount++; |
389 | return; |
390 | } |
391 | } |
392 | |
393 | totalStudySeconds = studyDuration * 60; |
394 | totalBreakSeconds = breakDuration * 60; |
395 | } |
396 | |
397 | users[userIndex].pomodoroCount++; |
398 | users[loggedIn].sessions[users[loggedIn].sessionCount].sessionActive = 0; |
399 | users[loggedIn].sessionCount++; |
400 | |
401 | printf("Pomodoro session completed.\n"); |
402 | |
403 | |
404 | for (int i = 0; i < 3; i++) { |
405 | Beep(750, 300); |
406 | } |
407 | |
408 | pressEnterToContinue(); |
409 | } |
410 | |
411 | int main() { |
412 | int choice; |
413 | while (1) { |
414 | displayMainMenu(); |
415 | scanf("%d", &choice); |
416 | getchar(); |
417 | switch (choice) { |
418 | case 1: |
419 | createUser(); |
420 | break; |
421 | case 2: |
422 | loginUser(); |
423 | if (loggedIn != -1) { |
424 | while (1) { |
425 | displayUserMenu(); |
426 | scanf("%d", &choice); |
427 | getchar(); |
428 | if (choice == 4) break; |
429 | switch (choice) { |
430 | case 1: |
431 | startStudyOption(); |
432 | break; |
433 | case 2: |
434 | showStatistics(); |
435 | break; |
436 | case 3: |
437 | manageToDoList(); |
438 | break; |
439 | default: |
440 | printf("Invalid choice. Please try again.\n"); |
441 | pressEnterToContinue(); |
442 | } |
443 | } |
444 | } |
445 | break; |
446 | case 3: |
447 | exit(0); |
448 | default: |
449 | printf("Invalid choice. Please try again.\n"); |
450 | pressEnterToContinue(); |
451 | } |
452 | } |
453 | } |
454 | |
455 | |
456 | void endSession() {} |
457 | void showStatistics() {} |
458 | void manageToDoList() {} |