// __author__ = Juan Carlos De Abreu (jcabreur@gmail.com)

#include "window.h"

// TODO: faltan definir bien los parametros
#include "window_management.h"
#include "../Includes/OpenGL.h"

BEGIN_TEG_NAMESPACE();
BEGIN_NAMESPACE(gui);

Window::Window(int x, int y, int width, int height, std::tstring caption)
	: Frame(x, y, width, height), caption_(caption) {
	// TODO: tomar en cuenta el valor minimo para la ventana; GUI::Control(x_, y_, min(0, MIN_GUI_WINDOW_WIDHT)) {
	// TODO: estos valores son temporales ...
	alpha = 0.8f;
	z_order_ = 0.0f;
}

Window::~Window() {}

// Method to render the button
void Window::Render() const {
  if (is_visible_) {
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, GUI_TEXTURE);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    glEnable(GL_DEPTH_TEST);

    glColor4f(1,1,1,alpha);

    glPushMatrix();

      // ...(falta)
      //glTranslate(x, Window.height - Window.captionBarHeight-y, zOrder);
      //glTranslatef(x, 600 - 26 - y, zOrder);	
      glTranslatef(x_ + 0.0f, y_ + 0.0f, z_order_);

      // TODO: el 28 que se le suma debe estar especificado en algun lado no puede salir como por obra de magia1!!

      // TODO: creo que me puedo quitar los x + .. y + .. si hago un translate antes y ya!!

      const float kLeftX0 = static_cast<float>(0);
      const float kLeftX1 = static_cast<float>(63);
      const float kRightX0 = static_cast<float>(width_ - 32);
      const float kRightX1 = static_cast<float>(width_);
      const float kTopY0 = static_cast<float>(0);
      const float kTopY1 = static_cast<float>(-27);
      const float kBottomY0 = static_cast<float>(-height_ + 27);
      const float kBottomY1 = static_cast<float>(-height_);

      const float kCloseButtonX0 = static_cast<float>(width_ - 22);
      const float kCloseButtonX1 = static_cast<float>(width_ - 6);
      const float kCloseButtonY0 = static_cast<float>(-8);
      const float kCloseButtonY1 = static_cast<float>(-24);

      glBegin(GL_QUADS);
        // top left corner of window.
        glTexCoord2f(0.f, 1.f);
        glVertex3f(kLeftX0, kTopY0, 0.f);
        glTexCoord2f(0.f, 0.789062f);
        glVertex3f(kLeftX0, kTopY1, 0.f);
        glTexCoord2f(0.5f, 0.789062f);
        glVertex3f(kLeftX1, kTopY1, 0.f);
        glTexCoord2f(0.5f, 1.f);
        glVertex3f(kLeftX1, kTopY0, 0.f);

        // top of window.
        glTexCoord2f(0.5f, 1.f);
        glVertex3f(kLeftX1, kTopY0, 0.f);
        glTexCoord2f(0.5f, 0.789062f);
        glVertex3f(kLeftX1, kTopY1, 0.f);
        glTexCoord2f(0.75f, 0.789062f);
        glVertex3f(kRightX0, kTopY1, 0.f);
        glTexCoord2f(0.75f, 1.f);
        glVertex3f(kRightX0, kTopY0, 0.f);

        // top right corder of window.
        glTexCoord2f(0.75f, 1.f);
        glVertex3f(kRightX0, kTopY0, 0.f);
        glTexCoord2f(0.75f, 0.789062f);
        glVertex3f(kRightX0, kTopY1, 0.f);
        glTexCoord2f(1.f, 0.789062f);
        glVertex3f(kRightX1, kTopY1, 0.f);
        glTexCoord2f(1.f, 1.f);
        glVertex3f(kRightX1, kTopY0, 0.f);

        // left side of window.
        glTexCoord2f(0.f, 0.789062f);
        glVertex3f(kLeftX0, kTopY0, 0);
        glTexCoord2f(0.f, 0.210937f);
        glVertex3f(kLeftX0, kBottomY0, 0);
        glTexCoord2f(0.046875f, 0.210937f);
        glVertex3f(6.f, kBottomY0, 0);
        glTexCoord2f(0.046875f, 0.789062f);
        glVertex3f(6, kTopY0, 0);

        // draw the main body of the window
        glTexCoord2f(0.070312f, 0.75f);
        glVertex3f(6, kTopY0, 0);
        glTexCoord2f(0.070312f, 0.5f);
        glVertex3f(6, kBottomY0, 0);
        glTexCoord2f(0.304687f, 0.5f);
        glVertex3f(width_ - 7.f, kBottomY0, 0);
        glTexCoord2f(0.304687f, 0.75f);
        glVertex3f(width_ - 7.f, kTopY0, 0);

        // right side of window.
        glTexCoord2f(0.945312f, 0.789062f);
        glVertex3f(width_ - 7.0f, kTopY0, 0);
        glTexCoord2f(0.945312f, 0.210937f);
        glVertex3f(width_ - 7.0f, kBottomY0, 0);
        glTexCoord2f(1.f, 0.210937f);
        glVertex3f(kRightX1, kBottomY0, 0);
        glTexCoord2f(1.f, 0.789062f);
        glVertex3f(kRightX1, kTopY0, 0);

        // bottom left corner of window.
        glTexCoord2f(0.f, 0.210937f);
        glVertex3f(kLeftX0, kBottomY0, 0);
        glTexCoord2f(0.f, 0.f);
        glVertex3f(kLeftX0, kBottomY1, 0);
        glTexCoord2f(0.5f, 0.f);
        glVertex3f(kLeftX1, kBottomY1, 0);
        glTexCoord2f(0.5f, 0.210937f);
        glVertex3f(kLeftX1, kBottomY0, 0);

        // bottom of window.
        glTexCoord2f(0.5f, 0.210937f);
        glVertex3f(kLeftX1, kBottomY0, 0);
        glTexCoord2f(0.5f, 0.f);
        glVertex3f(kLeftX1, kBottomY1, 0);
        glTexCoord2f(0.75f, 0.f);
        glVertex3f(kRightX0, kBottomY1, 0);
        glTexCoord2f(0.75f, 0.210937f);
        glVertex3f(kRightX0, kBottomY0, 0);

        // bottom right corder of window.
        glTexCoord2f(0.75f, 0.210937f);
        glVertex3f(kRightX0, kBottomY0, 0.f);
        glTexCoord2f(0.75f, 0.f);
        glVertex3f(kRightX0, kBottomY1,0.f);
        glTexCoord2f(1.f, 0.f);
        glVertex3f(kRightX1, kBottomY1, 0.f);
        glTexCoord2f(1.f, 0.210937f);
        glVertex3f(kRightX1, kBottomY0, 0.f);

        // window close button
        glTexCoord2f(0.8125f, 0.75f);
        glVertex3f(kCloseButtonX0, kCloseButtonY0, 0.01f);
        glTexCoord2f(0.8125f, 0.625f);
        glVertex3f(kCloseButtonX0, kCloseButtonY1, 0.01f);
        glTexCoord2f(0.9375f, 0.625f);
        glVertex3f(kCloseButtonX1, kCloseButtonY1, 0.01f);
        glTexCoord2f(0.9375f, 0.75f);
        glVertex3f(kCloseButtonX1, kCloseButtonY0, 0.01f);
      glEnd();

      glBindTexture(GL_TEXTURE_2D, 0);
      glDisable(GL_TEXTURE_2D);

      // draw the tittle of the window
      GL_WRITE(45, 23, caption_.c_str());

      // draw the Panels
      glTranslatef(0, 0, 0.02f);
      const int kNumberOfPanels = static_cast<int>(panel_.size());
      for (int i = 0; i < kNumberOfPanels; i++)
        panel_[i].Render();

      // draw the Buttons
      glTranslatef(0, 0, 0.02f);
	  const int kNumberOfButtons = static_cast<int>(button_.size());
      for (int i = 0; i < kNumberOfButtons; i++)	
        button_[i].Render();

      // draw the Checkboxes
      const int kNumberOfCheckBox = static_cast<int>(check_box_.size());
      for (int i = 0; i < kNumberOfCheckBox; i++)	
        check_box_[i].Render();

      // draw the RadioButtons
      const int kNumberOfRadioButtons = static_cast<int>(radio_button_.size());
      for (int i = 0; i < kNumberOfRadioButtons; i++)
        radio_button_[i].Render();

      // draw the Text
      const int kNumberOfTexts = static_cast<int>(text_.size());
      for (int i = 0; i < kNumberOfTexts; i++)
        text_[i].Render();
      // por ahora prueba
      //renderText(i);
      //	pruebaWrite(wManagement, text[i]);

      glPopMatrix();

    glDisable(GL_BLEND);
  }
}

