#include "talk/media/base/yuvframegenerator.h"

#include <string.h>
#include <sstream>

#include "webrtc/base/basictypes.h"
#include "webrtc/base/common.h"

namespace cricket {

// These values were figured out by trial and error. If you change any
// basic parameters e.g. unit-bar size or bars-x-offset, you may need to change
// background-width/background-height.
const int kBarcodeBackgroundWidth = 160;
const int kBarcodeBackgroundHeight = 100;
const int kBarsXOffset = 12;
const int kBarsYOffset = 4;
const int kUnitBarSize = 2;
const int kBarcodeNormalBarHeight = 80;
const int kBarcodeGuardBarHeight = 96;
const int kBarcodeMaxEncodableDigits = 7;

YuvFrameGenerator::YuvFrameGenerator(int width, int height,
                                     bool enable_barcode) {
  width_ = width;
  height_ = height;
  frame_index_ = 0;
  int size = width_ * height_;
  int qsize = size / 4;
  frame_data_size_ = size + 2 * qsize;
  y_data_ = new uint8[size];
  u_data_ = new uint8[qsize];
  v_data_ = new uint8[qsize];
  if (enable_barcode) {
    ASSERT(width_ >= kBarcodeBackgroundWidth);
    ASSERT(height_>= kBarcodeBackgroundHeight);
    barcode_start_x_ = 0;
    barcode_start_y_ = height_ - kBarcodeBackgroundHeight;
  } else {
    barcode_start_x_ = -1;
    barcode_start_y_ = -1;
  }
}

YuvFrameGenerator::~YuvFrameGenerator() {
  delete y_data_;
  delete u_data_;
  delete v_data_;
}

void YuvFrameGenerator::GenerateNextFrame(uint8* frame_buffer,
                                          int32 barcode_value) {
  int size = width_ * height_;
  int qsize = size / 4;
  memset(y_data_, 0, size);
  memset(u_data_, 0, qsize);
  memset(v_data_, 0, qsize);

  DrawLandscape(y_data_, width_, height_);
  DrawGradientX(u_data_, width_/2, height_/2);
  DrawGradientY(v_data_, width_/2, height_/2);
  DrawMovingLineX(u_data_, width_/2, height_/2, frame_index_);
  DrawMovingLineY(v_data_, width_/2, height_/2, frame_index_);
  DrawBouncingCube(y_data_, width_, height_, frame_index_);

  if (barcode_value >= 0) {
      ASSERT(barcode_start_x_ != -1);
      DrawBarcode(barcode_value);
  }

  memcpy(frame_buffer, y_data_, size);
  frame_buffer += size;
  memcpy(frame_buffer, u_data_, qsize);
  frame_buffer += qsize;
  memcpy(frame_buffer, v_data_, qsize);

  frame_index_ = (frame_index_ + 1) & 0x0000FFFF;
}

void YuvFrameGenerator::DrawLandscape(uint8 *p, int w, int h) {
  int x, y;
  for (y = 0; y < h; y++) {
    for (x = 0; x < w; x++) {
      p[x + y * w] = x % (y+1);
      if (((x > w / 2 - (w / 32)) && (x < w / 2 + (w / 32))) ||
          ((y > h / 2 - (h / 32)) && (y < h / 2 + (h / 32)))) {
        p[x + y * w] = (((x + y) / 8 % 2)) ? 255 : 0;
      }
    }
  }
}

void YuvFrameGenerator::DrawGradientX(uint8 *p, int w, int h) {
  int x, y;
  for (y = 0; y < h; y++) {
    for (x = 0; x < w; x++) {
      p[x + y * w] = (x << 8) / w;
    }
  }
}

void YuvFrameGenerator::DrawGradientY(uint8 *p, int w, int h) {
  int x, y;
  for (y = 0; y < h; y++) {
    for (x = 0; x < w; x++) {
      p[x + y * w] = (y << 8) / h;
    }
  }
}

void YuvFrameGenerator::DrawMovingLineX(uint8 *p, int w, int h, int n) {
  int x, y;
  x = n % (w * 2);
  if (x >= w) x = w + w - x - 1;
  for (y = 0; y < h; y++) {
    p[x + y * w] = 255;
  }
}

void YuvFrameGenerator::DrawMovingLineY(uint8 *p, int w, int h, int n) {
  int x, y;
  y = n % (h * 2);
  if (y >= h) y = h + h - y - 1;
  for (x = 0; x < w; x++) {
    p[x + y * w] = 255;
  }
}

void YuvFrameGenerator::DrawBouncingCube(uint8 *p, int w, int h, int n) {
  int x, y, pw, ph, px, py;
  pw = w / 16;
  ph = h / 16;
  px = n % (w * 2);
  py = n % (h * 2);
  if (px >= w) px = w + w - px - 1;
  if (py >= h) py = h + h - py - 1;
  for (y = py - ph; y < py + ph; y++) {
    if (y >=0 && y < h) {
      for (x = px - pw; x < px + pw; x++) {
        if (x >= 0 && x < w) {
          p[x + y * w] = 255;
        }
      }
    }
  }
}

void YuvFrameGenerator::GetBarcodeBounds(int* top, int* left,
                                         int* width, int* height) {
  ASSERT(barcode_start_x_ != -1);
  *top = barcode_start_y_;
  *left = barcode_start_x_;
  *width = kBarcodeBackgroundWidth;
  *height = kBarcodeBackgroundHeight;
}

static void ComputeBarcodeDigits(uint32 value, std::stringstream* result) {
  // Serialize |value| as 7-char string, padded with 0's to the left.
  result->width(kBarcodeMaxEncodableDigits);
  result->fill('0');
  *result << value;

  // Compute check-digit and append to result. Steps described here:
  // http://en.wikipedia.org/wiki/European_Article_Number#Calculation_of_checksum_digit
  int sum = 0;
  for (int pos = 1; pos <= kBarcodeMaxEncodableDigits; pos++) {
    char next_char;
    result->get(next_char);
    uint8 digit = next_char - '0';
    sum += digit * (pos % 2 ? 3 : 1);
  }
  uint8 check_digit = sum % 10;
  if (check_digit != 0) {
    check_digit = 10 - check_digit;
  }

  *result << static_cast<int>(check_digit);
  result->seekg(0);
}

void YuvFrameGenerator::DrawBarcode(uint32 value) {
  std::stringstream value_str_stream;
  ComputeBarcodeDigits(value, &value_str_stream);

  // Draw white filled rectangle as background to barcode.
  DrawBlockRectangle(y_data_, barcode_start_x_, barcode_start_y_,
                     kBarcodeBackgroundWidth, kBarcodeBackgroundHeight,
                     width_, 255);
  DrawBlockRectangle(u_data_, barcode_start_x_ / 2, barcode_start_y_ / 2,
                     kBarcodeBackgroundWidth / 2, kBarcodeBackgroundHeight / 2,
                     width_ / 2, 128);
  DrawBlockRectangle(v_data_, barcode_start_x_ / 2, barcode_start_y_ / 2,
                     kBarcodeBackgroundWidth / 2, kBarcodeBackgroundHeight / 2,
                     width_ / 2, 128);

  // Scan through chars (digits) and draw black bars.
  int x = barcode_start_x_ + kBarsXOffset;
  int y = barcode_start_y_ + kBarsYOffset;
  int pos = 0;
  x = DrawSideGuardBars(x, y, kBarcodeGuardBarHeight);
  while (true) {
    char next_char;
    value_str_stream.get(next_char);
    if (!value_str_stream.good()) {
      break;
    }
    if (pos++ == 4) {
      x = DrawMiddleGuardBars(x, y, kBarcodeGuardBarHeight);
    }
    uint8 digit = next_char - '0';
    x = DrawEanEncodedDigit(digit, x, y, kBarcodeNormalBarHeight, pos > 4);
  }
  x = DrawSideGuardBars(x, y, kBarcodeGuardBarHeight);
}

int YuvFrameGenerator::DrawMiddleGuardBars(int x, int y, int height) {
  x += kUnitBarSize;
  DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0);
  x += (kUnitBarSize * 2);
  DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0);
  return x + (kUnitBarSize * 2);
}

