// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// 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.

#ifndef STARBOARD_RASPI_SHARED_DISPMANX_UTIL_H_
#define STARBOARD_RASPI_SHARED_DISPMANX_UTIL_H_

#include <bcm_host.h>

#include <functional>

#include "starboard/common/log.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/configuration.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/starboard/player/filter/video_frame_internal.h"
#include "starboard/types.h"

namespace starboard {
namespace raspi {
namespace shared {

class DispmanxRect : public VC_RECT_T {
 public:
  DispmanxRect() { vc_dispmanx_rect_set(this, 0, 0, 0, 0); }
  DispmanxRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
    vc_dispmanx_rect_set(this, x, y, width, height);
  }
};

class DispmanxDisplay {
 public:
  DispmanxDisplay() {
    bcm_host_init();
    handle_ = vc_dispmanx_display_open(0);
    SB_DCHECK(handle_ != DISPMANX_NO_HANDLE);
  }
  ~DispmanxDisplay() {
    int result = vc_dispmanx_display_close(handle_);
    SB_DCHECK(result == 0);
    bcm_host_deinit();
  }

  DISPMANX_DISPLAY_HANDLE_T handle() const { return handle_; }

 private:
  DISPMANX_DISPLAY_HANDLE_T handle_;

  SB_DISALLOW_COPY_AND_ASSIGN(DispmanxDisplay);
};

class DispmanxResource {
 public:
  DispmanxResource() : handle_(DISPMANX_NO_HANDLE) {}

  virtual ~DispmanxResource() {
    if (handle_ != DISPMANX_NO_HANDLE) {
      int32_t result = vc_dispmanx_resource_delete(handle_);
      SB_DCHECK(result == 0) << " result=" << result;
    }
  }

  DISPMANX_RESOURCE_HANDLE_T handle() const { return handle_; }
  uint32_t visible_width() const { return visible_width_; }
  uint32_t visible_height() const { return visible_height_; }
  uint32_t width() const { return width_; }
  uint32_t height() const { return height_; }

 protected:
  DispmanxResource(VC_IMAGE_TYPE_T image_type,
                   uint32_t width,
                   uint32_t height,
                   uint32_t visible_width,
                   uint32_t visible_height);

 private:
  DISPMANX_RESOURCE_HANDLE_T handle_;
  uint32_t width_;
  uint32_t height_;
  uint32_t visible_width_;
  uint32_t visible_height_;

  SB_DISALLOW_COPY_AND_ASSIGN(DispmanxResource);
};

class DispmanxYUV420Resource : public DispmanxResource {
 public:
  DispmanxYUV420Resource(uint32_t width,
                         uint32_t height,
                         uint32_t visible_width,
                         uint32_t visible_height)
      : DispmanxResource(VC_IMAGE_YUV420,
                         width,
                         height,
                         visible_width,
                         visible_height) {}

  void WriteData(const void* data);
  void ClearWithBlack();
};

class DispmanxRGB565Resource : public DispmanxResource {
 public:
  DispmanxRGB565Resource(uint32_t width,
                         uint32_t height,
                         uint32_t visible_width,
                         uint32_t visible_height)
      : DispmanxResource(VC_IMAGE_RGB565,
                         width,
                         height,
                         visible_width,
                         visible_height) {}

  void WriteData(const void* data);
  void ClearWithBlack();
};

class DispmanxElement {
 public:
  DispmanxElement(const DispmanxDisplay& display,
                  int32_t layer,
                  const DispmanxRect& dest_rect,
                  const DispmanxResource& src,
                  const DispmanxRect& src_rect);
  ~DispmanxElement();

  DISPMANX_ELEMENT_HANDLE_T handle() const { return handle_; }
  void ChangeSource(const DispmanxResource& new_src);

 private:
  DISPMANX_ELEMENT_HANDLE_T handle_;

  SB_DISALLOW_COPY_AND_ASSIGN(DispmanxElement);
};

class DispmanxVideoFrame
    : public starboard::shared::starboard::player::filter::VideoFrame {
 public:
  DispmanxVideoFrame(SbTime time,
                     DispmanxYUV420Resource* resource,
                     std::function<void(DispmanxYUV420Resource*)> release_cb)
      : VideoFrame(time), resource_(resource), release_cb_(release_cb) {
    SB_DCHECK(resource_);
    SB_DCHECK(release_cb_);
  }
  ~DispmanxVideoFrame() { release_cb_(resource_); }

  DispmanxYUV420Resource* resource() const { return resource_; }

 private:
  DispmanxYUV420Resource* resource_;
  std::function<void(DispmanxYUV420Resource*)> release_cb_;
};

class DispmanxVideoRenderer {
 public:
  typedef starboard::shared::starboard::player::filter::VideoFrame VideoFrame;

  DispmanxVideoRenderer(const DispmanxDisplay& display, int32_t layer);

  void Update(const scoped_refptr<VideoFrame>& video_frame);

  void HideElement();
  void ShowElement();

 private:
  scoped_ptr<DispmanxElement> element_;
  scoped_refptr<VideoFrame> frame_;
  // Value of |frame_| when HideElement() gets called.
  scoped_refptr<VideoFrame> hidden_frame_;

  // Used to fill the background with black if no video is playing so that the
  // console does not show through.
  DispmanxRGB565Resource black_frame_;

  SB_DISALLOW_COPY_AND_ASSIGN(DispmanxVideoRenderer);
};

}  // namespace shared
}  // namespace raspi
}  // namespace starboard

#endif  // STARBOARD_RASPI_SHARED_DISPMANX_UTIL_H_
