#include "Shader.h"
#include "../utils.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstring>
#include <memory>

Shader::Shader(GLenum type, const std::string& path): _path(path), _type(type), _shader(0) {
}

void Shader::compile() {
	std::ifstream is(_path, std::ios::binary);
	if(is) {
		std::ostringstream ss;
		ss << is.rdbuf();
		std::string text = ss.str();

		_shader = glCreateShader(_type);
		utils::throwIfGLError("error creating shader");

		const GLchar* textBuffer = text.c_str();
		glShaderSource(_shader, 1, &textBuffer, nullptr);
		utils::throwIfGLError("error setting shader source");

		glCompileShader(_shader);
		utils::throwIfGLError("error compiling shader");

		GLint success = GL_TRUE;
		glGetShaderiv(_shader, GL_COMPILE_STATUS, &success);
		if(success == GL_FALSE) {
			logCompileError();
			throw std::runtime_error("error compiling shader: " + _path);
		}
	} else {
		throw std::runtime_error("error opening file: " + _path);
	}
}

Shader::operator GLuint() const {
	return _shader;
}

Shader::~Shader() {
	glDeleteShader(_shader);
}

void Shader::logCompileError() {
	std::cout << "shader: " << _shader << std::endl;
	GLint logSize = 0;
	glGetShaderiv(_shader, GL_INFO_LOG_LENGTH, &logSize);
	std::cout << "log length: " << logSize << std::endl;

	auto log = std::make_unique<GLchar[]>(logSize);
	memset(log.get(), 0, (size_t)logSize);

	glGetShaderInfoLog(_shader, logSize, &logSize, log.get());
	std::cout << "log: " << log.get() << std::endl;
}


