# План реализации N_Var режимов в BIgo Reader

## Обзор

Реализовать функциональность отображения диаграмм в зависимости от значения `N_Var` из таблицы `Page_Diagram_Links`.

## Требования

### 1. N_Var = 0 (Режим решения задачи)

**Поведение:**
- Показать только начальную позицию (setup stones + labels для move_number=0)
- Отключить кнопки навигации по ходам и вариантам
- Включить режим клика по доске для решения
- Проверять координаты клика против первого хода **Variation 1**
- Отслеживать попытки (макс. 3)

**Реакция на клик:**
- **Правильно**: 
  - Показать сообщение "Правильно!"
  - Показать сделанный ход на доске с номером
  - Перейти к следующему ходу пользователя
- **Неправильно**:
  - Показать "Ошибка"
  - Увеличить счётчик попыток
  - Если попытки исчерпаны (3): показать правильный первый ход Variation 1
  - Если остались попытки: дать возможность попробовать снова

**Опционально (п.б - для обеих программ):**
- Поддержка показа ходов из Main Line с последующим переходом к вариантам
- При переходе к варианту стирать номера с Main Line ходов
- Вариант начинать с хода 1

### 2. N_Var = 1 (Показать Variation 1)

**Поведение:**
- Показать ВСЕ ходы Variation 1 с номерами
- Включить навигацию по ходам (|< < > >|)
- Включить навигацию по вариантам (если есть > 1 вариации)
- Разрешить пользователю шагать через ходы

### 3. N_Var = 2 (Показать Variation 2)

**Поведение:**
- Аналогично N_Var = 1, но для Variation 2

## Существующий код

**Файл:** `bigo_reader/diagrams/diagram_viewer.py`

**Текущие атрибуты:**
```python
self.n_var = n_var  # Уже есть!
self.variations = []  # List of variation dicts
self.current_variant_index = 0
self.current_move = 0
```

**Кнопки навигации (строки ~130-145):**
```python
# Move navigation buttons
ttk.Button(toolbar, text="|<", width=2, command=self._go_to_start)
ttk.Button(toolbar, text="<", width=2, command=self._prev_move)
ttk.Button(toolbar, text=">", width=2, command=self._next_move)
ttk.Button(toolbar, text=">|", width=2, command=self._go_to_end)

# Variant navigation buttons
ttk.Button(toolbar, text="<", width=2, command=self._prev_variant)
ttk.Button(toolbar, text=">", width=2, command=self._next_variant)
```

## Изменения

### Добавить атрибуты для problem mode

```python
# In __init__
self.problem_mode = False  # Is N_Var = 0?
self.problem_attempts = 0  # Current attempts (max 3)
self.problem_max_attempts = 3
self.problem_solved = False
self.problem_current_move = 0  # Which move we're checking
```

### Добавить сохранение кнопок как атрибуты

Изменить `_build_ui()` для сохранения ссылок на кнопки:
```python
self.btn_first_move = ttk.Button(toolbar, text="|<", width=2, command=self._go_to_start)
self.btn_prev_move = ttk.Button(toolbar, text="<", width=2, command=self._prev_move)
self.btn_next_move = ttk.Button(toolbar, text=">", width=2, command=self._next_move)
self.btn_last_move = ttk.Button(toolbar, text=">|", width=2, command=self._go_to_end)
self.btn_prev_variant = ttk.Button(toolbar, text="<", width=2, command=self._prev_variant)
self.btn_next_variant = ttk.Button(toolbar, text=">", width=2, command=self._next_variant)
```

### Изменить логику после загрузки диаграммы

В конце `_parse_sgf()` вместо простого `_load_variant(self.n_var)`:

```python
# Determine display mode based on N_Var
if self.n_var == 0:
    self._enter_problem_mode()
elif self.n_var > 0 and self.n_var <= len(self.variations):
    self._enter_variation_mode(self.n_var)
else:
    # N_Var not specified or invalid - show main line
    self._enter_normal_mode()
```

### Добавить новые методы

