/**************************************************************************\
 ibtk (Insomnia's Basic ToolKit)

  By Insomnia (Steaphan Greene)
  (insomnia@core.binghamton.edu)

  Copyright (C) 1999 Steaphan Greene

  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., 59 Temple Place, Suite 330, Boston, MA 02111, USA.

\**************************************************************************/

#include <string.h>
#include <stdio.h>

#include "igbox.h"

IGBox::~IGBox()  {
  Win->RemoveClaim(this);
  }

IGBox::IGBox(IWindow *w, int xp, int yp, int xs, int ys)  {
  Init(w, xp, yp, xs, ys);
  }

void IGBox::Init(IWindow *w, int xp, int yp, int xs, int ys)  {
  xpos = xp; ypos = yp; xsize = xs; ysize = ys;
  Win = w;
  Img = None;
  parent=NULL;
  clickcallback = NULL;
  dragcallback = NULL;
  lastx = -1;
  lasty = -1;
  Create();
  }

void IGBox::Create()  {
  Window wind = Win->GetWindowBuffer();
  Display *disp = Win->GetDisplay();
  unsigned int p, b, g, gl, gd;
  if(Img != None)  XFreePixmap(disp, Img);
  Img = XCreatePixmap(disp, wind, xsize, ysize, DefaultDepth(disp, 0));
  GC gc = XCreateGC(disp, Img, 0, 0);

//  printf("Depth = %d\n", DefaultDepth(disp, 0));

  p = Win->GetPaperColor();
  b = Win->GetFGColor();
  g = Win->GetBGColor();
  gl = Win->GetLBGColor();
  gd = Win->GetDBGColor();

  XSetBackground(disp, gc, p);
  XSetForeground(disp, gc, gl);
  XFillRectangle(disp, Img, gc, 0, 0, xsize, ysize);

  XSetForeground(disp, gc, p);
  XFillRectangle(disp, Img, gc, 2, 2, xsize-4, ysize-4);

  XSetForeground(disp, gc, gd);
  XFillRectangle(disp, Img, gc, 0, 0, xsize-1, 2);
  XFillRectangle(disp, Img, gc, 0, 2, 2, ysize-3);
  XDrawPoint(disp, Img, gc, 0, ysize-1);
  XDrawPoint(disp, Img, gc, xsize-1, 0);

  Win->AddClaim(this, xpos, ypos, xsize, ysize);

  XFreeGC(disp, gc);
  Redraw();
  }

void IGBox::Rebuild()  {
  Redraw();
  }

void IGBox::Redraw()  {
  if(hidden) { Win->Rebuild(xpos, ypos, xsize, ysize); return; }
  XCopyArea(Win->GetDisplay(), Img, Win->GetWindowBuffer(), Win->GetGC(),
	0, 0, xsize, ysize, xpos, ypos);
  }

void IGBox::DrawPoint(int x, int y, int r, int g, int b) {
  unsigned int c = Win->GetRGBColor(r, g, b);
  GC gc = Win->GetGC();
  Display *Disp = Win->GetDisplay();
  XSetForeground(Disp, gc, c);
  XDrawPoint(Disp, Img, gc, x+2, y+2);
  }

void IGBox::DrawLine(int x1, int y1, int x2, int y2, int r, int g, int b) {
  unsigned int c = Win->GetRGBColor(r, g, b);
  GC gc = Win->GetGC();
  Display *Disp = Win->GetDisplay();
  XSetForeground(Disp, gc, c);
  int xd = (x2-x1), yd = (y2-y1);
  int xd2 = xd*xd, yd2 = yd*yd;
  int ctr;
  if(xd==0 && yd==0) XDrawPoint(Disp, Img, gc, x1, y1);
  if(xd2>yd2 && xd>=0) for(ctr=0; ctr<xd; ctr++)
    XDrawPoint(Disp, Img, gc, 2+x1+ctr, 2+y1+((ctr*yd)/xd));
  else if(xd2>yd2) for(ctr=0; ctr>xd; ctr--)
    XDrawPoint(Disp, Img, gc, 2+x1+ctr, 2+y1+((ctr*yd)/xd));
  else if(yd>=0) for(ctr=0; ctr<yd; ctr++)
    XDrawPoint(Disp, Img, gc, 2+x1+((ctr*xd)/yd), 2+y1+ctr);
  else for(ctr=0; ctr>yd; ctr--)
    XDrawPoint(Disp, Img, gc, 2+x1+((ctr*xd)/yd), 2+y1+ctr);
  }

void IGBox::DrawRect(int x1, int y1, int x2, int y2, int r, int g, int b) {
  }

void IGBox::FillRect(int xp, int yp, int xs, int ys, int r, int g, int b) {
  unsigned int c = Win->GetRGBColor(r, g, b);
  GC gc = Win->GetGC();
  Display *Disp = Win->GetDisplay();
  XSetForeground(Disp, gc, c);
  XFillRectangle(Disp, Img, gc, xp+2, yp+2, xs, ys);
  }

void IGBox::Resize(int xs, int ys)  {
  xsize = xs; ysize = ys;
  Create();
  }
        
void IGBox::Move(int xp, int yp)  {
  xpos = xp; ypos = yp;
  Create();
  }
 
void IGBox::MoveAndResize(int xp, int yp, int xs, int ys)  {
  xsize = xs; ysize = ys; xpos = xp; ypos = yp;
//  printf("MoveAndResize(%d, %d, %d, %d)\n", xp, yp, xs, ys);
  Create();
  }

int IGBox::Press(int b, int x, int y)  {
  lastx = x; lasty = y;
  return 1;
  }
 
int IGBox::Release(int b, int x, int y)  {
  if(lastx == x && lasty == y && clickcallback != NULL)
    (*clickcallback)(parent, this, x-2, y-2);
  else if(dragcallback != NULL)
    (*dragcallback)(parent, this, lastx, lasty, x-2, y-2);
  lastx = -1; lasty = -1;
  return 1;
  }

void IGBox::SetClickCallback(void (*cb)(IDoDad *, IDoDad *, int, int))  {
  clickcallback = cb;
  }
 
void IGBox::SetDragCallback(
	void (*cb)(IDoDad *, IDoDad *, int, int, int, int))  {
  dragcallback = cb;
  }
