# Exports & Events

HZ-Television exposes client/server exports and events to allow complete integration with your custom scripts.

***

## Client Exports

### StartTVPlacement

Starts TV placement mode for the player.

```lua
exports['HZ-Television']:StartTVPlacement(tvModel)
```

**Parameters:**

* `tvModel` (string): TV model hash (ex: `'prop_tv_flat_01'`)

**Example:**

```lua
-- In a custom script, use an item to place a TV
RegisterNetEvent('myresource:placeTV', function()
    exports['HZ-Television']:StartTVPlacement('prop_tv_flat_01')
end)
```

***

### IsTVPlacing

Check if the player is currently placing a TV.

```lua
local isPlacing = exports['HZ-Television']:IsTVPlacing()
```

**Return:**

* `boolean`: `true` if in placement mode, `false` otherwise

**Example:**

```lua
-- Prevent an action if the player is placing a TV
if exports['HZ-Television']:IsTVPlacing() then
    Notify('You cannot do that while placing a TV', 'error')
    return
end
```

***

### GetNearestTV

Get the nearest TV to the player.

```lua
local tvData = exports['HZ-Television']:GetNearestTV(maxDistance)
```

**Parameters:**

* `maxDistance` (float, optional): Max search distance (default: 5.0)

**Return:**

* `table` or `nil`: TV data
  * `entity`: Entity handle
  * `model`: Model hash
  * `coords`: Coordinates
  * `distance`: Distance from player

**Example:**

```lua
local tv = exports['HZ-Television']:GetNearestTV(10.0)
if tv then
    print('TV found: ' .. tv.model .. ' at ' .. tv.distance .. 'm')
end
```

***

### SetTVURL

Change the URL displayed on a specific TV.

```lua
exports['HZ-Television']:SetTVURL(tvEntity, url)
```

**Parameters:**

* `tvEntity` (entity): TV entity handle
* `url` (string): URL to display

**Example:**

```lua
local tv = exports['HZ-Television']:GetNearestTV()
if tv then
    exports['HZ-Television']:SetTVURL(tv.entity, 'https://www.youtube.com/watch?v=dQw4w9WgXcQ')
end
```

***

### PowerOffTV

Turn off a specific TV.

```lua
exports['HZ-Television']:PowerOffTV(tvEntity)
```

**Parameters:**

* `tvEntity` (entity): TV entity handle

**Example:**

```lua
-- Turn off all nearby TVs
local tv = exports['HZ-Television']:GetNearestTV(50.0)
while tv do
    exports['HZ-Television']:PowerOffTV(tv.entity)
    tv = exports['HZ-Television']:GetNearestTV(50.0)
end
```

***

## Server Exports

### GetAllPlacedTVs

Get all placed TVs on the server.

```lua
local tvs = exports['HZ-Television']:GetAllPlacedTVs()
```

**Return:**

* `table`: List of placed TVs
  * Each entry contains: `id`, `owner`, `model`, `coords`, `url`

**Example:**

```lua
-- Count placed TVs
local tvs = exports['HZ-Television']:GetAllPlacedTVs()
print('Number of placed TVs: ' .. #tvs)
```

***

### GetPlayerPlacedTVs

Get TVs placed by a specific player.

```lua
local tvs = exports['HZ-Television']:GetPlayerPlacedTVs(identifier)
```

**Parameters:**

* `identifier` (string): Player identifier (license:xxx)

**Return:**

* `table`: List of player's TVs

**Example:**

```lua
-- Check how many TVs a player has placed
RegisterCommand('checkmytvs', function(source)
    local xPlayer = ESX.GetPlayerFromId(source) -- or QBCore
    local identifier = xPlayer.identifier
    local tvs = exports['HZ-Television']:GetPlayerPlacedTVs(identifier)

    TriggerClientEvent('chat:addMessage', source, {
        args = { 'TV System', 'You have placed ' .. #tvs .. ' TV(s)' }
    })
end)
```

***

### RemovePlacedTV

Remove a placed TV by its ID.

```lua
exports['HZ-Television']:RemovePlacedTV(tvId)
```

**Parameters:**

* `tvId` (integer): TV ID in database

**Example:**

```lua
-- Admin: remove all TVs from a banned player
RegisterCommand('cleartvs', function(source, args)
    if not IsPlayerAdmin(source) then return end

    local targetIdentifier = args[1]
    local tvs = exports['HZ-Television']:GetPlayerPlacedTVs(targetIdentifier)

    for _, tv in ipairs(tvs) do
        exports['HZ-Television']:RemovePlacedTV(tv.id)
    end

    print('Removed ' .. #tvs .. ' TVs from player ' .. targetIdentifier)
end)
```

