// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/paint_vector_icon.h"

#include <map>

#include "base/lazy_instance.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkXfermode.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/gfx/vector_icons.h"

namespace gfx {

namespace {

// Translates a string such as "MOVE_TO" into a command such as MOVE_TO.
CommandType CommandFromString(const std::string& source) {
#define RETURN_IF_IS(command) \
  if (source == #command)     \
    return command;

  RETURN_IF_IS(NEW_PATH);
  RETURN_IF_IS(PATH_COLOR_ARGB);
  RETURN_IF_IS(PATH_MODE_CLEAR);
  RETURN_IF_IS(STROKE);
  RETURN_IF_IS(CAP_SQUARE);
  RETURN_IF_IS(MOVE_TO);
  RETURN_IF_IS(R_MOVE_TO);
  RETURN_IF_IS(LINE_TO);
  RETURN_IF_IS(R_LINE_TO);
  RETURN_IF_IS(H_LINE_TO);
  RETURN_IF_IS(R_H_LINE_TO);
  RETURN_IF_IS(V_LINE_TO);
  RETURN_IF_IS(R_V_LINE_TO);
  RETURN_IF_IS(CUBIC_TO);
  RETURN_IF_IS(R_CUBIC_TO);
  RETURN_IF_IS(CIRCLE);
  RETURN_IF_IS(ROUND_RECT);
  RETURN_IF_IS(CLOSE);
  RETURN_IF_IS(CANVAS_DIMENSIONS);
  RETURN_IF_IS(CLIP);
  RETURN_IF_IS(DISABLE_AA);
  RETURN_IF_IS(END);
#undef RETURN_IF_IS

  NOTREACHED();
  return CLOSE;
}

std::vector<PathElement> PathFromSource(const std::string& source) {
  std::vector<PathElement> path;
  std::vector<std::string> pieces = base::SplitString(
      source, "\n ,f", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  for (const auto& piece : pieces) {
    double value;
    if (base::StringToDouble(piece, &value))
      path.push_back(PathElement(SkDoubleToScalar(value)));
    else
      path.push_back(PathElement(CommandFromString(piece)));
  }
  return path;
}

void PaintPath(Canvas* canvas,
               const PathElement* path_elements,
               size_t dip_size,
               SkColor color) {
  canvas->Save();
  SkPath path;
  path.setFillType(SkPath::kEvenOdd_FillType);

  size_t canvas_size = kReferenceSizeDip;
  std::vector<SkPath> paths;
  std::vector<SkPaint> paints;
  SkRect clip_rect = SkRect::MakeEmpty();

  for (size_t i = 0; path_elements[i].type != END; i++) {
    if (paths.empty() || path_elements[i].type == NEW_PATH) {
      paths.push_back(SkPath());
      paths.back().setFillType(SkPath::kEvenOdd_FillType);

      paints.push_back(SkPaint());
      paints.back().setColor(color);
      paints.back().setAntiAlias(true);
      paints.back().setStrokeCap(SkPaint::kRound_Cap);
    }

    SkPath& path = paths.back();
    SkPaint& paint = paints.back();
    switch (path_elements[i].type) {
      // Handled above.
      case NEW_PATH:
        continue;

      case PATH_COLOR_ARGB: {
        int a = SkScalarFloorToInt(path_elements[++i].arg);
        int r = SkScalarFloorToInt(path_elements[++i].arg);
        int g = SkScalarFloorToInt(path_elements[++i].arg);
        int b = SkScalarFloorToInt(path_elements[++i].arg);
        paint.setColor(SkColorSetARGB(a, r, g, b));
        break;
      }

      case PATH_MODE_CLEAR: {
        paint.setXfermodeMode(SkXfermode::kClear_Mode);
        break;
      };

      case STROKE: {
        paint.setStyle(SkPaint::kStroke_Style);
        SkScalar width = path_elements[++i].arg;
        paint.setStrokeWidth(width);
        break;
      }

      case CAP_SQUARE: {
        paint.setStrokeCap(SkPaint::kSquare_Cap);
        break;
      }

      case MOVE_TO: {
        SkScalar x = path_elements[++i].arg;
        SkScalar y = path_elements[++i].arg;
        path.moveTo(x, y);
        break;
      }

      case R_MOVE_TO: {
        SkScalar x = path_elements[++i].arg;
        SkScalar y = path_elements[++i].arg;
        path.rMoveTo(x, y);
        break;
      }

      case LINE_TO: {
        SkScalar x = path_elements[++i].arg;
        SkScalar y = path_elements[++i].arg;
        path.lineTo(x, y);
        break;
      }

      case R_LINE_TO: {
        SkScalar x = path_elements[++i].arg;
        SkScalar y = path_elements[++i].arg;
        path.rLineTo(x, y);
        break;
      }

      case H_LINE_TO: {
        SkPoint last_point;
        path.getLastPt(&last_point);
        SkScalar x = path_elements[++i].arg;
        path.lineTo(x, last_point.fY);
        break;
      }

      case R_H_LINE_TO: {
        SkScalar x = path_elements[++i].arg;
        path.rLineTo(x, 0);
        break;
      }

      case V_LINE_TO: {
        SkPoint last_point;
        path.getLastPt(&last_point);
        SkScalar y = path_elements[++i].arg;
        path.lineTo(last_point.fX, y);
        break;
      }

      case R_V_LINE_TO: {
        SkScalar y = path_elements[++i].arg;
        path.rLineTo(0, y);
        break;
      }

      case CUBIC_TO: {
        SkScalar x1 = path_elements[++i].arg;
        SkScalar y1 = path_elements[++i].arg;
        SkScalar x2 = path_elements[++i].arg;
        SkScalar y2 = path_elements[++i].arg;
        SkScalar x3 = path_elements[++i].arg;
        SkScalar y3 = path_elements[++i].arg;
        path.cubicTo(x1, y1, x2, y2, x3, y3);
        break;
      }

      case R_CUBIC_TO: {
        SkScalar x1 = path_elements[++i].arg;
        SkScalar y1 = path_elements[++i].arg;
        SkScalar x2 = path_elements[++i].arg;
        SkScalar y2 = path_elements[++i].arg;
        SkScalar x3 = path_elements[++i].arg;
        SkScalar y3 = path_elements[++i].arg;
        path.rCubicTo(x1, y1, x2, y2, x3, y3);
        break;
      }

      case CIRCLE: {
        SkScalar x = path_elements[++i].arg;
        SkScalar y = path_elements[++i].arg;
        SkScalar r = path_elements[++i].arg;
        path.addCircle(x, y, r);
        break;
      }

      case ROUND_RECT: {
        SkScalar x = path_elements[++i].arg;
        SkScalar y = path_elements[++i].arg;
        SkScalar w = path_elements[++i].arg;
        SkScalar h = path_elements[++i].arg;
        SkScalar radius = path_elements[++i].arg;
        path.addRoundRect(SkRect::MakeXYWH(x, y, w, h), radius, radius);
        break;
      }

      case CLOSE: {
        path.close();
        break;
      }

      case CANVAS_DIMENSIONS: {
        SkScalar width = path_elements[++i].arg;
        canvas_size = SkScalarTruncToInt(width);
        break;
      }

      case CLIP: {
        SkScalar x = path_elements[++i].arg;
        SkScalar y = path_elements[++i].arg;
        SkScalar w = path_elements[++i].arg;
        SkScalar h = path_elements[++i].arg;
        clip_rect = SkRect::MakeXYWH(x, y, w, h);
        break;
      }

      case DISABLE_AA: {
        paint.setAntiAlias(false);
        break;
      }

      case END:
        NOTREACHED();
        break;
    }
  }

  if (dip_size != canvas_size) {
    SkScalar scale = SkIntToScalar(dip_size) / SkIntToScalar(canvas_size);
    canvas->sk_canvas()->scale(scale, scale);
  }

  if (!clip_rect.isEmpty())
    canvas->sk_canvas()->clipRect(clip_rect);

  DCHECK_EQ(paints.size(), paths.size());
  for (size_t i = 0; i < paths.size(); ++i)
    canvas->DrawPath(paths[i], paints[i]);
  canvas->Restore();
}

class VectorIconSource : public CanvasImageSource {
 public:
  VectorIconSource(VectorIconId id,
                   size_t dip_size,
                   SkColor color,
                   VectorIconId badge_id)
      : CanvasImageSource(
            gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)),
            false),
        id_(id),
        color_(color),
        badge_id_(badge_id) {}

  VectorIconSource(const std::string& definition,
                   size_t dip_size,
                   SkColor color)
      : CanvasImageSource(
            gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)),
            false),
        id_(VectorIconId::VECTOR_ICON_NONE),
        path_(PathFromSource(definition)),
        color_(color),
        badge_id_(VectorIconId::VECTOR_ICON_NONE) {}

