# Milestone 6: System Apps

**Status**: 75% Complete
**Goal**: Core smartphone apps with full functionality.

---

## Overview

System apps provide the essential smartphone experience:
- Home launcher
- Phone/Dialer
- Messages
- Contacts
- Settings
- Browser
- Store (TODO)
- Camera (TODO)
- Music (TODO)

---

## App Status

### Completed Apps

| App | Location | Features | Status |
|-----|----------|----------|--------|
| Home | `apps/home/` | App grid, dock, navigation | Complete |
| Dialer | `apps/dialer/` | Keypad, call UI (mock) | Complete |
| Messages | `apps/messages/` | Conversation list, chat | Complete |
| Contacts | `apps/contacts/` | List, search, detail | Complete |
| Settings | `apps/settings/` | Display, sound, about | Complete |
| Browser | `apps/browser/` | URL bar, placeholder | Complete |

### Remaining Apps

| App | Priority | Description |
|-----|----------|-------------|
| Store | High | Browse and install apps |
| Camera | Medium | Viewfinder, capture photos |
| Music | Low | Audio playback |

---

## App: Store

**Location**: `src/main/assets/apps/store/`

### Features

1. **Browse Apps**
   - Featured apps carousel
   - Categories (Games, Utilities, Social)
   - Search functionality

2. **App Details**
   - Name, icon, description
   - Screenshots
   - Permissions list
   - Install/Update button

3. **My Apps**
   - Installed apps list
   - Update available indicator
   - Uninstall option

### UI Screens

```
store/
├── store.rml           # Main store screen
├── store.rcss          # Store styles
├── category.rml        # Category listing
├── detail.rml          # App detail page
└── scripts/
    └── store.lua       # Store logic
```

### Main Screen (`store.rml`)

```html
<rml>
<head>
    <link type="text/rcss" href="store.rcss"/>
    <link type="text/rcss" href="../../ui/theme.rcss"/>
</head>
<body class="store-screen">
    <div class="app-bar">
        <div class="app-bar-nav btn-icon" onclick="goBack()">
            <img src="../../icons/back.tga"/>
        </div>
        <span class="app-bar-title">Store</span>
        <div class="app-bar-action btn-icon" onclick="openSearch()">
            <img src="../../icons/search.tga"/>
        </div>
    </div>

    <div class="store-content">
        <!-- Featured carousel -->
        <div class="featured-section">
            <h2>Featured</h2>
            <div class="featured-carousel" data-for="app : featured_apps">
                <div class="featured-card" data-event-click="showDetail(app.id)">
                    <img class="featured-banner" data-attr-src="app.banner"/>
                    <span class="featured-name" data-text="app.name"/>
                </div>
            </div>
        </div>

        <!-- Categories -->
        <div class="category-section">
            <h2>Categories</h2>
            <div class="category-grid">
                <div class="category-item" onclick="showCategory('games')">
                    <img src="../../icons/games.tga"/>
                    <span>Games</span>
                </div>
                <div class="category-item" onclick="showCategory('utilities')">
                    <img src="../../icons/tools.tga"/>
                    <span>Utilities</span>
                </div>
            </div>
        </div>

        <!-- Top Apps -->
        <div class="top-apps-section">
            <h2>Top Apps</h2>
            <div class="app-list" data-for="app : top_apps">
                <div class="app-list-item" data-event-click="showDetail(app.id)">
                    <img class="app-icon" data-attr-src="app.icon"/>
                    <div class="app-info">
                        <span class="app-name" data-text="app.name"/>
                        <span class="app-category" data-text="app.category"/>
                    </div>
                    <button class="install-btn" data-event-click="install(app.id)">
                        Install
                    </button>
                </div>
            </div>
        </div>
    </div>
</body>
</rml>
```

### Data Model

```cpp
// In data_models.cpp
struct StoreApp {
    std::string id;
    std::string name;
    std::string icon;
    std::string banner;
    std::string category;
    std::string description;
    std::string version;
    std::vector<std::string> screenshots;
    std::vector<std::string> permissions;
    bool installed;
};

void setupStoreDataModel(Rml::Context* context) {
    auto model = context->CreateDataModel("store");

    model.Bind("featured_apps", &g_featured_apps);
    model.Bind("top_apps", &g_top_apps);
    model.Bind("categories", &g_categories);
    model.Bind("current_app", &g_current_app);

    model.BindEventCallback("install", [](auto& event, auto& args) {
        // Install app
    });
}
```

---

## App: Camera

**Location**: `src/main/assets/apps/camera/`

### Features

1. **Viewfinder**
   - Live camera preview (from ICamera)
   - Capture button
   - Switch camera (front/back)
   - Flash toggle

2. **Capture**
   - Take photo
   - Save to gallery
   - Share option

3. **Gallery**
   - View captured photos
   - Delete photos
   - Share photos

### UI Screens

```
camera/
├── camera.rml          # Viewfinder
├── camera.rcss         # Camera styles
├── gallery.rml         # Photo gallery
└── scripts/
    └── camera.lua      # Camera logic
```

### Viewfinder (`camera.rml`)

