/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Contains implementation of a class EmulatedFakeCameraDevice that encapsulates
 * fake camera device.
 */

#define LOG_NDEBUG 0
#define LOG_TAG "EmulatedCamera_FakeDevice"
#include "EmulatedFakeCameraDevice.h"
#include <log/log.h>
#include "EmulatedFakeCamera.h"

namespace android {

EmulatedFakeCameraDevice::EmulatedFakeCameraDevice(
    EmulatedFakeCamera* camera_hal)
    : EmulatedCameraDevice(camera_hal),
      mBlackYUV(kBlack32),
      mWhiteYUV(kWhite32),
      mRedYUV(kRed8),
      mGreenYUV(kGreen8),
      mBlueYUV(kBlue8),
      mLastRedrawn(0),
      mCheckX(0),
      mCheckY(0),
      mCcounter(0)
#if EFCD_ROTATE_FRAME
      ,
      mLastRotatedAt(0),
      mCurrentFrameType(0),
      mCurrentColor(&mWhiteYUV)
#endif  // EFCD_ROTATE_FRAME
{
  // Makes the image with the original exposure compensation darker.
  // So the effects of changing the exposure compensation can be seen.
  mBlackYUV.Y = mBlackYUV.Y / 2;
  mWhiteYUV.Y = mWhiteYUV.Y / 2;
  mRedYUV.Y = mRedYUV.Y / 2;
  mGreenYUV.Y = mGreenYUV.Y / 2;
  mBlueYUV.Y = mBlueYUV.Y / 2;
}

EmulatedFakeCameraDevice::~EmulatedFakeCameraDevice() {}

/****************************************************************************
 * Emulated camera device abstract interface implementation.
 ***************************************************************************/

status_t EmulatedFakeCameraDevice::connectDevice() {
  ALOGV("%s", __FUNCTION__);

  Mutex::Autolock locker(&mObjectLock);
  if (!isInitialized()) {
    ALOGE("%s: Fake camera device is not initialized.", __FUNCTION__);
    return EINVAL;
  }
  if (isConnected()) {
    ALOGW("%s: Fake camera device is already connected.", __FUNCTION__);
    return NO_ERROR;
  }

  /* There is no device to connect to. */
  mState = ECDS_CONNECTED;

  return NO_ERROR;
}

status_t EmulatedFakeCameraDevice::disconnectDevice() {
  ALOGV("%s", __FUNCTION__);

  Mutex::Autolock locker(&mObjectLock);
  if (!isConnected()) {
    ALOGW("%s: Fake camera device is already disconnected.", __FUNCTION__);
    return NO_ERROR;
  }
  if (isStarted()) {
    ALOGE("%s: Cannot disconnect from the started device.", __FUNCTION__);
    return EINVAL;
  }

  /* There is no device to disconnect from. */
  mState = ECDS_INITIALIZED;

  return NO_ERROR;
}

status_t EmulatedFakeCameraDevice::startDevice(int width, int height,
                                               uint32_t pix_fmt, int fps) {
  ALOGV("%s", __FUNCTION__);

  Mutex::Autolock locker(&mObjectLock);
  if (!isConnected()) {
    ALOGE("%s: Fake camera device is not connected.", __FUNCTION__);
    return EINVAL;
  }
  if (isStarted()) {
    ALOGE("%s: Fake camera device is already started.", __FUNCTION__);
    return EINVAL;
  }

  /* Initialize the base class. */
  const status_t res =
      EmulatedCameraDevice::commonStartDevice(width, height, pix_fmt, fps);
  if (res == NO_ERROR) {
    /* Calculate U/V panes inside the framebuffer. */
    switch (mPixelFormat) {
      case V4L2_PIX_FMT_YVU420:
        mFrameV = mCurrentFrame + mTotalPixels;
        mFrameU = mFrameU + mTotalPixels / 4;
        mUVStep = 1;
        mUVTotalNum = mTotalPixels / 4;
        break;

      case V4L2_PIX_FMT_YUV420:
        mFrameU = mCurrentFrame + mTotalPixels;
        mFrameV = mFrameU + mTotalPixels / 4;
        mUVStep = 1;
        mUVTotalNum = mTotalPixels / 4;
        break;

      case V4L2_PIX_FMT_NV21:
        /* Interleaved UV pane, V first. */
        mFrameV = mCurrentFrame + mTotalPixels;
        mFrameU = mFrameV + 1;
        mUVStep = 2;
        mUVTotalNum = mTotalPixels / 4;
        break;

      case V4L2_PIX_FMT_NV12:
        /* Interleaved UV pane, U first. */
        mFrameU = mCurrentFrame + mTotalPixels;
        mFrameV = mFrameU + 1;
        mUVStep = 2;
        mUVTotalNum = mTotalPixels / 4;
        break;

      default:
        ALOGE("%s: Unknown pixel format %.4s", __FUNCTION__,
              reinterpret_cast<const char*>(&mPixelFormat));
        return EINVAL;
    }
    /* Number of items in a single row inside U/V panes. */
    mUVInRow = (width / 2) * mUVStep;
    mState = ECDS_STARTED;
    mCurFrameTimestamp = 0;
  } else {
    ALOGE("%s: commonStartDevice failed", __FUNCTION__);
  }

  return res;
}

status_t EmulatedFakeCameraDevice::stopDevice() {
  ALOGV("%s", __FUNCTION__);

  Mutex::Autolock locker(&mObjectLock);
  if (!isStarted()) {
    ALOGW("%s: Fake camera device is not started.", __FUNCTION__);
    return NO_ERROR;
  }

  mFrameU = mFrameV = NULL;
  EmulatedCameraDevice::commonStopDevice();
  mState = ECDS_CONNECTED;

  return NO_ERROR;
}

/****************************************************************************
 * Worker thread management overrides.
 ***************************************************************************/

bool EmulatedFakeCameraDevice::inWorkerThread() {
  /* Wait till FPS timeout expires, or thread exit message is received. */
  WorkerThread::SelectRes res =
      getWorkerThread()->Select(-1, 1000000 / (mTargetFps / 1000));
  if (res == WorkerThread::EXIT_THREAD) {
    ALOGV("%s: Worker thread has been terminated.", __FUNCTION__);
    return false;
  }

  /* Lets see if we need to generate a new frame. */
  if ((systemTime(SYSTEM_TIME_MONOTONIC) - mLastRedrawn) >= mRedrawAfter) {
    /*
     * Time to generate a new frame.
     */

#if EFCD_ROTATE_FRAME
    const int frame_type = rotateFrame();
    switch (frame_type) {
      case 0:
        drawCheckerboard();
        break;
      case 1:
        drawStripes();
        break;
      case 2:
        drawSolid(mCurrentColor);
        break;
    }
#else
    /* Draw the checker board. */
    drawCheckerboard();

#endif  // EFCD_ROTATE_FRAME

    // mCurFrameTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
    mCurFrameTimestamp += (1000000000 / (mTargetFps / 1000));
    /* Timestamp the current frame, and notify the camera HAL about new frame.
     */
    mLastRedrawn = systemTime(SYSTEM_TIME_MONOTONIC);
    mCameraHAL->onNextFrameAvailable(mCurrentFrame, mCurFrameTimestamp, this);
  }

  return true;
}

/****************************************************************************
 * Fake camera device private API
 ***************************************************************************/

void EmulatedFakeCameraDevice::drawCheckerboard() {
  const int size = mFrameWidth / 10;
  bool black = true;

  if (size == 0) {
    // When this happens, it happens at a very high rate,
    //     so don't log any messages and just return.
    return;
  }

  if ((mCheckX / size) & 1) black = false;
  if ((mCheckY / size) & 1) black = !black;

  int county = mCheckY % size;
  int checkxremainder = mCheckX % size;
  uint8_t* Y = mCurrentFrame;
  uint8_t* U_pos = mFrameU;
  uint8_t* V_pos = mFrameV;
  uint8_t* U = U_pos;
  uint8_t* V = V_pos;

  YUVPixel adjustedWhite = YUVPixel(mWhiteYUV);
  changeWhiteBalance(adjustedWhite.Y, adjustedWhite.U, adjustedWhite.V);

  for (int y = 0; y < mFrameHeight; y++) {
    int countx = checkxremainder;
    bool current = black;
    for (int x = 0; x < mFrameWidth; x += 2) {
      if (current) {
        mBlackYUV.get(Y, U, V);
      } else {
        adjustedWhite.get(Y, U, V);
      }
      *Y = changeExposure(*Y);
      Y[1] = *Y;
      Y += 2;
      U += mUVStep;
      V += mUVStep;
      countx += 2;
      if (countx >= size) {
        countx = 0;
        current = !current;
      }
    }
    if (y & 0x1) {
      U_pos = U;
      V_pos = V;
    } else {
      U = U_pos;
      V = V_pos;
    }
    if (county++ >= size) {
      county = 0;
      black = !black;
    }
  }
  mCheckX += 3;
  mCheckY++;

  /* Run the square. */
  int sqx = ((mCcounter * 3) & 255);
  if (sqx > 128) sqx = 255 - sqx;
  int sqy = ((mCcounter * 5) & 255);
  if (sqy > 128) sqy = 255 - sqy;
  const int sqsize = mFrameWidth / 10;
  drawSquare(sqx * sqsize / 32, sqy * sqsize / 32, (sqsize * 5) >> 1,
             (mCcounter & 0x100) ? &mRedYUV : &mGreenYUV);
  mCcounter++;
}

void EmulatedFakeCameraDevice::drawSquare(int x, int y, int size,
                                          const YUVPixel* color) {
  const int square_xstop = std::min(mFrameWidth, x + size);
  const int square_ystop = std::min(mFrameHeight, y + size);
  uint8_t* Y_pos = mCurrentFrame + y * mFrameWidth + x;

  YUVPixel adjustedColor = *color;
  changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V);