```python
def _enter_problem_mode(self):
    """Activate problem solving mode (N_Var = 0)"""
    self.problem_mode = True
    self.problem_attempts = 0
    self.problem_solved = False
    self.problem_current_move = 0
    
    # Disable navigation buttons
    self.btn_first_move.config(state=tk.DISABLED)
    self.btn_prev_move.config(state=tk.DISABLED)
    self.btn_next_move.config(state=tk.DISABLED)
    self.btn_last_move.config(state=tk.DISABLED)
    self.btn_prev_variant.config(state=tk.DISABLED)
    self.btn_next_variant.config(state=tk.DISABLED)
    
    # Show only initial position (no moves)
    self.current_move = 0
    self._render_position()
    
    # Bind canvas click
    self.canvas.bind("<Button-1>", self._on_canvas_click)
    
    # Update status
    self.status_var.set("Problem mode: Click to place stone. Attempts: 0/3")
    
    # Show initial comment
    self._show_comments(0)

def _enter_variation_mode(self, n_var: int):
    """Show specific variation (N_Var = 1, 2, etc.)"""
    self.problem_mode = False
    
    # Find variation by number
    target_var = None
    for var in self.variations:
        if var.get('number') == n_var:
            target_var = var
            break
    
    if not target_var:
        messagebox.showwarning("Warning", f"Variation {n_var} not found")
        return
    
    # Load variation
    self.current_variant_index = self.variations.index(target_var)
    self._load_variant_moves(target_var)
    
    # Show all moves
    self.current_move = len(target_var.get('moves', []))
    self._render_position()
    
    # Enable navigation
    self.btn_first_move.config(state=tk.NORMAL)
    self.btn_prev_move.config(state=tk.NORMAL)
    self.btn_next_move.config(state=tk.NORMAL)
    self.btn_last_move.config(state=tk.NORMAL)
    
    # Enable variant navigation if multiple variants exist
    self.btn_prev_variant.config(state=tk.NORMAL if self.current_variant_index > 0 else tk.DISABLED)
    self.btn_next_variant.config(state=tk.NORMAL if self.current_variant_index < len(self.variations) - 1 else tk.DISABLED)
    
    # Update status
    self.status_var.set(f"Showing Variation {n_var} - {self.current_move} moves")

def _on_canvas_click(self, event):
    """Handle canvas click in problem mode"""
    if not self.problem_mode or self.problem_solved:
        return
    
    # Convert click to board coordinates
    x, y = self._canvas_to_board_coords(event.x, event.y)
    if x is None or y is None:
        return
    
    LOGGER.info(f"Problem mode click: ({x}, {y})")
    
    # Check if we have Variation 1
    if not self.variations or len(self.variations) == 0:
        return
    
    first_var = self.variations[0]  # Variation 1
    var_moves = first_var.get('moves', [])
    
    if not var_moves:
        return
    
    # Get expected move
    if self.problem_current_move >= len(var_moves):
        return  # All moves checked
    
    expected_move = var_moves[self.problem_current_move]
    expected_point = expected_move['point']
    expected_x, expected_y = self._sgf_to_coords(expected_point)
    
    # Check if correct
    if (x, y) == (expected_x, expected_y):
        # Correct!
        self._handle_correct_move(expected_move)
    else:
        # Wrong!
        self._handle_wrong_move()

def _handle_correct_move(self, move):
    """Handle correct move in problem mode"""
    messagebox.showinfo("Correct!", "Правильно!")
    
    # Place the stone
    color = 'Black Stone' if move['color'] == 'B' else 'White Stone'
    x, y = self._sgf_to_coords(move['point'])
    self.go_board.set_stone(x, y, color)
    
    # Add move number
    move_num = self.problem_current_move + 1
    self.go_board.set_markup(x, y, f'Label:{move_num}')
    
    # Render
    self.board_renderer.draw_board()
    
    # Move to next
    self.problem_current_move += 1
    self.problem_attempts = 0  # Reset for next move
    
    # Check if finished
    first_var = self.variations[0]
    var_moves = first_var.get('moves', [])
    
    if self.problem_current_move >= len(var_moves):
        self.problem_solved = True
        self.status_var.set("Problem solved! All moves correct!")
        messagebox.showinfo("Success!", "Отлично! Все ходы правильные!")
    else:
        self.status_var.set(f"Problem mode: Move {self.problem_current_move + 1}. Attempts: 0/3")

def _handle_wrong_move(self):
    """Handle wrong move in problem mode"""
    self.problem_attempts += 1
    
    messagebox.showerror("Wrong!", "Ошибка!")
    
    if self.problem_attempts >= self.problem_max_attempts:
        # Show correct move
        self.problem_solved = True
        
        first_var = self.variations[0]
        first_move = first_var.get('moves', [])[self.problem_current_move]
        
        color = 'Black Stone' if first_move['color'] == 'B' else 'White Stone'
        x, y = self._sgf_to_coords(first_move['point'])
        self.go_board.set_stone(x, y, color)
        self.go_board.set_markup(x, y, 'Label:1')
        self.board_renderer.draw_board()
        
        self.status_var.set("Attempts exhausted. Showing correct move.")
        messagebox.showinfo("Solution", "Попытки исчерпаны. Показан правильный ход.")
    else:
        remaining = self.problem_max_attempts - self.problem_attempts
        self.status_var.set(f"Wrong! {remaining} attempts remaining")

def _canvas_to_board_coords(self, canvas_x: int, canvas_y: int) -> Tuple[Optional[int], Optional[int]]:
    """Convert canvas click coordinates to board coordinates"""
    if not self.board_renderer:
        return None, None
    
    # Use renderer's margin and cell_size
    margin = self.board_renderer.margin
    cell_size = self.board_renderer.cell_size
    
    # Calculate board position
    x = round((canvas_x - margin) / cell_size)
    y = round((canvas_y - margin) / cell_size)
    
    # Validate
    if 0 <= x < self.go_board.width and 0 <= y < self.go_board.height:
        return x, y
    
    return None, None
```

## Референс из bigo_mobile

См. файл: `d:\BIgo\bigo_mobile\screens\book_reader_screen.py`
- Строки 1898-2040: `_enter_problem_mode` и `_enter_variation_mode` логика
- Строки 2804-2930: `_on_goban_click` и `_handle_problem_click`

## Тестирование

1. Открыть диаграмму с N_Var = 0 → должен включиться problem mode
2. Кликнуть правильный ход → должно показать "Правильно"
3. Кликнуть неправильный ход 3 раза → должно показать решение
4. Открыть диаграмму с N_Var = 1 → должна показаться Variation 1 полностью
5. Навигация по ходам должна работать

## Статус

- [ ] Добавлены атрибуты problem mode
- [ ] Сохранены ссылки на кнопки навигации
- [ ] Реализован `_enter_problem_mode()`
- [ ] Реализован `_enter_variation_mode()`
- [ ] Реализован `_on_canvas_click()`
- [ ] Реализован `_handle_correct_move()`
- [ ] Реализован `_handle_wrong_move()`
- [ ] Реализован `_canvas_to_board_coords()`
- [ ] Протестировано с обеими БД
- [ ] Добавлена поддержка Main Line для N_Var=0 (п.б)
