/* StarField.h
Copyright (c) 2014 by Michael Zahniser

Endless Sky 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.

Endless Sky 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
this program. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include "../Point.h"
#include "Shader.h"

#include "../opengl.h"

#include <vector>

class Body;
class Interface;
class Sprite;
class System;



// Object to hold a set of "stars" to be drawn as a backdrop. The star pattern
// repeats every 4096 pixels. The pattern is generated by a random walk method
// so that some parts will be much denser than others, which is visually more
// interesting than if the stars were evenly spread out in perfectly random
// noise. If the view is moving, the stars are elongated in a motion blur to
// match the motion; otherwise they would seem to jitter around.
class StarField {
public:
	void Init(int stars, int width);
	void FinishLoading();
	const Point &Position() const;
	void SetPosition(const Point &position);
	void SetHaze(const Sprite *sprite, bool allowAnimation);

	void Step(Point vel, double zoom = 1.);
	void Draw(const Point &blur, const System *system = nullptr) const;


private:
	void EnableAttribArrays() const;
	void SetUpGraphics();
	void MakeStars(int stars, int width);


private:
	int widthMod;
	int tileCols;
	std::vector<int> tileIndex;

	// Constants from an Interface that modify the starfield's behavior.
	double fixedZoom = 1.;
	double velocityReducer = 1.;

	Point pos;
	double baseZoom = 1.;

	double minZoom;
	double zoomClamp;
	double clampSlope;

	// Track the haze sprite, so we can animate the transition between different hazes.
	const Sprite *lastSprite;
	mutable double transparency = 0.;
	std::vector<Body> haze[2];

	const Shader *shader;
	GLuint vao;
	GLuint vbo;

	GLuint offsetI;
	GLuint sizeI;
	GLuint cornerI;

	GLuint scaleI;
	GLuint rotateI;
	GLuint elongationI;
	GLuint translateI;
	GLuint brightnessI;
};
