/** 
 *  Yudit Unicode Editor Source File
 *
 *  GNU Copyright (C) 1997-2023  Gaspar Sinai <gaspar@yudit.org>  
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, version 2,
 *  dated June 1991. See file COPYYING for details.
 *
 *  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, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
#ifndef SX11Window_h
#define SX11Window_h

#include "swindow/sx11/SX11Impl.h"
#include "swindow/sx11/SX11Color.h"
#include "swindow/sx11/SXInputMethod.h"

#include "swindow/SGEngine.h"

#include "stoolkit/SBinVector.h"
#include "stoolkit/SBinHashtable.h"
#include "stoolkit/SVector.h"

class SX11DoubleBuffer 
{
public:
  SX11DoubleBuffer (void) {}
  long          id;
  GC		gc; /* always set to gb and pen fg */
  GC		gc_draw_or; /* always set to gb and pen fg */
  GC		gc_draw_and; /* always set to gb and pen fg */
  GC		gc_default; /* always set to gb and pen fg */
  unsigned long gcFD;
  unsigned long gcFG;
};

class SX11Region 
{
public:
  SX11Region (void) 
    : x(0), y(0), width (0), height (0) {}
  SX11Region (int _x, int _y, unsigned int _w, unsigned int _h)
    : x(_x), y(_y), width (_w), height (_h) {}
  SX11Region (const SX11Region& old) 
    : x(old.x), y(old.y), width (old.width), height (old.height) {}
  SX11Region operator = (const SX11Region& old)
    { x = old.x; y = old.y; width = old.width; height = old.height; 
     return *this; }
  int x;
  int y;
  unsigned int width;
  unsigned int height;
};

/**
 * @author: Gaspar Sinai <gaspar@yudit.org>
 * @version: 2000-04-23
 * This is the abstract widget toolkit
 */
class SX11Window : public SWindow
{
public:
  SX11Window (const SString &name, SX11Impl* impl, long id);
  virtual ~SX11Window();
  virtual bool isShown () { return shown; }
  virtual bool isModal () { return modalFlag; }
  virtual void setModal (SWindow*w, bool decorated);


  static void setPixmapCacheSize(unsigned int size);
  static void setPixmapCacheOn (bool isOn=true);

  virtual bool cacheOn (bool on=true);

  virtual SS_Matrix2D  getCurrentMatrix() const;

  virtual void setMinimumSize (unsigned int width, unsigned int height);

  /* Low level routines */
  virtual void clear (int x, int y, unsigned int width, unsigned int height);

  virtual void copy (int x, int y, unsigned int width, unsigned int height, int tox, int toy);

  virtual void show ();
  virtual void hide ();

  virtual void setApplicationImage (const SImage& im);

  /*---------------- from canvas --------------*/
  virtual bool beginImage (double x, double y, const SString& id, const SColor& background);
  virtual void endImage ();
  virtual void newpath ();
  virtual void fill (const SPen& pen);
  virtual void stroke (const SPen& pen);

  virtual void moveto (double x, double y);
  virtual void lineto (double x, double y);
  virtual void curveto (double x0, double y0, 
      double x1, double y1, double x3, double y3);
  virtual void closepath();
  virtual void pushmatrix();
  virtual void popmatrix();
  virtual void scale (double x, double y);
  virtual void translate (double x, double y);
  virtual void rotate (double angle);

  virtual void putImage (int x, int y, const SImage& image);
  virtual void bitfont (const SPen& pen, double x, double y, 
      void* native, char* data, unsigned int len);
  virtual void bitfill (const SColor& bg, int x, int y, 
      unsigned int width, unsigned int height);
  virtual void bitline (const SColor& fg, int x, int y, int tox, int toy);
  virtual void bitpoint (const SColor& fg, int x, int y);
  virtual void bitpoints (const SColor& fg, const int* x, const int* y, 
         unsigned int arraySize);
  /*---------------- end of canvas ---------------*/

  virtual void setBackground(const SColor &color);
  virtual void resize (unsigned int width, unsigned int height);
  virtual void redraw (bool clear, int x, int y, 
       unsigned int width, unsigned int height);
  virtual void move (int x, int y);
  virtual void setParent (SWindow* w, int x, int y);
  virtual void getKeyboardFocus();
  virtual long getID();
  virtual void setClippingArea (int x, int y, 
      unsigned int width, unsigned int height);
  virtual void removeClippingArea ();

  virtual bool startInputMethod (const SString& name, const SProperties& prop, SPreEditor* preEditor);
  virtual void stopInputMethod ();
  virtual void setInputMethodProperties (const SProperties& prop);
  virtual SString getInputMethod ();
  virtual bool hasStatusArea ();
  virtual bool isVisible ();

  virtual SString  getClipUTF8(bool isPrimary=true);
  virtual void putClipUTF8(const SString& utf8, bool isPrimary=true);
  virtual void setTitle (const SString& title);

  virtual void addAccelerator (const SAccelerator& a, SAcceleratorListener* l);
  virtual void removeAccelerator (const SAccelerator& a, SAcceleratorListener* l);
  void _acceleratorPressed (const SAccelerator& a);
  void _acceleratorReleased (const SAccelerator& a);

  /*------- xdnd -----------*/
  virtual void setDroppable (const SStringVector& targets);
  const SStringVector& getDroppable() const;

  /* Xutf8LookupString needs this from input context */
  XIC getIC ();
  const SString& getICEncoding () const;
  bool isAsciiInput ();
  bool isKInput ();

  SBinVector<Atom> targetAtoms;
  SStringVector    targets;
  virtual void center (SWindow* window);
  virtual void wait ();

  bool mapNotified;
  bool exposedOnce; // The first expose event in X11 gives old size.
  bool isChild;

  /*--- get an integer id for the underlying window ---*/
  virtual unsigned long getWindowID() const;
  // default off
  virtual void setDoubleBuffer (bool isOn);
  virtual bool isDoubleBufferEnabled () const;
  // called before redraw area
  void freeDoubleBuffer ();
  void beginDoubleBuffer (const SX11Region& region);
  void endDoubleBuffer (const SX11Region& region);

private:
  SBinHashtable <SAcceleratorListener*> accelerators;
  void createShadedPixmap (const SImage& im, Pixmap* p, Pixmap* m);
  void createColoredPixmap (const SImage& im, Pixmap* p, Pixmap* m);
  void createMaskedPixmap (const SImage& im, Pixmap* p, Pixmap* m);

  SString       name;
  SXInputMethod inputMethod;
  SX11Color     background;
  SX11Impl*     impl;
  SPen		pen;
  bool 		clipped; /* gc is clipped */
  SGEngine*     engine;
  // added in 2.8.2
  unsigned int     dbindex;
  SX11DoubleBuffer dbuffer[2];
  SX11Region       clipRegion;

protected:
  /* From canvas. */
  bool isCacheOn;
  /* common */
  bool    shown;
  bool    modalFlag;

  int     xpos;
  int     ypos;
  unsigned int xwidth;
  unsigned int yheight;

public:
  virtual bool commitInputMethod() {return false; }


  void setSize (unsigned int _width, unsigned int _height) {
    xwidth =  _width;
    yheight = _height;
  }
  void setPosition (int _posx, int _posy) {
    xpos = _posx;
    ypos = _posy;
  }

  virtual unsigned int getWidth() const {
    return xwidth;
  }
  virtual unsigned int getHeight() const {
    return yheight;
  }
  virtual int getPositionX() const {
    return xpos;
  }
  virtual int getPositionY() const {
    return ypos;
  }
};

#endif /* SX11Window_h */
