+#include "graphic.h"
+#include "resources.h"
+
+using namespace std;
+
+#include <iostream>
+
+namespace Msp {
+namespace GLtk {
+
+Graphic::Graphic(const Resources &r, const string &n):
+ res(r),
+ name(n),
+ texture(0)
+{ }
+
+void Graphic::render(unsigned wd, unsigned ht) const
+{
+ float x[4];
+ float y[4];
+ float u[4];
+ float v[4];
+
+ x[0]=0.0f-shadow.left;
+ x[1]=x[0]+border.left;
+ x[3]=wd+shadow.right;
+ x[2]=x[3]-border.right;
+
+ y[0]=0.0f-shadow.bottom;
+ y[1]=y[0]+border.bottom;
+ y[3]=ht+shadow.top;
+ y[2]=y[3]-border.top;
+
+ const unsigned twidth=texture->get_width();
+ u[0]=static_cast<float>(slice.x)/twidth;
+ u[1]=static_cast<float>(slice.x+border.left)/twidth;
+ u[2]=static_cast<float>(slice.x+slice.w-border.right)/twidth;
+ u[3]=static_cast<float>(slice.x+slice.w)/twidth;
+
+ const unsigned theight=texture->get_height();
+ v[0]=static_cast<float>(slice.y)/theight;
+ v[1]=static_cast<float>(slice.y+border.bottom)/theight;
+ v[2]=static_cast<float>(slice.y+slice.h-border.top)/theight;
+ v[3]=static_cast<float>(slice.y+slice.h)/theight;
+
+ texture->bind();
+ unsigned xmin=border.left ? 0 : 1;
+ unsigned xmax=border.right ? 3 : 2;
+ unsigned ymin=border.bottom ? 0 : 1;
+ unsigned ymax=border.top ? 3 : 2;
+
+ for(unsigned i=ymin; i<ymax; ++i)
+ {
+ glBegin(GL_QUAD_STRIP);
+ for(unsigned j=xmin; j<=xmax; ++j)
+ {
+ glTexCoord2f(u[j], v[i]);
+ glVertex2f(x[j], y[i]);
+ glTexCoord2f(u[j], v[i+1]);
+ glVertex2f(x[j], y[i+1]);
+ }
+ glEnd();
+ }
+}
+
+
+Graphic::Sides::Sides():
+ top(0),
+ right(0),
+ bottom(0),
+ left(0)
+{ }
+
+
+Graphic::Loader::Loader(Graphic &g):
+ graph(g)
+{
+ add("texture", &Loader::texture);
+ add("slice", &Loader::slice);
+ add("border", &Loader::border);
+ add("shadow", &Loader::shadow);
+}
+
+void Graphic::Loader::texture(const string &n)
+{
+ graph.texture=&graph.res.get_texture(n);
+ graph.slice=Geometry(0, 0, graph.texture->get_width(), graph.texture->get_height());
+}
+
+void Graphic::Loader::slice(unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ graph.slice=Geometry(x, y, w, h);
+}
+
+void Graphic::Loader::border()
+{
+ load_sub(graph.border);
+}
+
+void Graphic::Loader::shadow()
+{
+ load_sub(graph.shadow);
+}
+
+
+Graphic::Sides::Loader::Loader(Sides &s):
+ sides(s)
+{
+ add("top", &Sides::top);
+ add("right", &Sides::right);
+ add("bottom", &Sides::bottom);
+ add("left", &Sides::left);
+}
+
+} // namespace GLtk
+} // namespace Msp