/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
package skia

/*
#cgo LDFLAGS: -L${SRCDIR}/../../out/Shared
#cgo LDFLAGS: -Wl,-rpath,${SRCDIR}/../../out/Shared
#cgo LDFLAGS: -lskia
#cgo CFLAGS: -I../../include/c
#cgo CFLAGS: -I../..
#include "sk_canvas.h"
#include "sk_data.h"
#include "sk_image.h"
#include "sk_imageinfo.h"
#include "sk_paint.h"
#include "sk_path.h"
#include "sk_surface.h"
*/
import "C"

import (
	"fmt"
	"io"
	"runtime"
	"unsafe"
)

// TODO(stephana): Add proper documentation to the types defined here.

//////////////////////////////////////////////////////////////////////////
// Surface
//////////////////////////////////////////////////////////////////////////
type Surface struct {
	ptr *C.sk_surface_t
}

// func NewRasterSurface(width, height int32, alphaType AlphaType) (*Surface, error) {
func NewRasterSurface(imgInfo *ImageInfo) (*Surface, error) {
	ptr := C.sk_surface_new_raster(imgInfo.cPointer(), (*C.sk_surfaceprops_t)(nil))
	if ptr == nil {
		return nil, fmt.Errorf("Unable to create raster surface.")
	}

	ret := &Surface{ptr: ptr}
	runtime.SetFinalizer(ret, func(s *Surface) {
		C.sk_surface_unref(s.ptr)
	})
	return ret, nil
}

func (s *Surface) Canvas() *Canvas {
	return &Canvas{
		ptr:             C.sk_surface_get_canvas(s.ptr),
		keepParentAlive: s,
	}
}

func (s *Surface) Image() *Image {
	ret := &Image{
		ptr:             C.sk_surface_new_image_snapshot(s.ptr),
		keepParentAlive: s,
	}
	runtime.SetFinalizer(ret, func(i *Image) {
		C.sk_image_unref(i.ptr)
	})
	return ret
}

//////////////////////////////////////////////////////////////////////////
// Image
//////////////////////////////////////////////////////////////////////////
type Image struct {
	ptr             *C.sk_image_t
	keepParentAlive *Surface
}

func (i *Image) WritePNG(w io.Writer) error {
	data := C.sk_image_encode(i.ptr)
	defer C.sk_data_unref(data)

	dataPtr := C.sk_data_get_data(data)
	dataSize := C.sk_data_get_size(data)
	byteSlice := C.GoBytes(dataPtr, C.int(dataSize))
	_, err := w.Write(byteSlice)
	if err != nil {
		return err
	}
	return nil
}

//////////////////////////////////////////////////////////////////////////
// Canvas
//////////////////////////////////////////////////////////////////////////
type Canvas struct {
	ptr             *C.sk_canvas_t
	keepParentAlive *Surface
}

func (c *Canvas) DrawPaint(paint *Paint) {
	C.sk_canvas_draw_paint(c.ptr, paint.ptr)
}

func (c *Canvas) DrawOval(rect *Rect, paint *Paint) {
	// C.sk_canvas_draw_oval(c.ptr, (*C.sk_rect_t)(unsafe.Pointer(rect)), (*C.sk_paint_t)(paint.ptr))
	C.sk_canvas_draw_oval(c.ptr, rect.cPointer(), paint.ptr)
}

func (c *Canvas) DrawRect(rect *Rect, paint *Paint) {
	// C.sk_canvas_draw_rect(c.ptr, (*C.sk_rect_t)(unsafe.Pointer(rect)), (*C.sk_paint_t)(paint.ptr))
	C.sk_canvas_draw_rect(c.ptr, rect.cPointer(), paint.ptr)
}

func (c *Canvas) DrawPath(path *Path, paint *Paint) {
	// C.sk_canvas_draw_path(c.ptr, (*C.sk_path_t)(path.ptr), (*C.sk_paint_t)(paint.ptr))
	C.sk_canvas_draw_path(c.ptr, path.ptr, paint.ptr)
}

//////////////////////////////////////////////////////////////////////////
// Paint
//////////////////////////////////////////////////////////////////////////
type Paint struct {
	ptr *C.sk_paint_t
}

func NewPaint() *Paint {
	ret := &Paint{ptr: C.sk_paint_new()}
	runtime.SetFinalizer(ret, func(p *Paint) {
		C.sk_paint_delete(p.ptr)
	})
	return ret
}

func (p *Paint) SetColor(color Color) {
	C.sk_paint_set_color(p.ptr, C.sk_color_t(color))
}

func (p *Paint) SetAntiAlias(antiAlias bool) {
	C.sk_paint_set_antialias(p.ptr, C._Bool(antiAlias))
}

func (p *Paint) SetStroke(val bool) {
	C.sk_paint_set_stroke(p.ptr, C._Bool(val))
}

func (p *Paint) SetStrokeWidth(width float32) {
	C.sk_paint_set_stroke_width(p.ptr, C.float(width))
}

//////////////////////////////////////////////////////////////////////////
// Path
//////////////////////////////////////////////////////////////////////////
type Path struct {
	ptr *C.sk_path_t
}

func NewPath() *Path {
	ret := &Path{ptr: C.sk_path_new()}
	runtime.SetFinalizer(ret, func(p *Path) {
		C.sk_path_delete(p.ptr)
	})
	return ret
}

func (p *Path) MoveTo(x, y float32) {
	C.sk_path_move_to(p.ptr, C.float(x), C.float(y))
}

func (p *Path) LineTo(x, y float32) {
	C.sk_path_line_to(p.ptr, C.float(x), C.float(y))
}

func (p *Path) QuadTo(x0, y0, x1, y1 float32) {
	C.sk_path_quad_to(p.ptr, C.float(x0), C.float(y0), C.float(x1), C.float(y1))
}

func (p *Path) ConicTo(x0, y0, x1, y1, w float32) {
	C.sk_path_conic_to(p.ptr, C.float(x0), C.float(y0), C.float(x1), C.float(y1), C.float(w))
}

func (p *Path) CubicTo(x0, y0, x1, y1, x2, y2 float32) {
	C.sk_path_cubic_to(p.ptr, C.float(x0), C.float(y0), C.float(x1), C.float(y1), C.float(x2), C.float(y2))
}

func (p *Path) Close() {
	C.sk_path_close(p.ptr)
}

// NewRect is a convenience function to define a Rect in a single line.
func NewRect(left, top, right, bottom float32) *Rect {
	return &Rect{
		Left:   left,
		Top:    top,
		Right:  right,
		Bottom: bottom,
	}
}

// cPointer casts the pointer to Rect to the corresponding C pointer.
func (r *Rect) cPointer() *C.sk_rect_t {
	return (*C.sk_rect_t)(unsafe.Pointer(r))
}

// cPointer casts the pointer to ImageInfo to the corresponding C pointer.
func (i *ImageInfo) cPointer() *C.sk_imageinfo_t {
	return (*C.sk_imageinfo_t)(unsafe.Pointer(i))
}

// Utility functions.
func GetDefaultColortype() ColorType {
	return ColorType(C.RGBA_8888_SK_COLORTYPE)
}
