/**************************************************************************
 *
 * Copyright 2009 VMware, Inc.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/

#include "VG/openvg.h"

#include "vg_context.h"
#include "path.h"
#include "polygon.h"
#include "paint.h"

#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
#include "util/u_draw_quad.h"

VGPath vgCreatePath(VGint pathFormat,
                    VGPathDatatype datatype,
                    VGfloat scale, VGfloat bias,
                    VGint segmentCapacityHint,
                    VGint coordCapacityHint,
                    VGbitfield capabilities)
{
   struct vg_context *ctx = vg_current_context();

   if (pathFormat != VG_PATH_FORMAT_STANDARD) {
      vg_set_error(ctx, VG_UNSUPPORTED_PATH_FORMAT_ERROR);
      return VG_INVALID_HANDLE;
   }
   if (datatype < VG_PATH_DATATYPE_S_8 ||
       datatype > VG_PATH_DATATYPE_F) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return VG_INVALID_HANDLE;
   }
   if (!scale) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return VG_INVALID_HANDLE;
   }

   return (VGPath)path_create(datatype, scale, bias,
                              segmentCapacityHint, coordCapacityHint,
                              capabilities);
}

void vgClearPath(VGPath path, VGbitfield capabilities)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }

   p = (struct path *)path;
   path_clear(p, capabilities);
}

void vgDestroyPath(VGPath p)
{
   struct path *path = 0;
   struct vg_context *ctx = vg_current_context();

   if (p == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }

   path = (struct path *)p;
   path_destroy(path);
}

void vgRemovePathCapabilities(VGPath path,
                              VGbitfield capabilities)
{
   struct vg_context *ctx = vg_current_context();
   VGbitfield current;
   struct path *p;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }

   p = (struct path*)path;
   current = path_capabilities(p);
   path_set_capabilities(p, (current &
                             (~(capabilities & VG_PATH_CAPABILITY_ALL))));
}

VGbitfield vgGetPathCapabilities(VGPath path)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return 0;
   }
   p = (struct path*)path;
   return path_capabilities(p);
}

void vgAppendPath(VGPath dstPath, VGPath srcPath)
{
   struct vg_context *ctx = vg_current_context();
   struct path *src, *dst;

   if (dstPath == VG_INVALID_HANDLE || srcPath == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }
   src = (struct path *)srcPath;
   dst = (struct path *)dstPath;

   if (!(path_capabilities(src) & VG_PATH_CAPABILITY_APPEND_FROM) ||
       !(path_capabilities(dst) & VG_PATH_CAPABILITY_APPEND_TO)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }
   path_append_path(dst, src);
}

void vgAppendPathData(VGPath dstPath,
                      VGint numSegments,
                      const VGubyte * pathSegments,
                      const void * pathData)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;
   VGint i;

   if (dstPath == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }
   if (!pathSegments) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }
   if (numSegments <= 0) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }
   for (i = 0; i < numSegments; ++i) {
      if (pathSegments[i] < VG_CLOSE_PATH ||
          pathSegments[i] > VG_LCWARC_TO_REL) {
         vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
         return;
      }
   }

   p = (struct path*)dstPath;

   if (!pathData || !is_aligned_to(pathData, path_datatype_size(p))) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (!(path_capabilities(p)&VG_PATH_CAPABILITY_APPEND_TO)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }

   path_append_data(p, numSegments, pathSegments, pathData);
}

void vgModifyPathCoords(VGPath dstPath,
                        VGint startIndex,
                        VGint numSegments,
                        const void * pathData)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;

   if (dstPath == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }
   if (startIndex < 0 || numSegments <= 0) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   p = (struct path *)dstPath;

   if (!pathData || !is_aligned_to(pathData, path_datatype_size(p))) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (startIndex + numSegments > path_num_segments(p)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }
   if (!(path_capabilities(p)&VG_PATH_CAPABILITY_MODIFY)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }
   path_modify_coords(p, startIndex, numSegments, pathData);
}

void vgTransformPath(VGPath dstPath, VGPath srcPath)
{
   struct vg_context *ctx = vg_current_context();
   struct path *src = 0, *dst = 0;

   if (dstPath == VG_INVALID_HANDLE || srcPath == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }
   src = (struct path *)srcPath;
   dst = (struct path *)dstPath;

   if (!(path_capabilities(src) & VG_PATH_CAPABILITY_TRANSFORM_FROM) ||
       !(path_capabilities(dst) & VG_PATH_CAPABILITY_TRANSFORM_TO)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }
   path_transform(dst, src);
}

VGboolean vgInterpolatePath(VGPath dstPath,
                            VGPath startPath,
                            VGPath endPath,
                            VGfloat amount)
{
   struct vg_context *ctx = vg_current_context();
   struct path *start = 0, *dst = 0, *end = 0;

   if (dstPath == VG_INVALID_HANDLE ||
       startPath == VG_INVALID_HANDLE ||
       endPath == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return VG_FALSE;
   }
   dst = (struct path *)dstPath;
   start = (struct path *)startPath;
   end = (struct path *)endPath;

   if (!(path_capabilities(dst) & VG_PATH_CAPABILITY_INTERPOLATE_TO) ||
       !(path_capabilities(start) & VG_PATH_CAPABILITY_INTERPOLATE_FROM) ||
       !(path_capabilities(end) & VG_PATH_CAPABILITY_INTERPOLATE_FROM)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return VG_FALSE;
   }

   return path_interpolate(dst,
                           start, end, amount);
}

VGfloat vgPathLength(VGPath path,
                     VGint startSegment,
                     VGint numSegments)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return -1;
   }
   if (startSegment < 0) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return -1;
   }
   if (numSegments <= 0) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return -1;
   }
   p = (struct path*)path;

   if (!(path_capabilities(p) & VG_PATH_CAPABILITY_PATH_LENGTH)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return -1;
   }
   if (startSegment + numSegments > path_num_segments(p)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return -1;
   }

   return path_length(p, startSegment, numSegments);
}

void vgPointAlongPath(VGPath path,
                      VGint startSegment,
                      VGint numSegments,
                      VGfloat distance,
                      VGfloat * x, VGfloat * y,
                      VGfloat * tangentX,
                      VGfloat * tangentY)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;
   VGbitfield caps;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }
   if (startSegment < 0) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }
   if (numSegments <= 0) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (!is_aligned(x) || !is_aligned(y) ||
       !is_aligned(tangentX) || !is_aligned(tangentY)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   p = (struct path*)path;

   caps = path_capabilities(p);
   if (!(caps & VG_PATH_CAPABILITY_POINT_ALONG_PATH) ||
       !(caps & VG_PATH_CAPABILITY_TANGENT_ALONG_PATH)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }

   if (startSegment + numSegments > path_num_segments(p)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   {
      VGfloat point[2], normal[2];
      path_point(p, startSegment, numSegments, distance,
                 point, normal);
      if (x)
         *x = point[0];
      if (y)
         *y = point[1];
      if (tangentX)
         *tangentX = -normal[1];
      if (tangentY)
         *tangentY = normal[0];
   }
}

void vgPathBounds(VGPath path,
                  VGfloat * minX,
                  VGfloat * minY,
                  VGfloat * width,
                  VGfloat * height)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;
   VGbitfield caps;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }

   if (!minX || !minY || !width || !height) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (!is_aligned(minX) || !is_aligned(minY) ||
       !is_aligned(width) || !is_aligned(height)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   p = (struct path*)path;

   caps = path_capabilities(p);
   if (!(caps & VG_PATH_CAPABILITY_PATH_BOUNDS)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }

   path_bounding_rect(p, minX, minY, width, height);
}

void vgPathTransformedBounds(VGPath path,
                             VGfloat * minX,
                             VGfloat * minY,
                             VGfloat * width,
                             VGfloat * height)
{
   struct vg_context *ctx = vg_current_context();
   struct path *p = 0;
   VGbitfield caps;

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }

   if (!minX || !minY || !width || !height) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (!is_aligned(minX) || !is_aligned(minY) ||
       !is_aligned(width) || !is_aligned(height)) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   p = (struct path*)path;

   caps = path_capabilities(p);
   if (!(caps & VG_PATH_CAPABILITY_PATH_TRANSFORMED_BOUNDS)) {
      vg_set_error(ctx, VG_PATH_CAPABILITY_ERROR);
      return;
   }

#if 0
   /* faster, but seems to have precision problems... */
   path_bounding_rect(p, minX, minY, width, height);
   if (*width > 0 && *height > 0) {
      VGfloat pts[] = {*minX,          *minY,
                       *minX + *width, *minY,
                       *minX + *width, *minY + *height,
                       *minX,          *minY + *height};
      struct matrix *matrix = &ctx->state.vg.path_user_to_surface_matrix;
      VGfloat maxX, maxY;
      matrix_map_point(matrix, pts[0], pts[1], pts + 0, pts + 1);
      matrix_map_point(matrix, pts[2], pts[3], pts + 2, pts + 3);
      matrix_map_point(matrix, pts[4], pts[5], pts + 4, pts + 5);
      matrix_map_point(matrix, pts[6], pts[7], pts + 6, pts + 7);
      *minX = MIN2(pts[0], MIN2(pts[2], MIN2(pts[4], pts[6])));
      *minY = MIN2(pts[1], MIN2(pts[3], MIN2(pts[5], pts[7])));
      maxX = MAX2(pts[0], MAX2(pts[2], MAX2(pts[4], pts[6])));
      maxY = MAX2(pts[1], MAX2(pts[3], MAX2(pts[5], pts[7])));
      *width  = maxX - *minX;
      *height = maxY - *minY;
   }
#else
   {
      struct path *dst = path_create(VG_PATH_DATATYPE_F, 1.0, 0,
                                     0, 0, VG_PATH_CAPABILITY_ALL);
      path_transform(dst, p);
      path_bounding_rect(dst, minX, minY, width, height);
      path_destroy(dst);
   }
#endif
}


void vgDrawPath(VGPath path, VGbitfield paintModes)
{
   struct vg_context *ctx = vg_current_context();

   if (path == VG_INVALID_HANDLE) {
      vg_set_error(ctx, VG_BAD_HANDLE_ERROR);
      return;
   }

   if (!(paintModes & (VG_STROKE_PATH | VG_FILL_PATH))) {
      vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
      return;
   }

   if (path_is_empty((struct path*)path))
      return;
   path_render((struct path*)path, paintModes);
}

