#include "stdafx.h"


#include "mdc_draw_util.h"

namespace mdc {

void draw_shadow(CairoCtx *cr, const Rect &around_rect, const Color &color)
{
  cairo_pattern_t *pat;

  // right
  cr->save();
  pat= cairo_pattern_create_linear(0, 0, 1.0, 0);
  cairo_pattern_add_color_stop_rgba(pat, 0, color.r, color.g, color.b, 1.0);
  cairo_pattern_add_color_stop_rgba(pat, 1, color.r, color.g, color.b, 0.0);

  cr->translate(around_rect.xmax(), around_rect.ymin()+2);
  cr->scale(5, around_rect.size.height-2);
  cr->rectangle(0, 0, 1, 1);
  cr->set_pattern(pat);
  cr->fill();
  cairo_pattern_destroy(pat);
  cr->restore();

  // corner
  cr->save();
  pat= cairo_pattern_create_linear(0, 0, 1.0, 1.0);
  cairo_pattern_add_color_stop_rgba(pat, 0, color.r, color.g, color.b, 0.6);
  cairo_pattern_add_color_stop_rgba(pat, 1, color.r, color.g, color.b, 0.0);

  cr->translate(around_rect.xmax(), around_rect.ymax());
  cr->scale(5, 5);
  cr->move_to(0, 0);
  cr->line_to(0, 1);
  cr->line_to(1, 0);
  cr->set_pattern(pat);
  cr->fill();
  cairo_pattern_destroy(pat);
  cr->restore();


  // bottom
  cr->save();
  pat= cairo_pattern_create_linear(0, 0, 0, 1);
  cairo_pattern_add_color_stop_rgba(pat, 0, color.r, color.g, color.b, 1.0);
  cairo_pattern_add_color_stop_rgba(pat, 1, color.r, color.g, color.b, 0.0);

  cr->translate(around_rect.xmin(), around_rect.ymax());
  cr->scale(around_rect.size.width, 5);
  cr->rectangle(0, 0, 1, 1);
  cr->set_pattern(pat);
  cr->fill();
  cairo_pattern_destroy(pat);
  cr->restore();


  // corner
  cr->save();
  pat= cairo_pattern_create_linear(0, 1.0, 1.0, 0.0);
  cairo_pattern_add_color_stop_rgba(pat, 1, color.r, color.g, color.b, 0.6);
  cairo_pattern_add_color_stop_rgba(pat, 0, color.r, color.g, color.b, 0.0);

  cr->translate(around_rect.xmin()-4, around_rect.ymax());
  cr->scale(4, 5);
  cr->move_to(0, 0);
  cr->line_to(1, 1);
  cr->line_to(1, 0);
  cr->close_path();
  cr->set_pattern(pat);
  cr->fill();
  cairo_pattern_destroy(pat);
  cr->restore();


  // left
  cr->save();
  pat= cairo_pattern_create_linear(0, 0, 1.0, 0);
  cairo_pattern_add_color_stop_rgba(pat, 1, color.r, color.g, color.b, 1.0);
  cairo_pattern_add_color_stop_rgba(pat, 0, color.r, color.g, color.b, 0.0);

  cr->translate(around_rect.xmin()-4, around_rect.ymin()+2);
  cr->scale(5, around_rect.size.height-1);
  cr->rectangle(0, 0, 1, 1);
  cr->set_pattern(pat);
  cr->fill();
  cairo_pattern_destroy(pat);
  cr->restore();
}



void draw_glow(CairoCtx *cr, const Rect &around_rect, const Color &color)
{
  cr->save();
  cr->set_color(color, 0.6);
  cr->set_line_width(5);
  cr->rectangle(around_rect.xmin()-2.5, around_rect.ymin()-2.5, around_rect.width()+6, around_rect.height()+6);
  cr->stroke();
  /*
  cr->set_source_rgba(color.r, color.g, color.b, 0.8);
  cr->set_line_width(2);
  cr->rectangle(around_rect.xmin()-0.5, around_rect.ymin()-0.5, around_rect.width()+2, around_rect.height()+2);
  cr->stroke();  
   */
  cr->restore();
}


void fill_hollow_rectangle(CairoCtx *cr, const Rect &outer_rect,
                                const Rect &inner_rect)
{
  cr->rectangle(outer_rect.xmin(), outer_rect.ymin(),
                  outer_rect.width(), inner_rect.ymin() - outer_rect.ymin());
  
  cr->rectangle(outer_rect.xmin(), inner_rect.ymax(),
                  outer_rect.width(), outer_rect.ymax() - inner_rect.ymax());


  cr->rectangle(outer_rect.xmin(), inner_rect.ymin(),
                  inner_rect.xmin() - outer_rect.xmin(), inner_rect.height());

  cr->rectangle(inner_rect.xmax()+1, inner_rect.ymin(),
                  outer_rect.xmax() - inner_rect.xmin(), inner_rect.height());

  cr->fill();
}



void stroke_rounded_rectangle(CairoCtx *cr,
                                   const Rect &rect, CornerMask corners,
                                   float corner_radius, float offset)
{
  Rect bounds= rect;
  
  bounds.pos.x+= 0.5 - offset;
  bounds.pos.y+= 0.5 - offset;
  bounds.size.width+= offset*2;
  bounds.size.height+= offset*2;
  
  if (corner_radius > 0 && corners)
  {
    double r= corner_radius;
    int dtl= (corners & CTopLeft)!=0;
    int dtr= (corners & CTopRight)!=0;
    int dbl= (corners & CBottomLeft)!=0;
    int dbr= (corners & CBottomRight)!=0;

    cr->new_path();

    if (dtl)
    {
      cr->arc(bounds.xmin() + r, bounds.ymin() + r, r,
              180 * M_PI / 180.0, 270 * M_PI / 180.0);
    }
    
    cr->line_to(bounds.xmax() - r * dtr, bounds.ymin());
    
    if (dtr)
    {
      cr->arc(bounds.xmax() - r, bounds.ymin() + r, r,
              270 * M_PI / 180.0, 0 * M_PI / 180.0);
    }
    
    cr->line_to(bounds.xmax(), bounds.ymax() - r * dbr);
    
    if (dbr)
    {
      cr->arc(bounds.xmax() - r, bounds.ymax() - r, r,
                0 * M_PI / 180.0, 90 * M_PI / 180.0);
    }

    cr->line_to(bounds.xmin() + r * dbl, bounds.ymax());

    if (dbl)
    {
      cr->arc(bounds.xmin() + r, bounds.ymax() - r, r,
              90 * M_PI / 180.0, 180 * M_PI / 180.0);
    }

    cr->line_to(bounds.xmin(), bounds.ymin() + r * dtl);

    cr->close_path();
  }
  else
    cr->rectangle(bounds);
}


void gl_setcolor(const Color &color)
{
  glColor4d(color.r, color.g, color.b, color.a);
}


void gl_rectangle(GLenum mode, double x, double y, double w, double h)
{
  glBegin(mode);
  glVertex2d(x, y);
  glVertex2d(x + w, y);
  glVertex2d(x + w, y + h);
  glVertex2d(x, y + h);
  glEnd();
}


void gl_rectangle(GLenum mode, const Rect &rect)
{
  glBegin(mode);
  glVertex2d(rect.xmin(), rect.ymin());
  glVertex2d(rect.xmax(), rect.ymin());
  glVertex2d(rect.xmax(), rect.ymax());
  glVertex2d(rect.xmin(), rect.ymax());
  glEnd();
}

};
