// 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_;

  DispmanxDisplay(const DispmanxDisplay&) = delete;
  void operator=(const DispmanxDisplay&) = delete;
};

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_;

  DispmanxResource(const DispmanxResource&) = delete;
  void operator=(const DispmanxResource&) = delete;
};

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_;

  DispmanxElement(const DispmanxElement&) = delete;
  void operator=(const DispmanxElement&) = delete;
};

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_;

  DispmanxVideoRenderer(const DispmanxVideoRenderer&) = delete;
  void operator=(const DispmanxVideoRenderer&) = delete;
};

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

#endif  // STARBOARD_RASPI_SHARED_DISPMANX_UTIL_H_
