/*
    QGL RendererService
    Ivan Pelipenko peri4ko@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef RENDERER_SERVICE_H
#define RENDERER_SERVICE_H

#include "glframebuffer.h"
#include "glshaders_types.h"

#include <QQueue>


class QGLENGINE_CORE_EXPORT RendererService {
	friend class QGLView;
	friend class MouseController;
	friend class Renderer;
	friend class RendererSelection;

public:
	RendererService(Renderer * r_);
	virtual ~RendererService();

	enum HandleAction {
		haNoAction,
		haMove,
		haRotate,
		haScale,
	};

	enum HandleMesh {
		hmMoveX     = 0x01,
		hmMoveY     = 0x02,
		hmMoveZ     = 0x04,
		hmMoveXY    = hmMoveX | hmMoveY,
		hmMoveXZ    = hmMoveX | hmMoveZ,
		hmMoveYZ    = hmMoveY | hmMoveZ,
		hmMaxMove   = hmMoveX | hmMoveY | hmMoveZ,
		hmRotateX   = 0x08,
		hmRotateY   = 0x10,
		hmRotateZ   = 0x20,
		hmMaxRotate = hmRotateX | hmRotateY | hmRotateZ,
		hmScaleX    = 0x40,
		hmScaleY    = 0x80,
		hmScaleZ    = 0x100,
		hmScaleXY   = hmScaleX | hmScaleY,
		hmScaleXZ   = hmScaleX | hmScaleZ,
		hmScaleYZ   = hmScaleY | hmScaleZ,
		hmMaxScale  = hmScaleX | hmScaleY | hmScaleZ,
	};

	void init(int width, int height);
	void resize(int width, int height);

	QMatrix4x4 invariantSizeMatrix(QVector3D p, double * ret_scale = 0);
	QMatrix4x4 parentRotationMatrix(ObjectBase * o, bool self_rotation = true);
	void fillXYZObjects();
	void fillOmniObjects();
	void fillAimedObjects(const ObjectBaseList & objects, Mesh * line_mesh);
	void fillHandleObjects(QVector3D center,
	                       HandleMesh ids[],
	                       const QVector<QMatrix4x4> & mats,
	                       const QVector<QVector4D> & colors,
	                       QMatrix4x4 add_mat,
	                       int count = 3);
	bool calculateCenter();
	void drawCurrentHandleObjects();
	void drawLights();
	void drawLightsFrame(QColor color);
	void drawCameras();
	void drawCamerasFrame(QColor color);
	void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col);
	void renderService();
	void setCurrentAction(HandleAction ha) { current_action = ha; }
	Mesh * currentHandleMesh();

private:
	Renderer * r;
	Mesh *axis_mesh, *handle_move_mesh, *handle_rotate_mesh, *handle_scale_mesh;
	Mesh *handle_ms_2_mesh, *handle_scale_3_mesh;
	Mesh *box_mesh_f, *omni_mesh_f, *cone_mesh_f, *camera_mesh_f;
	Mesh *box_mesh, *omni_mesh, *cone_mesh, *camera_mesh;
	Mesh *line_spot_f, *line_camera_f;
	QMatrix4x4 v_mat, axis_mat;
	QVector3D selection_center;
	QVector<QMatrix4x4> mat_xyz, mat_ms2;
	QVector<QVector4D> color_xyz, color_ms2;
	QVector<QGLEngineShaders::Object> cur_objects, cur_aims;
	QGLEngineShaders::Object line_object;
	Camera * axis_camera;
	QSize axis_viewport;
	HandleAction current_action;
	QFlags<HandleMesh> current_handle;
	int line_width;
	double size_vp_scale, size_full_scale;
};

#endif // RENDERER_SERVICE_H
