package flow

import (
	"log"
)

func (f *Flow) linkOptions() {
	f.onClick(options, "2.8", f.setReturningDriver(options, kbd)) // Keyboard settings button

	f.configureSlider(options, "2.9", h3Slider)   // Resolution slider
	f.configureSlider(options, "2.10", v10Slider) // Music volume slider
	f.configureSlider(options, "2.11", v10Slider) // SFX volume slider

	f.onClick(options, "2.12", f.acceptOptions) // OK button
	f.onClick(options, "2.24", f.cancelOptions) // Cancel button

	f.configureSlider(options, "2.26", h9Slider) // Unit speed slider
	f.configureSlider(options, "2.27", h9Slider) // Animation speed slider

	f.linkKeyboard()
}

// FIXME: exiting is a bit OTT. Perhaps display "save failed"?
func (f *Flow) acceptOptions() {
	if err := f.optionsIntoConfig(); err != nil {
		log.Printf("Saving options to config failed: %v", err)
		f.exit = err
	} else {
		f.returnToLastDriverNow(options)
	}
}

// FIXME: again, exiting is OTT. We're just resetting the state of
// the interface to the values in config.
func (f *Flow) cancelOptions() {
	if err := f.configIntoOptions(); err != nil {
		log.Printf("Saving options to config failed: %v", err)
		f.exit = err
	} else {
		f.exit = f.returnToLastDriverNow(options)
	}
}

func (f *Flow) configIntoOptions() error {
	var err error

	cfg := &f.config.Options
	optionsUI := f.drivers[options]

	try(optionsUI.SetValueBool("2.1", cfg.PlayMovies), &err)
	try(optionsUI.SetValueBool("2.1", cfg.Animations), &err)
	try(optionsUI.SetValueBool("2.3", cfg.PlayMusic), &err)
	try(optionsUI.SetValueBool("2.4", cfg.CombatVoices), &err)
	try(optionsUI.SetValueBool("2.5", cfg.ShowGrid), &err)
	try(optionsUI.SetValueBool("2.6", cfg.ShowPaths), &err)
	try(optionsUI.SetValueBool("2.7", cfg.PointSaving), &err)
	try(optionsUI.SetValueInt("2.9", cfg.ResolutionIndex()), &err)
	try(optionsUI.SetValueInt("2.10", cfg.MusicVolume), &err)
	try(optionsUI.SetValueInt("2.11", cfg.SFXVolume), &err)
	try(optionsUI.SetValueBool("2.25", cfg.AutoCutLevel), &err)
	try(optionsUI.SetValueInt("2.26", cfg.UnitSpeed), &err)
	try(optionsUI.SetValueInt("2.27", cfg.AnimSpeed), &err)

	return err
}

func (f *Flow) optionsIntoConfig() error {
	var resIdx int // needs handling manually
	var err error

	cfg := &f.config.Options
	optionsUI := f.drivers[options]

	try(optionsUI.ValueBool("2.1", &cfg.PlayMovies), &err)
	try(optionsUI.ValueBool("2.2", &cfg.Animations), &err)
	try(optionsUI.ValueBool("2.3", &cfg.PlayMusic), &err)
	try(optionsUI.ValueBool("2.4", &cfg.CombatVoices), &err)
	try(optionsUI.ValueBool("2.5", &cfg.ShowGrid), &err)
	try(optionsUI.ValueBool("2.6", &cfg.ShowPaths), &err)
	try(optionsUI.ValueBool("2.7", &cfg.PointSaving), &err)
	try(optionsUI.ValueInt("2.9", &resIdx), &err)
	try(optionsUI.ValueInt("2.10", &cfg.MusicVolume), &err)
	try(optionsUI.ValueInt("2.11", &cfg.SFXVolume), &err)
	try(optionsUI.ValueBool("2.25", &cfg.AutoCutLevel), &err)
	try(optionsUI.ValueInt("2.26", &cfg.UnitSpeed), &err)
	try(optionsUI.ValueInt("2.27", &cfg.AnimSpeed), &err)

	if err != nil {
		return err
	}

	cfg.SetResolutionIndex(resIdx)

	if err := f.config.Save(); err != nil {
		return err
	}

	return nil
}

func try(result error, into *error) {
	if *into == nil {
		*into = result
	}
}
