# Advanced Banners

Advanced Banners let you define responsive, context-aware banner ad layouts that adapt to device type, screen orientation, and screen size. Unlike regular banners (which support only top/bottom positioning), Advanced Banners allow you to place multiple banners at arbitrary positions on the screen and automatically switch layouts when conditions change.

### Checking Support

```javascript
if (bridge.advertisement.isAdvancedBannersSupported) {
    // Advanced Banners are available
}
```

### Usage

#### Method 1: Explicit API Call

Show and hide Advanced Banners directly from your game code:

```javascript
// Show banners for a specific placement
bridge.advertisement.showAdvancedBanners('main_menu')

// Hide banners
bridge.advertisement.hideAdvancedBanners()
```

If `placementFallback` is set in the config, you can call without arguments:

```javascript
bridge.advertisement.showAdvancedBanners()
```

#### Method 2: Automatic via Platform Messages

Advanced Banners automatically react to platform messages. When you call `bridge.platform.sendMessage()` or `bridge.platform.sendCustomMessage()`, the system checks if a matching placement exists in the config and triggers it.

```javascript
// This will automatically show banners if "level_paused" placement is configured
bridge.platform.sendMessage('level_paused')

// This will hide banners if "level_resumed" has action: "hide"
bridge.platform.sendMessage('level_resumed')

// Custom messages work the same way
bridge.platform.sendCustomMessage('shop_opened')
```

This is the recommended approach because it ties banner visibility to your game's lifecycle without extra code.

#### Tracking State

```javascript
// Check current state
const state = bridge.advertisement.advancedBannersState
// Possible values: 'loading', 'shown', 'hidden', 'failed'

// Listen for state changes
bridge.advertisement.on('advanced_banners_state_changed', (state) => {
    switch (state) {
        case 'loading':
            // Banners are being loaded
            break
        case 'shown':
            // Banners are visible
            break
        case 'hidden':
            // Banners were hidden
            break
        case 'failed':
            // Banners failed to load
            break
    }
})
```

### Automatic Behavior

#### Fullscreen Ad Coordination

Advanced Banners are **automatically hidden** when an interstitial or rewarded ad starts (loading or opened) and **automatically restored** when the ad finishes (closed or failed). No additional code is needed.

```
Interstitial starts → Advanced Banners hidden
Interstitial ends   → Advanced Banners restored

Rewarded starts     → Advanced Banners hidden
Rewarded ends       → Advanced Banners restored
```

#### Responsive Re-evaluation

When the screen orientation changes or the window is resized, the system automatically re-evaluates conditions and switches to a better-matching variant if one exists. This happens with a 200ms debounce to avoid excessive updates.

For example, if a user rotates their phone from portrait to landscape, and your config has different layouts for each orientation, the banners will seamlessly switch.

### Complete Example

#### Config

```json
{
    "advertisement": {
        "advancedBanners": {
            "placementFallback": "gameplay_stopped",
            "gameplay_started": {
                "action": "hide"
            },
            "gameplay_stopped": {
                "action": "show",
                "default": [
                    { "width": "300px", "height": "250px", "bottom": "10%", "right": "5%" }
                ],
                "mobile:portrait": [
                    { "width": "320px", "height": "50px", "bottom": "0", "left": "0" }
                ],
                "mobile:landscape": [
                    { "width": "300px", "height": "250px", "top": "50%", "right": "0" }
                ],
                "desktop:w>1200": [
                    { "width": "160px", "height": "600px", "top": "10%", "left": "1%" },
                    { "width": "160px", "height": "600px", "top": "10%", "right": "1%" }
                ],
                "desktop:w<=1200": [
                    { "width": "728px", "height": "90px", "bottom": "0", "left": "50%" }
                ],
                "desktop:landscape:ar>=1.78": [
                    { "width": "200px", "height": "600px", "top": "5%", "left": "0" },
                    { "width": "200px", "height": "600px", "top": "5%", "right": "0" },
                    { "width": "970px", "height": "90px", "bottom": "0", "left": "50%" }
                ]
            },
            "<your_placement_here>": {
                "default": [
                    { "width": "728px", "height": "90px", "bottom": "0", "left": "50%" }
                ]
            },
            "<your_placement_here>": {
                "action": "hide"
            }
        }
    }
}
```

#### Game Code

```javascript
// Game lifecycle messages automatically trigger banners
bridge.platform.sendMessage('gameplay_started')   // hides banners
bridge.platform.sendMessage('gameplay_stopped')   // shows banners (best layout auto-selected)

// Custom messages for game-specific screens
bridge.platform.sendCustomMessage('your_placement_here')  // shows shop banners
bridge.platform.sendCustomMessage('your_placement_here')  // hides banners

// Or call directly
bridge.advertisement.showAdvancedBanners('gameplay_stopped')
bridge.advertisement.hideAdvancedBanners()
```

### Configuration

Advanced Banners are configured in `playgama-bridge-config.json` under `advertisement.advancedBanners`.