  // Draw the square.
  for (; y < square_ystop; y++) {
    const int iUV = (y / 2) * mUVInRow + (x / 2) * mUVStep;
    uint8_t* sqU = mFrameU + iUV;
    uint8_t* sqV = mFrameV + iUV;
    uint8_t* sqY = Y_pos;
    for (int i = x; i < square_xstop; i += 2) {
      adjustedColor.get(sqY, sqU, sqV);
      *sqY = changeExposure(*sqY);
      sqY[1] = *sqY;
      sqY += 2;
      sqU += mUVStep;
      sqV += mUVStep;
    }
    Y_pos += mFrameWidth;
  }
}

#if EFCD_ROTATE_FRAME

void EmulatedFakeCameraDevice::drawSolid(YUVPixel* color) {
  YUVPixel adjustedColor = *color;
  changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V);

  /* All Ys are the same. */
  memset(mCurrentFrame, changeExposure(adjustedColor.Y), mTotalPixels);

  /* Fill U, and V panes. */
  uint8_t* U = mFrameU;
  uint8_t* V = mFrameV;
  for (int k = 0; k < mUVTotalNum; k++, U += mUVStep, V += mUVStep) {
    *U = color->U;
    *V = color->V;
  }
}

void EmulatedFakeCameraDevice::drawStripes() {
  /* Divide frame into 4 stripes. */
  const int change_color_at = mFrameHeight / 4;
  const int each_in_row = mUVInRow / mUVStep;
  uint8_t* pY = mCurrentFrame;
  for (int y = 0; y < mFrameHeight; y++, pY += mFrameWidth) {
    /* Select the color. */
    YUVPixel* color;
    const int color_index = y / change_color_at;
    if (color_index == 0) {
      /* White stripe on top. */
      color = &mWhiteYUV;
    } else if (color_index == 1) {
      /* Then the red stripe. */
      color = &mRedYUV;
    } else if (color_index == 2) {
      /* Then the green stripe. */
      color = &mGreenYUV;
    } else {
      /* And the blue stripe at the bottom. */
      color = &mBlueYUV;
    }
    changeWhiteBalance(color->Y, color->U, color->V);

    /* All Ys at the row are the same. */
    memset(pY, changeExposure(color->Y), mFrameWidth);

    /* Offset of the current row inside U/V panes. */
    const int uv_off = (y / 2) * mUVInRow;
    /* Fill U, and V panes. */
    uint8_t* U = mFrameU + uv_off;
    uint8_t* V = mFrameV + uv_off;
    for (int k = 0; k < each_in_row; k++, U += mUVStep, V += mUVStep) {
      *U = color->U;
      *V = color->V;
    }
  }
}

