# 機能設計書 24-Calendar

## 概要

本ドキュメントは、AvaloniaフレームワークにおけるCalendarコントロールの機能設計を記載する。Calendarは、カレンダー形式で日付を表示・選択するためのUIコントロールである。

### 本機能の処理概要

Calendarは、月表示・年表示・10年表示の3つのモードを持ち、日付の選択・範囲選択・ブラックアウト日（選択不可日）の設定などの機能を提供するカレンダーコントロールである。Microsoft WPFのCalendarコントロールを移植したもので、同様のAPIを提供する。

**業務上の目的・背景**：
業務アプリケーションにおいて日付入力は頻繁に発生する操作であり、カレンダーUIによる直感的な日付選択が必要である。予定管理、期日設定、スケジュール表示など幅広い用途で使用される。

**機能の利用シーン**：
- 予定・イベントの日付選択
- 予約システムでの日付指定
- レポートの期間選択
- 締め切り・期日の設定
- スケジュールカレンダーの表示

**主要な処理内容**：
1. 月表示モードでの日付グリッド表示
2. 年表示モードでの月選択
3. 10年表示モードでの年選択
4. 単一日付選択（SingleDate）
5. 複数日付選択（MultipleRange）
6. ブラックアウト日の設定（選択不可日）
7. 表示範囲の制限（DisplayDateStart/End）
8. 選択範囲の制限（SelectableDateStart/End）
9. SelectedDatesChangedイベントの発行

**関連システム・外部連携**：
- DatePickerとの連携（Calendarをポップアップとして使用）
- CalendarBlackoutDatesCollectionによる選択不可日管理

**権限による制御**：
本コントロールには権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | Calendar | 主画面 | Calendarコントロールのデモ |
| 18 | CalendarDatePicker | 関連 | DatePickerがCalendarを使用 |
| 26 | DatePicker | 関連 | DatePickerがCalendarをポップアップで使用 |

## 機能種別

UI操作 / 入力コントロール / 日付選択

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| DisplayDate | DateTime | No | カレンダーに表示する月/年 | DisplayDateStart〜DisplayDateEnd内 |
| DisplayDateStart | DateTime? | No | 表示可能な最小日付 | - |
| DisplayDateEnd | DateTime? | No | 表示可能な最大日付 | DisplayDateStart以上 |
| SelectionMode | CalendarSelectionMode | No | 選択モード | SingleDate/SingleRange/MultipleRange/None |
| SelectedDate | DateTime? | No | 選択された日付（単一選択時） | - |
| SelectedDates | SelectedDatesCollection | No | 選択された日付コレクション | - |
| FirstDayOfWeek | DayOfWeek | No | 週の開始曜日 | デフォルト: カルチャ依存 |
| IsTodayHighlighted | bool | No | 今日の日付をハイライト | デフォルト: true |
| DisplayMode | CalendarMode | No | 表示モード | Month/Year/Decade |
| BlackoutDates | CalendarBlackoutDatesCollection | No | 選択不可日のコレクション | - |
| HeaderBackground | IBrush | No | ヘッダー背景色 | - |

### 入力データソース

- ユーザーによる日付クリック
- ユーザーによるナビゲーション操作（前月/次月）
- プログラムによるSelectedDate/SelectedDates設定
- データバインディングによる日付制御

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SelectedDate | DateTime? | 選択された日付 |
| SelectedDates | SelectedDatesCollection | 選択された日付のコレクション |
| DisplayDate | DateTime | 現在表示中の月/年 |
| DisplayMode | CalendarMode | 現在の表示モード |

### 出力先

- UI表示（カレンダーグリッド、選択状態）
- SelectedDatesChangedイベントの発行
- DisplayDateChangedイベントの発行
- DisplayModeChangedイベントの発行

## 処理フロー

### 処理シーケンス

```
1. カレンダー初期化
   └─ CalendarInfo生成、MonthControl設定
2. 表示モード判定
   ├─ Month: 日付グリッド表示
   ├─ Year: 月選択グリッド表示
   └─ Decade: 年選択グリッド表示
3. 日付選択操作
   └─ OnCalendarDayButtonMouseDown/Up
4. 選択モード判定
   ├─ None: 選択不可
   ├─ SingleDate: 単一選択
   ├─ SingleRange: 連続範囲選択
   └─ MultipleRange: 複数範囲選択
5. 選択日検証
   ├─ ブラックアウト日チェック
   └─ SelectableDateStart/End範囲チェック
6. SelectedDates更新
   └─ コレクション更新
7. イベント発行
   └─ SelectedDatesChanged
```

### フローチャート

