//********************************************************************************
//* File       : WaylandCB.hpp                                                   *
//* Author     : Mahlon R. Smith                                                 *
//*              Copyright (c) 2019-2026 Mahlon R. Smith, The Software Samurai   *
//*                  GNU GPL copyright notice located below                      *
//* Date       : 02-Oct-2025                                                     *
//* Version    : (see WaylandCB_Version in WaylandCB.cpp)                        *
//*                                                                              *
//* Description:                                                                 *
//* The WaylandCB class provides a simple interface between console              *
//* applications and the GNOME/Wayland compositor's two clipboards:              *
//* "Primary" and "Regular".                                                     *
//*                                                                              *
//********************************************************************************
//* Copyright Notice:                                                            *
//* This program is free software: you can redistribute it and/or modify it      *
//* under the terms of the GNU General Public License as published by the Free   *
//* Software Foundation, either version 3 of the License, or (at your option)    *
//* any later version.                                                           *
//*                                                                              *
//* This program is distributed in the hope that it will be useful, but          *
//* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY   *
//* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License     *
//* for more details.                                                            *
//*                                                                              *
//* You should have received a copy of the GNU General Public License along      *
//* with this program.  If not, see <http://www.gnu.org/licenses/>.              *
//*                                                                              *
//*         Full text of the GPL License may be found in the Texinfo             *
//*         documentation for this program under 'Copyright Notice'.             *
//********************************************************************************

//************
//* Includes *
//************
#include <filesystem>      //* filesystem (C++17)
#include <fstream>         //* C++ file I/O
#include <limits.h>        //* for realpath() and PATH_MAX
#include <dirent.h>        //* Read directory entries
#include <sys/stat.h>      //* Define stat(), lstat(), etc.
#include <fcntl.h>         //* For fcntl() and bitfield macros
#include <unistd.h>        //* UNIX system interface
#include <chrono>          //* timers
#include <thread>          //* std::thread definition (and POSIX thread defs)
#include "gString.hpp"     //* Text analysis and formatting

using namespace std ;      //* Scope quailfier

//* Enable/disable debugging log.*
#define DEBUG_WCB (0)

//* The mainline prototypes for wcbSet and wcbGet have been       *
//* redefined by* placing the 'len' (buffer length) parameter     *
//* BEFORE the 'primary' (clipboard-selection parameter).         *
//* Prototypes for the previous parameter order will be retained  *
//* temporarily to allow time for updating any existing           *
//* application code  which relies on the deprecated prototyes.   *
//* The obsolete gString buffer-size constants are also retained  *
//* under this declaration. See below.                            *
#define DEPRECATED_OVERLOADS (0)

//***************
//* Definitions *
//***************
//* Useful MIME types/encodings ("charset") for text data.      *
//* All of these are encodings of the "text/plain" MIME type.   *
//* - Please note that "charset=unicode" is actually an invalid *
//*   bit of MS-Word(tm) garbage and should not be used.        *
//* - "UTF8_STRING" is an outgrowth of X11 support for UTF-8    *
//*   encoding an is an "official" X11 "atom" (token). It seems *
//*   that the Wayland developers have embraced it as a proper  *
//*   representation for UTF-8 encoding, so we use it           *
//*   throughout the WaylandCB class to indicate the use of     *
//*   UTF-8 MIME-type/encoding.                                 *
enum MIMEtypes : short
{
   mtUTF8,     // "UTF8_STRING", "utf-8", "UTF-8", "TEXT", "STRING"
   mtUTF32,    // 32-bit unicode (wchar_t type)
               // Note: To be retrieved as UTF-32, it must have been saved as UTF-32
   mtUTF16LE,  // "UTF-16LE" (Windoze little-endian)
   mtUTF16BE,  // "UTF-16BE" (Windoze big-endian)
   mtISO88591, // Western European, aka:"extended ASCII" (another Windoze mess)
   mtUSASCII,  // ASCII (a proper subset of UTF-8)
} ;

//* Status code returned by a call to wcbTest() method. (see below) *
enum wcbStatus : int
{
   wcbsNOINSTALL = (-2), // 'wl-copy' and/or 'wl-paste' utility not installed
   wcbsNOCONNECT,        // unable to establish connection with system clipboard,
                         // or communication interrupted
   wcbsNOINIT,           // WaylandCB class not instantiated (used at application level)
   wcbsACTIVE,           // system clipboard communication established and active
} ;


//*****************
//* Constant Data *
//*****************
#if DEPRECATED_OVERLOADS != 0    // see note above
#define gsMAXCHARS (gsALLOCDFLT)
#define gsMAXBYTES (gsDFLTBYTES)
#endif   // DEPRECATED_OVERLOADS

