// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.device.gamepad;

import android.os.SystemClock;
import android.view.InputDevice;
import android.view.InputDevice.MotionRange;
import android.view.KeyEvent;
import android.view.MotionEvent;

import org.chromium.base.VisibleForTesting;

import java.util.Arrays;
import java.util.List;

/**
 * Manages information related to each connected gamepad device.
 */
class GamepadDevice {
    // Axis ids are used as indices which are empirically always smaller than 256 so this allows
    // us to create cheap associative arrays.
    @VisibleForTesting
    static final int MAX_RAW_AXIS_VALUES = 256;

    // Keycodes are used as indices which are empirically always smaller than 256 so this allows
    // us to create cheap associative arrays.
    @VisibleForTesting
    static final int MAX_RAW_BUTTON_VALUES = 256;

    // An id for the gamepad.
    private int mDeviceId;
    // The index of the gamepad in the Navigator.
    private int mDeviceIndex;
    // Last time the data for this gamepad was updated.
    private long mTimestamp;
    // If this gamepad is mapped to standard gamepad?
    private boolean mIsStandardGamepad;

    // Array of values for all axes of the gamepad.
    // All axis values must be linearly normalized to the range [-1.0 .. 1.0].
    // As appropriate, -1.0 should correspond to "up" or "left", and 1.0
    // should correspond to "down" or "right".
    private final float[] mAxisValues = new float[CanonicalAxisIndex.COUNT];

    private final float[] mButtonsValues = new float[CanonicalButtonIndex.COUNT];

    // When the user agent recognizes the attached inputDevice, it is recommended
    // that it be remapped to a canonical ordering when possible. Devices that are
    // not recognized should still be exposed in their raw form. Therefore we must
    // pass the raw Button and raw Axis values.
    private final float[] mRawButtons = new float[MAX_RAW_BUTTON_VALUES];
    private final float[] mRawAxes = new float[MAX_RAW_AXIS_VALUES];

    // An identification string for the gamepad.
    private String mDeviceName;

    // Array of axes ids.
    private int[] mAxes;

    GamepadDevice(int index, InputDevice inputDevice) {
        mDeviceIndex = index;
        mDeviceId = inputDevice.getId();
        mDeviceName = inputDevice.getName();
        mTimestamp = SystemClock.uptimeMillis();
        // Get axis ids and initialize axes values.
        final List<MotionRange> ranges = inputDevice.getMotionRanges();
        mAxes = new int[ranges.size()];
        int i = 0;
        for (MotionRange range : ranges) {
            if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
                int axis = range.getAxis();
                assert axis < MAX_RAW_AXIS_VALUES;
                mAxes[i++] = axis;
            }
        }
    }

    /**
     * Updates the axes and buttons maping of a gamepad device to a standard gamepad format.
     */
    public void updateButtonsAndAxesMapping() {
        mIsStandardGamepad = GamepadMappings.mapToStandardGamepad(
                mAxisValues, mButtonsValues, mRawAxes, mRawButtons, mDeviceName);
    }

    /**
     * @return Device Id of the gamepad device.
     */
    public int getId() {
        return mDeviceId;
    }

    /**
     * @return Mapping status of the gamepad device.
     */
    public boolean isStandardGamepad() {
        return mIsStandardGamepad;
    }

    /**
     * @return Device name of the gamepad device.
     */
    public String getName() {
        return mDeviceName;
    }

    /**
     * @return Device index of the gamepad device.
     */
    public int getIndex() {
        return mDeviceIndex;
    }

    /**
     * @return The timestamp when the gamepad device was last interacted.
     */
    public long getTimestamp() {
        return mTimestamp;
    }

    /**
     * @return The axes state of the gamepad device.
     */
    public float[] getAxes() {
        return mAxisValues;
    }

    /**
     * @return The buttons state of the gamepad device.
     */
    public float[] getButtons() {
        return mButtonsValues;
    }

    /**
     * Reset the axes and buttons data of the gamepad device everytime gamepad data access is
     * paused.
     */
    public void clearData() {
        Arrays.fill(mAxisValues, 0);
        Arrays.fill(mRawAxes, 0);
        Arrays.fill(mButtonsValues, 0);
        Arrays.fill(mRawButtons, 0);
    }

    /**
     * Handles key event from the gamepad device.
     * @return True if the key event from the gamepad device has been consumed.
     */
    public boolean handleKeyEvent(KeyEvent event) {
        // Ignore event if it is not for standard gamepad key.
        if (!GamepadList.isGamepadEvent(event)) return false;
        int keyCode = event.getKeyCode();
        assert keyCode < MAX_RAW_BUTTON_VALUES;
        // Button value 0.0 must mean fully unpressed, and 1.0 must mean fully pressed.
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            mRawButtons[keyCode] = 1.0f;
        } else if (event.getAction() == KeyEvent.ACTION_UP) {
            mRawButtons[keyCode] = 0.0f;
        }
        mTimestamp = event.getEventTime();

        return true;
    }

    /**
     * Handles motion event from the gamepad device.
     * @return True if the motion event from the gamepad device has been consumed.
     */
    public boolean handleMotionEvent(MotionEvent event) {
        // Ignore event if it is not a standard gamepad motion event.
        if (!GamepadList.isGamepadEvent(event)) return false;
        // Update axes values.
        for (int i = 0; i < mAxes.length; i++) {
            int axis = mAxes[i];
            mRawAxes[axis] = event.getAxisValue(axis);
        }
        mTimestamp = event.getEventTime();
        return true;
    }
}
