# JackpotTicketNFT

ERC-721 contract that mints NFTs representing lottery tickets. Each ticket NFT contains the selected numbers and drawing information.

## State Variables

| Variable      | Type                                | Description                                 |
| ------------- | ----------------------------------- | ------------------------------------------- |
| `jackpot`     | `IJackpot`                          | Immutable reference to the Jackpot contract |
| `ticketArt`   | `ITicketArt`                        | Contract for generating ticket NFT art      |
| `contractURI` | `string`                            | Contract-level metadata URI                 |
| `userTickets` | `mapping`                           | Tracks tickets per user per drawing         |
| `tickets`     | `mapping(uint256 => TrackedTicket)` | Ticket data by token ID                     |

## Structs

### TrackedTicket

```solidity
struct TrackedTicket {
    uint256 drawingId;       // Drawing this ticket is for
    uint256 packedTicket;    // Packed normal numbers and bonusball
    bytes32 referralScheme;  // Hash of referral scheme applied
}
```

### ExtendedTrackedTicket

```solidity
struct ExtendedTrackedTicket {
    uint256 ticketId;        // NFT token ID
    TrackedTicket ticket;    // Core ticket data
    uint8[] normals;         // Unpacked normal numbers
    uint8 bonusball;         // Unpacked bonusball
}
```

### UserTickets (internal)

```solidity
struct UserTickets {
    uint256 totalTicketsBought;                    // Total tickets for this drawing
    mapping(uint256 => uint256) ticketIds;         // Index → ticketId
    mapping(uint256 => uint256) indexOfTicketId;   // ticketId → index
}
```

## Events

### Transfer (ERC-721)

```solidity
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
```

### Approval (ERC-721)

```solidity
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
```

## Functions

### getUserTickets

Get all tickets owned by a user for a specific drawing.

```solidity
function getUserTickets(address user, uint256 drawingId) external view returns (ExtendedTrackedTicket[] memory)
```

**Parameters:**

| Name        | Type      | Description                     |
| ----------- | --------- | ------------------------------- |
| `user`      | `address` | Address of the ticket owner     |
| `drawingId` | `uint256` | Drawing ID to query tickets for |

**Returns:**

| Type                      | Description                                              |
| ------------------------- | -------------------------------------------------------- |
| `ExtendedTrackedTicket[]` | Array of extended ticket info including unpacked numbers |

**Example:**

```solidity
uint256 currentDrawing = jackpot.currentDrawingId();
IJackpotTicketNFT.ExtendedTrackedTicket[] memory myTickets =
    ticketNFT.getUserTickets(msg.sender, currentDrawing);

for (uint256 i = 0; i < myTickets.length; i++) {
    uint256 ticketId = myTickets[i].ticketId;
    uint8[] memory normals = myTickets[i].normals;
    uint8 bonusball = myTickets[i].bonusball;
}
```

***

### getTicketInfo

Get basic ticket information by token ID.

```solidity
function getTicketInfo(uint256 ticketId) external view returns (TrackedTicket memory)
```

**Parameters:**

| Name       | Type      | Description  |
| ---------- | --------- | ------------ |
| `ticketId` | `uint256` | NFT token ID |

**Returns:**

| Type            | Description                                                     |
| --------------- | --------------------------------------------------------------- |
| `TrackedTicket` | Ticket data with drawing ID, packed ticket, and referral scheme |

**Example:**

```solidity
IJackpotTicketNFT.TrackedTicket memory ticket = ticketNFT.getTicketInfo(123);
uint256 drawingId = ticket.drawingId;
```

***

### getExtendedTicketInfo

Get full ticket information with unpacked numbers.

```solidity
function getExtendedTicketInfo(uint256 ticketId) external view returns (ExtendedTrackedTicket memory)
```

**Parameters:**

| Name       | Type      | Description  |
| ---------- | --------- | ------------ |
| `ticketId` | `uint256` | NFT token ID |

**Returns:**

| Type                    | Description                                     |
| ----------------------- | ----------------------------------------------- |
| `ExtendedTrackedTicket` | Complete ticket info including unpacked numbers |

**Example:**

```solidity
IJackpotTicketNFT.ExtendedTrackedTicket memory ticket =
    ticketNFT.getExtendedTicketInfo(123);

// Access unpacked numbers
uint8[] memory normals = ticket.normals;  // e.g., [1, 15, 23, 42, 55]
uint8 bonusball = ticket.bonusball;       // e.g., 10
```

***

### tokenURI

Get the metadata URI for a ticket NFT.

```solidity
function tokenURI(uint256 tokenId) external view returns (string memory)
```

**Parameters:**

| Name      | Type      | Description  |
| --------- | --------- | ------------ |
| `tokenId` | `uint256` | NFT token ID |

**Returns:**

| Type     | Description                                      |
| -------- | ------------------------------------------------ |
| `string` | Base64-encoded JSON metadata URI with ticket art |

***

### ownerOf (ERC-721)

Get the owner of a ticket NFT.

```solidity
function ownerOf(uint256 tokenId) external view returns (address)
```

***

### balanceOf (ERC-721)

Get total NFT balance for an address.

```solidity
function balanceOf(address owner) external view returns (uint256)
```

***

### transferFrom (ERC-721)

Transfer a ticket NFT to another address.

```solidity
function transferFrom(address from, address to, uint256 tokenId) external
```

**Example:**

```solidity
// Transfer ticket to another address
ticketNFT.transferFrom(msg.sender, recipientAddress, ticketId);
```

***

### approve (ERC-721)

Approve another address to transfer a specific ticket.

```solidity
function approve(address to, uint256 tokenId) external
```

***

### setApprovalForAll (ERC-721)

Approve/revoke an operator for all tickets.

```solidity
function setApprovalForAll(address operator, bool approved) external
```
