#include <stdio.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>

#include "pipixmapx.h"

static  GC    mygc;

/* --Methode-- */
PIPixmapX::PIPixmapX(PIContainerGen *par, char *nom,
                         int sx, int sy, int px, int py)
: PIPixmapGen(par,nom,sx,sy,px,py) 
{
Init();
AllocXImg();
}


/* --Methode-- */
PIPixmapX::~PIPixmapX()
{
delete[] myximg->data;
XFree(myximg); 
}

/* --Methode-- */
void PIPixmapX::Refresh()
{
int i,j;
unsigned char *pp;

if (pixmap)
  {
  for(j=0; j<ny; j++)
    {
    pp = pixmap+j*nx;
    for(i=0; i<nx; i++)
      { XPutPixel(myximg, i, j, cmap->Color(*pp) );  pp++; }
    }
  }

for(j=ny; j<YSize(); j++)
  for(i=nx; i<XSize(); i++)
     XPutPixel(myximg, i, j, 0 );

PIBaseWdgX::Refresh();
}


/* --Methode-- */
void PIPixmapX::Resize()
{
delete[] myximg->data;
XFree(myximg); 
AllocXImg();
if (Msg())  Send(Msg(), PIMsg_Resize, mPpos);
}

/*DEL07 --Methode-- 
void PIPixmapX::Draw(PIGraphicGen* g)
{
if (!pixmap)  return;
if (!g) return; 
if (g->kind() == PI_PSFileGraphics ) {
    g->DrawPixmap(ofx, ofy, pixmap, nx, ny, cmap);
    //  Il faut faire quelque chose Sinon ??! 
  }
else  Draw(g, 0, 0, XSize(), YSize());
}
*/

/* --Methode-- */
void PIPixmapX::Draw(PIGraphic* g, int x0, int y0, int dx, int dy)
{

if (!g) return; 
if ((myximg == NULL) || (cmap == NULL)) return;

if (g->kind() == PI_PSFileGraphics ) {
  if (pixmap) g->DrawPixmap(ofx, ofy, pixmap, nx, ny, cmap);
  return;
  }

Window xw = XtWindow(XtWdg());
Display * mdsp = PIXDisplay();

int mx, my, ox, oy;

if (x0 < 0)  x0 = 0;
if (y0 < 0)  y0 = 0;
mx = nx+ofx;   my = ny+ofy;
if (dx > (XSize()-x0)) dx = XSize()-x0;
if (dy > (YSize()-y0)) dy = YSize()-y0;
if ((dx <= 0) || (dy <= 0))  return;

if ( (mx < x0 ) || (my < y0) )
  { XClearArea(mdsp, xw, x0, y0, dx, dy, False);  return; }

ox = oy = 0;  

if (ofx > x0)
  { XClearArea(mdsp, xw, x0, y0, ofx-x0, dy, False);   
  dx -= (ofx-x0);  x0 = ofx;  ox = 0; }
else  ox = x0-ofx;
if (ofy > y0)
  { XClearArea(mdsp, xw, x0, y0, dx, ofy-y0, False);  
  dy -= (ofy-y0);  y0 = ofy;  oy = 0; }
else  oy = y0-ofy;
 
if (mx < (x0+dx))
  { XClearArea(mdsp, xw, mx, y0, x0+dx-mx, dy, False);  dx = mx-x0; }
if (my < (y0+dy))
  { XClearArea(mdsp, xw, x0, my, dx, y0+dy-my, False);  dy = my-y0; }
 
XPutImage(mdsp, xw, mygc, myximg, ox, oy, x0, y0, dx, dy);
XFlush(mdsp);
return;
 
}

static bool fgxpxm = false;


/* --Methode-- */
void PIPixmapX::Init()
{
XGCValues       values;
XtGCMask        mask;

if (fgxpxm)  return; 
fgxpxm = true;


mask = GCFunction | GCPlaneMask;
// mask = GCForeground | GCBackground;
values.function = GXcopy;
values.plane_mask = ~0;
// values.foreground = WhitePixel(mdsp, scr);
// values.background = BlackPixel(mdsp, scr);
mygc = XtGetGC(XtWdg(), mask, &values);

return;
}


/* --Methode-- */
void PIPixmapX::AllocXImg()
{
Display * mdsp;
int scr;
int depth;
int pad;
int i,j;

mdsp = PIXDisplay();
scr = PIXScreen();

depth = DefaultDepth(mdsp,scr);
pad = (depth > 8) ? 32 : 8;
myximg = XCreateImage (mdsp,DefaultVisual(mdsp,scr),
           depth,ZPixmap,0,NULL, XSize(), YSize(), pad,0);
if (myximg == NULL)  return;
myximg->data = new char [YSize()*myximg->bytes_per_line];
if (myximg->data == NULL)  
  { XFree(myximg); myximg = NULL;  return; } 

for(j=0; j<YSize(); j++)
  for(i=0; i<XSize(); i++)
    XPutPixel(myximg, i, j, 0 );

return;
}
