/*
 * Copyright 2017 The Cobalt Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef COBALT_INPUT_CAMERA_3D_INPUT_POLLER_H_
#define COBALT_INPUT_CAMERA_3D_INPUT_POLLER_H_

#include <map>
#include <utility>

#include "base/basictypes.h"
#include "base/optional.h"
#include "base/synchronization/lock.h"
#include "cobalt/input/camera_3d.h"
#include "cobalt/input/input_poller.h"
#include "third_party/glm/glm/mat4x4.hpp"

namespace cobalt {
namespace input {

// Implements a camera that gets its orientation information from hand-
// controlled inputs.
class Camera3DInputPoller : public Camera3D {
 public:
  explicit Camera3DInputPoller(
      const scoped_refptr<input::InputPoller>& input_poller);

  void CreateKeyMapping(int keycode, uint32 camera_axis,
                        float degrees_per_second) override;
  void ClearKeyMapping(int keycode) override;
  void ClearAllKeyMappings() override;
  glm::quat GetOrientation() const override;

  // Returns the camera transforms based on hand-controlled inputs mapped
  // by the functions above
  base::CameraTransform GetCameraTransformAndUpdateOrientation() override;

  void UpdatePerspective(float width_to_height_aspect_ratio,
                         float vertical_fov) override;

  void Reset() override;

  void SetInput(const scoped_refptr<Camera3D>& other) override;

 private:
  struct KeycodeMappingInfo {
    KeycodeMappingInfo() : axis(0), degrees_per_second(0.0f) {}
    KeycodeMappingInfo(uint32 axis, float degrees_per_second)
        : axis(axis), degrees_per_second(degrees_per_second) {}

    uint32 axis;
    float degrees_per_second;
  };

  typedef std::map<int, KeycodeMappingInfo> KeycodeMap;

  void AccumulateOrientation();
  void ClampAngles();

  glm::quat orientation() const;

  mutable base::Lock mutex_;

  // The current accumulated camera orientation state.
  float roll_in_radians_;
  float pitch_in_radians_;
  float yaw_in_radians_;

  // The time that the last update to the camera's state has occurred.
  base::Optional<base::TimeTicks> last_update_;

  // A map of keys bound to camera movements.
  KeycodeMap keycode_map_;

  // The input poller from which we can check the state of a given key.
  scoped_refptr<input::InputPoller> input_poller_;

  float width_to_height_aspect_ratio_;
  float vertical_fov_;

  DISALLOW_COPY_AND_ASSIGN(Camera3DInputPoller);
};

}  // namespace input
}  // namespace cobalt

#endif  // COBALT_INPUT_CAMERA_3D_INPUT_POLLER_H_
