use maraiah::{durandal::image::*, rozinante::draw::*};

fn flt_color(cr: impl Color) -> (f64, f64, f64)
{
   fn flt_color(n: u16) -> f64 {f64::from(n) / f64::from(u16::max_value())}

   (flt_color(cr.r()), flt_color(cr.g()), flt_color(cr.b()))
}

impl CacheImage for CairoPixbuf
{
   fn w(&self) -> Coord {self.0.get_width() as Coord}
   fn h(&self) -> Coord {self.0.get_height() as Coord}
}

impl CairoDrawArea
{
   pub const fn new(ctx: cairo::Context, w: f64, h: f64) -> Self
   {
      CairoDrawArea{ctx, w: w as Coord, h: h as Coord}
   }
}

impl DrawArea for CairoDrawArea
{
   type NativeImage = CairoPixbuf;

   fn w(&self) -> Coord {self.w}
   fn h(&self) -> Coord {self.h}

   fn clear(&self, cr: impl Color)
   {
      use cairo::{FontSlant, FontWeight};

      self.rect(Rect{x: 0, y: 0, w: self.w(), h: self.h()}, cr);

      self.ctx
          .select_font_face("Sans", FontSlant::Normal, FontWeight::Normal);
      self.ctx.set_font_size(14.0);
   }

   fn rect(&self, rect: Rect, cr: impl Color)
   {
      let x1 = f64::from(rect.x);
      let y1 = f64::from(rect.y);
      let x2 = f64::from(rect.w) + x1;
      let y2 = f64::from(rect.h) + y1;

      let (r, g, b) = flt_color(cr);

      self.ctx.set_source_rgb(r, g, b);
      self.ctx.rectangle(x1, y1, x2, y2);
      self.ctx.fill();
   }

   fn text(&self, pos: Point, text: &str, cr: impl Color)
   {
      let (r, g, b) = flt_color(cr);

      self.ctx.set_source_rgb(r, g, b);
      self.ctx.move_to(f64::from(pos.0), f64::from(pos.1));
      self.ctx.show_text(text);
   }

   fn image(&self, pos: Point, im: &Self::NativeImage)
   {
      use gdk::prelude::*;
      self.ctx
          .set_source_pixbuf(&im.0, f64::from(pos.0), f64::from(pos.1));
      self.ctx.paint();
   }
}

pub struct CairoPixbuf(pub gdk_pixbuf::Pixbuf);

pub struct CairoDrawArea
{
   ctx: cairo::Context,
   w:   Coord,
   h:   Coord,
}

// EOF
