#include "widget/button.hpp"

#include "ta_parameter.hpp"
#include "graphics_primitive.hpp"

namespace widget {

  const static float shadow_depth = 1.0 / 10.0;
  const static int shadow_color = 0x0000000;

  const static float lowlight_depth = 1.0 / 9.0;
  const static int lowlight_color = 0x0c0d0d;

  const static float highlight_depth = 1.0 / 8.0;
  const static int highlight_color = 0x353a3a;

  const static int highlight_click_color = 0x141616;

  const static float background_depth = 1.0 / 7.0;
  const static int background_color = 0x282c2c;

  const static float label_depth = 1.0 / 6.0;
  const static int label_color = 0xffffff;

  void button::draw_shadow(ta_parameter_writer& writer)
  {
    {
      float x0 = x() + 1;
      float x1 = x() + width - 1;
      float y0 = y();
      float y1 = y() + height;
      quad_type_0(writer,
                  {x0, y0, shadow_depth},
                  {x1, y0, shadow_depth},
                  {x1, y1, shadow_depth},
                  {x0, y1, shadow_depth},
                  shadow_color);
    }
    {
      float x0 = x();
      float x1 = x() + width;
      float y0 = y() + 1;
      float y1 = y() + height - 1;
      quad_type_0(writer,
                  {x0, y0, shadow_depth},
                  {x1, y0, shadow_depth},
                  {x1, y1, shadow_depth},
                  {x0, y1, shadow_depth},
                  shadow_color);
    }
  }

  void button::draw_lowlight(ta_parameter_writer& writer)
  {
    float x0 = x() + 1;
    float x1 = x() + width - 1;
    float y0 = y() + 1;
    float y1 = y() + height - 1;
    quad_type_0(writer,
                {x0, y0, lowlight_depth},
                {x1, y0, lowlight_depth},
                {x1, y1, lowlight_depth},
                {x0, y1, lowlight_depth},
                lowlight_color);
  }

  void button::draw_highlight(ta_parameter_writer& writer)
  {
    float x0 = x() + 1;
    float x1 = x() + width - 2;
    float y0 = y() + 1;
    float y1 = y() + height - 2;

    int color = (click_state == click_type::release) ? highlight_color : highlight_click_color;
    quad_type_0(writer,
                {x0, y0, highlight_depth},
                {x1, y0, highlight_depth},
                {x1, y1, highlight_depth},
                {x0, y1, highlight_depth},
                color);
  }

  void button::draw_background(ta_parameter_writer& writer)
  {
    float x0 = x() + 2;
    float x1 = x() + width - 2;
    float y0 = y() + 2;
    float y1 = y() + height - 2;
    quad_type_0(writer,
                {x0, y0, background_depth},
                {x1, y0, background_depth},
                {x1, y1, background_depth},
                {x0, y1, background_depth},
                background_color);
  }

  void button::draw_label(ta_parameter_writer& writer)
  {
    float y_offset = (float)(click_state != click_type::release);

    float cx = x() + width / 2 - (glyph::hori_advance * label_length) / 2;
    float cy = y() + height / 2 - glyph::vert_advance / 2 + y_offset;

    transfer_string(writer, label, cx, cy, label_depth, label_color);
  }

  void button::draw(ta_multiwriter& multi)
  {
    global_polygon_untextured(multi.op,
                              para_control::list_type::opaque,
                              tsp_instruction_word::dst_alpha_instr::zero);

    draw_shadow(multi.op);

    draw_lowlight(multi.op);

    draw_highlight(multi.op);

    draw_background(multi.op);

    transfer_global_polygon_glyph(multi.pt);

    draw_label(multi.pt);

    widget::draw(multi);
  }

  void button::click()
  {
    if (click_state == click_type::release && on_click != nullptr)
      on_click();

    widget::click();
  }
}