//* Maximum size for clipboard transfer to/from the application.*
const int MAX_CB_UTF8  = (gsDFLTBYTES - 1) ;    // 16K UTF-8 bytes
const int MAX_CB_UTF32 = (gsALLOCMED - 1) ;     //  4K UTF-32 codepoints

//********************
//* Class Definition *
//********************
class WaylandCB
{
   public:
   virtual ~WaylandCB ( void ) ;                      //* destructor
   WaylandCB ( void ) ;                               //* default constructor
   int wcbGet ( uint8_t* trg, int len, bool primary = false ) ;
   int wcbGet ( char* trg,    int len, bool primary = false ) ;
   int wcbGet ( wchar_t* trg, int len, bool primary = false ) ;
   int wcbGet ( gString& trg, int len = gsALLOCDFLT, bool primary = false ) ;
   int wcbSet ( const uint8_t* csrc, int cnt = -1, bool primary = false ) ;
   int wcbSet ( const char* csrc,    int cnt = -1, bool primary = false ) ;
   int wcbSet ( const gString& csrc, int cnt = -1, bool primary = false ) ;
   int wcbSet ( const wchar_t* csrc, int cnt = -1, bool primary = false ) ;

#if DEPRECATED_OVERLOADS != 0    // see note above
   short wcbGet ( uint8_t* trg, bool primary = false, short len = gsALLOCDFLT ) ;
   short wcbGet ( char* trg, bool primary = false, short len = gsALLOCDFLT ) ;
   short wcbGet ( gString& trg, bool primary = false, short len = gsALLOCDFLT ) ;
   short wcbGet ( wchar_t* trg, bool primary = false, short len = gsALLOCDFLT ) ;
   short wcbSet ( const uint8_t* csrc, bool primary = false, int cnt = -1 ) ;
   short wcbSet ( const char* csrc,    bool primary = false, int cnt = -1 ) ;
   short wcbSet ( const gString& csrc, bool primary = false, int cnt = -1 ) ;
   short wcbSet ( const wchar_t* csrc, bool primary = false, int cnt = -1 ) ;
#endif   // DEPRECATED_OVERLOADS

   bool  wcbClear ( bool primary = false, bool useCmd = false ) ;
   int   wcbBytes ( bool primary = false ) ;    //* report number of data bytes on clipboard
   int   wcbChars ( bool primary = false ) ;    //* report number of data characters on clipboard
   int   wcbTypes ( gString& trg, int cnt = -1, bool primary = false ) ; //* report available data formats
   int   wcbTypes ( char* trg, int cnt = -1, bool primary = false ) ;
   int   wcbTypes ( wchar_t* trg, int cnt = -1, bool primary = false ) ;
   bool  wcbIsConnected ( void ) ;              //* report whether connection established
   wcbStatus wcbTest ( const char* testdata ) ; //* test the connection
   bool  wcbReinit ( void ) ; //* delete local data and reconnect with Wayland clipboard
   short wcbVersion ( gString& gsVersion ) ;    //* report wl-clipboard version AND WaylandCB version
   const char* wcbVersion ( void ) ;            //* report version number

   protected:
   void  reset ( void ) ;                       //* initialize data members
   void  StartupSequence ( void ) ;             //* execute the start sequence
   bool  EstablishIndirectConnection ( void ) ; //* locate and exercise wl utilities
   void  Systemcall ( const char* cmd ) ;       //* call the "system()" library function
   bool  GetTempdirPath ( gString& tdPath ) ;   //* locate temp-file directory
   bool  CreateTempname ( gString& tmpPath ) ;  //* create a temporary file
   bool  DeleteTempname ( const gString& tmpPath ) ; //* delete a temporary file

   //* For development only. Not implemented at this time.*
   short wcbGet32bit ( wchar_t* trg, bool primary = false, short cnt = -1 ) ;
   short wcbSet32bit ( const wchar_t* src, bool primary = false, short cnt = -1 ) ;
   bool  wcbGetMime ( gString& trg, bool primary = false ) ;
   bool  wcbSetMime ( MIMEtypes mtype ) ;
   bool  wcbGet_tfspec ( gString& tfs ) ;

   //******************
   //** Data Members **
   //******************
   private:
   char  tfdir[gsALLOCMED] ;           //* filespec of system temp directory
   char  tfspec[gsALLOCMED] ;          //* filespec of primary temp file
   short tfspecLen ;                   //* bytes in tfspec string
   bool  connected ;                   //* 'true' if connection established

   #if DEBUG_WCB != 0                  //* for debugging only
   ofstream dbofs ;                    //* file to receive debugging data
   gString gsdb ;                      //* formatting debugging text data
   #endif   // DEBUG_WCB

   friend class NcDialog ;    // Allow NcDialog class access during development
} ;

