/*
 *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef EXAMPLES_PEERCONNECTION_CLIENT_LINUX_MAIN_WND_H_
#define EXAMPLES_PEERCONNECTION_CLIENT_LINUX_MAIN_WND_H_

#include <stdint.h>

#include <memory>
#include <span>
#include <string>

#include "api/media_stream_interface.h"
#include "api/scoped_refptr.h"
#include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h"
#include "examples/peerconnection/client/main_wnd.h"
#include "examples/peerconnection/client/peer_connection_client.h"
#include "rtc_base/buffer.h"

// Forward declarations.
typedef struct _GtkWidget GtkWidget;
typedef union _GdkEvent GdkEvent;
typedef struct _GdkEventKey GdkEventKey;
typedef struct _GtkTreeView GtkTreeView;
typedef struct _GtkTreePath GtkTreePath;
typedef struct _GtkTreeViewColumn GtkTreeViewColumn;
typedef struct _cairo cairo_t;

// Implements the main UI of the peer connection client.
// This is functionally equivalent to the MainWnd class in the Windows
// implementation.
class GtkMainWnd : public MainWindow {
 public:
  GtkMainWnd(const char* server, int port, bool autoconnect, bool autocall);
  ~GtkMainWnd() override;

  void RegisterObserver(MainWndCallback* callback) override;
  bool IsWindow() override;
  void SwitchToConnectUI() override;
  void SwitchToPeerList(const Peers& peers) override;
  void SwitchToStreamingUI() override;
  void MessageBox(const char* caption,
                  const char* text,
                  bool is_error) override;
  MainWindow::UI current_ui() override;
  void StartLocalRenderer(webrtc::VideoTrackInterface* local_video) override;
  void StopLocalRenderer() override;
  void StartRemoteRenderer(webrtc::VideoTrackInterface* remote_video) override;
  void StopRemoteRenderer() override;

  void QueueUIThreadCallback(int msg_id, void* data) override;

  // Creates and shows the main window with the |Connect UI| enabled.
  bool Create();

  // Destroys the window.  When the window is destroyed, it ends the
  // main message loop.
  bool Destroy();

  // Callback for when the main window is destroyed.
  void OnDestroyed(GtkWidget* widget, GdkEvent* event);

  // Callback for when the user clicks the "Connect" button.
  void OnClicked(GtkWidget* widget);

  // Callback for keystrokes.  Used to capture Esc and Return.
  void OnKeyPress(GtkWidget* widget, GdkEventKey* key);

  // Callback when the user double clicks a peer in order to initiate a
  // connection.
  void OnRowActivated(GtkTreeView* tree_view,
                      GtkTreePath* path,
                      GtkTreeViewColumn* column);

  void OnRedraw();

  void Draw(GtkWidget* widget, cairo_t* cr);

 protected:
  class VideoRenderer : public webrtc::VideoSinkInterface<webrtc::VideoFrame> {
   public:
    VideoRenderer(GtkMainWnd* main_wnd,
                  webrtc::VideoTrackInterface* track_to_render);
    ~VideoRenderer() override;

    // VideoSinkInterface implementation
    void OnFrame(const webrtc::VideoFrame& frame) override;

    std::span<const uint8_t> image() const { return image_; }

    int width() const { return width_; }

    int height() const { return height_; }

   protected:
    void SetSize(int width, int height);
    webrtc::Buffer image_;
    int width_;
    int height_;
    GtkMainWnd* main_wnd_;
    webrtc::scoped_refptr<webrtc::VideoTrackInterface> rendered_track_;
  };

 protected:
  GtkWidget* window_;     // Our main window.
  GtkWidget* draw_area_;  // The drawing surface for rendering video streams.
  GtkWidget* vbox_;       // Container for the Connect UI.
  GtkWidget* server_edit_;
  GtkWidget* port_edit_;
  GtkWidget* peer_list_;  // The list of peers.
  MainWndCallback* callback_;
  std::string server_;
  std::string port_;
  bool autoconnect_;
  bool autocall_;
  std::unique_ptr<VideoRenderer> local_renderer_;
  std::unique_ptr<VideoRenderer> remote_renderer_;
  int width_ = 0;
  int height_ = 0;
  webrtc::Buffer draw_buffer_;
  int draw_buffer_size_;
};

#endif  // EXAMPLES_PEERCONNECTION_CLIENT_LINUX_MAIN_WND_H_