```html
<rml>
<head>
    <link type="text/rcss" href="camera.rcss"/>
</head>
<body class="camera-screen">
    <!-- Camera preview (texture from ICamera) -->
    <div id="camera-preview">
        <img id="preview-frame" data-attr-src="camera_frame"/>
    </div>

    <!-- Top controls -->
    <div class="camera-top-bar">
        <div class="btn-icon" onclick="goBack()">
            <img src="../../icons/close.tga"/>
        </div>
        <div class="btn-icon" onclick="toggleFlash()">
            <img id="flash-icon" src="../../icons/flash_off.tga"/>
        </div>
    </div>

    <!-- Bottom controls -->
    <div class="camera-bottom-bar">
        <div class="btn-icon" onclick="openGallery()">
            <img id="last-photo" data-attr-src="last_photo_thumb"/>
        </div>

        <div id="capture-btn" onclick="capture()">
            <div class="capture-ring"/>
        </div>

        <div class="btn-icon" onclick="switchCamera()">
            <img src="../../icons/flip_camera.tga"/>
        </div>
    </div>
</body>
</rml>
```

### Camera Lua Script

```lua
-- camera.lua
local camera = mosis.platform.getCamera()
local capture = mosis.testing.VisualCapture(540, 960)

local is_front_camera = false
local flash_on = false

function onAppCreate()
    if camera:isAvailable() then
        camera:startCapture(function(frame)
            -- Update preview texture
            document:GetElementById("preview-frame"):SetAttribute("src", frame.texture_url)
        end)
    else
        -- Show "no camera" message
    end
end

function capture()
    local path = mosis.filesystem:getSharedMediaPath() .. "/photos/" .. os.time() .. ".png"
    capture:CaptureScreenshot(path)

    -- Show capture animation
    playSound("shutter")
    flashScreen()

    -- Update last photo thumbnail
    document:GetElementById("last-photo"):SetAttribute("src", path)
end

function switchCamera()
    is_front_camera = not is_front_camera
    -- camera:setFacing(is_front_camera and "front" or "back")
end

function toggleFlash()
    flash_on = not flash_on
    local icon = flash_on and "flash_on" or "flash_off"
    document:GetElementById("flash-icon"):SetAttribute("src", "../../icons/" .. icon .. ".tga")
end

function openGallery()
    navigateTo("camera/gallery")
end
```

---

## App: Music

**Location**: `src/main/assets/apps/music/`

### Features

1. **Library**
   - Songs list
   - Albums
   - Artists
   - Playlists

2. **Player**
   - Play/pause
   - Next/previous
   - Seek bar
   - Volume control
   - Shuffle/repeat

3. **Now Playing**
   - Album art
   - Song info
   - Progress bar

### UI Screens

```
music/
├── music.rml           # Library view
├── music.rcss          # Music styles
├── player.rml          # Now playing
├── playlist.rml        # Playlist view
└── scripts/
    └── music.lua       # Player logic
```

---

## Data Persistence

### Storage Layer

Apps need persistent storage for:
- Contacts
- Messages
- Settings
- Photos

**Implementation Options**:

1. **JSON Files** (Simple)
   ```
   /data/contacts.json
   /data/messages.json
   /data/settings.json
   ```

2. **SQLite** (Robust)
   ```
   /data/mosis.db
   - contacts table
   - messages table
   - settings table
   ```

### Contact Storage

```cpp
// contact_storage.h
struct Contact {
    std::string id;
    std::string name;
    std::string phone;
    std::string email;
    std::string avatar;
};

class ContactStorage {
public:
    std::vector<Contact> GetAll();
    std::optional<Contact> GetById(const std::string& id);
    bool Save(const Contact& contact);
    bool Delete(const std::string& id);
    std::vector<Contact> Search(const std::string& query);
};
```

### Message Storage

```cpp
// message_storage.h
struct Message {
    std::string id;
    std::string conversation_id;
    std::string sender;
    std::string text;
    int64_t timestamp;
    bool read;
};

struct Conversation {
    std::string id;
    std::string contact_id;
    std::string last_message;
    int64_t last_timestamp;
    int unread_count;
};

class MessageStorage {
public:
    std::vector<Conversation> GetConversations();
    std::vector<Message> GetMessages(const std::string& conversation_id);
    bool SaveMessage(const Message& message);
    bool MarkAsRead(const std::string& conversation_id);
};
```

---

## Implementation Plan

### Phase 1: Store App UI
- [ ] Main store screen layout
- [ ] Category browsing
- [ ] App detail page
- [ ] Mock data for testing

### Phase 2: Camera App
- [ ] Viewfinder UI
- [ ] Capture to file
- [ ] Gallery view
- [ ] Integration with ICamera

### Phase 3: Music App
- [ ] Library UI
- [ ] Player UI
- [ ] Audio playback (stub)

### Phase 4: Data Persistence
- [ ] JSON storage layer
- [ ] Contact CRUD
- [ ] Message storage
- [ ] Settings persistence

### Phase 5: Real Functionality
- [ ] Store: Install real .mpkg files
- [ ] Camera: Real camera frames
- [ ] Music: Audio playback

---

## Testing

### Test IDs for Store

| ID | Element |
|----|---------|
| `store-search` | Search button |
| `store-featured` | Featured carousel |
| `store-categories` | Category grid |
| `app-install-btn` | Install button on detail |

### Test IDs for Camera

| ID | Element |
|----|---------|
| `camera-preview` | Preview area |
| `capture-btn` | Capture button |
| `gallery-btn` | Gallery button |
| `switch-camera-btn` | Switch camera |

---

## Acceptance Criteria

### Store
- [ ] Browse featured and top apps
- [ ] View app details
- [ ] See permission requirements
- [ ] Install apps (mock or real)

### Camera
- [ ] Display camera preview
- [ ] Capture photos
- [ ] View in gallery
- [ ] Share photos

### Music
- [ ] Display music library
- [ ] Play/pause audio
- [ ] Show now playing

### Persistence
- [ ] Contacts persist across sessions
- [ ] Messages persist across sessions
- [ ] Settings persist across sessions
