#include <iostream>

#include <Eigen/Dense>

#include "aos/vision/blob/move_scale.h"
#include "aos/vision/blob/stream_view.h"
#include "aos/vision/blob/transpose.h"
#include "aos/vision/debug/debug_framework.h"
#include "aos/vision/math/vector.h"
#include "y2017/vision/target_finder.h"

using aos::vision::BlobList;
using aos::vision::ImageFormat;
using aos::vision::ImageRange;
using aos::vision::RangeImage;

namespace y2017::vision {

BlobList RenderTargetListShifted(const std::vector<TargetComponent> &list) {
  BlobList out;
  for (const auto &entity : list) {
    out.emplace_back(entity.RenderShifted());
  }
  return out;
}

RangeImage TargetComponent::RenderShifted() const {
  std::vector<std::vector<ImageRange>> out_range_list;
  int y = 0;
  double max_y = -b / (2 * a);
  double parab_off = max_y * max_y * a + max_y * b;
  RangeImage t_img = Transpose(*img);
  for (const auto &row : t_img) {
    int off = -(y * y * a + y * b - parab_off);
    // int off = 0;
    // fprintf(stderr, "off: %d %d\n", off, y);
    std::vector<ImageRange> row_out;
    for (const ImageRange &range : row) {
      row_out.emplace_back(ImageRange{off + range.st, off + range.ed});
    }
    ++y;
    out_range_list.emplace_back(std::move(row_out));
  }
  return RangeImage(t_img.min_y(), std::move(out_range_list));
}

class FilterHarnessExample : public aos::vision::FilterHarness {
 public:
  aos::vision::RangeImage Threshold(aos::vision::ImagePtr image) override {
    return finder_.Threshold(image);
  }

  void InstallViewer(aos::vision::BlobStreamViewer *viewer) override {
    viewer_ = viewer;
    viewer_->SetScale(0.5);
    overlays_.push_back(&overlay_);
    overlays_.push_back(finder_.GetOverlay());
    viewer_->view()->SetOverlays(&overlays_);
  }

  bool HandleBlobs(BlobList imgs, ImageFormat /*fmt*/) override {
    // reset for next drawing cycle
    for (auto &overlay : overlays_) {
      overlay->Reset();
    }

    // Remove bad blobs.
    finder_.PreFilter(imgs);

    // calculate each component/
    std::vector<TargetComponent> target_component_list =
        finder_.FillTargetComponentList(imgs);

    DrawComponents(target_component_list);

    // Put the compenents together into targets and pick the best.
    Target final_target;
    bool found_target =
        finder_.FindTargetFromComponents(target_component_list, &final_target);

    // BlobList newImg = RenderTargetListShifted(target_component_list);
    if (viewer_) {
      viewer_->DrawBlobList(imgs, {0, 0, 255});
    }

    if (found_target) {
      BlobList list;
      list.emplace_back(*(final_target.comp1.img));
      list.emplace_back(*(final_target.comp2.img));
      viewer_->DrawBlobList(list, {0, 255, 0});
      overlay_.DrawCross(final_target.screen_coord, 25, {255, 255, 255});
    }

    // No targets.
    return found_target;
  }

  void DrawComponents(const std::vector<TargetComponent> comp) {
    for (const TargetComponent &t : comp) {
      aos::vision::ImageBBox bbox;
      GetBBox(*(t.img), &bbox);
      overlay_.DrawBBox(bbox, {255, 0, 0});

      overlay_.StartNewProfile();
      for (int i = 0; i < bbox.maxx - bbox.minx; i += 10) {
        double y0 = t.a * i * i + t.b * i + t.c_0;
        double y1 = t.a * i * i + t.b * i + t.c_1;
        overlay_.AddPoint(aos::vision::Vector<2>(i + t.mini, y0), {255, 0, 0});
        overlay_.AddPoint(aos::vision::Vector<2>(i + t.mini, y1), {255, 0, 0});
      }
    }
  }

 private:
  // implementation of the filter pipeline.
  TargetFinder finder_;
  aos::vision::BlobStreamViewer *viewer_ = nullptr;
  aos::vision::PixelLinesOverlay overlay_;
  std::vector<aos::vision::OverlayBase *> overlays_;
};

}  // namespace y2017::vision

int main(int argc, char **argv) {
  y2017::vision::FilterHarnessExample filter_harness;
  aos::vision::DebugFrameworkMain(argc, argv, &filter_harness,
                                  aos::vision::CameraParams());
}