```mermaid
flowchart TD
    A[日付クリック] --> B{選択モード?}
    B -->|None| C[処理なし]
    B -->|SingleDate| D[単一選択処理]
    B -->|SingleRange| E[範囲選択処理]
    B -->|MultipleRange| F[複数範囲選択処理]
    D --> G{ブラックアウト日?}
    E --> G
    F --> G
    G -->|Yes| C
    G -->|No| H{選択可能範囲内?}
    H -->|No| C
    H -->|Yes| I[SelectedDates更新]
    I --> J[UI更新]
    J --> K[SelectedDatesChangedイベント]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ブラックアウト日 | BlackoutDatesに含まれる日付は選択不可 | 常時適用 |
| BR-002 | 表示範囲制限 | DisplayDateはDisplayDateStart〜DisplayDateEnd内に制限 | 範囲設定時 |
| BR-003 | 選択範囲制限 | 選択可能な日付はSelectableDateStart〜SelectableDateEnd内に制限 | 範囲設定時 |
| BR-004 | 週開始曜日 | FirstDayOfWeekに基づいて曜日ヘッダーを配置 | 常時適用 |
| BR-005 | 今日ハイライト | IsTodayHighlighted=trueの場合、今日の日付を視覚的にハイライト | 設定時 |

### 計算ロジック

10年表示の範囲計算：
```
decadeStart = (DisplayDate.Year / 10) * 10
decadeEnd = decadeStart + 9
表示範囲: decadeStart - 1 〜 decadeEnd + 1
```

## データベース操作仕様

本コントロールはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効な日付範囲 | DisplayDateEndがDisplayDateStart未満 | 自動的にコエルスして調整 |
| - | ブラックアウト日選択 | ブラックアウト日をプログラムで選択 | 例外をスローせず無視 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- 月表示の切り替えは即座に行われる必要がある
- 大量のブラックアウト日がある場合もスムーズに動作

## セキュリティ考慮事項

本コントロールにはセキュリティ上の特別な考慮事項はない。

## 備考

- Microsoft WPFのCalendarコントロールをベースに実装されている
- DatePickerと組み合わせて使用することが多い

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

カレンダー関連の列挙型とコレクションを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Calendar.cs | `src/Avalonia.Controls/Calendar/Calendar.cs` | CalendarMode、CalendarSelectionMode列挙型（22-79行目） |
| 1-2 | CalendarBlackoutDatesCollection.cs | `src/Avalonia.Controls/Calendar/CalendarBlackoutDatesCollection.cs` | ブラックアウト日コレクション |
| 1-3 | SelectedDatesCollection.cs | `src/Avalonia.Controls/Calendar/SelectedDatesCollection.cs` | 選択日コレクション |

**読解のコツ**: Calendarは3つの表示モード（Month/Year/Decade）を持ち、それぞれで異なるグリッドを表示する。

#### Step 2: エントリーポイントを理解する

Calendarクラスの主要プロパティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Calendar.cs | `src/Avalonia.Controls/Calendar/Calendar.cs` | プロパティ定義（101-350行目） |

**主要処理フロー**:
1. **22-41行目**: CalendarMode列挙型（Month/Year/Decade）
2. **51-79行目**: CalendarSelectionMode列挙型（SingleDate/SingleRange/MultipleRange/None）
3. **101-350行目**: DisplayDate/DisplayDateStart/DisplayDateEnd等のプロパティ定義

#### Step 3: テンプレートパーツを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Calendar.cs | `src/Avalonia.Controls/Calendar/Calendar.cs` | OnApplyTemplate、MonthControl |

**主要処理フロー**:
- **600-650行目**: OnApplyTemplateでMonthControlを取得
- **850-900行目**: SetMonthModeCalendarでMonthモードのカレンダーを構築

#### Step 4: 日付選択ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Calendar.cs | `src/Avalonia.Controls/Calendar/Calendar.cs` | OnCalendarDayButtonMouseDown/Up |
| 4-2 | CalendarDayButton.cs | `src/Avalonia.Controls/Calendar/CalendarDayButton.cs` | 日付ボタンコントロール |

**主要処理フロー**:
- **1100-1200行目**: OnCalendarDayButtonMouseDownで選択処理開始
- **1250-1350行目**: ProcessSelectionで選択モードに応じた処理

### プログラム呼び出し階層図

```
Calendar
    │
    ├─ OnApplyTemplate
    │      └─ SetCalendarDisplayMode
    │             ├─ SetMonthModeCalendar
    │             ├─ SetYearModeCalendar
    │             └─ SetDecadeModeCalendar
    │
    ├─ OnDisplayDateChanged
    │      └─ UpdateMonthMode
    │
    ├─ OnCalendarDayButtonMouseDown
    │      └─ ProcessSelection
    │             ├─ SingleDate選択
    │             ├─ SingleRange選択
    │             └─ MultipleRange選択
    │
    └─ OnSelectedDatesCollectionChanged
           └─ RaiseSelectedDatesChanged
```

### データフロー図

```
[入力]                    [処理]                         [出力]

DisplayDate設定 ─────▶ SetCalendarDisplayMode
                              │
                              ├─▶ SetMonthModeCalendar
                              ├─▶ SetYearModeCalendar
                              └─▶ SetDecadeModeCalendar
                                     │
日付クリック ───────▶ OnCalendarDayButtonMouseDown
                              │
                              ▼
                       ProcessSelection
                              │
                              ├─ ブラックアウト日チェック
                              └─ SelectableDateRange チェック
                                     │
                                     ▼
                              SelectedDates更新 ──▶ SelectedDatesChangedイベント
                                     │
                                     ▼
                              UI更新（選択状態表示）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Calendar.cs | `src/Avalonia.Controls/Calendar/Calendar.cs` | ソース | メインコントロールクラス |
| CalendarItem.cs | `src/Avalonia.Controls/Calendar/CalendarItem.cs` | ソース | 月表示コンテナ |
| CalendarDayButton.cs | `src/Avalonia.Controls/Calendar/CalendarDayButton.cs` | ソース | 日付ボタン |
| CalendarButton.cs | `src/Avalonia.Controls/Calendar/CalendarButton.cs` | ソース | 月/年ボタン |
| CalendarBlackoutDatesCollection.cs | `src/Avalonia.Controls/Calendar/CalendarBlackoutDatesCollection.cs` | ソース | ブラックアウト日コレクション |
| SelectedDatesCollection.cs | `src/Avalonia.Controls/Calendar/SelectedDatesCollection.cs` | ソース | 選択日コレクション |
| CalendarDateRange.cs | `src/Avalonia.Controls/Calendar/CalendarDateRange.cs` | ソース | 日付範囲クラス |
| Calendar.xaml | `src/Avalonia.Themes.Fluent/Controls/Calendar.xaml` | テンプレート | Fluentテーマのテンプレート |