```json
{
    "advertisement": {
        "advancedBanners": {
            "disable": false,
            "placementFallback": "main_menu",
            "main_menu": {
                "default": [
                    { "width": "300px", "height": "250px", "top": "10%", "right": "10%" }
                ]
            },
            "level_paused": {
                "action": "show",
                "default": [
                    { "width": "300px", "height": "250px", "top": "10%", "right": "10%" }
                ],
                "mobile:portrait": [
                    { "width": "100%", "height": "80px", "bottom": "0", "left": "0" }
                ],
                "desktop:landscape:w>1200": [
                    { "width": "160px", "height": "600px", "top": "10%", "left": "2%" },
                    { "width": "160px", "height": "600px", "top": "10%", "right": "2%" }
                ]
            },
            "level_resumed": {
                "action": "hide"
            }
        }
    }
}
```

#### General Options

| Parameter           | Type    | Default | Description                                                                         |
| ------------------- | ------- | ------- | ----------------------------------------------------------------------------------- |
| `disable`           | boolean | `false` | Disable Advanced Banners entirely, even if the platform supports them               |
| `placementFallback` | string  | —       | Default placement to use when `showAdvancedBanners()` is called without an argument |

#### Placement Configuration

Each key under `advancedBanners` (other than `disable` and `placementFallback`) defines a **placement**. A placement is identified by a string that matches either:

* A built-in platform message (e.g. `game_ready`, `level_paused`, `gameplay_started`)
* A custom message ID passed to `platform.sendCustomMessage()`
* A string passed directly to `advertisement.showAdvancedBanners()`

Each placement contains:

| Property        | Type                 | Default  | Description                                                      |
| --------------- | -------------------- | -------- | ---------------------------------------------------------------- |
| `action`        | `"show"` \| `"hide"` | `"show"` | Whether to show or hide banners when this placement is triggered |
| `default`       | array                | —        | Fallback banner layout when no condition-based variant matches   |
| *condition key* | array                | —        | Banner layout for a specific set of conditions (see below)       |

#### Banner Object

Each banner in the array is an object with CSS positioning values:

| Property | Type   | Description                           |
| -------- | ------ | ------------------------------------- |
| `width`  | string | CSS width (e.g. `"300px"`, `"100%"`)  |
| `height` | string | CSS height (e.g. `"250px"`, `"80px"`) |
| `top`    | string | CSS top offset (e.g. `"0"`, `"10%"`)  |
| `bottom` | string | CSS bottom offset                     |
| `left`   | string | CSS left offset                       |
| `right`  | string | CSS right offset                      |

You can define multiple banners per variant to show several ads simultaneously:

```json
"desktop:landscape": [
    { "width": "160px", "height": "600px", "top": "10%", "left": "2%" },
    { "width": "160px", "height": "600px", "top": "10%", "right": "2%" },
    { "width": "728px", "height": "90px", "bottom": "0", "left": "50%" }
]
```

### Condition Keys

Condition keys are colon-separated segments that describe when a variant should be used. The system evaluates all keys against the current environment and picks the best match.

#### Available Segments

| Segment          | Example                             | Description                                                                                                                                      |
| ---------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Device type      | `mobile`, `desktop`, `tablet`, `tv` | Matches the current device type                                                                                                                  |
| Orientation      | `portrait`, `landscape`             | Matches the current screen orientation                                                                                                           |
| Width condition  | `w>600`, `w<=1024`, `w>=768`        | Matches against `window.innerWidth` (or canvas width if `canvas` segment is present)                                                             |
| Height condition | `h>400`, `h<=900`                   | Matches against `window.innerHeight` (or canvas height)                                                                                          |
| Aspect ratio     | `ar>1.5`, `ar>=1.78`, `ar<=1.0`     | Matches screen width/height ratio                                                                                                                |
| Canvas mode      | `canvas`                            | Use game `<canvas>` element dimensions instead of window size for all `w`/`h`/`ar` conditions. If no canvas is found, the variant will not match |

#### Combining Segments

Combine segments with `:` to create compound conditions. All segments must match for the variant to be selected:

```json
{
    "mobile:portrait": [...],
    "mobile:portrait:w>400": [...],
    "desktop:landscape:w>1200:ar>=1.5": [...],
    "tablet:canvas:w>800": [...]
}
```

#### Priority Scoring

When multiple variants match, the one with the highest score wins:

| Segment Type                            | Score |
| --------------------------------------- | ----- |
| Device type (`mobile`, `desktop`, etc.) | +4    |
| Orientation (`portrait`, `landscape`)   | +2    |
| Canvas mode (`canvas`)                  | +1    |
| Each dimension/aspect ratio condition   | +1    |

If two variants have the same score, the one with **more segments** wins. If they also have the same number of segments, the one whose dimension/aspect ratio threshold is **closest to the actual value** takes priority.

**Example**: screen is 1300px wide, device is desktop

| Key                        | Matches?       | Score                        |
| -------------------------- | -------------- | ---------------------------- |
| `default`                  | yes (fallback) | -1                           |
| `desktop`                  | yes            | 4                            |
| `desktop:w>500`            | yes            | 4 + 1 = 5                    |
| `desktop:w>1200`           | yes            | 5 + higher specificity bonus |
| `desktop:landscape:w>1200` | yes            | 4 + 2 + 1 = 7                |
| `mobile:portrait`          | no             | —                            |
