package extensions

import (
	"encoding/xml"

	"gosrc.io/xmpp/stanza"
)

// PresenceNickExtension is from XEP-0172
type PresenceNickExtension struct {
	XMLName xml.Name `xml:"http://jabber.org/protocol/nick nick"`
	Text    string   `xml:",chardata"`
}

// PresenceXVCardUpdateExtension is from XEP-0153
type PresenceXVCardUpdateExtension struct {
	XMLName xml.Name `xml:"vcard-temp:x:update x"`
	Photo   PresenceXVCardUpdatePhoto
}

// PresenceXVCardUpdatePhoto is from XEP-0153
type PresenceXVCardUpdatePhoto struct {
	XMLName xml.Name `xml:"photo"`
	Text    string   `xml:",chardata"`
}

// IqVcardTemp is from XEP-0054
type IqVcardTemp struct {
	XMLName   xml.Name `xml:"vcard-temp vCard"`
	Fn        IqVcardFn
	Nickname  IqVcardNickname
	N         IqVcardN
	Tel       IqVcardTel
	Photo     IqVcardPhoto
	ResultSet *stanza.ResultSet `xml:"set,omitempty"`
}

// IqVcardFn is vCard/FN
type IqVcardFn struct {
	XMLName xml.Name `xml:"FN"`
	Text    string   `xml:",chardata"`
}

// IqVcardNickname is vCard/NICKNAME
type IqVcardNickname struct {
	XMLName xml.Name `xml:"NICKNAME"`
	Text    string   `xml:",chardata"`
}

// IqVcardN is vCard/N
type IqVcardN struct {
	XMLName xml.Name `xml:"N"`
	Family  IqVcardNFamily
	Given   IqVcardNGiven
	Middle  IqVcardNMiddle
}

// IqVcardNFamily is vCard/N/FAMILY
type IqVcardNFamily struct {
	XMLName xml.Name `xml:"FAMILY"`
	Text    string   `xml:",chardata"`
}

// IqVcardNGiven is vCard/N/GIVEN
type IqVcardNGiven struct {
	XMLName xml.Name `xml:"GIVEN"`
	Text    string   `xml:",chardata"`
}

// IqVcardNMiddle is vCard/N/MIDDLE
type IqVcardNMiddle struct {
	XMLName xml.Name `xml:"MIDDLE"`
	Text    string   `xml:",chardata"`
}

// IqVcardTel is vCard/TEL
type IqVcardTel struct {
	XMLName xml.Name `xml:"TEL"`
	Number  IqVcardTelNumber
}

// IqVcardTelNumber is vCard/TEL/NUMBER
type IqVcardTelNumber struct {
	XMLName xml.Name `xml:"NUMBER"`
	Text    string   `xml:",chardata"`
}

// IqVcardPhoto is vCard/PHOTO
type IqVcardPhoto struct {
	XMLName xml.Name `xml:"PHOTO"`
	Type    IqVcardPhotoType
	Binval  IqVcardPhotoBinval
}

// IqVcardPhotoType is vCard/PHOTO/TYPE
type IqVcardPhotoType struct {
	XMLName xml.Name `xml:"TYPE"`
	Text    string   `xml:",chardata"`
}

// IqVcardPhotoBinval is vCard/PHOTO/BINVAL
type IqVcardPhotoBinval struct {
	XMLName xml.Name `xml:"BINVAL"`
	Text    string   `xml:",chardata"`
}

// Namespace is a namespace!
func (c PresenceNickExtension) Namespace() string {
	return c.XMLName.Space
}

// Namespace is a namespace!
func (c PresenceXVCardUpdateExtension) Namespace() string {
	return c.XMLName.Space
}

// Namespace is a namespace!
func (c IqVcardTemp) Namespace() string {
	return c.XMLName.Space
}

// Namespace is a namespace!
func (c IqVcardTemp) GetSet() *stanza.ResultSet {
	return c.ResultSet
}

func init() {
	// presence nick
	stanza.TypeRegistry.MapExtension(stanza.PKTPresence, xml.Name{
		"http://jabber.org/protocol/nick",
		"nick",
	}, PresenceNickExtension{})

	// presence vcard update
	stanza.TypeRegistry.MapExtension(stanza.PKTPresence, xml.Name{
		"vcard-temp:x:update",
		"x",
	}, PresenceXVCardUpdateExtension{})

	// iq vcard request
	stanza.TypeRegistry.MapExtension(stanza.PKTIQ, xml.Name{
		"vcard-temp",
		"vCard",
	}, IqVcardTemp{})
}