// funcion para agregar un botton a la ventana
void Window::addButton(int x, int y, int width, int height, const char *caption) {
	// se crea el boton con las caracteristicas indicadas
	//GEO_BUTTON oneButton = GEO_BUTTON(_x, _y, _width, _height, caption);
	Button oneButton = Button(x, y, width, height, caption);
	
	// se actualiza a que ventana pertenece el boton
//	oneButton.parent = this;
	
	// se agrega el boton a la lista de botones de la ventana
	button_.push_back(oneButton);
}

// funcion para agregarle un texto a la ventana
void Window::addText(int x, int y, const char *caption) {
	// se crea el texto con las caracteristicas indicadas
//	GEO_TEXT oneText = GEO_TEXT(_x, _y, caption);
	Text oneText = Text(x, y, caption);

	// se actualiza a que ventana pertenece el texto
//	oneText.parent = this;

	// se agrega el texto a la lista de textos de la ventana
	text_.push_back(oneText);
}

// funcion para agregar un panel a la ventana
void Window::addPanel(int x, int y, int width, int height) {
	// se crea el panel con las caracteristicas indicadas
//	GEO_PANEL onePanel = GEO_PANEL(_x, _y, _width, _height);
	Panel onePanel = Panel(x, y, width, height);

	// se actualiza a que ventana pertenece el panel
//	onePanel.parent = this;

	// se agrega el panel a la lista de panels de la ventana
	panel_.push_back(onePanel);
}

// funcion para agregar un checkBox a la ventana
void Window::addCheckBox(int x, int y, bool checked) {
	// se crea el checkBox con las caracteristicas indicadas
	//GEO_CHECKBOX oneCheckBox = GEO_CHECKBOX(_x, _y, _checked);
	CheckBox oneCheckBox = CheckBox(x, y, checked);

	// se actualiza a que ventana pertenece el checkBox
//	oneCheckBox.parent = this;

	// se agrega el checkBox a la lista de checkBox's de la ventana
	check_box_.push_back(oneCheckBox);
}

// funcion para agregar un radioButton a la ventana
void Window::addRadioButton(int x, int y, bool checked, int group) {
	// se crea el radioButton con las caracteristicas indicadas
//	GEO_RADIOBUTTON oneRadioButton = GEO_RADIOBUTTON(_x, _y, _group, _checked);
	RadioButton oneRadioButton = RadioButton(x, y, checked, group);

	// se actualiza a que ventana pertenece el radioButton
//	oneRadioButton.parent = this;

	// se agrega el radioButton a la lista de radioButton's de la ventana
	radio_button_.push_back(oneRadioButton);
}

END_NAMESPACE(gui);
END_TEG_NAMESPACE();
