#include <iostream>
#include <benchmark/benchmark.h>
#include <contour.h>


using contour::Contour;
using contour::Path;
using contour::XY;

static Contour GenerateBoxy(int num) {
    Contour A(0, 10, 0, 10), res = A;
    for (int i = 0; i < num; i++)
        res += A.Shift(XY(5, 5));
    return res;
}

static Contour GenerateCurvy(int num) {
    Contour A(XY(5,5), 4), res = A;
    for (int i = 0; i < num; i++)
        res += A.Shift(XY(5, 5));
    return res;
}

constexpr int mul_ = 16, max_ = 256;

static void ExpandBoxy(benchmark::State& state) {
    Contour x = GenerateBoxy(state.range(0));
    for (auto _ : state)
        benchmark::DoNotOptimize(x.CreateExpand(1));
}
BENCHMARK(ExpandBoxy)->RangeMultiplier(mul_)->Range(1, max_);

static void ExpandBoxyRotate(benchmark::State& state) {
    Contour x = GenerateBoxy(state.range(0));
    x.Rotate(15);
    for (auto _ : state)
        benchmark::DoNotOptimize(x.CreateExpand(1));
}
BENCHMARK(ExpandBoxyRotate)->RangeMultiplier(mul_)->Range(1, max_);

static void ExpandCurvy(benchmark::State& state) {
    Contour x = GenerateCurvy(state.range(0));
    for (auto _ : state)
        benchmark::DoNotOptimize(x.CreateExpand(1));
}
BENCHMARK(ExpandCurvy)->RangeMultiplier(mul_)->Range(1, max_);

static void UnionBoxy(benchmark::State& state) {
    Contour x = GenerateBoxy(state.range(0)), y = x.CreateShifted(XY(1,1));
    for (auto _ : state)
        benchmark::DoNotOptimize(x+y);
}
BENCHMARK(UnionBoxy)->RangeMultiplier(mul_)->Range(1, max_);

static void UnionBoxyRotate(benchmark::State& state) {
    Contour x = GenerateBoxy(state.range(0)), y = x.CreateShifted(XY(1, 1));
    x.Rotate(15); y.Rotate(15);
    for (auto _ : state)
        benchmark::DoNotOptimize(x+y);
}
BENCHMARK(UnionBoxyRotate)->RangeMultiplier(mul_)->Range(1, max_);

static void UnionCurvy(benchmark::State& state) {
    Contour x = GenerateCurvy(state.range(0)), y = x.CreateShifted(XY(1, 1));
    for (auto _ : state)
        benchmark::DoNotOptimize(x+y);
}
BENCHMARK(UnionCurvy)->RangeMultiplier(mul_)->Range(1, max_);

BENCHMARK_MAIN();