// Copyright 2013 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/host/screen_capturer_fake.h"

#include "base/logging.h"
#include "base/time/time.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"

namespace remoting {

// ScreenCapturerFake generates a white picture of size kWidth x kHeight
// with a rectangle of size kBoxWidth x kBoxHeight. The rectangle moves kSpeed
// pixels per frame along both axes, and bounces off the sides of the screen.
static const int kWidth = ScreenCapturerFake::kWidth;
static const int kHeight = ScreenCapturerFake::kHeight;
static const int kBoxWidth = 140;
static const int kBoxHeight = 140;
static const int kSpeed = 20;

COMPILE_ASSERT(kBoxWidth < kWidth && kBoxHeight < kHeight, bad_box_size);
COMPILE_ASSERT((kBoxWidth % kSpeed == 0) && (kWidth % kSpeed == 0) &&
               (kBoxHeight % kSpeed == 0) && (kHeight % kSpeed == 0),
               sizes_must_be_multiple_of_kSpeed);

ScreenCapturerFake::ScreenCapturerFake()
    : callback_(NULL),
      mouse_shape_observer_(NULL),
      bytes_per_row_(0),
      box_pos_x_(0),
      box_pos_y_(0),
      box_speed_x_(kSpeed),
      box_speed_y_(kSpeed) {
  ScreenConfigurationChanged();
}

ScreenCapturerFake::~ScreenCapturerFake() {
}

void ScreenCapturerFake::Start(Callback* callback) {
  DCHECK(!callback_);
  DCHECK(callback);
  callback_ = callback;
}

void ScreenCapturerFake::Capture(const webrtc::DesktopRegion& region) {
  base::Time capture_start_time = base::Time::Now();

  queue_.MoveToNextFrame();

  if (!queue_.current_frame()) {
    int buffer_size = size_.height() * bytes_per_row_;
    webrtc::SharedMemory* shared_memory =
        callback_->CreateSharedMemory(buffer_size);
    scoped_ptr<webrtc::DesktopFrame> frame;
    webrtc::DesktopSize frame_size(size_.width(), size_.height());
    if (shared_memory) {
      frame.reset(new webrtc::SharedMemoryDesktopFrame(
          frame_size, bytes_per_row_, shared_memory));
    } else {
      frame.reset(new webrtc::BasicDesktopFrame(frame_size));
    }
    queue_.ReplaceCurrentFrame(frame.release());
  }

  DCHECK(queue_.current_frame());
  GenerateImage();

  queue_.current_frame()->mutable_updated_region()->SetRect(
      webrtc::DesktopRect::MakeSize(size_));
  queue_.current_frame()->set_capture_time_ms(
      (base::Time::Now() - capture_start_time).InMillisecondsRoundedUp());

  callback_->OnCaptureCompleted(queue_.current_frame()->Share());
}

void ScreenCapturerFake::SetMouseShapeObserver(
      MouseShapeObserver* mouse_shape_observer) {
  DCHECK(!mouse_shape_observer_);
  DCHECK(mouse_shape_observer);
  mouse_shape_observer_ = mouse_shape_observer;
}

bool ScreenCapturerFake::GetScreenList(ScreenList* screens) {
  NOTIMPLEMENTED();
  return false;
}

bool ScreenCapturerFake::SelectScreen(webrtc::ScreenId id) {
  NOTIMPLEMENTED();
  return false;
}

void ScreenCapturerFake::GenerateImage() {
  webrtc::DesktopFrame* frame = queue_.current_frame();

  const int kBytesPerPixel = webrtc::DesktopFrame::kBytesPerPixel;

  memset(frame->data(), 0xff,
         size_.width() * size_.height() * kBytesPerPixel);

  uint8* row = frame->data() +
      (box_pos_y_ * size_.width() + box_pos_x_) * kBytesPerPixel;

  box_pos_x_ += box_speed_x_;
  if (box_pos_x_ + kBoxWidth >= size_.width() || box_pos_x_ == 0)
    box_speed_x_ = -box_speed_x_;

  box_pos_y_ += box_speed_y_;
  if (box_pos_y_ + kBoxHeight >= size_.height() || box_pos_y_ == 0)
    box_speed_y_ = -box_speed_y_;

  // Draw rectangle with the following colors in its corners:
  //     cyan....yellow
  //     ..............
  //     blue.......red
  for (int y = 0; y < kBoxHeight; ++y) {
    for (int x = 0; x < kBoxWidth; ++x) {
      int r = x * 255 / kBoxWidth;
      int g = y * 255 / kBoxHeight;
      int b = 255 - (x * 255 / kBoxWidth);
      row[x * kBytesPerPixel] = r;
      row[x * kBytesPerPixel + 1] = g;
      row[x * kBytesPerPixel + 2] = b;
      row[x * kBytesPerPixel + 3] = 0xff;
    }
    row += bytes_per_row_;
  }
}

void ScreenCapturerFake::ScreenConfigurationChanged() {
  size_.set(kWidth, kHeight);
  queue_.Reset();
  bytes_per_row_ = size_.width() * webrtc::DesktopFrame::kBytesPerPixel;
}

}  // namespace remoting