int YuvFrameGenerator::DrawSideGuardBars(int x, int y, int height) {
  DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0);
  x += (kUnitBarSize * 2);
  DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0);
  return x + kUnitBarSize;
}

// For each digit: 0-9, |kEanEncodings| contains a bit-mask indicating
// which bars are black (1) and which are blank (0). These are for the L-code
// only. R-code values are bitwise negation of these. Reference:
// http://en.wikipedia.org/wiki/European_Article_Number#Binary_encoding_of_data_digits_into_EAN-13_barcode // NOLINT
const uint8 kEanEncodings[] = { 13, 25, 19, 61, 35, 49, 47, 59, 55, 11 };

int YuvFrameGenerator::DrawEanEncodedDigit(int digit, int x, int y,
                                           int height, bool flip) {
  uint8 ean_encoding = kEanEncodings[digit];
  if (flip) {
    ean_encoding = ~ean_encoding;
  }
  uint8 mask = 0x40;
  for (int i = 6; i >= 0; i--, mask >>= 1) {
    if (ean_encoding & mask) {
      DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0);
    }
    x += kUnitBarSize;
  }
  return x;
}

void YuvFrameGenerator::DrawBlockRectangle(uint8* p,
    int x_start, int y_start, int width, int height, int pitch, uint8 value) {
  for (int x = x_start; x < x_start + width; x++) {
    for (int y = y_start; y < y_start + height; y++) {
      p[x + y * pitch] = value;
    }
  }
}

}  // namespace cricket
