# EmployeeFormPage

**Namespace:** `FrymasterBadgeApp`  
**Base Class:** `ContentPage`  
**Purpose:** Modal page for creating or editing employee records. Handles form binding, photo capture/cropping/zooming, badge generation, and SQL persistence.

## 🔑 Fields & Properties
| Name | Type | Access | Description |
|------|------|--------|-------------|
| `_db` | `SqlService` | `private readonly` | Database access service. |
| `_existingEmployee` | `Dictionary<string, object>?` | `private readonly` | Holds employee data when in edit mode. |
| `OnSavedCallback` | `Action<Dictionary<string, object>>` | `public` | Callback triggered after successful save. |
| `_isEditMode` | `bool` | `private readonly` | Determines if page is adding or updating. |
| `_tempCapturePath` | `string` | `private` | Path to temporarily cached camera image. |
| `_editX`, `_editY` | `double` | `private` | Current pan offset for photo cropping. |
| `_photosBasePath` | `string` | `private readonly` | Directory for employee photos (from Preferences). |
| `IsSaved` | `bool` | `public` | Tracks if save operation completed successfully. |
| `SavedEmployee` | `Dictionary<string, object>?` | `public` | Stores minimal data of the saved record. |

## 🛠 Constructor
### `EmployeeFormPage(SqlService db, Dictionary<string, object>? employee = null)`
- **Access:** `public`
- **Parameters:** `db` (`SqlService`), `employee` (`Dictionary?`, optional)
- **Behavior:** Binds `ZoomSlider` to `Image.ScaleProperty`. Routes to `SetupEditMode` or `SetupAddMode` based on `employee` parameter.

## 📦 Methods

### `SetupEditMode(Dictionary<string, object> employee)`
- **Access:** `private`
- **Behavior:** Populates form fields, disables `Data1Entry`, parses dates/booleans safely, loads photo if exists, and applies saved crop/zoom state.

### `SetupAddMode()`
- **Access:** `private`
- **Behavior:** Resets form: title `"Add Employee"`, clears `Data1Entry`, sets date to today, checks `ActiveCheckBox`.

### `OnTakePhotoClicked(object sender, EventArgs e)`
- **Access:** `private async void`
- **Behavior:** Captures photo via `MediaPicker`, saves to cache as `temp_form_capture.jpg`, updates preview, resets transforms.

### `OnPanUpdated(object sender, PanUpdatedEventArgs e)`
- **Access:** `private`
- **Behavior:** Updates `TranslationX/Y` in real-time during `Running`; commits offsets to `_editX/_editY` on `Completed`.

### `OnFetchBadgeClicked(object sender, EventArgs e)`
- **Access:** `private async void`
- **Behavior:** Generates and assigns unique badge to `Data9Entry` via `GenerateUniqueBadgeNumberAsync()`.

### `OnSaveClicked(object sender, EventArgs e)`
- **Access:** `private async void`
- **Behavior:** Validates `Data2Entry`, copies temp photo to `_photosBasePath` with unique name, builds `SqlParameter` array, executes `INSERT`/`UPDATE`, invokes callback, sets `IsSaved = true`, and pops modal.

### `GenerateUniqueBadgeNumberAsync()`
- **Access:** `private async Task<string>`
- **Returns:** `Task<string>` (Format: `*$F{6-digit}$A*`)

### `GenerateNextRecordNumber()`
- **Access:** `private`
- **Returns:** `string`
- **Behavior:** Queries `MAX(CAST(Data1 AS INT))`, returns next sequential number (starts at `100001`). *Currently unused in save flow.*

### `SafeToDouble(object? val, double defaultVal)`
- **Access:** `private`
- **Returns:** `double`
- **Behavior:** Safely parses object to `double`, returns `defaultVal` on failure/null.

### `OnCancelClicked(object sender, EventArgs e)`
- **Access:** `private async void`
- **Behavior:** Closes modal without saving.

---
**⚠️ Developer Notes:**
- `OnSaveClicked` contains a nested `try/catch` that calls `Navigation.PopModalAsync()` twice on success. Remove the outer call to prevent `InvalidOperationException`.
- `GenerateNextRecordNumber()` is implemented but never invoked. Wire it to auto-fill `Data1Entry` or remove it.