#include "xheaders.h"

#include XGraphicDevice_i
#include XGraphicObject_i
#include XWindow_i
#include XColor_i
#include XMessageBox_i
#include XFont_i


void XGraphicDevice :: Copy( XGraphicDevice * source, XPoint * targetLeft, XPoint * targetRight, XPoint * sourceLeft, XPoint * sourceRight)
{
   POINTL p[4];
   LONG m = 3;

   p[0].x = targetLeft->GetX();
   p[0].y = targetLeft->GetY();
   p[1].x = targetRight->GetX();
   p[1].y = targetRight->GetY();
   p[2].x = sourceLeft->GetX();
   p[2].y = sourceLeft->GetY();

   if( sourceRight )
      {
         m = 4;
         p[3].x = sourceRight->GetX();
         p[3].y = sourceRight->GetY();
      }
   GpiBitBlt( hps, source->hps, m, p, ROP_SRCCOPY, BBO_IGNORE );
}


extern char * pszdata[9];
XGraphicDevice :: XGraphicDevice(XWindow * w, BOOL memory)
{
  fontId = 0;
  xOffset = yOffset = 0;
  wight = hight = 0;
  SIZEL g = {0,0};
  first = last = NULL;

  hwnd = w->GetClientHandle();
  hab =  WinQueryAnchorBlock(hwnd);

  if(!( memory ))
     {
         HDC hdc = WinOpenWindowDC( hwnd);
         hps = GpiCreatePS( hab, hdc, &g, PU_PELS | GPIF_LONG | GPIA_ASSOC);
     }
  else
     {
         HDC hdc = DevOpenDC( hab, OD_MEMORY, (PSZ) "*", 4, (PDEVOPENDATA) pszdata, 0L);
         hps = GpiCreatePS( hab, hdc, &g, PU_PELS | GPIA_ASSOC);
         BITMAPINFOHEADER2 h;
         memset(&h, 0, sizeof(BITMAPINFOHEADER2));
         h.cbFix = sizeof(BITMAPINFOHEADER2);
         h.cx = 2000;
         h.cy = 2000;
         h.cBitCount = 8;
         h.cPlanes = 1;
         HBITMAP hbm = GpiCreateBitmap( hps, &h, 0, NULL, NULL);
         GpiSetBitmap( hps, hbm);
     }

  GpiCreateLogColorTable( hps, LCOL_RESET, LCOLF_RGB, 0, 1, &backCol);

/*
   GpiSetBackColor( hps, 0);

   if (GpiSetBackMix( hps, BM_SRCTRANSPARENT ) == FALSE)
      XMessageBox( "error 2" );
*/
  backCol = 16777216;
  aktColor = 0;
  aktLineEnding = LINEEND_DEFAULT;
  aktLineJoining = LINEJOIN_DEFAULT;
  aktLineWidth = LINEWIDTH_DEFAULT;
  aktFont = 0;
}


void XGraphicDevice :: SetXOffset( LONG x)
{
  xOffset = x;
}


void XGraphicDevice :: SetYOffset( LONG y)
{
  yOffset = y;
}


void XGraphicDevice :: SetPaintColor( LONG c)
{
  aktColor = c;
  GpiSetColor( hps, aktColor);
}


void XGraphicDevice :: SetBackgroundColor( XColor * c)
{
  backCol = c->GetColor();
}


XGraphicObject * XGraphicDevice :: FindObject( LONG x, LONG y, XGraphicObject * searchBehind)
{
   LONG x1 = x + xOffset;
   LONG y1 = y + yOffset;

   XGraphicObject * b;
   if( searchBehind)
      b = searchBehind->next;
   else
      b = first;

   while( b )
     {
        if(b->HitTest( x1, y1) == TRUE)
           return b;
        b = b->next;
     }
   return NULL;
}


XGraphicDevice :: ~XGraphicDevice()
{
  XGraphicObject * b = first, * d;
  while( b )
    {
      d = b->next;
      delete b;
      b = d;
    }
  GpiDestroyPS( hps);
}


void XGraphicDevice :: AddObject( XGraphicObject * obj)
{
  if(last)
     last->next = obj;
  else
     first = obj;
  last = obj;
}


BOOL XGraphicDevice :: RemoveObject( XGraphicObject * obj, BOOL destroyObject )
{
   XGraphicObject * b= first, * d;

   if( b == obj)
      {
         first = b->next;
         b->dev = NULL;
         if(destroyObject)
            delete b;
         return TRUE;
      }
   while ( b )
      {
         d = b;
         if( b->next == obj)
            {
               d->next = b->next;
               b->dev = NULL;
               if(destroyObject)
                  delete b;
               return TRUE;
            }
         b = b->next;
      }
   return FALSE;

}


void XGraphicDevice :: Draw( void )
{
  RECTL rect;
  WinQueryUpdateRect( hwnd, &rect);
  WinFillRect( hps, &rect, backCol);

  XGraphicObject * o = first;

  while( o )
     {
       o->Draw();
       o = o->next;
     }
}


void XGraphicDevice :: SetLineJoin( char lineJoin )
{
  GpiSetLineJoin( hps, lineJoin);
  aktLineJoining = lineJoin;
}


void XGraphicDevice :: SetLineEnd( char lineEnd)
{
  GpiSetLineEnd( hps, lineEnd );
  aktLineEnding = lineEnd;
}


void XGraphicDevice :: SetLineWidth( SHORT width)
{
  GpiSetLineWidthGeom( hps, width );
  aktLineWidth = width;
}


void XGraphicDevice :: ResetFont( void )
{
  GpiSetCharSet( hps, 0);
  aktFont =0;
}


void XGraphicDevice :: SetFont( XFont * font)
{
  aktFont = font->fontId;
  GpiSetCharSet( hps, aktFont);
  SIZEF sc;
  sc.cx = MAKEFIXED( font->fontSize * 1.5, 0);
  sc.cy = MAKEFIXED( font->fontSize * 1.5, 0);
  GpiSetCharBox( hps, &sc);
}


