text: #pragma once
  #include <vector>
  #include <GL/glew.h>
  #include <glm/glm.hpp>
  #include <glm/gtc/matrix_transform.hpp>
  
  // Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
  enum Camera_Movement {
      FORWARD,
      BACKWARD,
      LEFT,
      RIGHT
  };
  
  const GLfloat YAW = -90.0f;
  const GLfloat PITCH = 0.0f;
  const GLfloat SPEED = 3.0f;
  const GLfloat SENSITIVITY = 0.25f;
  const GLfloat ZOOM = 45.0f;
  
  // An abstract camera class that processes input and calculates the corresponding Eular Angles, Vectors and Matrices for use in OpenGL
  class Camera {
  public:
      //Camera Attributes
      glm::vec3 Position;
      glm::vec3 Front;
      glm::vec3 Up;
      glm::vec3 WorldUp;
      glm::vec3 Right;
      //Euler Angles
      GLfloat Pitch;
      GLfloat Yaw;
      //Camera options
      GLfloat MovementSpeed;
      GLfloat MouseSensitivity;
      GLfloat Zoom;
      //Constructor with vectors
      Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f),
             glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW, GLfloat pitch = PITCH)
              : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM) {
          this->Position = position;
          this->WorldUp = up;
          this->Yaw = yaw;
          this->Pitch = pitch;
          this->updateCameraVectors();
      }
      //Constructor with scalar vectors
  	Camera(GLfloat posX, GLfloat posY, GLfloat posZ,
             GLfloat upX, GLfloat upY, GLfloat upZ,
             GLfloat yaw = YAW, GLfloat pitch = PITCH)
              : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM) {
          this->Position = glm::vec3(posX , posY, posZ);
          this->WorldUp = glm::vec3(upX, upY, upZ);
          this->Yaw = yaw;
          this->Pitch = pitch;
          this->updateCameraVectors();
      }
      // Returns the view matrix calculated using Eular Angles and the LookAt Matrix
      glm::mat4 GetViewMatrix();
  
      // Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
      void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime);
  
  
      // Processes input received from a mouse input system. Expects the offset value in both the x and y direction.
      void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch = true);
  
      // Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
      void ProcessMouseScroll(GLfloat yoffset);
  
  private:
      // Calculates the front vector from the Camera's (updated) Eular Angles
      void updateCameraVectors();
  
  };
  
  