package tw

import (
	"encoding/xml"
	"fmt"
	"strings"
)

type ServerConfigBuild struct {
	Destroy int `xml:"destroy"`
}

type ServerConfigMisc struct {
	KillRanking     int `xml:"kill_ranking"`
	Tutorial        int `xml:"tutorial"`
	TradeCancelTime int `xml:"trade_cancel_time"`
}

type ServerConfigCommands struct {
	MillisArrival     int `xml:"millis_arrival"`
	CommandCancelTime int `xml:"command_cancel_time"`
}

type ServerConfigNewbie struct {
	Days                 int `xml:"days"`
	RatioDays            int `xml:"ratio_days"`
	Ratio                int `xml:"ratio"`
	RemoveNewbieVillages int `xml:"removeNewbieVillages"`
}

type KnightNewItems int

func (k KnightNewItems) Int() int {
	return int(k)
}

func (k *KnightNewItems) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var s string

	if err := d.DecodeElement(&s, &start); err != nil {
		return err
	}

	switch strings.ToUpper(s) {
	case "ON", "1":
		*k = 1
	case "OFF", "0", "":
		*k = 0
	default:
		return xml.UnmarshalError(fmt.Sprintf(`KnightNewItems: parsing "%s": invalid syntax`, s))
	}

	return nil
}

type ServerConfigGame struct {
	BuildtimeFormula   int            `xml:"buildtime_formula"`
	Knight             int            `xml:"knight"`
	KnightNewItems     KnightNewItems `xml:"knight_new_items"`
	Archer             int            `xml:"archer"`
	Tech               int            `xml:"tech"`
	FarmLimit          int            `xml:"farm_limit"`
	Church             int            `xml:"church"`
	Watchtower         int            `xml:"watchtower"`
	Stronghold         int            `xml:"stronghold"`
	FakeLimit          float64        `xml:"fake_limit"`
	BarbarianRise      float64        `xml:"barbarian_rise"`
	BarbarianShrink    int            `xml:"barbarian_shrink"`
	BarbarianMaxPoints int            `xml:"barbarian_max_points"`
	Scavenging         int            `xml:"scavenging"`
	Hauls              int            `xml:"hauls"`
	HaulsBase          int            `xml:"hauls_base"`
	HaulsMax           int            `xml:"hauls_max"`
	BaseProduction     int            `xml:"base_production"`
	Event              int            `xml:"event"`
	SuppressEvents     int            `xml:"suppress_events"`
}

type ServerConfigBuildings struct {
	CustomMain       int `xml:"custom_main"`
	CustomFarm       int `xml:"custom_farm"`
	CustomStorage    int `xml:"custom_storage"`
	CustomPlace      int `xml:"custom_place"`
	CustomBarracks   int `xml:"custom_barracks"`
	CustomChurch     int `xml:"custom_church"`
	CustomSmith      int `xml:"custom_smith"`
	CustomWood       int `xml:"custom_wood"`
	CustomStone      int `xml:"custom_stone"`
	CustomIron       int `xml:"custom_iron"`
	CustomMarket     int `xml:"custom_market"`
	CustomStable     int `xml:"custom_stable"`
	CustomWall       int `xml:"custom_wall"`
	CustomGarage     int `xml:"custom_garage"`
	CustomHide       int `xml:"custom_hide"`
	CustomSnob       int `xml:"custom_snob"`
	CustomStatue     int `xml:"custom_statue"`
	CustomWatchtower int `xml:"custom_watchtower"`
}

type ServerConfigSnob struct {
	Gold          int     `xml:"gold"`
	CheapRebuild  int     `xml:"cheap_rebuild"`
	Rise          int     `xml:"rise"`
	MaxDist       int     `xml:"max_dist"`
	Factor        float64 `xml:"factor"`
	CoinWood      int     `xml:"coin_wood"`
	CoinStone     int     `xml:"coin_stone"`
	CoinIron      int     `xml:"coin_iron"`
	NoBarbConquer int     `xml:"no_barb_conquer"`
}

type ServerConfigAlly struct {
	NoHarm                int    `xml:"no_harm"`
	NoOtherSupport        int    `xml:"no_other_support"`
	NoOtherSupportType    int    `xml:"no_other_support_type"`
	AllytimeSupport       int    `xml:"allytime_support"`
	NoLeave               int    `xml:"no_leave"`
	NoJoin                int    `xml:"no_join"`
	Limit                 int    `xml:"limit"`
	FixedAllies           int    `xml:"fixed_allies"`
	PointsMemberCount     int    `xml:"points_member_count"`
	WarsMemberRequirement int    `xml:"wars_member_requirement"`
	WarsPointsRequirement int    `xml:"wars_points_requirement"`
	WarsAutoacceptDays    int    `xml:"wars_autoaccept_days"`
	Levels                int    `xml:"levels"`
	XpRequirements        string `xml:"xp_requirements"`
}

type ServerConfigCoord struct {
	MapSize         int `xml:"map_size"`
	Func            int `xml:"func"`
	EmptyVillages   int `xml:"empty_villages"`
	BonusVillages   int `xml:"bonus_villages"`
	BonusNew        int `xml:"bonus_new"`
	Inner           int `xml:"inner"`
	SelectStart     int `xml:"select_start"`
	VillageMoveWait int `xml:"village_move_wait"`
	NobleRestart    int `xml:"noble_restart"`
	StartVillages   int `xml:"start_villages"`
}

type ServerConfigSitter struct {
	Allow int `xml:"allow"`
}

type ServerConfigSleep struct {
	Active   int `xml:"active"`
	Delay    int `xml:"delay"`
	Min      int `xml:"min"`
	Max      int `xml:"max"`
	MinAwake int `xml:"min_awake"`
	MaxAwake int `xml:"max_awake"`
	WarnTime int `xml:"warn_time"`
}

type ServerConfigNight struct {
	Active    int     `xml:"active"`
	StartHour int     `xml:"start_hour"`
	EndHour   int     `xml:"end_hour"`
	DefFactor float64 `xml:"def_factor"`
	Duration  int     `xml:"duration"`
}

type ServerConfigWin struct {
	Check int `xml:"check"`
}

type ServerConfig struct {
	XMLName   xml.Name              `xml:"config"`
	Speed     float64               `xml:"speed"`
	UnitSpeed float64               `xml:"unit_speed"`
	Moral     int                   `xml:"moral"`
	Build     ServerConfigBuild     `xml:"build"`
	Misc      ServerConfigMisc      `xml:"misc"`
	Commands  ServerConfigCommands  `xml:"commands"`
	Newbie    ServerConfigNewbie    `xml:"newbie"`
	Game      ServerConfigGame      `xml:"game"`
	Buildings ServerConfigBuildings `xml:"buildings"`
	Snob      ServerConfigSnob      `xml:"snob"`
	Ally      ServerConfigAlly      `xml:"ally"`
	Coord     ServerConfigCoord     `xml:"coord"`
	Sitter    ServerConfigSitter    `xml:"sitter"`
	Sleep     ServerConfigSleep     `xml:"sleep"`
	Night     ServerConfigNight     `xml:"night"`
	Win       ServerConfigWin       `xml:"win"`
}
