package message

import (
	"fmt"
)

type PlaceholderMap = map[string]Placeholder

type Placeholder interface {
	// Only allow types in this package to implement this interface.
	placeholder()
}

type String string

func NewString(value string) *String {
	str := String(value)
	return &str
}

func (String) placeholder() {}

type NestedMessage struct {
	message      *Message
	placeholders PlaceholderMap
}

func NewNestedMessage(message *Message, placeholders PlaceholderMap) *NestedMessage {
	return &NestedMessage{message, placeholders}
}

func (NestedMessage) placeholder() {}

func (m *NestedMessage) Format() ([]Fragment, error) {
	return m.message.Format(m.placeholders)
}

type NumberFormat byte

const (
	NumberFormat_Integer NumberFormat = iota
	NumberFormat_Currency
	// Represented as a floating point value from 0.0 = 0% to 1.0 = 100%
	NumberFormat_Percent
)

type Number float64

func NewNumber(value float64) *Number {
	number := Number(value)
	return &number
}

func (Number) placeholder() {}

type IDKind byte

const (
	IDKind_User IDKind = iota
	IDKind_Emote
)

type ID interface {
	fmt.Stringer

	Kind() IDKind
	// Only allow types in this package to implement this interface.
	id()
}

type UserID string

func NewUserID(id string) *UserID {
	userID := UserID(id)
	return &userID
}

func (u UserID) String() string {
	return string(u)
}

func (UserID) Kind() IDKind {
	return IDKind_User
}

func (UserID) id()          {}
func (UserID) placeholder() {}

type EmoteID string

func NewEmoteID(id string) *EmoteID {
	emoteID := EmoteID(id)
	return &emoteID
}

func (u EmoteID) String() string {
	return string(u)
}

func (EmoteID) Kind() IDKind {
	return IDKind_Emote
}

func (EmoteID) id()          {}
func (EmoteID) placeholder() {}
