+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#define GL_GLEXT_PROTOTYPES
+#include "program.h"
+#include "shader.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+Program::Program()
+{
+ id=glCreateProgram();
+}
+
+Program::~Program()
+{
+ glDeleteProgram(id);
+}
+
+void Program::attach_shader(Shader &shader)
+{
+ if(find(shaders.begin(), shaders.end(), &shader)==shaders.end())
+ {
+ glAttachShader(id, shader.get_id());
+ shaders.push_back(&shader);
+ }
+}
+
+void Program::detach_shader(Shader &shader)
+{
+ list<Shader *>::iterator i=remove(shaders.begin(), shaders.end(), &shader);
+ if(i!=shaders.end())
+ {
+ shaders.erase(i, shaders.end());
+ glDetachShader(id, shader.get_id());
+ }
+}
+
+bool Program::link()
+{
+ for(list<Shader *>::iterator i=shaders.begin(); i!=shaders.end(); ++i)
+ if(!(*i)->get_compiled() && !(*i)->compile())
+ return false;
+
+ glLinkProgram(id);
+ linked=get_param(GL_LINK_STATUS);
+ return linked;
+}
+
+int Program::get_param(GLenum param) const
+{
+ int value;
+ glGetProgramiv(id, param, &value);
+ return value;
+}
+
+string Program::get_info_log() const
+{
+ sizei len=get_param(GL_INFO_LOG_LENGTH);
+ char log[len+1];
+ glGetProgramInfoLog(id, len+1, reinterpret_cast<GLsizei *>(&len), log);
+ return string(log, len);
+}
+
+} // namespace GL
+} // namespace Msp