***

### BroadcastToTV

Broadcast a URL to one or all TVs.

```lua
exports['HZ-Television']:BroadcastToTV(url, tvEntity)
```

**Parameters:**

* `url` (string): URL to broadcast
* `tvEntity` (entity, optional): Specific entity. If `nil`, broadcasts to all TVs.

**Example:**

```lua
-- Server event: broadcast an alert on all TVs
RegisterNetEvent('police:broadcastAlert', function()
    exports['HZ-Television']:BroadcastToTV('https://i.imgur.com/alert.png')
end)
```

***

## Events

### Client → Server

#### hz-televisionplaceTV

Triggered when a player places a TV.

```lua
-- Server
RegisterNetEvent('hz-televisionplaceTV', function(model, coords, heading)
    local src = source
    print('Player ' .. src .. ' placed a TV: ' .. model)

    -- Custom logic (logs, limits, etc.)
end)
```

***

#### hz-televisionpickupTV

Triggered when a player picks up a TV.

```lua
-- Server
RegisterNetEvent('hz-televisionpickupTV', function(tvId)
    local src = source
    print('Player ' .. src .. ' picked up TV #' .. tvId)
end)
```

***

### Server → Client

#### hz-televisionupdateTV

Force update a TV on client side.

```lua
-- Server → All clients
TriggerClientEvent('hz-televisionupdateTV', -1, tvEntity, {
    url = 'https://youtube.com/watch?v=xxx',
    power = true,
    volume = 0.8
})
```

**Parameters:**

* `tvEntity` (entity): TV entity
* `data` (table):
  * `url` (string): New URL
  * `power` (boolean): ON/OFF state
  * `volume` (float): Volume (0.0 - 1.0)

***

#### hz-televisionpowerOff

Turn off a TV for all clients.

```lua
-- Server
TriggerClientEvent('hz-televisionpowerOff', -1, tvEntity)
```

***

## Integration Examples

### Cinema System

```lua
-- Cinema script: play a movie on a billboard
RegisterCommand('startmovie', function(source)
    if not IsPlayerAdmin(source) then return end

    local billboardEntity = GetClosestBillboard() -- Custom function
    local movieURL = 'https://www.youtube.com/watch?v=movieID'

    exports['HZ-Television']:BroadcastToTV(movieURL, billboardEntity)

    TriggerClientEvent('chat:addMessage', -1, {
        args = { 'Cinema', 'The show is starting!' }
    })
end)
```

***

### Limit TVs by Property

```lua
-- ESX: only allow in player's properties
AddEventHandler('hz-televisionplaceTV', function(model, coords, heading)
    local src = source
    local xPlayer = ESX.GetPlayerFromId(src)

    -- Check if player is in THEIR property
    local ownedProperty = exports['esx_property']:IsPlayerInOwnedProperty(src)

    if not ownedProperty then
        TriggerClientEvent('esx:showNotification', src, 'You must be in your property!')
        CancelEvent()
        return
    end

    -- Allow placement
end)
```

***

### Emergency Broadcast Event

```lua
-- Admin: trigger emergency message on all TVs
RegisterCommand('emergency', function(source, args)
    if not IsPlayerAdmin(source) then return end

    local message = table.concat(args, ' ')
    local imageURL = 'https://i.imgur.com/emergency.png'

    -- Turn off all TVs
    TriggerClientEvent('hz-televisionpowerOff', -1, nil)

    -- Wait 1 second
    Wait(1000)

    -- Display emergency message
    exports['HZ-Television']:BroadcastToTV(imageURL)

    -- Notification
    TriggerClientEvent('chat:addMessage', -1, {
        color = { 255, 0, 0 },
        args = { 'ALERT', message }
    })
end)
```

***

### Job Synchronization

```lua
-- QBCore: reporter can control billboards
RegisterNetEvent('reporter:broadcastNews', function(url)
    local src = source
    local Player = QBCore.Functions.GetPlayer(src)

    if Player.PlayerData.job.name ~= 'reporter' then
        TriggerClientEvent('QBCore:Notify', src, 'You are not a reporter', 'error')
        return
    end

    exports['HZ-Television']:BroadcastToTV(url) -- All TVs

    TriggerClientEvent('QBCore:Notify', -1, 'New live broadcast!', 'info')
end)
```

***

{% hint style="success" %}
**Need help integrating these exports?** Join our [Discord](https://discord.gg/D2jMNswvBM) and open a ticket in #support!
{% endhint %}