int EmulatedFakeCameraDevice::rotateFrame() {
  if ((systemTime(SYSTEM_TIME_MONOTONIC) - mLastRotatedAt) >= mRotateFreq) {
    mLastRotatedAt = systemTime(SYSTEM_TIME_MONOTONIC);
    mCurrentFrameType++;
    if (mCurrentFrameType > 2) {
      mCurrentFrameType = 0;
    }
    if (mCurrentFrameType == 2) {
      ALOGD("********** Rotated to the SOLID COLOR frame **********");
      /* Solid color: lets rotate color too. */
      if (mCurrentColor == &mWhiteYUV) {
        ALOGD("----- Painting a solid RED frame -----");
        mCurrentColor = &mRedYUV;
      } else if (mCurrentColor == &mRedYUV) {
        ALOGD("----- Painting a solid GREEN frame -----");
        mCurrentColor = &mGreenYUV;
      } else if (mCurrentColor == &mGreenYUV) {
        ALOGD("----- Painting a solid BLUE frame -----");
        mCurrentColor = &mBlueYUV;
      } else {
        /* Back to white. */
        ALOGD("----- Painting a solid WHITE frame -----");
        mCurrentColor = &mWhiteYUV;
      }
    } else if (mCurrentFrameType == 0) {
      ALOGD("********** Rotated to the CHECKERBOARD frame **********");
    } else if (mCurrentFrameType == 1) {
      ALOGD("********** Rotated to the STRIPED frame **********");
    }
  }

  return mCurrentFrameType;
}

#endif  // EFCD_ROTATE_FRAME

}; /* namespace android */
