// Copyright 2016 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 "remoting/test/cyclic_frame_generator.h"

#include "base/time/default_tick_clock.h"
#include "remoting/test/frame_generator_util.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"

namespace remoting {
namespace test {

CyclicFrameGenerator::ChangeInfo::ChangeInfo() = default;
CyclicFrameGenerator::ChangeInfo::ChangeInfo(ChangeType type,
                                             base::TimeTicks timestamp)
    : type(type), timestamp(timestamp) {}

// static
scoped_refptr<CyclicFrameGenerator> CyclicFrameGenerator::Create() {
  std::vector<std::unique_ptr<webrtc::DesktopFrame>> frames;
  frames.push_back(LoadDesktopFrameFromPng("test_frame1.png"));
  frames.push_back(LoadDesktopFrameFromPng("test_frame2.png"));
  return new CyclicFrameGenerator(std::move(frames));
}

CyclicFrameGenerator::CyclicFrameGenerator(
    std::vector<std::unique_ptr<webrtc::DesktopFrame>> reference_frames)
    : reference_frames_(std::move(reference_frames)),
      clock_(&default_tick_clock_),
      started_time_(clock_->NowTicks()) {
  CHECK(!reference_frames_.empty());
  screen_size_ = reference_frames_[0]->size();
  for (const auto& frame : reference_frames_) {
    CHECK(screen_size_.equals(frame->size()))
        << "All reference frames should have the same size.";
  }
}

CyclicFrameGenerator::~CyclicFrameGenerator() = default;

void CyclicFrameGenerator::SetTickClock(base::TickClock* tick_clock) {
  clock_ = tick_clock;
  started_time_ = clock_->NowTicks();
}

std::unique_ptr<webrtc::DesktopFrame> CyclicFrameGenerator::GenerateFrame(
    webrtc::SharedMemoryFactory* shared_memory_factory) {
  base::TimeTicks now = clock_->NowTicks();

  int frame_id = (now - started_time_) / cursor_blink_period_;
  int reference_frame =
      ((now - started_time_) / frame_cycle_period_) % reference_frames_.size();
  bool cursor_state = frame_id % 2;

  std::unique_ptr<webrtc::DesktopFrame> frame(
      new webrtc::BasicDesktopFrame(screen_size_));
  frame->CopyPixelsFrom(*reference_frames_[reference_frame],
                        webrtc::DesktopVector(),
                        webrtc::DesktopRect::MakeSize(screen_size_));

  // Render the cursor.
  webrtc::DesktopRect cursor_rect =
      webrtc::DesktopRect::MakeXYWH(20, 20, 2, 20);
  if (cursor_state) {
    DrawRect(frame.get(), cursor_rect, 0);
  }

  if (last_reference_frame_ != reference_frame) {
    // The whole frame has changed.
    frame->mutable_updated_region()->AddRect(
        webrtc::DesktopRect::MakeSize(screen_size_));
    last_frame_type_ = ChangeType::FULL;
  } else if (last_cursor_state_ != cursor_state) {
    // Cursor state has changed.
    frame->mutable_updated_region()->AddRect(cursor_rect);
    last_frame_type_ = ChangeType::CURSOR;
  } else {
    // No changes.
    last_frame_type_ = ChangeType::NO_CHANGES;
  }

  last_reference_frame_ = reference_frame;
  last_cursor_state_ = cursor_state;

  return frame;
}

CyclicFrameGenerator::ChangeInfoList CyclicFrameGenerator::GetChangeList(
    base::TimeTicks timestamp) {
  int frame_id = (timestamp - started_time_) / cursor_blink_period_;
  CHECK_GE(frame_id, last_identifier_frame_);

  ChangeInfoList result;
  for (int i = last_identifier_frame_ + 1; i <= frame_id; ++i) {
    ChangeType type = (i % (frame_cycle_period_ / cursor_blink_period_) == 0)
                          ? ChangeType::FULL
                          : ChangeType::CURSOR;
    base::TimeTicks timestamp =
        started_time_ + i * base::TimeDelta(cursor_blink_period_);
    result.push_back(ChangeInfo(type, timestamp));
  }
  last_identifier_frame_ = frame_id;

  return result;
}

protocol::InputEventTimestamps CyclicFrameGenerator::TakeLastEventTimestamps() {
  base::TimeTicks now = clock_->NowTicks();
  return protocol::InputEventTimestamps{now, now};
}

}  // namespace test
}  // namespace remoting