  ~VectorIconSource() override {}

  // CanvasImageSource:
  void Draw(gfx::Canvas* canvas) override {
    if (path_.empty()) {
      PaintVectorIcon(canvas, id_, size_.width(), color_);
      if (badge_id_ != VectorIconId::VECTOR_ICON_NONE)
        PaintVectorIcon(canvas, badge_id_, size_.width(), color_);
    } else {
      PaintPath(canvas, path_.data(), size_.width(), color_);
    }
  }

 private:
  const VectorIconId id_;
  const std::vector<PathElement> path_;
  const SkColor color_;
  const VectorIconId badge_id_;

  DISALLOW_COPY_AND_ASSIGN(VectorIconSource);
};

// This class caches vector icons (as ImageSkia) so they don't have to be drawn
// more than once. This also guarantees the backing data for the images returned
// by CreateVectorIcon will persist in memory until program termination.
class VectorIconCache {
 public:
  VectorIconCache() {}
  ~VectorIconCache() {}

  ImageSkia GetOrCreateIcon(VectorIconId id,
                            size_t dip_size,
                            SkColor color,
                            VectorIconId badge_id) {
    IconDescription description(id, dip_size, color, badge_id);
    auto iter = images_.find(description);
    if (iter != images_.end())
      return iter->second;

    ImageSkia icon(
        new VectorIconSource(id, dip_size, color, badge_id),
        gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)));
    images_.insert(std::make_pair(description, icon));
    return icon;
  }

 private:
  struct IconDescription {
    IconDescription(VectorIconId id,
                    size_t dip_size,
                    SkColor color,
                    VectorIconId badge_id)
        : id(id), dip_size(dip_size), color(color), badge_id(badge_id) {}

    bool operator<(const IconDescription& other) const {
      if (id != other.id)
        return id < other.id;
      if (dip_size != other.dip_size)
        return dip_size < other.dip_size;
      if (color != other.color)
        return color < other.color;
      return badge_id < other.badge_id;
    }

    VectorIconId id;
    size_t dip_size;
    SkColor color;
    VectorIconId badge_id;
  };

  std::map<IconDescription, ImageSkia> images_;

  DISALLOW_COPY_AND_ASSIGN(VectorIconCache);
};

static base::LazyInstance<VectorIconCache> g_icon_cache =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

void PaintVectorIcon(Canvas* canvas,
                     VectorIconId id,
                     size_t dip_size,
                     SkColor color) {
  DCHECK(VectorIconId::VECTOR_ICON_NONE != id);
  const PathElement* path = canvas->image_scale() == 1.f
                                ? GetPathForVectorIconAt1xScale(id)
                                : GetPathForVectorIcon(id);
  PaintPath(canvas, path, dip_size, color);
}

ImageSkia CreateVectorIcon(VectorIconId id, size_t dip_size, SkColor color) {
  return CreateVectorIconWithBadge(id, dip_size, color,
                                   VectorIconId::VECTOR_ICON_NONE);
}

ImageSkia CreateVectorIconWithBadge(VectorIconId id,
                                    size_t dip_size,
                                    SkColor color,
                                    VectorIconId badge_id) {
  return g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color, badge_id);
}

ImageSkia CreateVectorIconFromSource(const std::string& source,
                                     size_t dip_size,
                                     SkColor color) {
  return ImageSkia(
      new VectorIconSource(source, dip_size, color),
      gfx::Size(static_cast<int>(dip_size), static_cast<int>(dip_size)));
}

}  // namespace gfx
