/*
  Copyright 2025 Matthias-Sebastian Schröder <matthias.schroeder@dolanghub.de>

  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.
*/

#pragma once

#include "dobase/namespace.hpp"

#ifdef _WINDOWS
typedef void* HANDLE;
#endif

__NAMESPACE_DO_START

#define MSGBOX_TYPE_OK             1
#define MSGBOX_TYPE_YES            2
#define MSGBOX_TYPE_NO             4
#define MSGBOX_TYPE_CANCEL         8
#define MSGBOX_TYPE_ABORT         16
#define MSGBOX_TYPE_RETRY         32
#define MSGBOX_TYPE_IGNORE        64

#define MSGBOX_ICON_INFO           0
#define MSGBOX_ICON_STOP           1
#define MSGBOX_ICON_QUESTION       2
#define MSGBOX_ICON_EXCLAMATION    3

const int SCREEN_TYPE_MASK = 0xFF;
const int SCREEN_TYPE_CONSOLE = 1;

const int SCREEN_FLAG_MASK = 0xFF00;
const int SCREEN_FLAG_INTERACTIVE = 0x100;

enum class ScrHeaderTypes : int
{
  HTTP,
};

class Runtime;
class VmStack;
class String;
class Charset;
struct screen_pimpl_st;

// Screen as public interface
class DOBASE_EXPORT Screen
{
public:
  Screen();
  virtual ~Screen();
  // to_size and read_num_chars can divert if
  // console charset is multi-byte, for example utf8
  // returns the number of bytes consumed by
  // num chars read
  virtual size_t read(char* to, size_t to_size, size_t read_num_chars,
    const Charset** inOutCharset);
  virtual void errendl();
  virtual void set_output_charset(const Charset* cs);
  virtual void set_input_charset(const Charset* cs);
  virtual int msgbox(const String& title, const String& text,
    const int buttons = 0, const int default_button = 0,
    const int icon = 0);
  virtual void clear();
  virtual void header(ScrHeaderTypes type, const String& header, bool replace) {};
  void set_interactive(bool interactive);
  // Allow UI to save modules before compiling it
  virtual void on_load_module(VmStack *stack, const String& filename);  
  virtual void modify_command(VmStack *stack, const String& filename);
  virtual void browse(VmStack *stack);
  virtual void wait(VmStack* stack);
  void out(const String& text);
  void outendl(const String& text);
  void outendl();
  void err(const String& text);
  void errendl(const String& text);
  virtual void flush() {};
  void ob_start();
  void ob_get(String* to);
  void ob_end_flush();
  void ob_end_clean();
  // Lock screen for current thread for non
  // interleave output
  void lock_for_output();
  void unlock_output();
protected:
  virtual void internal_out(const String& text) = 0;
  virtual void internal_err(const String& text) = 0;
  screen_pimpl_st* pimpl;
};

DOBASE_EXPORT Screen* CreateScreen(int screent_type);

DOBASE_EXPORT int SetOutputCharset(Screen*, const char* u8charsetName);

DOBASE_EXPORT int SetInputCharset(Screen*, const char* u8charsetName);

DOBASE_EXPORT void ReleaseScreen(Screen* screen);

DOBASE_EXPORT void PrintScreenUtf8(Screen* screen,
  const char* u8string);

__NAMESPACE_END
