package door

import "time"

type Updater interface {
	Update() string
}

type Dispatcher struct {
	UpdateList     []Updater
	UpdateInterval *time.Ticker
	door           *Door
}

func (d *Dispatcher) register(u Updater) {
	d.UpdateList = append(d.UpdateList, u)
}

func removeFromSlice(UpdateList []Updater, toRemove Updater) []Updater {
	len := len(UpdateList)
	for i, obs := range UpdateList {
		if toRemove == obs {
			UpdateList[len-1], UpdateList[i] = UpdateList[i], UpdateList[len-1]
			return UpdateList[:len-1]
		}
	}
	return UpdateList
}

func (d *Dispatcher) unregister(u Updater) {
	d.UpdateList = removeFromSlice(d.UpdateList, u)
}

func (d *Dispatcher) Start(duration time.Duration, door *Door) {
	d.door = door
	d.UpdateInterval = time.NewTicker(duration)
	go d.TickerRoutine()
}

func (d *Dispatcher) TickerRoutine() {
	for range d.UpdateInterval.C {
		d.Update()
	}
}

func (d *Dispatcher) Stop() {
	d.UpdateInterval.Stop()
}

func (d *Dispatcher) Update() bool {
	var result bool
	for _, ob := range d.UpdateList {
		var output string = ob.Update()
		if output != "" {
			d.door.Write(SavePos + output + RestorePos)
			result = true
		}
	}
	return result
}