// This file is part of Gopher2600.
//
// Gopher2600 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Gopher2600 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Gopher2600.  If not, see <https://www.gnu.org/licenses/>.

package userinput

import "github.com/jetsetilly/gopher2600/hardware/riot/ports/plugging"

// Event represents all the different type of events that can occur in the GUI.
//
// Events are the things that happen in the GUI, as a result of user interaction,
// and sent over a registered event channel.
type Event interface{}

// EventQuit is sent, for example, when the GUI window is closed.
type EventQuit struct{}

// KeyMod identifies.
type KeyMod int

// list of valud key modifiers.
const (
	KeyModNone KeyMod = iota
	KeyModShift
	KeyModCtrl
	KeyModAlt
)

// EventKeyboard data is generated by the system keyboard.
type EventKeyboard struct {
	Key  string
	Down bool
	Mod  KeyMod
}

// EventMouseMotion data is generated by the motion of the system mouse.
type EventMouseMotion struct {
	X int16
	Y int16
}

// MouseButton identifies the mouse button.
type MouseButton int

// List of valid MouseButtonIDs.
const (
	MouseButtonNone MouseButton = iota
	MouseButtonLeft
	MouseButtonRight
	MouseButtonMiddle
)

// EventMouseButton data is generated by any of the system mouse buttons.
type EventMouseButton struct {
	Button MouseButton
	Down   bool
}

// EventMouseWheel data is generated by the mouse wheel (jog wheel).
type EventMouseWheel struct {
	Delta float32
	Mod   KeyMod
}

// DPadDirection indentifies the direction the dpad is being pressed.
type DPadDirection int

// List of valid DPadDirection values.
const (
	DPadNone DPadDirection = iota
	DPadCentre
	DPadUp
	DPadDown
	DPadLeft
	DPadRight
	DPadLeftUp
	DPadLeftDown
	DPadRightUp
	DPadRightDown
)

// EventGamepadDpad data is generated by a game controller's DPad.
type EventGamepadDPad struct {
	ID        plugging.PortID
	Direction DPadDirection
}

// GamepadButton identifies a gamepad button.
type GamepadButton int

// List of valid GamepadButtons.
const (
	GamepadButtonNone GamepadButton = iota
	GamepadButtonBack
	GamepadButtonStart
	GamepadButtonA
	GamepadButtonB
	GamepadButtonBumperLeft
	GamepadButtonBumperRight
	GamepadButtonGuide
)

// EventGamepadButton data is generated by any of a game controller's buttons.
type EventGamepadButton struct {
	ID     plugging.PortID
	Button GamepadButton
	Down   bool
}

// GamepadThumbstick identifies the gamepad thumbstick.
type GamepadThumbstick int

// List of GamepadAxis values.
const (
	GamepadThumbstickLeft GamepadThumbstick = iota
	GamepadThumbstickRight
)

// EventGamepadThumbstick data is generated by a gamepad's analogue sticks.
type EventGamepadThumbstick struct {
	ID plugging.PortID

	// the axis being moved
	Thumbstick GamepadThumbstick

	// value from hardware controller should use full range
	Horiz int16
	Vert  int16
}

// GamepadTrigger identifies the gamepad triggers.
type GamepadTrigger int

// List of GamepadTrigger values.
const (
	GamepadTriggerNone GamepadTrigger = iota
	GamepadTriggerLeft
	GamepadTriggerRight
)

// EventGamepadAnalogue data is generated by a gamepads analogue triggers.
type EventGamepadTrigger struct {
	ID plugging.PortID

	// the trigger being flexed
	Trigger GamepadTrigger

	// value from hardware controller should use full range
	Amount int16
}

// EventStelladaptor data is generated by the stelladaptor.
type EventStelladaptor struct {
	ID plugging.PortID

	// joystick, paddle and driving controllers all alter the horiz/vert values
	Horiz int16
	Vert  int16

	// the fire button on the hardware controller is a regular gamepad button event
}
