package ast

type Node interface {
	// Ensure only types in this package can implement Node
	node()
}

type ElementKind byte

const (
	ElementKind_Emphasis ElementKind = iota
)

type Element struct {
	kind  ElementKind
	nodes []Node
}

func NewElement(kind ElementKind, nodes []Node) *Element {
	return &Element{kind, nodes}
}

func (e *Element) Kind() ElementKind {
	return e.kind
}

func (e *Element) Nodes() []Node {
	return e.nodes
}

func (*Element) node() {}

type TextSpan struct {
	value string
}

func NewTextSpan(value string) *TextSpan {
	return &TextSpan{value}
}

func (t *TextSpan) Value() string {
	return t.value
}

func (*TextSpan) node() {}

type Argument struct {
	argument string
}

func NewArgument(name string) *Argument {
	return &Argument{name}
}

func (a *Argument) Argument() string {
	return a.argument
}

func (*Argument) node() {}

type NumberFormat byte

const (
	NumberFormat_Integer NumberFormat = iota
	NumberFormat_Currency
	NumberFormat_Percent
)

type NumberFunction struct {
	argument string
	format   NumberFormat
}

func NewNumberFunction(argument string, format NumberFormat) *NumberFunction {
	return &NumberFunction{argument, format}
}

func (f *NumberFunction) Argument() string {
	return f.argument
}

func (f *NumberFunction) Format() NumberFormat {
	return f.format
}

func (*NumberFunction) node() {}

type PluralForm byte

const (
	PluralForm_Other PluralForm = iota
	PluralForm_Zero
	PluralForm_One
	PluralForm_Two
	PluralForm_Few
	PluralForm_Many
)

type PluralFunction struct {
	argument string
	variants map[PluralForm][]Node
}

func NewPluralFunction(argument string, variants map[PluralForm][]Node) *PluralFunction {
	return &PluralFunction{argument, variants}
}

func (f *PluralFunction) Argument() string {
	return f.argument
}

func (f *PluralFunction) Variants() map[PluralForm][]Node {
	return f.variants
}

func (*PluralFunction) node() {}
