#!/usr/bin/env python3
"""SC-Controller - AREA_TO_ACTION

Maps areas on SVG images into actions.
Used by ActionEditor.
"""

from scc.actions import (
	AxisAction,
	ButtonAction,
	HatDownAction,
	HatLeftAction,
	HatRightAction,
	HatUpAction,
	MouseAction,
	RAxisAction,
)
from scc.uinput import Axes, Keys, Rels

AREA_TO_ACTION = {
	# Values in tuples: ActionClass, param1, param2...
	# Buttons
	"TL": (ButtonAction, Keys.BTN_TL),
	"TR": (ButtonAction, Keys.BTN_TR),
	"THUMBL": (ButtonAction, Keys.BTN_THUMBL),
	"THUMBR": (ButtonAction, Keys.BTN_THUMBR),
	"SELECT": (ButtonAction, Keys.BTN_SELECT),
	"MODE": (ButtonAction, Keys.BTN_MODE),
	"START": (ButtonAction, Keys.BTN_START),
	"A": (ButtonAction, Keys.BTN_A),
	"B": (ButtonAction, Keys.BTN_B),
	"X": (ButtonAction, Keys.BTN_X),
	"Y": (ButtonAction, Keys.BTN_Y),
	# Media keys
	"KEY_PREVIOUSSONG": (ButtonAction, Keys.KEY_PREVIOUSSONG),
	"KEY_STOP": (ButtonAction, Keys.KEY_STOP),
	"KEY_PLAYPAUSE": (ButtonAction, Keys.KEY_PLAYPAUSE),
	"KEY_NEXTSONG": (ButtonAction, Keys.KEY_NEXTSONG),
	"KEY_VOLUMEDOWN": (ButtonAction, Keys.KEY_VOLUMEDOWN),
	"KEY_VOLUMEUP": (ButtonAction, Keys.KEY_VOLUMEUP),
	# Dpad
	"DPAD_LEFT": (HatLeftAction, Axes.ABS_HAT0X),
	"DPAD_RIGHT": (HatRightAction, Axes.ABS_HAT0X),
	"DPAD_UP": (HatUpAction, Axes.ABS_HAT0Y),
	"DPAD_DOWN": (HatDownAction, Axes.ABS_HAT0Y),
	"ABS_HAT0X": (AxisAction, Axes.ABS_HAT0X),
	"ABS_HAT0Y": (AxisAction, Axes.ABS_HAT0Y),
	# Left stick
	"LSTICK_LEFT": (AxisAction, Axes.ABS_X, 0, -32767),
	"LSTICK_RIGHT": (AxisAction, Axes.ABS_X, 0, 32767),
	"LSTICK_UP": (AxisAction, Axes.ABS_Y, 0, -32767),
	"LSTICK_DOWN": (AxisAction, Axes.ABS_Y, 0, 32767),
	"ABS_X": (AxisAction, Axes.ABS_X),
	"ABS_Y": (AxisAction, Axes.ABS_Y),
	# Right stick
	"RSTICK_LEFT": (AxisAction, Axes.ABS_RX, 0, -32767),
	"RSTICK_RIGHT": (AxisAction, Axes.ABS_RX, 0, 32767),
	"RSTICK_UP": (AxisAction, Axes.ABS_RY, 0, 32767),
	"RSTICK_DOWN": (AxisAction, Axes.ABS_RY, 0, -32767),
	"ABS_RX": (AxisAction, Axes.ABS_RX),
	"ABS_RY": (AxisAction, Axes.ABS_RY),
	# Halves
	"MINUSHALF_X": (AxisAction, Axes.ABS_X, 0, -32767),
	"PLUSHALF_X": (AxisAction, Axes.ABS_X, 0, 32767),
	"MINUSHALF_Y": (AxisAction, Axes.ABS_Y, 0, -32767),
	"PLUSHALF_Y": (AxisAction, Axes.ABS_Y, 0, 32767),
	"MINUSHALF_RX": (AxisAction, Axes.ABS_RX, 0, -32767),
	"PLUSHALF_RX": (AxisAction, Axes.ABS_RX, 0, 32767),
	"MINUSHALF_RY": (AxisAction, Axes.ABS_RY, 0, -32767),
	"PLUSHALF_RY": (AxisAction, Axes.ABS_RY, 0, 32767),
	# Triggers
	"ABS_Z": (AxisAction, Axes.ABS_Z),
	"ABS_RZ": (AxisAction, Axes.ABS_RZ),
	# Mouse
	"MOUSE_LEFT": (MouseAction, Rels.REL_X, -1),
	"MOUSE_RIGHT": (MouseAction, Rels.REL_X, 1),
	"MOUSE_UP": (MouseAction, Rels.REL_Y, -1),
	"MOUSE_DOWN": (
		MouseAction,
		Rels.REL_Y,
		1,
	),
	"MOUSE_X": (MouseAction, Rels.REL_X, 1),
	"MOUSE_Y": (MouseAction, Rels.REL_Y, 1),
	"MOUSE_WHEEL": (MouseAction, Rels.REL_WHEEL, 1),
	"MOUSE_HWHEEL": (MouseAction, Rels.REL_HWHEEL, 1),
	# Mouse buttons
	"MOUSE1": (ButtonAction, Keys.BTN_LEFT),
	"MOUSE2": (ButtonAction, Keys.BTN_MIDDLE),
	"MOUSE3": (ButtonAction, Keys.BTN_RIGHT),
	"MOUSE4": (MouseAction, Rels.REL_WHEEL, 1),
	"MOUSE5": (MouseAction, Rels.REL_WHEEL, -1),
	"MOUSE8": (ButtonAction, Keys.BTN_SIDE),
	"MOUSE9": (ButtonAction, Keys.BTN_EXTRA),
}

_CLS_TO_AREA = {}
for x in AREA_TO_ACTION:
	cls, params = AREA_TO_ACTION[x][0], AREA_TO_ACTION[x][1:]
	if cls not in _CLS_TO_AREA:
		_CLS_TO_AREA[cls] = []
	_CLS_TO_AREA[cls].append((x, params))


def action_to_area(action):
	"""Returns area that matches provided action (both class and parameters)
	or None if there is no such area.
	"""
	cls = action.__class__
	if cls == RAxisAction:
		cls = AxisAction
	if cls not in _CLS_TO_AREA:
		return None
	for area, pars in _CLS_TO_AREA[cls]:
		if len(pars) > len(action.parameters):
			continue
		differs = False
		for i in range(len(pars)):
			if pars[i] != action.parameters[i]:
				differs = True
				break
		if differs:
			continue
		return area
	return None
