// screen.h  Bildschirm fuer Status-Anzeige

#include "objekte_classdef.h"
#include "fonts/myfonts.h"
//#include "fonts/myfonts.cc"

void Screen::clearDrawings()
{
 if(model!=NULL) {delete model; model=NULL;}
 modeldata.clear();
}

void Screen::flush()
{
 if(model!=NULL) delete model;
 model=new Model;
 model->init2(&modeldata,shader);
}

void Screen::render(Objekte& objekte) //Objekte auf dem Screen zeichnen
{
 objekte.render(screenId, camera, shader);
}

void Screen::render2() //Linien, Punkte, Texte zeichnen
{
 if(model!=NULL)
  {
   matrizen_an_GPU_senden(camera, glm::mat4(1.0f), shader);
   model->render();
  }
}

void Screen::init(int br,int ho,int screenid,Shader *shad)
{
 //bool orthoflag=false; //Normale Kamera, perspektivische Darstellung
 bool orthoflag=true; //Ortho-Kamera, besser fuer Schrift?
 float fov = 45.0f; //field of view (Sichtwinkel in Grad)
 shader=shad;
 breite=(float)br; hoehe=(float)ho; screenId=screenid;
 //printf("Screen::init() breite/hoehe = %f\n",breite/hoehe);//test
 camera = new MyCamera(fov, breite, hoehe, orthoflag); //wie normale Kamera
 float zdistanz = 0.1f; //Abstand der Kamera in z-Achse in Weltkoordinaten (Meter)
 //Die Grenzen in Pixelkoordinaten sind: oben=0 links=0 unten=hoehe rechts=breite
 //also
 //Fuer xmin..ymax die Grenzen in Weltkoordinaten setzen:
 if(orthoflag)
  {
   //printf("Testpunkt Screen::init(): orthoflag gesetzt\n");//test
   xmax = 0.075;
   ymax = xmax/breite*hoehe;
  }
 else
  {
   // ymax/abstand = tan(winkel/2) --> ymax = abstand*tan(winkel/2)
   float faktor = tanf(fov*GRAD/2.0f);
   //printf("Testpunkt Screen::init(): faktor=%f\n",faktor);//test
   ymax = zdistanz*faktor;
   xmax = ymax/hoehe*breite;
  }
 ymin = -ymax;
 xmin = -xmax;
 //printf("  xmax=%f ymax=%f\n",xmax,ymax);//test
 //Skalierfaktoren fuer Umrechnung zwischen Weltkoordinaten und Pixelkoordinaten:
 xscal = (xmax-xmin)/breite;
 yscal = (ymax-ymin)/hoehe;
 //printf("in Screen::init()  xscal=%f yscal=%f\n",xscal,yscal);//test
 
 aktfont->init(xscal,yscal);
 int fbreite,fhoehe;
 getmaxsize(&fbreite, &fhoehe);
 if(fhoehe>1200) aktfont->itextsize(24,32); //TODO: ev. anderen Font waehlbar?
 //else          aktfont->itextsize(12,16); //schon so voreingestellt (in fonts/myfonts.cc)

 //Position der Kamera setzen:
 //camera->translate(glm::vec3(0.0f, 0.0f, zdistanz-0.1f)); //in MyCamera::MyCamera() schon auf 0.1 gesetzt
 //camera->update();
}

void Screen::rgbcolor(int r,int g,int b)
{
 int bgr=(b<<16)+(g<<8)+r;
 altefarbe=aktuellefarbe;
 aktuellefarbe=bgr;
 glm::vec3 color(r/255.0f, g/255.0f, b/255.0f);
 material.diffuse=color;
 material.specular=color;
 material.emissive={0.0f, 0.0f, 0.0f};//nicht selbstleuchtend
 material.shininess=2.0f;
 modeldata.addmesh(material);
}

//Umrechnung von Weltkoordinaten in Pixelkoordinaten:
void Screen::welt2pixel(float32 xf, float32 yf, int *ix, int *iy)
{
 *ix = (int)((xf-xmin)/xscal+0.5);
 *iy = (int)((ymax-yf)/yscal+0.5);
}

void Screen::welt2pixel(float32 xf, int *ix) //Distanz umrechnen
{
 *ix = int(xf/xscal+0.5);
}

//Umrechnung von Pixelkoordinaten in Weltkoordinaten:
void Screen::pixel2welt(int ix, int iy, float32* xf, float32* yf)
{
 *xf = xmin + ix*xscal;
 *yf = ymax - iy*yscal;
}

void Screen::pixel2welt(int ix, float32* xf) //Distanz umrechnen
{
 *xf = ix*xscal;
}

void Screen::fillbox(float x1,float y1,float x2,float y2)
{
 int ix1,iy1,ix2,iy2;
 welt2pixel(x1,y1,&ix1,&iy1);
 welt2pixel(x2,y2,&ix2,&iy2);
 ifillbox(ix1,iy1,ix2,iy2);
}

void Screen::drawPoint(float x,float y)
{
 //TODO: Mesh fuer Punkte definieren (ev wie in OpenGLTekplot)
 //provisorisch:
 //printf("Screen::drawPoint(x=%f,y=%f)\n",x,y);//test 
 fillbox(x,y,x+xscal,y+yscal);
}

void Screen::ifillbox(int ix1,int iy1,int ix2,int iy2)
{
 float x1, y1, x2, y2;
 const float zwert = 0.0f;//TODO
 pixel2welt(ix1, iy1, &x1, &y1); //Umrechnung auf Welt-Koordinaten
 pixel2welt(ix2, iy2, &x2, &y2);
 //printf("  Weltkoordinaten: %f,%f,%f,%f\n",x1,y1,x2,y2);//test
 Vertex vertex[4];
 //x2 sollte groesser als x1 sein:
 if(x1 > x2)
  {
   float h=x1; x1=x2; x2=h; //x1 und x2 vertauschen
   h=y1; y1=y2; y2=h;       //y1 und y2 vertauschen
  }
 if(y2 > y1)
  {
   vertex[0].setPosition(x1, y1, zwert); //Punkte im Gegenuhrzeigersinn
   vertex[1].setPosition(x2, y1, zwert);
   vertex[2].setPosition(x2, y2, zwert);
   vertex[3].setPosition(x1, y2, zwert);
  }
 else
  {
   vertex[0].setPosition(x1, y2, zwert); //Punkte im Gegenuhrzeigersinn
   vertex[1].setPosition(x2, y2, zwert);
   vertex[2].setPosition(x2, y1, zwert);
   vertex[3].setPosition(x1, y1, zwert);
  }
 glm::vec3 normal={0.0f, 0.0f, 1.0f};
 for(int i=0;i<4;i++) vertex[i].setNormal(normal);
 
 uint32 i0 = modeldata.getNumVertices();
 for(int i=0;i<4;i++) modeldata.addVertex(vertex[i]);
 uint32 index[6]={0,1,2, 0,2,3}; //Indexe fuer 2 Dreiecke
 for(int i=0;i<6;i++) modeldata.addIndex(index[i]+i0);
}

void zwert_decrement()
{
 //TODO: wenn Text mit Hintergrund benoetigt
}
